1 // Copyright (C) 2007-2024 CEA, EDF
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"
29 using namespace INTERP_KERNEL;
31 ValueDouble::ValueDouble():_data(std::numeric_limits<double>::max())
35 Value *ValueDouble::newInstance() const
37 return new ValueDouble;
40 ValueDouble::ValueDouble(double val):_data(val)
44 void ValueDouble::setDouble(double val)
49 void ValueDouble::setVarname(int fastPos, const std::string& var)
51 std::string msg("Error var : "); msg+=var; msg+=" not numeric : use another expression evaluator !";
52 throw INTERP_KERNEL::Exception(msg.c_str());
55 void ValueDouble::positive()
59 void ValueDouble::negate()
64 void ValueDouble::sqrt()
66 _data=std::sqrt(_data);
69 void ValueDouble::cos()
71 _data=std::cos(_data);
74 void ValueDouble::sin()
76 _data=std::sin(_data);
79 void ValueDouble::tan()
81 _data=std::tan(_data);
84 void ValueDouble::acos()
86 _data=std::acos(_data);
89 void ValueDouble::asin()
91 _data=std::asin(_data);
94 void ValueDouble::atan()
96 _data=std::atan(_data);
99 void ValueDouble::cosh()
101 _data=std::cosh(_data);
104 void ValueDouble::sinh()
106 _data=std::sinh(_data);
109 void ValueDouble::tanh()
111 _data=std::tanh(_data);
114 void ValueDouble::abs()
120 void ValueDouble::exp()
122 _data=std::exp(_data);
125 void ValueDouble::ln()
127 _data=std::log(_data);
130 void ValueDouble::log10()
132 _data=std::log10(_data);
135 Value *ValueDouble::plus(const Value *other) const
137 const ValueDouble *valC=checkSameType(other);
138 return new ValueDouble(_data+valC->_data);
141 Value *ValueDouble::minus(const Value *other) const
143 const ValueDouble *valC=checkSameType(other);
144 return new ValueDouble(_data-valC->_data);
147 Value *ValueDouble::mult(const Value *other) const
149 const ValueDouble *valC=checkSameType(other);
150 return new ValueDouble(_data*valC->_data);
153 Value *ValueDouble::div(const Value *other) const
155 const ValueDouble *valC=checkSameType(other);
156 return new ValueDouble(_data/valC->_data);
159 Value *ValueDouble::pow(const Value *other) const
161 const ValueDouble *valC=checkSameType(other);
162 return new ValueDouble(std::pow(_data,valC->_data));
165 Value *ValueDouble::max(const Value *other) const
167 const ValueDouble *valC=checkSameType(other);
168 return new ValueDouble(std::max(_data,valC->_data));
171 Value *ValueDouble::min(const Value *other) const
173 const ValueDouble *valC=checkSameType(other);
174 return new ValueDouble(std::min(_data,valC->_data));
177 Value *ValueDouble::greaterThan(const Value *other) const
179 const ValueDouble *valC=checkSameType(other);
180 return new ValueDouble(_data>valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max());
183 Value *ValueDouble::lowerThan(const Value *other) const
185 const ValueDouble *valC=checkSameType(other);
186 return new ValueDouble(_data<valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max());
189 Value *ValueDouble::ifFunc(const Value *the, const Value *els) const
191 const ValueDouble *theC=checkSameType(the);
192 const ValueDouble *elsC=checkSameType(els);
193 if(_data==std::numeric_limits<double>::max())
194 return new ValueDouble(theC->_data);
195 if(_data==-std::numeric_limits<double>::max())
196 return new ValueDouble(elsC->_data);
197 throw INTERP_KERNEL::Exception("ValueDouble::ifFunc : The fist element of ternary function if is not a binary op !");
200 const ValueDouble *ValueDouble::checkSameType(const Value *val)
202 const ValueDouble *valC=dynamic_cast<const ValueDouble *>(val);
204 throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (double with other type) !");
208 ValueUnit::ValueUnit()
212 Value *ValueUnit::newInstance() const
214 return new ValueUnit;
217 ValueUnit::ValueUnit(const DecompositionInUnitBase& unit):_data(unit)
221 void ValueUnit::setDouble(double val)
223 _data.tryToConvertInUnit(val);
226 void ValueUnit::setVarname(int fastPos, const std::string& var)
229 const short *projInBase=UnitDataBase::GetUniqueMapForExpr().getInfoForUnit(var,add,mul);
230 _data.setInfo(projInBase,add,mul);
233 void ValueUnit::positive()
235 unsupportedOp(PositiveFunction::REPR);
238 void ValueUnit::negate()
243 void ValueUnit::sqrt()
245 unsupportedOp(SqrtFunction::REPR);
248 void ValueUnit::cos()
250 unsupportedOp(CosFunction::REPR);
253 void ValueUnit::sin()
255 unsupportedOp(SinFunction::REPR);
258 void ValueUnit::tan()
260 unsupportedOp(TanFunction::REPR);
263 void ValueUnit::acos()
265 unsupportedOp(ACosFunction::REPR);
268 void ValueUnit::asin()
270 unsupportedOp(ASinFunction::REPR);
273 void ValueUnit::atan()
275 unsupportedOp(ATanFunction::REPR);
278 void ValueUnit::cosh()
280 unsupportedOp(CoshFunction::REPR);
283 void ValueUnit::sinh()
285 unsupportedOp(SinhFunction::REPR);
288 void ValueUnit::tanh()
290 unsupportedOp(TanhFunction::REPR);
293 void ValueUnit::abs()
295 unsupportedOp(AbsFunction::REPR);
298 void ValueUnit::exp()
300 unsupportedOp(ExpFunction::REPR);
305 unsupportedOp(LnFunction::REPR);
308 void ValueUnit::log10()
310 unsupportedOp(Log10Function::REPR);
313 Value *ValueUnit::plus(const Value *other) const
315 unsupportedOp(PlusFunction::REPR);
319 Value *ValueUnit::minus(const Value *other) const
321 unsupportedOp(MinusFunction::REPR);
325 Value *ValueUnit::greaterThan(const Value *other) const
327 unsupportedOp(GreaterThanFunction::REPR);
331 Value *ValueUnit::lowerThan(const Value *other) const
333 unsupportedOp(LowerThanFunction::REPR);
337 Value *ValueUnit::ifFunc(const Value *the, const Value *els) const
339 unsupportedOp(IfFunction::REPR);
343 Value *ValueUnit::mult(const Value *other) const
345 const ValueUnit *valC=checkSameType(other);
346 DecompositionInUnitBase tmp=_data;
348 return new ValueUnit(tmp);
351 Value *ValueUnit::div(const Value *other) const
353 const ValueUnit *valC=checkSameType(other);
354 DecompositionInUnitBase tmp=_data;
356 return new ValueUnit(tmp);
359 Value *ValueUnit::pow(const Value *other) const
361 const ValueUnit *valC=checkSameType(other);
362 DecompositionInUnitBase tmp=_data;
364 return new ValueUnit(tmp);
367 Value *ValueUnit::max(const Value *other) const
369 unsupportedOp(MaxFunction::REPR);
373 Value *ValueUnit::min(const Value *other) const
375 unsupportedOp(MinFunction::REPR);
379 const ValueUnit *ValueUnit::checkSameType(const Value *val)
381 const ValueUnit *valC=dynamic_cast<const ValueUnit *>(val);
383 throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (Units with other type) !");
387 void ValueUnit::unsupportedOp(const char *type)
389 const char msg[]="Unsupported operation for units :";
390 std::string msgStr(msg);
392 throw INTERP_KERNEL::Exception(msgStr.c_str());
395 ValueDoubleExpr::ValueDoubleExpr(int szDestData, const double *srcData):_sz_dest_data(szDestData),_dest_data(new double[_sz_dest_data]),_src_data(srcData)
399 ValueDoubleExpr::~ValueDoubleExpr()
401 delete [] _dest_data;
404 Value *ValueDoubleExpr::newInstance() const
406 return new ValueDoubleExpr(_sz_dest_data,_src_data);
409 void ValueDoubleExpr::setDouble(double val)
411 std::fill(_dest_data,_dest_data+_sz_dest_data,val);
414 void ValueDoubleExpr::setVarname(int fastPos, const std::string& var)
417 std::copy(_src_data,_src_data+_sz_dest_data,_dest_data);
419 std::fill(_dest_data,_dest_data+_sz_dest_data,_src_data[fastPos]);
422 std::fill(_dest_data,_dest_data+_sz_dest_data,0.);
423 _dest_data[-7-fastPos]=1.;
427 void ValueDoubleExpr::positive()
431 void ValueDoubleExpr::negate()
433 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::negate<double>());
436 void ValueDoubleExpr::sqrt()
438 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind(std::less<double>(),std::placeholders::_1,0.));
439 if(it!=_dest_data+_sz_dest_data)
440 throw INTERP_KERNEL::Exception("Trying to apply sqrt on < 0. value !");
441 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::sqrt(c);});
444 void ValueDoubleExpr::cos()
446 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::cos(c);});
449 void ValueDoubleExpr::sin()
451 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::sin(c);});
454 void ValueDoubleExpr::tan()
456 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::tan(c);});
459 void ValueDoubleExpr::acos()
461 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind(std::less<double>(),std::placeholders::_1,-1.));
462 if(it!=_dest_data+_sz_dest_data)
463 throw INTERP_KERNEL::Exception("Trying to apply acos on < 1. value !");
464 it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind(std::greater<double>(),std::placeholders::_1,1.));
465 if(it!=_dest_data+_sz_dest_data)
466 throw INTERP_KERNEL::Exception("Trying to apply acos on > 1. value !");
467 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::acos(c);});
470 void ValueDoubleExpr::asin()
472 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind(std::less<double>(),std::placeholders::_1,-1.));
473 if(it!=_dest_data+_sz_dest_data)
474 throw INTERP_KERNEL::Exception("Trying to apply asin on < 1. value !");
475 it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind(std::greater<double>(),std::placeholders::_1,1.));
476 if(it!=_dest_data+_sz_dest_data)
477 throw INTERP_KERNEL::Exception("Trying to apply asin on > 1. value !");
478 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::asin(c);});
481 void ValueDoubleExpr::atan()
483 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::atan(c);});
486 void ValueDoubleExpr::cosh()
488 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::cosh(c);});
491 void ValueDoubleExpr::sinh()
493 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::sinh(c);});
496 void ValueDoubleExpr::tanh()
498 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::tanh(c);});
501 void ValueDoubleExpr::abs()
503 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::fabs(c);});
506 void ValueDoubleExpr::exp()
508 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::exp(c);});
511 void ValueDoubleExpr::ln()
513 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind(std::less_equal<double>(),std::placeholders::_1,0.));
514 if(it!=_dest_data+_sz_dest_data)
515 throw INTERP_KERNEL::Exception("Trying to apply neperian/natural log on <= 0. value !");
516 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::log(c);});
519 void ValueDoubleExpr::log10()
521 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind(std::less_equal<double>(),std::placeholders::_1,0.));
522 if(it!=_dest_data+_sz_dest_data)
523 throw INTERP_KERNEL::Exception("Trying to apply log10 on <= 0. value !");
524 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,[](double c){return std::log10(c);});
527 Value *ValueDoubleExpr::plus(const Value *other) const
529 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
530 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
531 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::plus<double>());
535 Value *ValueDoubleExpr::minus(const Value *other) const
537 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
538 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
539 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::minus<double>());
543 Value *ValueDoubleExpr::mult(const Value *other) const
545 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
546 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
547 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::multiplies<double>());
551 Value *ValueDoubleExpr::div(const Value *other) const
553 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
554 double *it=std::find(otherC->getData(),otherC->getData()+_sz_dest_data,0.);
555 if(it!=otherC->getData()+_sz_dest_data)
556 throw INTERP_KERNEL::Exception("Trying to operate division by 0. !");
557 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
558 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::divides<double>());
562 Value *ValueDoubleExpr::pow(const Value *other) const
564 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
565 double p=otherC->getData()[0];
566 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind(std::less<double>(),std::placeholders::_1,0.));
567 if(it!=_dest_data+_sz_dest_data)
568 throw INTERP_KERNEL::Exception("Trying to operate pow(a,b) with a<0. !");
569 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
570 std::transform(_dest_data,_dest_data+_sz_dest_data,ret->getData(),std::bind([](double x, double y){return std::pow(x,y);},std::placeholders::_1,p));
574 Value *ValueDoubleExpr::max(const Value *other) const
576 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
577 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
578 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),[](const double& x, const double& y){return std::max(x,y);});
582 Value *ValueDoubleExpr::min(const Value *other) const
584 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
585 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
586 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),[](const double& x, const double& y){return std::min(x,y);});
590 Value *ValueDoubleExpr::greaterThan(const Value *other) const
592 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
593 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
594 for(int i=0;i<_sz_dest_data;i++)
595 if(_dest_data[i]<=otherC->getData()[i])
597 std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max());
600 std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max());
604 Value *ValueDoubleExpr::lowerThan(const Value *other) const
606 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
607 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
608 for(int i=0;i<_sz_dest_data;i++)
609 if(_dest_data[i]>=otherC->getData()[i])
611 std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max());
614 std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max());
618 Value *ValueDoubleExpr::ifFunc(const Value *the, const Value *els) const
620 const ValueDoubleExpr *theC=static_cast<const ValueDoubleExpr *>(the);
621 const ValueDoubleExpr *elsC=static_cast<const ValueDoubleExpr *>(els);
622 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
625 for(int i=0;i<_sz_dest_data && (okmax || okmin);i++)
627 okmax=_dest_data[i]==std::numeric_limits<double>::max();
628 okmin=_dest_data[i]==-std::numeric_limits<double>::max();
633 std::copy(theC->getData(),theC->getData()+_sz_dest_data,ret->getData());
635 std::copy(elsC->getData(),elsC->getData()+_sz_dest_data,ret->getData());
640 throw INTERP_KERNEL::Exception("ValueDoubleExpr::ifFunc : first parameter of ternary func is NOT a consequence of a boolean op !");