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::abs() throw(INTERP_KERNEL::Exception)
89 void ValueDouble::exp() throw(INTERP_KERNEL::Exception)
91 _data=std::exp(_data);
94 void ValueDouble::ln() throw(INTERP_KERNEL::Exception)
96 _data=std::log(_data);
99 void ValueDouble::log10() throw(INTERP_KERNEL::Exception)
101 _data=std::log10(_data);
104 Value *ValueDouble::plus(const Value *other) const throw(INTERP_KERNEL::Exception)
106 const ValueDouble *valC=checkSameType(other);
107 return new ValueDouble(_data+valC->_data);
110 Value *ValueDouble::minus(const Value *other) const throw(INTERP_KERNEL::Exception)
112 const ValueDouble *valC=checkSameType(other);
113 return new ValueDouble(_data-valC->_data);
116 Value *ValueDouble::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
118 const ValueDouble *valC=checkSameType(other);
119 return new ValueDouble(_data*valC->_data);
122 Value *ValueDouble::div(const Value *other) const throw(INTERP_KERNEL::Exception)
124 const ValueDouble *valC=checkSameType(other);
125 return new ValueDouble(_data/valC->_data);
128 Value *ValueDouble::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
130 const ValueDouble *valC=checkSameType(other);
131 return new ValueDouble(std::pow(_data,valC->_data));
134 Value *ValueDouble::max(const Value *other) const throw(INTERP_KERNEL::Exception)
136 const ValueDouble *valC=checkSameType(other);
137 return new ValueDouble(std::max(_data,valC->_data));
140 Value *ValueDouble::min(const Value *other) const throw(INTERP_KERNEL::Exception)
142 const ValueDouble *valC=checkSameType(other);
143 return new ValueDouble(std::min(_data,valC->_data));
146 Value *ValueDouble::greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception)
148 const ValueDouble *valC=checkSameType(other);
149 return new ValueDouble(_data>valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max());
152 Value *ValueDouble::lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception)
154 const ValueDouble *valC=checkSameType(other);
155 return new ValueDouble(_data<valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max());
158 Value *ValueDouble::ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception)
160 const ValueDouble *theC=checkSameType(the);
161 const ValueDouble *elsC=checkSameType(els);
162 if(_data==std::numeric_limits<double>::max())
163 return new ValueDouble(theC->_data);
164 if(_data==-std::numeric_limits<double>::max())
165 return new ValueDouble(elsC->_data);
166 throw INTERP_KERNEL::Exception("ValueDouble::ifFunc : The fist element of ternary function if is not a binary op !");
169 const ValueDouble *ValueDouble::checkSameType(const Value *val) throw(INTERP_KERNEL::Exception)
171 const ValueDouble *valC=dynamic_cast<const ValueDouble *>(val);
173 throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (double with other type) !");
177 ValueUnit::ValueUnit()
181 Value *ValueUnit::newInstance() const
183 return new ValueUnit;
186 ValueUnit::ValueUnit(const DecompositionInUnitBase& unit):_data(unit)
190 void ValueUnit::setDouble(double val) throw(INTERP_KERNEL::Exception)
192 _data.tryToConvertInUnit(val);
195 void ValueUnit::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
198 const short *projInBase=UnitDataBase::_uniqueMapForExpr.getInfoForUnit(var,add,mul);
199 _data.setInfo(projInBase,add,mul);
202 void ValueUnit::positive() throw(INTERP_KERNEL::Exception)
204 unsupportedOp(PositiveFunction::REPR);
207 void ValueUnit::negate() throw(INTERP_KERNEL::Exception)
212 void ValueUnit::sqrt() throw(INTERP_KERNEL::Exception)
214 unsupportedOp(SqrtFunction::REPR);
217 void ValueUnit::cos() throw(INTERP_KERNEL::Exception)
219 unsupportedOp(CosFunction::REPR);
222 void ValueUnit::sin() throw(INTERP_KERNEL::Exception)
224 unsupportedOp(SinFunction::REPR);
227 void ValueUnit::tan() throw(INTERP_KERNEL::Exception)
229 unsupportedOp(TanFunction::REPR);
232 void ValueUnit::abs() throw(INTERP_KERNEL::Exception)
234 unsupportedOp(AbsFunction::REPR);
237 void ValueUnit::exp() throw(INTERP_KERNEL::Exception)
239 unsupportedOp(ExpFunction::REPR);
242 void ValueUnit::ln() throw(INTERP_KERNEL::Exception)
244 unsupportedOp(LnFunction::REPR);
247 void ValueUnit::log10() throw(INTERP_KERNEL::Exception)
249 unsupportedOp(Log10Function::REPR);
252 Value *ValueUnit::plus(const Value *other) const throw(INTERP_KERNEL::Exception)
254 unsupportedOp(PlusFunction::REPR);
258 Value *ValueUnit::minus(const Value *other) const throw(INTERP_KERNEL::Exception)
260 unsupportedOp(MinusFunction::REPR);
264 Value *ValueUnit::greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception)
266 unsupportedOp(GreaterThanFunction::REPR);
270 Value *ValueUnit::lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception)
272 unsupportedOp(LowerThanFunction::REPR);
276 Value *ValueUnit::ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception)
278 unsupportedOp(IfFunction::REPR);
282 Value *ValueUnit::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
284 const ValueUnit *valC=checkSameType(other);
285 DecompositionInUnitBase tmp=_data;
287 return new ValueUnit(tmp);
290 Value *ValueUnit::div(const Value *other) const throw(INTERP_KERNEL::Exception)
292 const ValueUnit *valC=checkSameType(other);
293 DecompositionInUnitBase tmp=_data;
295 return new ValueUnit(tmp);
298 Value *ValueUnit::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
300 const ValueUnit *valC=checkSameType(other);
301 DecompositionInUnitBase tmp=_data;
303 return new ValueUnit(tmp);
306 Value *ValueUnit::max(const Value *other) const throw(INTERP_KERNEL::Exception)
308 unsupportedOp(MaxFunction::REPR);
312 Value *ValueUnit::min(const Value *other) const throw(INTERP_KERNEL::Exception)
314 unsupportedOp(MinFunction::REPR);
318 const ValueUnit *ValueUnit::checkSameType(const Value *val) throw(INTERP_KERNEL::Exception)
320 const ValueUnit *valC=dynamic_cast<const ValueUnit *>(val);
322 throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (Units with other type) !");
326 void ValueUnit::unsupportedOp(const char *type) throw(INTERP_KERNEL::Exception)
328 const char msg[]="Unsupported operation for units :";
329 std::string msgStr(msg);
331 throw INTERP_KERNEL::Exception(msgStr.c_str());
334 ValueDoubleExpr::ValueDoubleExpr(int szDestData, const double *srcData):_sz_dest_data(szDestData),_dest_data(new double[_sz_dest_data]),_src_data(srcData)
338 ValueDoubleExpr::~ValueDoubleExpr()
340 delete [] _dest_data;
343 Value *ValueDoubleExpr::newInstance() const
345 return new ValueDoubleExpr(_sz_dest_data,_src_data);
348 void ValueDoubleExpr::setDouble(double val) throw(INTERP_KERNEL::Exception)
350 std::fill(_dest_data,_dest_data+_sz_dest_data,val);
353 void ValueDoubleExpr::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
356 std::copy(_src_data,_src_data+_sz_dest_data,_dest_data);
358 std::fill(_dest_data,_dest_data+_sz_dest_data,_src_data[fastPos]);
361 std::fill(_dest_data,_dest_data+_sz_dest_data,0.);
362 _dest_data[-7-fastPos]=1.;
366 void ValueDoubleExpr::positive() throw(INTERP_KERNEL::Exception)
370 void ValueDoubleExpr::negate() throw(INTERP_KERNEL::Exception)
372 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::negate<double>());
375 void ValueDoubleExpr::sqrt() throw(INTERP_KERNEL::Exception)
377 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.));
378 if(it!=_dest_data+_sz_dest_data)
379 throw INTERP_KERNEL::Exception("Trying to apply sqrt on < 0. value !");
380 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sqrt));
383 void ValueDoubleExpr::cos() throw(INTERP_KERNEL::Exception)
385 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::cos));
388 void ValueDoubleExpr::sin() throw(INTERP_KERNEL::Exception)
390 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sin));
393 void ValueDoubleExpr::tan() throw(INTERP_KERNEL::Exception)
395 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tan));
398 void ValueDoubleExpr::abs() throw(INTERP_KERNEL::Exception)
400 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(fabs));
403 void ValueDoubleExpr::exp() throw(INTERP_KERNEL::Exception)
405 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::exp));
408 void ValueDoubleExpr::ln() throw(INTERP_KERNEL::Exception)
410 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal<double>(),0.));
411 if(it!=_dest_data+_sz_dest_data)
412 throw INTERP_KERNEL::Exception("Trying to apply neperian/natural log on <= 0. value !");
413 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::log));
416 void ValueDoubleExpr::log10() throw(INTERP_KERNEL::Exception)
418 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal<double>(),0.));
419 if(it!=_dest_data+_sz_dest_data)
420 throw INTERP_KERNEL::Exception("Trying to apply log10 on <= 0. value !");
421 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::log10));
424 Value *ValueDoubleExpr::plus(const Value *other) const throw(INTERP_KERNEL::Exception)
426 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
427 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
428 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::plus<double>());
432 Value *ValueDoubleExpr::minus(const Value *other) const throw(INTERP_KERNEL::Exception)
434 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
435 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
436 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::minus<double>());
440 Value *ValueDoubleExpr::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
442 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
443 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
444 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::multiplies<double>());
448 Value *ValueDoubleExpr::div(const Value *other) const throw(INTERP_KERNEL::Exception)
450 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
451 double *it=std::find(otherC->getData(),otherC->getData()+_sz_dest_data,0.);
452 if(it!=otherC->getData()+_sz_dest_data)
453 throw INTERP_KERNEL::Exception("Trying to operate division by 0. !");
454 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
455 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::divides<double>());
459 Value *ValueDoubleExpr::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
461 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
462 double p=otherC->getData()[0];
463 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.));
464 if(it!=_dest_data+_sz_dest_data)
465 throw INTERP_KERNEL::Exception("Trying to operate pow(a,b) with a<0. !");
466 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
467 std::transform(_dest_data,_dest_data+_sz_dest_data,ret->getData(),std::bind2nd(std::ptr_fun<double,double,double>(std::pow),p));
471 Value *ValueDoubleExpr::max(const Value *other) const throw(INTERP_KERNEL::Exception)
473 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
474 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
475 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun<const double&, const double&, const double& >(std::max));
479 Value *ValueDoubleExpr::min(const Value *other) const throw(INTERP_KERNEL::Exception)
481 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
482 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
483 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun<const double&, const double&, const double& >(std::min));
487 Value *ValueDoubleExpr::greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception)
489 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
490 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
491 for(int i=0;i<_sz_dest_data;i++)
492 if(_dest_data[i]<=otherC->getData()[i])
494 std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max());
497 std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max());
501 Value *ValueDoubleExpr::lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception)
503 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
504 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
505 for(int i=0;i<_sz_dest_data;i++)
506 if(_dest_data[i]>=otherC->getData()[i])
508 std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max());
511 std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max());
515 Value *ValueDoubleExpr::ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception)
517 const ValueDoubleExpr *theC=static_cast<const ValueDoubleExpr *>(the);
518 const ValueDoubleExpr *elsC=static_cast<const ValueDoubleExpr *>(els);
519 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
522 for(int i=0;i<_sz_dest_data && (okmax || okmin);i++)
524 okmax=_dest_data[i]==std::numeric_limits<double>::max();
525 okmin=_dest_data[i]==-std::numeric_limits<double>::max();
530 std::copy(theC->getData(),theC->getData()+_sz_dest_data,ret->getData());
532 std::copy(elsC->getData(),elsC->getData()+_sz_dest_data,ret->getData());
537 throw INTERP_KERNEL::Exception("ValueDoubleExpr::ifFunc : first parameter of ternary func is NOT a consequence of a boolean op !");