1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "InterpKernelValue.hxx"
22 #include "InterpKernelFunction.hxx"
32 using namespace INTERP_KERNEL;
34 ValueDouble::ValueDouble():_data(std::numeric_limits<double>::max())
38 Value *ValueDouble::newInstance() const
40 return new ValueDouble;
43 ValueDouble::ValueDouble(double val):_data(val)
47 void ValueDouble::setDouble(double val)
52 void ValueDouble::setVarname(int fastPos, const std::string& var)
54 std::string msg("Error var : "); msg+=var; msg+=" not numeric : use another expression evaluator !";
55 throw INTERP_KERNEL::Exception(msg.c_str());
58 void ValueDouble::positive()
62 void ValueDouble::negate()
67 void ValueDouble::sqrt()
69 _data=std::sqrt(_data);
72 void ValueDouble::cos()
74 _data=std::cos(_data);
77 void ValueDouble::sin()
79 _data=std::sin(_data);
82 void ValueDouble::tan()
84 _data=std::tan(_data);
87 void ValueDouble::acos()
89 _data=std::acos(_data);
92 void ValueDouble::asin()
94 _data=std::asin(_data);
97 void ValueDouble::atan()
99 _data=std::atan(_data);
102 void ValueDouble::cosh()
104 _data=std::cosh(_data);
107 void ValueDouble::sinh()
109 _data=std::sinh(_data);
112 void ValueDouble::tanh()
114 _data=std::tanh(_data);
117 void ValueDouble::abs()
123 void ValueDouble::exp()
125 _data=std::exp(_data);
128 void ValueDouble::ln()
130 _data=std::log(_data);
133 void ValueDouble::log10()
135 _data=std::log10(_data);
138 Value *ValueDouble::plus(const Value *other) const
140 const ValueDouble *valC=checkSameType(other);
141 return new ValueDouble(_data+valC->_data);
144 Value *ValueDouble::minus(const Value *other) const
146 const ValueDouble *valC=checkSameType(other);
147 return new ValueDouble(_data-valC->_data);
150 Value *ValueDouble::mult(const Value *other) const
152 const ValueDouble *valC=checkSameType(other);
153 return new ValueDouble(_data*valC->_data);
156 Value *ValueDouble::div(const Value *other) const
158 const ValueDouble *valC=checkSameType(other);
159 return new ValueDouble(_data/valC->_data);
162 Value *ValueDouble::pow(const Value *other) const
164 const ValueDouble *valC=checkSameType(other);
165 return new ValueDouble(std::pow(_data,valC->_data));
168 Value *ValueDouble::max(const Value *other) const
170 const ValueDouble *valC=checkSameType(other);
171 return new ValueDouble(std::max(_data,valC->_data));
174 Value *ValueDouble::min(const Value *other) const
176 const ValueDouble *valC=checkSameType(other);
177 return new ValueDouble(std::min(_data,valC->_data));
180 Value *ValueDouble::greaterThan(const Value *other) const
182 const ValueDouble *valC=checkSameType(other);
183 return new ValueDouble(_data>valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max());
186 Value *ValueDouble::lowerThan(const Value *other) const
188 const ValueDouble *valC=checkSameType(other);
189 return new ValueDouble(_data<valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max());
192 Value *ValueDouble::ifFunc(const Value *the, const Value *els) const
194 const ValueDouble *theC=checkSameType(the);
195 const ValueDouble *elsC=checkSameType(els);
196 if(_data==std::numeric_limits<double>::max())
197 return new ValueDouble(theC->_data);
198 if(_data==-std::numeric_limits<double>::max())
199 return new ValueDouble(elsC->_data);
200 throw INTERP_KERNEL::Exception("ValueDouble::ifFunc : The fist element of ternary function if is not a binary op !");
203 const ValueDouble *ValueDouble::checkSameType(const Value *val)
205 const ValueDouble *valC=dynamic_cast<const ValueDouble *>(val);
207 throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (double with other type) !");
211 ValueUnit::ValueUnit()
215 Value *ValueUnit::newInstance() const
217 return new ValueUnit;
220 ValueUnit::ValueUnit(const DecompositionInUnitBase& unit):_data(unit)
224 void ValueUnit::setDouble(double val)
226 _data.tryToConvertInUnit(val);
229 void ValueUnit::setVarname(int fastPos, const std::string& var)
232 const short *projInBase=UnitDataBase::_uniqueMapForExpr.getInfoForUnit(var,add,mul);
233 _data.setInfo(projInBase,add,mul);
236 void ValueUnit::positive()
238 unsupportedOp(PositiveFunction::REPR);
241 void ValueUnit::negate()
246 void ValueUnit::sqrt()
248 unsupportedOp(SqrtFunction::REPR);
251 void ValueUnit::cos()
253 unsupportedOp(CosFunction::REPR);
256 void ValueUnit::sin()
258 unsupportedOp(SinFunction::REPR);
261 void ValueUnit::tan()
263 unsupportedOp(TanFunction::REPR);
266 void ValueUnit::acos()
268 unsupportedOp(ACosFunction::REPR);
271 void ValueUnit::asin()
273 unsupportedOp(ASinFunction::REPR);
276 void ValueUnit::atan()
278 unsupportedOp(ATanFunction::REPR);
281 void ValueUnit::cosh()
283 unsupportedOp(CoshFunction::REPR);
286 void ValueUnit::sinh()
288 unsupportedOp(SinhFunction::REPR);
291 void ValueUnit::tanh()
293 unsupportedOp(TanhFunction::REPR);
296 void ValueUnit::abs()
298 unsupportedOp(AbsFunction::REPR);
301 void ValueUnit::exp()
303 unsupportedOp(ExpFunction::REPR);
308 unsupportedOp(LnFunction::REPR);
311 void ValueUnit::log10()
313 unsupportedOp(Log10Function::REPR);
316 Value *ValueUnit::plus(const Value *other) const
318 unsupportedOp(PlusFunction::REPR);
322 Value *ValueUnit::minus(const Value *other) const
324 unsupportedOp(MinusFunction::REPR);
328 Value *ValueUnit::greaterThan(const Value *other) const
330 unsupportedOp(GreaterThanFunction::REPR);
334 Value *ValueUnit::lowerThan(const Value *other) const
336 unsupportedOp(LowerThanFunction::REPR);
340 Value *ValueUnit::ifFunc(const Value *the, const Value *els) const
342 unsupportedOp(IfFunction::REPR);
346 Value *ValueUnit::mult(const Value *other) const
348 const ValueUnit *valC=checkSameType(other);
349 DecompositionInUnitBase tmp=_data;
351 return new ValueUnit(tmp);
354 Value *ValueUnit::div(const Value *other) const
356 const ValueUnit *valC=checkSameType(other);
357 DecompositionInUnitBase tmp=_data;
359 return new ValueUnit(tmp);
362 Value *ValueUnit::pow(const Value *other) const
364 const ValueUnit *valC=checkSameType(other);
365 DecompositionInUnitBase tmp=_data;
367 return new ValueUnit(tmp);
370 Value *ValueUnit::max(const Value *other) const
372 unsupportedOp(MaxFunction::REPR);
376 Value *ValueUnit::min(const Value *other) const
378 unsupportedOp(MinFunction::REPR);
382 const ValueUnit *ValueUnit::checkSameType(const Value *val)
384 const ValueUnit *valC=dynamic_cast<const ValueUnit *>(val);
386 throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (Units with other type) !");
390 void ValueUnit::unsupportedOp(const char *type)
392 const char msg[]="Unsupported operation for units :";
393 std::string msgStr(msg);
395 throw INTERP_KERNEL::Exception(msgStr.c_str());
398 ValueDoubleExpr::ValueDoubleExpr(int szDestData, const double *srcData):_sz_dest_data(szDestData),_dest_data(new double[_sz_dest_data]),_src_data(srcData)
402 ValueDoubleExpr::~ValueDoubleExpr()
404 delete [] _dest_data;
407 Value *ValueDoubleExpr::newInstance() const
409 return new ValueDoubleExpr(_sz_dest_data,_src_data);
412 void ValueDoubleExpr::setDouble(double val)
414 std::fill(_dest_data,_dest_data+_sz_dest_data,val);
417 void ValueDoubleExpr::setVarname(int fastPos, const std::string& var)
420 std::copy(_src_data,_src_data+_sz_dest_data,_dest_data);
422 std::fill(_dest_data,_dest_data+_sz_dest_data,_src_data[fastPos]);
425 std::fill(_dest_data,_dest_data+_sz_dest_data,0.);
426 _dest_data[-7-fastPos]=1.;
430 void ValueDoubleExpr::positive()
434 void ValueDoubleExpr::negate()
436 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::negate<double>());
439 void ValueDoubleExpr::sqrt()
441 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.));
442 if(it!=_dest_data+_sz_dest_data)
443 throw INTERP_KERNEL::Exception("Trying to apply sqrt on < 0. value !");
444 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sqrt));
447 void ValueDoubleExpr::cos()
449 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::cos));
452 void ValueDoubleExpr::sin()
454 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sin));
457 void ValueDoubleExpr::tan()
459 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tan));
462 void ValueDoubleExpr::acos()
464 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),-1.));
465 if(it!=_dest_data+_sz_dest_data)
466 throw INTERP_KERNEL::Exception("Trying to apply acos on < 1. value !");
467 it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::greater<double>(),1.));
468 if(it!=_dest_data+_sz_dest_data)
469 throw INTERP_KERNEL::Exception("Trying to apply acos on > 1. value !");
470 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::acos));
473 void ValueDoubleExpr::asin()
475 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),-1.));
476 if(it!=_dest_data+_sz_dest_data)
477 throw INTERP_KERNEL::Exception("Trying to apply asin on < 1. value !");
478 it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::greater<double>(),1.));
479 if(it!=_dest_data+_sz_dest_data)
480 throw INTERP_KERNEL::Exception("Trying to apply asin on > 1. value !");
481 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::asin));
484 void ValueDoubleExpr::atan()
486 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::atan));
489 void ValueDoubleExpr::cosh()
491 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::cosh));
494 void ValueDoubleExpr::sinh()
496 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sinh));
499 void ValueDoubleExpr::tanh()
501 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tanh));
504 void ValueDoubleExpr::abs()
506 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(fabs));
509 void ValueDoubleExpr::exp()
511 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::exp));
514 void ValueDoubleExpr::ln()
516 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal<double>(),0.));
517 if(it!=_dest_data+_sz_dest_data)
518 throw INTERP_KERNEL::Exception("Trying to apply neperian/natural log on <= 0. value !");
519 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::log));
522 void ValueDoubleExpr::log10()
524 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal<double>(),0.));
525 if(it!=_dest_data+_sz_dest_data)
526 throw INTERP_KERNEL::Exception("Trying to apply log10 on <= 0. value !");
527 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::log10));
530 Value *ValueDoubleExpr::plus(const Value *other) const
532 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
533 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
534 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::plus<double>());
538 Value *ValueDoubleExpr::minus(const Value *other) const
540 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
541 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
542 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::minus<double>());
546 Value *ValueDoubleExpr::mult(const Value *other) const
548 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
549 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
550 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::multiplies<double>());
554 Value *ValueDoubleExpr::div(const Value *other) const
556 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
557 double *it=std::find(otherC->getData(),otherC->getData()+_sz_dest_data,0.);
558 if(it!=otherC->getData()+_sz_dest_data)
559 throw INTERP_KERNEL::Exception("Trying to operate division by 0. !");
560 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
561 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::divides<double>());
565 Value *ValueDoubleExpr::pow(const Value *other) const
567 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
568 double p=otherC->getData()[0];
569 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.));
570 if(it!=_dest_data+_sz_dest_data)
571 throw INTERP_KERNEL::Exception("Trying to operate pow(a,b) with a<0. !");
572 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
573 std::transform(_dest_data,_dest_data+_sz_dest_data,ret->getData(),std::bind2nd(std::ptr_fun<double,double,double>(std::pow),p));
577 Value *ValueDoubleExpr::max(const Value *other) const
579 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
580 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
581 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun<const double&, const double&, const double& >(std::max));
585 Value *ValueDoubleExpr::min(const Value *other) const
587 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
588 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
589 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun<const double&, const double&, const double& >(std::min));
593 Value *ValueDoubleExpr::greaterThan(const Value *other) const
595 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
596 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
597 for(int i=0;i<_sz_dest_data;i++)
598 if(_dest_data[i]<=otherC->getData()[i])
600 std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max());
603 std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max());
607 Value *ValueDoubleExpr::lowerThan(const Value *other) const
609 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
610 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
611 for(int i=0;i<_sz_dest_data;i++)
612 if(_dest_data[i]>=otherC->getData()[i])
614 std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max());
617 std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max());
621 Value *ValueDoubleExpr::ifFunc(const Value *the, const Value *els) const
623 const ValueDoubleExpr *theC=static_cast<const ValueDoubleExpr *>(the);
624 const ValueDoubleExpr *elsC=static_cast<const ValueDoubleExpr *>(els);
625 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
628 for(int i=0;i<_sz_dest_data && (okmax || okmin);i++)
630 okmax=_dest_data[i]==std::numeric_limits<double>::max();
631 okmin=_dest_data[i]==-std::numeric_limits<double>::max();
636 std::copy(theC->getData(),theC->getData()+_sz_dest_data,ret->getData());
638 std::copy(elsC->getData(),elsC->getData()+_sz_dest_data,ret->getData());
643 throw INTERP_KERNEL::Exception("ValueDoubleExpr::ifFunc : first parameter of ternary func is NOT a consequence of a boolean op !");