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
20 #include "InterpKernelValue.hxx"
21 #include "InterpKernelFunction.hxx"
27 using namespace INTERP_KERNEL;
29 ValueDouble::ValueDouble():_data(std::numeric_limits<double>::max())
33 Value *ValueDouble::newInstance() const
35 return new ValueDouble;
38 ValueDouble::ValueDouble(double val):_data(val)
42 void ValueDouble::setDouble(double val) throw(INTERP_KERNEL::Exception)
47 void ValueDouble::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
49 std::string msg("Error var : "); msg+=var; msg+=" not numeric : use another expression evaluator !";
50 throw INTERP_KERNEL::Exception(msg.c_str());
53 void ValueDouble::positive() throw(INTERP_KERNEL::Exception)
57 void ValueDouble::negate() throw(INTERP_KERNEL::Exception)
62 void ValueDouble::sqrt() throw(INTERP_KERNEL::Exception)
64 _data=std::sqrt(_data);
67 void ValueDouble::cos() throw(INTERP_KERNEL::Exception)
69 _data=std::cos(_data);
72 void ValueDouble::sin() throw(INTERP_KERNEL::Exception)
74 _data=std::sin(_data);
77 void ValueDouble::tan() throw(INTERP_KERNEL::Exception)
79 _data=std::tan(_data);
82 void ValueDouble::abs() throw(INTERP_KERNEL::Exception)
88 void ValueDouble::exp() throw(INTERP_KERNEL::Exception)
90 _data=std::exp(_data);
93 void ValueDouble::ln() throw(INTERP_KERNEL::Exception)
95 _data=std::log(_data);
98 void ValueDouble::log10() throw(INTERP_KERNEL::Exception)
100 _data=std::log10(_data);
103 Value *ValueDouble::plus(const Value *other) const throw(INTERP_KERNEL::Exception)
105 const ValueDouble *valC=checkSameType(other);
106 return new ValueDouble(_data+valC->_data);
109 Value *ValueDouble::minus(const Value *other) const throw(INTERP_KERNEL::Exception)
111 const ValueDouble *valC=checkSameType(other);
112 return new ValueDouble(_data-valC->_data);
115 Value *ValueDouble::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
117 const ValueDouble *valC=checkSameType(other);
118 return new ValueDouble(_data*valC->_data);
121 Value *ValueDouble::div(const Value *other) const throw(INTERP_KERNEL::Exception)
123 const ValueDouble *valC=checkSameType(other);
124 return new ValueDouble(_data/valC->_data);
127 Value *ValueDouble::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
129 const ValueDouble *valC=checkSameType(other);
130 return new ValueDouble(std::pow(_data,valC->_data));
133 Value *ValueDouble::max(const Value *other) const throw(INTERP_KERNEL::Exception)
135 const ValueDouble *valC=checkSameType(other);
136 return new ValueDouble(std::max(_data,valC->_data));
139 Value *ValueDouble::min(const Value *other) const throw(INTERP_KERNEL::Exception)
141 const ValueDouble *valC=checkSameType(other);
142 return new ValueDouble(std::min(_data,valC->_data));
145 Value *ValueDouble::greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception)
147 const ValueDouble *valC=checkSameType(other);
148 return new ValueDouble(_data>valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max());
151 Value *ValueDouble::lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception)
153 const ValueDouble *valC=checkSameType(other);
154 return new ValueDouble(_data<valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max());
157 Value *ValueDouble::ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception)
159 const ValueDouble *theC=checkSameType(the);
160 const ValueDouble *elsC=checkSameType(els);
161 if(_data==std::numeric_limits<double>::max())
162 return new ValueDouble(theC->_data);
163 if(_data==-std::numeric_limits<double>::max())
164 return new ValueDouble(elsC->_data);
165 throw INTERP_KERNEL::Exception("ValueDouble::ifFunc : The fist element of ternary function if is not a binary op !");
168 const ValueDouble *ValueDouble::checkSameType(const Value *val) throw(INTERP_KERNEL::Exception)
170 const ValueDouble *valC=dynamic_cast<const ValueDouble *>(val);
172 throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (double with other type) !");
176 ValueUnit::ValueUnit()
180 Value *ValueUnit::newInstance() const
182 return new ValueUnit;
185 ValueUnit::ValueUnit(const DecompositionInUnitBase& unit):_data(unit)
189 void ValueUnit::setDouble(double val) throw(INTERP_KERNEL::Exception)
191 _data.tryToConvertInUnit(val);
194 void ValueUnit::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
197 const short *projInBase=UnitDataBase::_uniqueMapForExpr.getInfoForUnit(var,add,mul);
198 _data.setInfo(projInBase,add,mul);
201 void ValueUnit::positive() throw(INTERP_KERNEL::Exception)
203 unsupportedOp(PositiveFunction::REPR);
206 void ValueUnit::negate() throw(INTERP_KERNEL::Exception)
211 void ValueUnit::sqrt() throw(INTERP_KERNEL::Exception)
213 unsupportedOp(SqrtFunction::REPR);
216 void ValueUnit::cos() throw(INTERP_KERNEL::Exception)
218 unsupportedOp(CosFunction::REPR);
221 void ValueUnit::sin() throw(INTERP_KERNEL::Exception)
223 unsupportedOp(SinFunction::REPR);
226 void ValueUnit::tan() throw(INTERP_KERNEL::Exception)
228 unsupportedOp(TanFunction::REPR);
231 void ValueUnit::abs() throw(INTERP_KERNEL::Exception)
233 unsupportedOp(AbsFunction::REPR);
236 void ValueUnit::exp() throw(INTERP_KERNEL::Exception)
238 unsupportedOp(ExpFunction::REPR);
241 void ValueUnit::ln() throw(INTERP_KERNEL::Exception)
243 unsupportedOp(LnFunction::REPR);
246 void ValueUnit::log10() throw(INTERP_KERNEL::Exception)
248 unsupportedOp(Log10Function::REPR);
251 Value *ValueUnit::plus(const Value *other) const throw(INTERP_KERNEL::Exception)
253 unsupportedOp(PlusFunction::REPR);
257 Value *ValueUnit::minus(const Value *other) const throw(INTERP_KERNEL::Exception)
259 unsupportedOp(MinusFunction::REPR);
263 Value *ValueUnit::greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception)
265 unsupportedOp(GreaterThanFunction::REPR);
269 Value *ValueUnit::lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception)
271 unsupportedOp(LowerThanFunction::REPR);
275 Value *ValueUnit::ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception)
277 unsupportedOp(IfFunction::REPR);
281 Value *ValueUnit::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
283 const ValueUnit *valC=checkSameType(other);
284 DecompositionInUnitBase tmp=_data;
286 return new ValueUnit(tmp);
289 Value *ValueUnit::div(const Value *other) const throw(INTERP_KERNEL::Exception)
291 const ValueUnit *valC=checkSameType(other);
292 DecompositionInUnitBase tmp=_data;
294 return new ValueUnit(tmp);
297 Value *ValueUnit::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
299 const ValueUnit *valC=checkSameType(other);
300 DecompositionInUnitBase tmp=_data;
302 return new ValueUnit(tmp);
305 Value *ValueUnit::max(const Value *other) const throw(INTERP_KERNEL::Exception)
307 unsupportedOp(MaxFunction::REPR);
311 Value *ValueUnit::min(const Value *other) const throw(INTERP_KERNEL::Exception)
313 unsupportedOp(MinFunction::REPR);
317 const ValueUnit *ValueUnit::checkSameType(const Value *val) throw(INTERP_KERNEL::Exception)
319 const ValueUnit *valC=dynamic_cast<const ValueUnit *>(val);
321 throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (Units with other type) !");
325 void ValueUnit::unsupportedOp(const char *type) throw(INTERP_KERNEL::Exception)
327 const char msg[]="Unsupported operation for units :";
328 std::string msgStr(msg);
330 throw INTERP_KERNEL::Exception(msgStr.c_str());
333 ValueDoubleExpr::ValueDoubleExpr(int szDestData, const double *srcData):_sz_dest_data(szDestData),_dest_data(new double[_sz_dest_data]),_src_data(srcData)
337 ValueDoubleExpr::~ValueDoubleExpr()
339 delete [] _dest_data;
342 Value *ValueDoubleExpr::newInstance() const
344 return new ValueDoubleExpr(_sz_dest_data,_src_data);
347 void ValueDoubleExpr::setDouble(double val) throw(INTERP_KERNEL::Exception)
349 std::fill(_dest_data,_dest_data+_sz_dest_data,val);
352 void ValueDoubleExpr::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
355 std::copy(_src_data,_src_data+_sz_dest_data,_dest_data);
357 std::fill(_dest_data,_dest_data+_sz_dest_data,_src_data[fastPos]);
360 std::fill(_dest_data,_dest_data+_sz_dest_data,0.);
361 _dest_data[-7-fastPos]=1.;
365 void ValueDoubleExpr::positive() throw(INTERP_KERNEL::Exception)
369 void ValueDoubleExpr::negate() throw(INTERP_KERNEL::Exception)
371 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::negate<double>());
374 void ValueDoubleExpr::sqrt() throw(INTERP_KERNEL::Exception)
376 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.));
377 if(it!=_dest_data+_sz_dest_data)
378 throw INTERP_KERNEL::Exception("Trying to apply sqrt on < 0. value !");
379 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sqrt));
382 void ValueDoubleExpr::cos() throw(INTERP_KERNEL::Exception)
384 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::cos));
387 void ValueDoubleExpr::sin() throw(INTERP_KERNEL::Exception)
389 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sin));
392 void ValueDoubleExpr::tan() throw(INTERP_KERNEL::Exception)
394 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tan));
397 void ValueDoubleExpr::abs() throw(INTERP_KERNEL::Exception)
399 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(fabs));
402 void ValueDoubleExpr::exp() throw(INTERP_KERNEL::Exception)
404 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::exp));
407 void ValueDoubleExpr::ln() throw(INTERP_KERNEL::Exception)
409 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal<double>(),0.));
410 if(it!=_dest_data+_sz_dest_data)
411 throw INTERP_KERNEL::Exception("Trying to apply neperian/natural log on <= 0. value !");
412 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::log));
415 void ValueDoubleExpr::log10() throw(INTERP_KERNEL::Exception)
417 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal<double>(),0.));
418 if(it!=_dest_data+_sz_dest_data)
419 throw INTERP_KERNEL::Exception("Trying to apply log10 on <= 0. value !");
420 std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::log10));
423 Value *ValueDoubleExpr::plus(const Value *other) const throw(INTERP_KERNEL::Exception)
425 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
426 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
427 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::plus<double>());
431 Value *ValueDoubleExpr::minus(const Value *other) const throw(INTERP_KERNEL::Exception)
433 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
434 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
435 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::minus<double>());
439 Value *ValueDoubleExpr::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
441 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
442 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
443 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::multiplies<double>());
447 Value *ValueDoubleExpr::div(const Value *other) const throw(INTERP_KERNEL::Exception)
449 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
450 double *it=std::find(otherC->getData(),otherC->getData()+_sz_dest_data,0.);
451 if(it!=otherC->getData()+_sz_dest_data)
452 throw INTERP_KERNEL::Exception("Trying to operate division by 0. !");
453 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
454 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::divides<double>());
458 Value *ValueDoubleExpr::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
460 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
461 double p=otherC->getData()[0];
462 double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.));
463 if(it!=_dest_data+_sz_dest_data)
464 throw INTERP_KERNEL::Exception("Trying to operate pow(a,b) with a<0. !");
465 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
466 std::transform(_dest_data,_dest_data+_sz_dest_data,ret->getData(),std::bind2nd(std::ptr_fun<double,double,double>(std::pow),p));
470 Value *ValueDoubleExpr::max(const Value *other) const throw(INTERP_KERNEL::Exception)
472 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
473 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
474 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun<const double&, const double&, const double& >(std::max));
478 Value *ValueDoubleExpr::min(const Value *other) const throw(INTERP_KERNEL::Exception)
480 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
481 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
482 std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun<const double&, const double&, const double& >(std::min));
486 Value *ValueDoubleExpr::greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception)
488 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
489 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
490 for(int i=0;i<_sz_dest_data;i++)
491 if(_dest_data[i]<=otherC->getData()[i])
493 std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max());
496 std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max());
500 Value *ValueDoubleExpr::lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception)
502 const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
503 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
504 for(int i=0;i<_sz_dest_data;i++)
505 if(_dest_data[i]>=otherC->getData()[i])
507 std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max());
510 std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max());
514 Value *ValueDoubleExpr::ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception)
516 const ValueDoubleExpr *theC=static_cast<const ValueDoubleExpr *>(the);
517 const ValueDoubleExpr *elsC=static_cast<const ValueDoubleExpr *>(els);
518 ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
521 for(int i=0;i<_sz_dest_data && (okmax || okmin);i++)
523 okmax=_dest_data[i]==std::numeric_limits<double>::max();
524 okmin=_dest_data[i]==-std::numeric_limits<double>::max();
529 std::copy(theC->getData(),theC->getData()+_sz_dest_data,ret->getData());
531 std::copy(elsC->getData(),elsC->getData()+_sz_dest_data,ret->getData());
536 throw INTERP_KERNEL::Exception("ValueDoubleExpr::ifFunc : first parameter of ternary func is NOT a consequence of a boolean op !");