1 // Copyright (C) 2007-2015 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"
28 using namespace INTERP_KERNEL;
30 ValueDouble::ValueDouble():_data(std::numeric_limits<double>::max())
34 Value *ValueDouble::newInstance() const
36 return new ValueDouble;
39 ValueDouble::ValueDouble(double val):_data(val)
43 void ValueDouble::setDouble(double val)
48 void ValueDouble::setVarname(int fastPos, const std::string& var)
50 std::string msg("Error var : "); msg+=var; msg+=" not numeric : use another expression evaluator !";
51 throw INTERP_KERNEL::Exception(msg.c_str());
54 void ValueDouble::positive()
58 void ValueDouble::negate()
63 void ValueDouble::sqrt()
65 _data=std::sqrt(_data);
68 void ValueDouble::cos()
70 _data=std::cos(_data);
73 void ValueDouble::sin()
75 _data=std::sin(_data);
78 void ValueDouble::tan()
80 _data=std::tan(_data);
83 void ValueDouble::acos()
85 _data=std::acos(_data);
88 void ValueDouble::asin()
90 _data=std::asin(_data);
93 void ValueDouble::atan()
95 _data=std::atan(_data);
98 void ValueDouble::cosh()
100 _data=std::cosh(_data);
103 void ValueDouble::sinh()
105 _data=std::sinh(_data);
108 void ValueDouble::tanh()
110 _data=std::tanh(_data);
113 void ValueDouble::abs()
119 void ValueDouble::exp()
121 _data=std::exp(_data);
124 void ValueDouble::ln()
126 _data=std::log(_data);
129 void ValueDouble::log10()
131 _data=std::log10(_data);
134 Value *ValueDouble::plus(const Value *other) const
136 const ValueDouble *valC=checkSameType(other);
137 return new ValueDouble(_data+valC->_data);
140 Value *ValueDouble::minus(const Value *other) const
142 const ValueDouble *valC=checkSameType(other);
143 return new ValueDouble(_data-valC->_data);
146 Value *ValueDouble::mult(const Value *other) const
148 const ValueDouble *valC=checkSameType(other);
149 return new ValueDouble(_data*valC->_data);
152 Value *ValueDouble::div(const Value *other) const
154 const ValueDouble *valC=checkSameType(other);
155 return new ValueDouble(_data/valC->_data);
158 Value *ValueDouble::pow(const Value *other) const
160 const ValueDouble *valC=checkSameType(other);
161 return new ValueDouble(std::pow(_data,valC->_data));
164 Value *ValueDouble::max(const Value *other) const
166 const ValueDouble *valC=checkSameType(other);
167 return new ValueDouble(std::max(_data,valC->_data));
170 Value *ValueDouble::min(const Value *other) const
172 const ValueDouble *valC=checkSameType(other);
173 return new ValueDouble(std::min(_data,valC->_data));
176 Value *ValueDouble::greaterThan(const Value *other) const
178 const ValueDouble *valC=checkSameType(other);
179 return new ValueDouble(_data>valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max());
182 Value *ValueDouble::lowerThan(const Value *other) const
184 const ValueDouble *valC=checkSameType(other);
185 return new ValueDouble(_data<valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max());
188 Value *ValueDouble::ifFunc(const Value *the, const Value *els) const
190 const ValueDouble *theC=checkSameType(the);
191 const ValueDouble *elsC=checkSameType(els);
192 if(_data==std::numeric_limits<double>::max())
193 return new ValueDouble(theC->_data);
194 if(_data==-std::numeric_limits<double>::max())
195 return new ValueDouble(elsC->_data);
196 throw INTERP_KERNEL::Exception("ValueDouble::ifFunc : The fist element of ternary function if is not a binary op !");
199 const ValueDouble *ValueDouble::checkSameType(const Value *val)
201 const ValueDouble *valC=dynamic_cast<const ValueDouble *>(val);
203 throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (double with other type) !");
207 ValueUnit::ValueUnit()
211 Value *ValueUnit::newInstance() const
213 return new ValueUnit;
216 ValueUnit::ValueUnit(const DecompositionInUnitBase& unit):_data(unit)
220 void ValueUnit::setDouble(double val)
222 _data.tryToConvertInUnit(val);
225 void ValueUnit::setVarname(int fastPos, const std::string& var)
228 const short *projInBase=UnitDataBase::_uniqueMapForExpr.getInfoForUnit(var,add,mul);
229 _data.setInfo(projInBase,add,mul);
232 void ValueUnit::positive()
234 unsupportedOp(PositiveFunction::REPR);
237 void ValueUnit::negate()
242 void ValueUnit::sqrt()
244 unsupportedOp(SqrtFunction::REPR);
247 void ValueUnit::cos()
249 unsupportedOp(CosFunction::REPR);
252 void ValueUnit::sin()
254 unsupportedOp(SinFunction::REPR);
257 void ValueUnit::tan()
259 unsupportedOp(TanFunction::REPR);
262 void ValueUnit::acos()
264 unsupportedOp(ACosFunction::REPR);
267 void ValueUnit::asin()
269 unsupportedOp(ASinFunction::REPR);
272 void ValueUnit::atan()
274 unsupportedOp(ATanFunction::REPR);
277 void ValueUnit::cosh()
279 unsupportedOp(CoshFunction::REPR);
282 void ValueUnit::sinh()
284 unsupportedOp(SinhFunction::REPR);
287 void ValueUnit::tanh()
289 unsupportedOp(TanhFunction::REPR);
292 void ValueUnit::abs()
294 unsupportedOp(AbsFunction::REPR);
297 void ValueUnit::exp()
299 unsupportedOp(ExpFunction::REPR);
304 unsupportedOp(LnFunction::REPR);
307 void ValueUnit::log10()
309 unsupportedOp(Log10Function::REPR);
312 Value *ValueUnit::plus(const Value *other) const
314 unsupportedOp(PlusFunction::REPR);
318 Value *ValueUnit::minus(const Value *other) const
320 unsupportedOp(MinusFunction::REPR);
324 Value *ValueUnit::greaterThan(const Value *other) const
326 unsupportedOp(GreaterThanFunction::REPR);
330 Value *ValueUnit::lowerThan(const Value *other) const
332 unsupportedOp(LowerThanFunction::REPR);
336 Value *ValueUnit::ifFunc(const Value *the, const Value *els) const
338 unsupportedOp(IfFunction::REPR);
342 Value *ValueUnit::mult(const Value *other) const
344 const ValueUnit *valC=checkSameType(other);
345 DecompositionInUnitBase tmp=_data;
347 return new ValueUnit(tmp);
350 Value *ValueUnit::div(const Value *other) const
352 const ValueUnit *valC=checkSameType(other);
353 DecompositionInUnitBase tmp=_data;
355 return new ValueUnit(tmp);
358 Value *ValueUnit::pow(const Value *other) const
360 const ValueUnit *valC=checkSameType(other);
361 DecompositionInUnitBase tmp=_data;
363 return new ValueUnit(tmp);
366 Value *ValueUnit::max(const Value *other) const
368 unsupportedOp(MaxFunction::REPR);
372 Value *ValueUnit::min(const Value *other) const
374 unsupportedOp(MinFunction::REPR);
378 const ValueUnit *ValueUnit::checkSameType(const Value *val)
380 const ValueUnit *valC=dynamic_cast<const ValueUnit *>(val);
382 throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (Units with other type) !");
386 void ValueUnit::unsupportedOp(const char *type)
388 const char msg[]="Unsupported operation for units :";
389 std::string msgStr(msg);
391 throw INTERP_KERNEL::Exception(msgStr.c_str());
394 ValueDoubleExpr::ValueDoubleExpr(int szDestData, const double *srcData):_sz_dest_data(szDestData),_dest_data(new double[_sz_dest_data]),_src_data(srcData)
398 ValueDoubleExpr::~ValueDoubleExpr()
400 delete [] _dest_data;
403 Value *ValueDoubleExpr::newInstance() const
405 return new ValueDoubleExpr(_sz_dest_data,_src_data);
408 void ValueDoubleExpr::setDouble(double val)
410 std::fill(_dest_data,_dest_data+_sz_dest_data,val);
413 void ValueDoubleExpr::setVarname(int fastPos, const std::string& var)
416 std::copy(_src_data,_src_data+_sz_dest_data,_dest_data);
418 std::fill(_dest_data,_dest_data+_sz_dest_data,_src_data[fastPos]);
421 std::fill(_dest_data,_dest_data+_sz_dest_data,0.);
422 _dest_data[-7-fastPos]=1.;
426 void ValueDoubleExpr::positive()
430 void ValueDoubleExpr::negate()
432 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::negate<double>());
435 void ValueDoubleExpr::sqrt()
437 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.));
438 if(it!=_dest_data+_sz_dest_data)
439 throw INTERP_KERNEL::Exception("Trying to apply sqrt on < 0. value !");
440 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sqrt));
443 void ValueDoubleExpr::cos()
445 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::cos));
448 void ValueDoubleExpr::sin()
450 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sin));
453 void ValueDoubleExpr::tan()
455 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tan));
458 void ValueDoubleExpr::acos()
460 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),-1.));
461 if(it!=_dest_data+_sz_dest_data)
462 throw INTERP_KERNEL::Exception("Trying to apply acos on < 1. value !");
463 it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::greater<double>(),1.));
464 if(it!=_dest_data+_sz_dest_data)
465 throw INTERP_KERNEL::Exception("Trying to apply acos on > 1. value !");
466 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::acos));
469 void ValueDoubleExpr::asin()
471 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),-1.));
472 if(it!=_dest_data+_sz_dest_data)
473 throw INTERP_KERNEL::Exception("Trying to apply asin on < 1. value !");
474 it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::greater<double>(),1.));
475 if(it!=_dest_data+_sz_dest_data)
476 throw INTERP_KERNEL::Exception("Trying to apply asin on > 1. value !");
477 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::asin));
480 void ValueDoubleExpr::atan()
482 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::atan));
485 void ValueDoubleExpr::cosh()
487 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::cosh));
490 void ValueDoubleExpr::sinh()
492 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sinh));
495 void ValueDoubleExpr::tanh()
497 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tanh));
500 void ValueDoubleExpr::abs()
502 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(fabs));
505 void ValueDoubleExpr::exp()
507 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::exp));
510 void ValueDoubleExpr::ln()
512 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal<double>(),0.));
513 if(it!=_dest_data+_sz_dest_data)
514 throw INTERP_KERNEL::Exception("Trying to apply neperian/natural log on <= 0. value !");
515 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::log));
518 void ValueDoubleExpr::log10()
520 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal<double>(),0.));
521 if(it!=_dest_data+_sz_dest_data)
522 throw INTERP_KERNEL::Exception("Trying to apply log10 on <= 0. value !");
523 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::log10));
526 Value *ValueDoubleExpr::plus(const Value *other) const
528 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
529 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
530 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::plus<double>());
534 Value *ValueDoubleExpr::minus(const Value *other) const
536 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
537 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
538 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::minus<double>());
542 Value *ValueDoubleExpr::mult(const Value *other) const
544 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
545 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
546 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::multiplies<double>());
550 Value *ValueDoubleExpr::div(const Value *other) const
552 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
553 double *it=std::find(otherC->getData(),otherC->getData()+_sz_dest_data,0.);
554 if(it!=otherC->getData()+_sz_dest_data)
555 throw INTERP_KERNEL::Exception("Trying to operate division by 0. !");
556 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
557 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::divides<double>());
561 Value *ValueDoubleExpr::pow(const Value *other) const
563 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
564 double p=otherC->getData()[0];
565 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.));
566 if(it!=_dest_data+_sz_dest_data)
567 throw INTERP_KERNEL::Exception("Trying to operate pow(a,b) with a<0. !");
568 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
569 std::transform(_dest_data,_dest_data+_sz_dest_data,ret->getData(),std::bind2nd(std::ptr_fun<double,double,double>(std::pow),p));
573 Value *ValueDoubleExpr::max(const Value *other) const
575 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
576 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
577 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun<const double&, const double&, const double& >(std::max));
581 Value *ValueDoubleExpr::min(const Value *other) const
583 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
584 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
585 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun<const double&, const double&, const double& >(std::min));
589 Value *ValueDoubleExpr::greaterThan(const Value *other) const
591 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
592 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
593 for(int i=0;i<_sz_dest_data;i++)
594 if(_dest_data[i]<=otherC->getData()[i])
596 std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max());
599 std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max());
603 Value *ValueDoubleExpr::lowerThan(const Value *other) const
605 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
606 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
607 for(int i=0;i<_sz_dest_data;i++)
608 if(_dest_data[i]>=otherC->getData()[i])
610 std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max());
613 std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max());
617 Value *ValueDoubleExpr::ifFunc(const Value *the, const Value *els) const
619 const ValueDoubleExpr *theC=static_cast<const ValueDoubleExpr *>(the);
620 const ValueDoubleExpr *elsC=static_cast<const ValueDoubleExpr *>(els);
621 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
624 for(int i=0;i<_sz_dest_data && (okmax || okmin);i++)
626 okmax=_dest_data[i]==std::numeric_limits<double>::max();
627 okmin=_dest_data[i]==-std::numeric_limits<double>::max();
632 std::copy(theC->getData(),theC->getData()+_sz_dest_data,ret->getData());
634 std::copy(elsC->getData(),elsC->getData()+_sz_dest_data,ret->getData());
639 throw INTERP_KERNEL::Exception("ValueDoubleExpr::ifFunc : first parameter of ternary func is NOT a consequence of a boolean op !");