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 "InterpKernelFunction.hxx"
22 #include "InterpKernelValue.hxx"
28 using namespace INTERP_KERNEL;
30 const char IdentityFunction::REPR[]="Id";
32 const char PositiveFunction::REPR[]="+";
34 const char NegateFunction::REPR[]="-";
36 const char CosFunction::REPR[]="cos";
38 const char SinFunction::REPR[]="sin";
40 const char TanFunction::REPR[]="tan";
42 const char ACosFunction::REPR[]="acos";
44 const char ASinFunction::REPR[]="asin";
46 const char ATanFunction::REPR[]="atan";
48 const char CoshFunction::REPR[]="cosh";
50 const char SinhFunction::REPR[]="sinh";
52 const char TanhFunction::REPR[]="tanh";
54 const char SqrtFunction::REPR[]="sqrt";
56 const char AbsFunction::REPR[]="abs";
58 const char PlusFunction::REPR[]="+";
60 const char MinusFunction::REPR[]="-";
62 const char MultFunction::REPR[]="*";
64 const char DivFunction::REPR[]="/";
66 const char PowFunction::REPR[]="^";
68 const char ExpFunction::REPR[]="exp";
70 const char LnFunction::REPR[]="ln";
72 const char LogFunction::REPR[]="log";
74 const char Log10Function::REPR[]="log10";
76 const char MaxFunction::REPR[]="max";
78 const char MinFunction::REPR[]="min";
80 const char GreaterThanFunction::REPR[]=">";
82 const char LowerThanFunction::REPR[]="<";
84 const char IfFunction::REPR[]="if";
86 Function *FunctionsFactory::buildFuncFromString(const char *type, int nbOfParams)
91 return buildUnaryFuncFromString(type);
93 return buildBinaryFuncFromString(type);
95 return buildTernaryFuncFromString(type);
97 throw INTERP_KERNEL::Exception("Invalid number of params detected : limited to 2 !");
101 Function *FunctionsFactory::buildUnaryFuncFromString(const char *type)
103 std::string tmp(type);
105 return new IdentityFunction;
106 if(tmp==CosFunction::REPR)
107 return new CosFunction;
108 if(tmp==SinFunction::REPR)
109 return new SinFunction;
110 if(tmp==TanFunction::REPR)
111 return new TanFunction;
112 if(tmp==ACosFunction::REPR)
113 return new ACosFunction;
114 if(tmp==ASinFunction::REPR)
115 return new ASinFunction;
116 if(tmp==ATanFunction::REPR)
117 return new ATanFunction;
118 if(tmp==CoshFunction::REPR)
119 return new CoshFunction;
120 if(tmp==SinhFunction::REPR)
121 return new SinhFunction;
122 if(tmp==TanhFunction::REPR)
123 return new TanhFunction;
124 if(tmp==SqrtFunction::REPR)
125 return new SqrtFunction;
126 if(tmp==AbsFunction::REPR)
127 return new AbsFunction;
128 if(tmp==PositiveFunction::REPR)
129 return new PositiveFunction;
130 if(tmp==NegateFunction::REPR)
131 return new NegateFunction;
132 if(tmp==ExpFunction::REPR)
133 return new ExpFunction;
134 if(tmp==LnFunction::REPR)
135 return new LnFunction;
136 if(tmp==LogFunction::REPR)
137 return new LogFunction;
138 if(tmp==Log10Function::REPR)
139 return new Log10Function;
141 std::string msg("Invalid unary function detected : \"");
142 msg+=type; msg+="\"";
143 throw INTERP_KERNEL::Exception(msg.c_str());
146 Function *FunctionsFactory::buildBinaryFuncFromString(const char *type)
148 std::string tmp(type);
149 if(tmp==PositiveFunction::REPR)
150 return new PlusFunction;
151 if(tmp==NegateFunction::REPR)
152 return new MinusFunction;
153 if(tmp==MultFunction::REPR)
154 return new MultFunction;
155 if(tmp==DivFunction::REPR)
156 return new DivFunction;
157 if(tmp==PowFunction::REPR)
158 return new PowFunction;
159 if(tmp==MaxFunction::REPR)
160 return new MaxFunction;
161 if(tmp==MinFunction::REPR)
162 return new MinFunction;
163 if(tmp==GreaterThanFunction::REPR)
164 return new GreaterThanFunction;
165 if(tmp==LowerThanFunction::REPR)
166 return new LowerThanFunction;
167 std::string msg("Invalid binary function detected : \"");
168 msg+=type; msg+="\"";
169 throw INTERP_KERNEL::Exception(msg.c_str());
172 Function *FunctionsFactory::buildTernaryFuncFromString(const char *type)
174 std::string tmp(type);
175 if(tmp==IfFunction::REPR)
176 return new IfFunction();
177 std::string msg("Invalid ternary function detected : \"");
178 msg+=type; msg+="\"";
179 throw INTERP_KERNEL::Exception(msg.c_str());
182 Function *FunctionsFactory::buildBinaryFuncFromString(char type)
184 char tmp[2]; tmp[0]=type; tmp[1]='\0';
185 return buildBinaryFuncFromString(tmp);
188 Function::~Function()
192 IdentityFunction::~IdentityFunction()
196 void IdentityFunction::operate(std::vector<Value *>& stck) const
200 void IdentityFunction::operateX86(std::vector<std::string>& asmb) const
204 void IdentityFunction::operateStackOfDouble(std::vector<double>& stck) const
208 const char *IdentityFunction::getRepr() const
213 bool IdentityFunction::isACall() const
218 PositiveFunction::~PositiveFunction()
222 int UnaryFunction::getNbInputParams() const
227 void PositiveFunction::operate(std::vector<Value *>& stck) const
231 void PositiveFunction::operateX86(std::vector<std::string>& asmb) const
235 void PositiveFunction::operateStackOfDouble(std::vector<double>& stck) const
239 const char *PositiveFunction::getRepr() const
244 bool PositiveFunction::isACall() const
249 NegateFunction::~NegateFunction()
253 void NegateFunction::operate(std::vector<Value *>& stck) const
255 Value *val=stck.back();
259 void NegateFunction::operateX86(std::vector<std::string>& asmb) const
261 asmb.push_back("fchs");
264 void NegateFunction::operateStackOfDouble(std::vector<double>& stck) const
266 double v(stck.back());
270 const char *NegateFunction::getRepr() const
275 bool NegateFunction::isACall() const
280 CosFunction::~CosFunction()
284 void CosFunction::operate(std::vector<Value *>& stck) const
286 Value *val=stck.back();
290 void CosFunction::operateX86(std::vector<std::string>& asmb) const
292 asmb.push_back("fcos");
295 void CosFunction::operateStackOfDouble(std::vector<double>& stck) const
297 double v(stck.back());
301 const char *CosFunction::getRepr() const
306 bool CosFunction::isACall() const
311 SinFunction::~SinFunction()
315 void SinFunction::operate(std::vector<Value *>& stck) const
317 Value *val=stck.back();
321 void SinFunction::operateX86(std::vector<std::string>& asmb) const
323 asmb.push_back("fsin");
326 void SinFunction::operateStackOfDouble(std::vector<double>& stck) const
328 double v(stck.back());
332 const char *SinFunction::getRepr() const
337 bool SinFunction::isACall() const
342 TanFunction::~TanFunction()
346 void TanFunction::operate(std::vector<Value *>& stck) const
348 Value *val=stck.back();
352 void TanFunction::operateX86(std::vector<std::string>& asmb) const
354 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
357 void TanFunction::operateStackOfDouble(std::vector<double>& stck) const
359 double v(stck.back());
363 const char *TanFunction::getRepr() const
368 bool TanFunction::isACall() const
373 ACosFunction::~ACosFunction()
377 void ACosFunction::operate(std::vector<Value *>& stck) const
379 Value *val=stck.back();
383 void ACosFunction::operateX86(std::vector<std::string>& asmb) const
385 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
388 void ACosFunction::operateStackOfDouble(std::vector<double>& stck) const
390 double v(stck.back());
394 void ACosFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const
396 double v(stck.back());
398 throw INTERP_KERNEL::Exception("acos on a value which absolute is > 1 !");
402 const char *ACosFunction::getRepr() const
407 bool ACosFunction::isACall() const
412 ASinFunction::~ASinFunction()
416 void ASinFunction::operate(std::vector<Value *>& stck) const
418 Value *val=stck.back();
422 void ASinFunction::operateX86(std::vector<std::string>& asmb) const
424 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
427 void ASinFunction::operateStackOfDouble(std::vector<double>& stck) const
429 double v(stck.back());
433 void ASinFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const
435 double v(stck.back());
437 throw INTERP_KERNEL::Exception("asin on a value which absolute is > 1 !");
441 const char *ASinFunction::getRepr() const
446 bool ASinFunction::isACall() const
451 ATanFunction::~ATanFunction()
455 void ATanFunction::operate(std::vector<Value *>& stck) const
457 Value *val=stck.back();
461 void ATanFunction::operateX86(std::vector<std::string>& asmb) const
463 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
466 void ATanFunction::operateStackOfDouble(std::vector<double>& stck) const
468 double v(stck.back());
472 const char *ATanFunction::getRepr() const
477 bool ATanFunction::isACall() const
482 CoshFunction::~CoshFunction()
486 void CoshFunction::operate(std::vector<Value *>& stck) const
488 Value *val=stck.back();
492 void CoshFunction::operateX86(std::vector<std::string>& asmb) const
494 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
497 void CoshFunction::operateStackOfDouble(std::vector<double>& stck) const
499 double v(stck.back());
503 const char *CoshFunction::getRepr() const
508 bool CoshFunction::isACall() const
513 SinhFunction::~SinhFunction()
517 void SinhFunction::operate(std::vector<Value *>& stck) const
519 Value *val=stck.back();
523 void SinhFunction::operateX86(std::vector<std::string>& asmb) const
525 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
528 void SinhFunction::operateStackOfDouble(std::vector<double>& stck) const
530 double v(stck.back());
534 const char *SinhFunction::getRepr() const
539 bool SinhFunction::isACall() const
544 TanhFunction::~TanhFunction()
548 void TanhFunction::operate(std::vector<Value *>& stck) const
550 Value *val=stck.back();
554 void TanhFunction::operateX86(std::vector<std::string>& asmb) const
556 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
559 void TanhFunction::operateStackOfDouble(std::vector<double>& stck) const
561 double v(stck.back());
565 const char *TanhFunction::getRepr() const
570 bool TanhFunction::isACall() const
575 SqrtFunction::~SqrtFunction()
579 void SqrtFunction::operate(std::vector<Value *>& stck) const
581 Value *val=stck.back();
585 void SqrtFunction::operateX86(std::vector<std::string>& asmb) const
587 asmb.push_back("fsqrt");
590 void SqrtFunction::operateStackOfDouble(std::vector<double>& stck) const
592 double v(stck.back());
596 void SqrtFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const
598 double v(stck.back());
600 throw INTERP_KERNEL::Exception("sqrt on a value < 0. !");
604 const char *SqrtFunction::getRepr() const
609 bool SqrtFunction::isACall() const
614 AbsFunction::~AbsFunction()
618 void AbsFunction::operate(std::vector<Value *>& stck) const
620 Value *val=stck.back();
624 void AbsFunction::operateX86(std::vector<std::string>& asmb) const
626 asmb.push_back("fabs");
629 void AbsFunction::operateStackOfDouble(std::vector<double>& stck) const
631 double v(stck.back());
635 const char *AbsFunction::getRepr() const
640 bool AbsFunction::isACall() const
645 void ExpFunction::operate(std::vector<Value *>& stck) const
647 Value *val=stck.back();
651 void ExpFunction::operateX86(std::vector<std::string>& asmb) const
653 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
656 void ExpFunction::operateStackOfDouble(std::vector<double>& stck) const
658 double v(stck.back());
659 stck.back()=std::exp(v);
662 const char *ExpFunction::getRepr() const
667 bool ExpFunction::isACall() const
672 LnFunction::~LnFunction()
676 void LnFunction::operate(std::vector<Value *>& stck) const
678 Value *val=stck.back();
682 void LnFunction::operateX86(std::vector<std::string>& asmb) const
684 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
687 void LnFunction::operateStackOfDouble(std::vector<double>& stck) const
689 double v(stck.back());
690 stck.back()=std::log(v);
693 void LnFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const
695 double v(stck.back());
697 throw INTERP_KERNEL::Exception("ln on a value < 0. !");
698 stck.back()=std::log(v);
701 const char *LnFunction::getRepr() const
706 bool LnFunction::isACall() const
711 LogFunction::~LogFunction()
715 void LogFunction::operate(std::vector<Value *>& stck) const
717 Value *val=stck.back();
721 void LogFunction::operateX86(std::vector<std::string>& asmb) const
723 throw INTERP_KERNEL::Exception("Assembly for log Not implemented yet !");
726 void LogFunction::operateStackOfDouble(std::vector<double>& stck) const
728 double v(stck.back());
729 stck.back()=std::log(v);
732 void LogFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const
734 double v(stck.back());
736 throw INTERP_KERNEL::Exception("log on a value < 0. !");
737 stck.back()=std::log(v);
740 const char *LogFunction::getRepr() const
745 bool LogFunction::isACall() const
750 Log10Function::~Log10Function()
754 void Log10Function::operate(std::vector<Value *>& stck) const
756 Value *val=stck.back();
760 void Log10Function::operateX86(std::vector<std::string>& asmb) const
762 throw INTERP_KERNEL::Exception("Assembly for log Not implemented yet !");
765 void Log10Function::operateStackOfDouble(std::vector<double>& stck) const
767 double v(stck.back());
768 stck.back()=std::log10(v);
771 void Log10Function::operateStackOfDoubleSafe(std::vector<double>& stck) const
773 double v(stck.back());
775 throw INTERP_KERNEL::Exception("log10 on a value < 0. !");
776 stck.back()=std::log10(v);
779 const char *Log10Function::getRepr() const
784 bool Log10Function::isACall() const
789 int BinaryFunction::getNbInputParams() const
794 PlusFunction::~PlusFunction()
798 void PlusFunction::operate(std::vector<Value *>& stck) const
800 Value *val1=stck.back();
802 Value *& val2=stck.back();
806 val3=val1->plus(val2);
808 catch(INTERP_KERNEL::Exception& e)
818 void PlusFunction::operateX86(std::vector<std::string>& asmb) const
820 asmb.push_back("faddp st1");
823 void PlusFunction::operateStackOfDouble(std::vector<double>& stck) const
825 double a(stck.back());
827 stck.back()=a+stck.back();
830 const char *PlusFunction::getRepr() const
835 bool PlusFunction::isACall() const
840 MinusFunction::~MinusFunction()
844 void MinusFunction::operate(std::vector<Value *>& stck) const
846 Value *val1=stck.back();
848 Value *& val2=stck.back();
852 val3=val1->minus(val2);
854 catch(INTERP_KERNEL::Exception& e)
864 void MinusFunction::operateX86(std::vector<std::string>& asmb) const
866 asmb.push_back("fsubp st1");
869 void MinusFunction::operateStackOfDouble(std::vector<double>& stck) const
871 double a(stck.back());
873 stck.back()=a-stck.back();
876 const char *MinusFunction::getRepr() const
881 bool MinusFunction::isACall() const
886 MultFunction::~MultFunction()
890 void MultFunction::operate(std::vector<Value *>& stck) const
892 Value *val1=stck.back();
894 Value *& val2=stck.back();
895 Value *val3=val1->mult(val2);
901 void MultFunction::operateX86(std::vector<std::string>& asmb) const
903 asmb.push_back("fmulp st1");
906 void MultFunction::operateStackOfDouble(std::vector<double>& stck) const
908 double a(stck.back());
910 stck.back()=a*stck.back();
913 const char *MultFunction::getRepr() const
918 bool MultFunction::isACall() const
923 DivFunction::~DivFunction()
927 void DivFunction::operate(std::vector<Value *>& stck) const
929 Value *val1=stck.back();
931 Value *& val2=stck.back();
935 val3=val1->div(val2);
937 catch(INTERP_KERNEL::Exception& e)
947 void DivFunction::operateX86(std::vector<std::string>& asmb) const
949 asmb.push_back("fdivp st1");
952 void DivFunction::operateStackOfDouble(std::vector<double>& stck) const
954 double a(stck.back());
956 stck.back()=a/stck.back();
959 void DivFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const
961 double a(stck.back());
964 throw INTERP_KERNEL::Exception("division by 0. !");
965 stck.back()=a/stck.back();
968 const char *DivFunction::getRepr() const
973 bool DivFunction::isACall() const
978 PowFunction::~PowFunction()
982 void PowFunction::operate(std::vector<Value *>& stck) const
984 Value *val1=stck.back();
986 Value *& val2=stck.back();
990 val3=val1->pow(val2);
992 catch(INTERP_KERNEL::Exception& e)
1002 void PowFunction::operateX86(std::vector<std::string>& asmb) const
1004 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
1007 void PowFunction::operateStackOfDouble(std::vector<double>& stck) const
1009 double a(stck.back());
1011 stck.back()=std::pow(a,stck.back());
1014 void PowFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const
1016 double a(stck.back());
1018 double b(stck.back());
1020 throw INTERP_KERNEL::Exception("pow with val < 0. !");
1021 stck.back()=std::pow(a,b);
1024 const char *PowFunction::getRepr() const
1029 bool PowFunction::isACall() const
1034 ExpFunction::~ExpFunction()
1038 MaxFunction::~MaxFunction()
1042 void MaxFunction::operate(std::vector<Value *>& stck) const
1044 Value *val1=stck.back();
1046 Value *& val2=stck.back();
1050 val3=val1->max(val2);
1052 catch(INTERP_KERNEL::Exception& e)
1062 void MaxFunction::operateX86(std::vector<std::string>& asmb) const
1064 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
1067 void MaxFunction::operateStackOfDouble(std::vector<double>& stck) const
1069 double a(stck.back());
1071 stck.back()=std::max(stck.back(),a);
1074 const char *MaxFunction::getRepr() const
1079 bool MaxFunction::isACall() const
1084 MinFunction::~MinFunction()
1088 void MinFunction::operate(std::vector<Value *>& stck) const
1090 Value *val1=stck.back();
1092 Value *& val2=stck.back();
1096 val3=val1->min(val2);
1098 catch(INTERP_KERNEL::Exception& e)
1108 void MinFunction::operateX86(std::vector<std::string>& asmb) const
1110 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
1113 void MinFunction::operateStackOfDouble(std::vector<double>& stck) const
1115 double a(stck.back());
1117 stck.back()=std::min(stck.back(),a);
1120 const char *MinFunction::getRepr() const
1125 bool MinFunction::isACall() const
1130 GreaterThanFunction::~GreaterThanFunction()
1134 void GreaterThanFunction::operate(std::vector<Value *>& stck) const
1136 Value *val1=stck.back();
1138 Value *& val2=stck.back();
1142 val3=val1->greaterThan(val2);
1144 catch(INTERP_KERNEL::Exception& e)
1154 void GreaterThanFunction::operateX86(std::vector<std::string>& asmb) const
1156 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
1159 void GreaterThanFunction::operateStackOfDouble(std::vector<double>& stck) const
1161 double a(stck.back());
1163 double b(stck.back());
1164 stck.back()=a>b?std::numeric_limits<double>::max():-std::numeric_limits<double>::max();
1167 const char *GreaterThanFunction::getRepr() const
1172 bool GreaterThanFunction::isACall() const
1177 LowerThanFunction::~LowerThanFunction()
1181 void LowerThanFunction::operate(std::vector<Value *>& stck) const
1183 Value *val1=stck.back();
1185 Value *& val2=stck.back();
1189 val3=val1->lowerThan(val2);
1191 catch(INTERP_KERNEL::Exception& e)
1201 void LowerThanFunction::operateX86(std::vector<std::string>& asmb) const
1203 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
1206 void LowerThanFunction::operateStackOfDouble(std::vector<double>& stck) const
1208 double a(stck.back());
1210 double b(stck.back());
1211 stck.back()=a<b?std::numeric_limits<double>::max():-std::numeric_limits<double>::max();
1214 const char *LowerThanFunction::getRepr() const
1219 bool LowerThanFunction::isACall() const
1224 int TernaryFunction::getNbInputParams() const
1229 IfFunction::~IfFunction()
1233 void IfFunction::operate(std::vector<Value *>& stck) const
1235 Value *val1=stck.back();
1237 Value *val2=stck.back();
1239 Value *&val3=stck.back();
1243 val4=val1->ifFunc(val2,val3);
1245 catch(INTERP_KERNEL::Exception& e)
1257 void IfFunction::operateX86(std::vector<std::string>& asmb) const
1259 throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
1262 void IfFunction::operateStackOfDouble(std::vector<double>& stck) const
1264 double cond(stck.back());
1266 double the(stck.back());
1268 if(cond==std::numeric_limits<double>::max())
1272 void IfFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const
1274 double cond(stck.back());
1276 double the(stck.back());
1278 if(cond!=std::numeric_limits<double>::max() && cond!=-std::numeric_limits<double>::max())
1279 throw INTERP_KERNEL::Exception("ifFunc : first parameter of ternary func is NOT a consequence of a boolean op !");
1280 if(cond==std::numeric_limits<double>::max())
1284 const char *IfFunction::getRepr() const
1289 bool IfFunction::isACall() const