NGSolve
4.9
|
00001 #ifndef FILE_EVALFUNC 00002 #define FILE_EVALFUNC 00003 00004 /**************************************************************************/ 00005 /* File: evalfunc.hpp */ 00006 /* Author: Joachim Schoeberl */ 00007 /* Date: 01. Oct. 95 */ 00008 /**************************************************************************/ 00009 00010 00011 namespace ngstd 00012 { 00013 00014 00021 class NGS_DLL_HEADER EvalFunction 00022 { 00023 00025 enum EVAL_TOKEN 00026 { 00027 ADD = '+', SUB = '-', MULT = '*', DIV = '/', LP ='(', RP = ')', 00028 COMMA = ',', 00029 NEG = 100, 00030 VEC_ADD, VEC_SUB, VEC_SCAL_MULT, SCAL_VEC_MULT, VEC_VEC_MULT, VEC_SCAL_DIV, 00031 AND, OR, NOT, GREATER, LESS, GREATEREQUAL, LESSEQUAL, EQUAL, 00032 CONSTANT, IMAG, VARIABLE, FUNCTION, GLOBVAR, /* COEFF_FUNC,*/ END, STRING, 00033 SIN, COS, TAN, ATAN, ATAN2, EXP, LOG, ABS, SIGN, SQRT, STEP, 00034 BESSELJ0, BESSELY0, BESSELJ1, BESSELY1 00035 }; 00036 00037 public: 00039 EvalFunction (); 00041 EvalFunction (istream & aist); 00043 EvalFunction (const string & str); 00045 EvalFunction (const EvalFunction & eval2); 00047 virtual ~EvalFunction (); 00048 00050 void Parse (istream & aist); 00052 void DefineConstant (const char * name, double val); 00054 void DefineGlobalVariable (const char * name, double * var); 00056 void DefineArgument (const char * name, int num, int vecdim = 1, bool iscomplex = false); 00057 00059 double Eval (const double * x = NULL) const; 00061 void Eval (const double * x, double * y, int ydim) const; 00062 00064 complex<double> Eval (const complex<double> * x = NULL) const; 00066 void Eval (const complex<double> * x, complex<double> * y, int ydim) const; 00068 void Eval (const complex<double> * x, double * y, int ydim) const; 00069 00070 /* 00072 template <typename TIN> 00073 void Eval (const TIN * x, complex<double> * y, int ydim) const; 00074 */ 00075 template <typename TIN, typename TCALC> 00076 void Eval (const TIN * x, TCALC * stack) const; 00077 00078 00080 bool IsComplex () const; 00081 00083 bool IsResultComplex () const { return res_type.iscomplex; } 00084 00086 bool IsConstant () const; 00087 00089 int Dimension() const { return res_type.vecdim; } 00090 00092 void AddConstant (double val) 00093 { program.Append (step (val)); } 00094 00096 void AddVariable (int varnum) 00097 { program.Append (step(varnum)); } 00098 00100 void AddGlobVariable (const double * dp) 00101 { program.Append (step(dp)); } 00102 00104 void AddOperation (EVAL_TOKEN op) 00105 { program.Append (step(op)); } 00106 00108 void AddFunction (double (*fun) (double)) 00109 { program.Append (step(fun)); } 00110 00112 void Print (ostream & ost) const; 00113 protected: 00114 00116 class step 00117 { 00118 public: 00120 EVAL_TOKEN op; 00122 union UNION_OP 00123 { 00125 double val; 00127 const double *globvar; 00129 int varnum; 00131 double (*fun) (double); 00132 }; 00134 UNION_OP operand; 00135 00137 short int vecdim; 00138 00139 step () { ; } 00140 00141 step (EVAL_TOKEN hop) 00142 { 00143 op = hop; 00144 operand.val = 0; 00145 } 00146 00147 step (double hval) 00148 { 00149 op = CONSTANT; 00150 operand.val = hval; 00151 } 00152 00153 step (int varnum) 00154 { 00155 op = VARIABLE; 00156 operand.varnum = varnum; 00157 } 00158 00159 step (const double * aglobvar) 00160 { 00161 op = GLOBVAR; 00162 operand.globvar = aglobvar; 00163 } 00164 00165 step (double (*fun) (double)) 00166 { 00167 op = FUNCTION; 00168 operand.fun = fun; 00169 } 00170 }; 00171 00173 Array<step> program; 00174 00175 class ResultType 00176 { 00177 public: 00178 int vecdim; 00179 bool isbool; 00180 bool iscomplex; 00181 ResultType () 00182 : vecdim(1), isbool(false), iscomplex(false) 00183 { ; } 00184 }; 00185 00186 ResultType res_type; 00187 const double eps; 00188 00190 ResultType ParseExpression (); 00192 ResultType ParseExpression2 (); 00194 ResultType ParseSubExpression (); 00196 ResultType ParseTerm (); 00198 ResultType ParsePrimary (); 00199 00201 istream * ist; 00202 00204 EVAL_TOKEN token; 00206 double num_value; 00208 char string_value[1000]; 00210 int var_num, var_dim; 00212 bool var_iscomplex; 00214 double * globvar; 00215 00216 typedef double(*TFUNP) (double); 00218 static SymbolTable<TFUNP> functions; 00219 00221 SymbolTable<double> constants; 00222 00224 SymbolTable<double*> globvariables; 00225 00226 public: 00228 struct argtype 00229 { 00230 int argnum; 00231 int dim; 00232 bool iscomplex; 00233 public: 00234 argtype () 00235 : argnum(-1), dim(1), iscomplex(false) { ; } 00236 argtype (int aanum, int adim = 1, bool acomplex = false) 00237 : argnum(aanum), dim(adim), iscomplex(acomplex) { ; } 00238 }; 00239 SymbolTable<argtype> arguments; 00240 int num_arguments; 00241 00243 EVAL_TOKEN GetToken() const 00244 { return token; } 00245 00247 double GetNumValue() const 00248 { return num_value; } 00249 00251 int GetVariableNumber() const 00252 { return var_num; } 00254 int GetVariableDimension() const 00255 { return var_dim; } 00256 bool GetVariableIsComplex() const 00257 { return var_iscomplex; } 00258 00260 const char * GetStringValue() const 00261 { return string_value; } 00262 00264 void ReadNext(); 00265 00266 bool ToBool (double x) const { return x > eps; } 00267 bool ToBool (complex<double> x) const { return x.real() > eps; } 00268 double CheckReal (double x) const { return x; } 00269 double CheckReal (complex<double> x) const { cerr << "illegal complex value" << endl; return 0; } 00270 00271 double Abs (double x) const { return fabs(x); } 00272 double Abs (complex<double> x) const { return abs(x); } 00273 }; 00274 00275 00276 } 00277 00278 00279 #endif 00280 00281