1 // Copyright (C) 2007-2012 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.
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) throw(INTERP_KERNEL::Exception)
48 void ValueDouble::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
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() throw(INTERP_KERNEL::Exception)
58 void ValueDouble::negate() throw(INTERP_KERNEL::Exception)
63 void ValueDouble::sqrt() throw(INTERP_KERNEL::Exception)
65 _data=std::sqrt(_data);
68 void ValueDouble::cos() throw(INTERP_KERNEL::Exception)
70 _data=std::cos(_data);
73 void ValueDouble::sin() throw(INTERP_KERNEL::Exception)
75 _data=std::sin(_data);
78 void ValueDouble::tan() throw(INTERP_KERNEL::Exception)
80 _data=std::tan(_data);
83 void ValueDouble::acos() throw(INTERP_KERNEL::Exception)
85 _data=std::acos(_data);
88 void ValueDouble::asin() throw(INTERP_KERNEL::Exception)
90 _data=std::asin(_data);
93 void ValueDouble::atan() throw(INTERP_KERNEL::Exception)
95 _data=std::atan(_data);
98 void ValueDouble::cosh() throw(INTERP_KERNEL::Exception)
100 _data=std::cosh(_data);
103 void ValueDouble::sinh() throw(INTERP_KERNEL::Exception)
105 _data=std::sinh(_data);
108 void ValueDouble::tanh() throw(INTERP_KERNEL::Exception)
110 _data=std::tanh(_data);
113 void ValueDouble::abs() throw(INTERP_KERNEL::Exception)
119 void ValueDouble::exp() throw(INTERP_KERNEL::Exception)
121 _data=std::exp(_data);
124 void ValueDouble::ln() throw(INTERP_KERNEL::Exception)
126 _data=std::log(_data);
129 void ValueDouble::log10() throw(INTERP_KERNEL::Exception)
131 _data=std::log10(_data);
134 Value *ValueDouble::plus(const Value *other) const throw(INTERP_KERNEL::Exception)
136 const ValueDouble *valC=checkSameType(other);
137 return new ValueDouble(_data+valC->_data);
140 Value *ValueDouble::minus(const Value *other) const throw(INTERP_KERNEL::Exception)
142 const ValueDouble *valC=checkSameType(other);
143 return new ValueDouble(_data-valC->_data);
146 Value *ValueDouble::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
148 const ValueDouble *valC=checkSameType(other);
149 return new ValueDouble(_data*valC->_data);
152 Value *ValueDouble::div(const Value *other) const throw(INTERP_KERNEL::Exception)
154 const ValueDouble *valC=checkSameType(other);
155 return new ValueDouble(_data/valC->_data);
158 Value *ValueDouble::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
160 const ValueDouble *valC=checkSameType(other);
161 return new ValueDouble(std::pow(_data,valC->_data));
164 Value *ValueDouble::max(const Value *other) const throw(INTERP_KERNEL::Exception)
166 const ValueDouble *valC=checkSameType(other);
167 return new ValueDouble(std::max(_data,valC->_data));
170 Value *ValueDouble::min(const Value *other) const throw(INTERP_KERNEL::Exception)
172 const ValueDouble *valC=checkSameType(other);
173 return new ValueDouble(std::min(_data,valC->_data));
176 Value *ValueDouble::greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception)
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 throw(INTERP_KERNEL::Exception)
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 throw(INTERP_KERNEL::Exception)
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) throw(INTERP_KERNEL::Exception)
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) throw(INTERP_KERNEL::Exception)
222 _data.tryToConvertInUnit(val);
225 void ValueUnit::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
228 const short *projInBase=UnitDataBase::_uniqueMapForExpr.getInfoForUnit(var,add,mul);
229 _data.setInfo(projInBase,add,mul);
232 void ValueUnit::positive() throw(INTERP_KERNEL::Exception)
234 unsupportedOp(PositiveFunction::REPR);
237 void ValueUnit::negate() throw(INTERP_KERNEL::Exception)
242 void ValueUnit::sqrt() throw(INTERP_KERNEL::Exception)
244 unsupportedOp(SqrtFunction::REPR);
247 void ValueUnit::cos() throw(INTERP_KERNEL::Exception)
249 unsupportedOp(CosFunction::REPR);
252 void ValueUnit::sin() throw(INTERP_KERNEL::Exception)
254 unsupportedOp(SinFunction::REPR);
257 void ValueUnit::tan() throw(INTERP_KERNEL::Exception)
259 unsupportedOp(TanFunction::REPR);
262 void ValueUnit::acos() throw(INTERP_KERNEL::Exception)
264 unsupportedOp(ACosFunction::REPR);
267 void ValueUnit::asin() throw(INTERP_KERNEL::Exception)
269 unsupportedOp(ASinFunction::REPR);
272 void ValueUnit::atan() throw(INTERP_KERNEL::Exception)
274 unsupportedOp(ATanFunction::REPR);
277 void ValueUnit::cosh() throw(INTERP_KERNEL::Exception)
279 unsupportedOp(CoshFunction::REPR);
282 void ValueUnit::sinh() throw(INTERP_KERNEL::Exception)
284 unsupportedOp(SinhFunction::REPR);
287 void ValueUnit::tanh() throw(INTERP_KERNEL::Exception)
289 unsupportedOp(TanhFunction::REPR);
292 void ValueUnit::abs() throw(INTERP_KERNEL::Exception)
294 unsupportedOp(AbsFunction::REPR);
297 void ValueUnit::exp() throw(INTERP_KERNEL::Exception)
299 unsupportedOp(ExpFunction::REPR);
302 void ValueUnit::ln() throw(INTERP_KERNEL::Exception)
304 unsupportedOp(LnFunction::REPR);
307 void ValueUnit::log10() throw(INTERP_KERNEL::Exception)
309 unsupportedOp(Log10Function::REPR);
312 Value *ValueUnit::plus(const Value *other) const throw(INTERP_KERNEL::Exception)
314 unsupportedOp(PlusFunction::REPR);
318 Value *ValueUnit::minus(const Value *other) const throw(INTERP_KERNEL::Exception)
320 unsupportedOp(MinusFunction::REPR);
324 Value *ValueUnit::greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception)
326 unsupportedOp(GreaterThanFunction::REPR);
330 Value *ValueUnit::lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception)
332 unsupportedOp(LowerThanFunction::REPR);
336 Value *ValueUnit::ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception)
338 unsupportedOp(IfFunction::REPR);
342 Value *ValueUnit::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
344 const ValueUnit *valC=checkSameType(other);
345 DecompositionInUnitBase tmp=_data;
347 return new ValueUnit(tmp);
350 Value *ValueUnit::div(const Value *other) const throw(INTERP_KERNEL::Exception)
352 const ValueUnit *valC=checkSameType(other);
353 DecompositionInUnitBase tmp=_data;
355 return new ValueUnit(tmp);
358 Value *ValueUnit::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
360 const ValueUnit *valC=checkSameType(other);
361 DecompositionInUnitBase tmp=_data;
363 return new ValueUnit(tmp);
366 Value *ValueUnit::max(const Value *other) const throw(INTERP_KERNEL::Exception)
368 unsupportedOp(MaxFunction::REPR);
372 Value *ValueUnit::min(const Value *other) const throw(INTERP_KERNEL::Exception)
374 unsupportedOp(MinFunction::REPR);
378 const ValueUnit *ValueUnit::checkSameType(const Value *val) throw(INTERP_KERNEL::Exception)
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) throw(INTERP_KERNEL::Exception)
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) throw(INTERP_KERNEL::Exception)
410 std::fill(_dest_data,_dest_data+_sz_dest_data,val);
413 void ValueDoubleExpr::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
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() throw(INTERP_KERNEL::Exception)
430 void ValueDoubleExpr::negate() throw(INTERP_KERNEL::Exception)
432 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::negate<double>());
435 void ValueDoubleExpr::sqrt() throw(INTERP_KERNEL::Exception)
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() throw(INTERP_KERNEL::Exception)
445 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::cos));
448 void ValueDoubleExpr::sin() throw(INTERP_KERNEL::Exception)
450 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sin));
453 void ValueDoubleExpr::tan() throw(INTERP_KERNEL::Exception)
455 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tan));
458 void ValueDoubleExpr::acos() throw(INTERP_KERNEL::Exception)
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() throw(INTERP_KERNEL::Exception)
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() throw(INTERP_KERNEL::Exception)
482 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::atan));
485 void ValueDoubleExpr::cosh() throw(INTERP_KERNEL::Exception)
487 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::cosh));
490 void ValueDoubleExpr::sinh() throw(INTERP_KERNEL::Exception)
492 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sinh));
495 void ValueDoubleExpr::tanh() throw(INTERP_KERNEL::Exception)
497 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tanh));
500 void ValueDoubleExpr::abs() throw(INTERP_KERNEL::Exception)
502 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(fabs));
505 void ValueDoubleExpr::exp() throw(INTERP_KERNEL::Exception)
507 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::exp));
510 void ValueDoubleExpr::ln() throw(INTERP_KERNEL::Exception)
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() throw(INTERP_KERNEL::Exception)
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 throw(INTERP_KERNEL::Exception)
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 throw(INTERP_KERNEL::Exception)
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 throw(INTERP_KERNEL::Exception)
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 throw(INTERP_KERNEL::Exception)
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 throw(INTERP_KERNEL::Exception)
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 throw(INTERP_KERNEL::Exception)
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 throw(INTERP_KERNEL::Exception)
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 throw(INTERP_KERNEL::Exception)
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 throw(INTERP_KERNEL::Exception)
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 throw(INTERP_KERNEL::Exception)
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 !");