NGSolve  4.9
ngstd/evalfunc.hpp
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