NGSolve  5.3
evalfunc.hpp
1 #ifndef FILE_EVALFUNC
2 #define FILE_EVALFUNC
3 
4 /**************************************************************************/
5 /* File: evalfunc.hpp */
6 /* Author: Joachim Schoeberl */
7 /* Date: 01. Oct. 95 */
8 /**************************************************************************/
9 
10 
11 namespace ngstd
12 {
13 
14 
15 
16 
18  {
19  int dim;
20  bool iscomplex;
21  double * data;
22  public:
23  GenericVariable (const GenericVariable & v2)
24  {
25  dim = v2.dim;
26  iscomplex = v2.iscomplex;
27  int hdim = iscomplex ? 2*dim : dim;
28  data = new double[hdim];
29  for (int j = 0; j < hdim; j++)
30  data[j] = v2.data[j];
31  }
33  {
34  cout << "move constr" << endl;
35  dim = v2.dim;
36  iscomplex = v2.iscomplex;
37  int hdim = iscomplex ? 2*dim : dim;
38  data = new double[hdim];
39  for (int j = 0; j < hdim; j++)
40  data[j] = v2.data[j];
41  }
42  GenericVariable (bool acomplex = false, int adim = 1)
43  : dim(adim), iscomplex(acomplex)
44  {
45  int hdim = iscomplex ? 2*dim : dim;
46  data = new double[hdim];
47  }
48  ~GenericVariable ()
49  {
50  delete [] data;
51  }
52  GenericVariable & operator= (const GenericVariable & v2)
53  {
54  dim = v2.dim;
55  iscomplex = v2.iscomplex;
56  int hdim = iscomplex ? 2*dim : dim;
57  delete [] data;
58  data = new double[hdim];
59  for (int j = 0; j < hdim; j++)
60  data[j] = v2.data[j];
61  return *this;
62  }
63 
64  int Dimension() const { return dim; }
65  bool IsComplex () const { return iscomplex; }
66 
67  double & ValueDouble(int i = 0) { return data[i]; }
68  complex<double> & ValueComplex (int i = 0)
69  { return reinterpret_cast<std::complex<double>*>(data)[i]; }
70 
71  const double & ValueDouble(int i = 0) const { return data[i]; }
72  const std::complex<double> & ValueComplex (int i = 0) const
73  { return reinterpret_cast<complex<double>*>(data)[i]; }
74 
75 
76  template <typename SCAL> SCAL Value (int i) const;
77  };
78 
79  template<>
80  inline double GenericVariable::Value<double> (int i) const
81  {
82  if (iscomplex) throw Exception ("Value<double> called for complex variable");
83  return data[i];
84  }
85  template<>
86  inline std::complex<double> GenericVariable::Value<std::complex<double>> (int i) const
87  {
88  if (iscomplex)
89  return complex<double> (data[2*i], data[2*i+1]);
90  else
91  return complex<double> (data[i]);
92  }
93 
94 
95  inline ostream & operator<< (ostream & ost, const GenericVariable & var)
96  {
97  if (var.IsComplex())
98  for (int i = 0; i < var.Dimension(); i++)
99  ost << var.ValueComplex(i) << ", ";
100  else
101  for (int i = 0; i < var.Dimension(); i++)
102  ost << var.ValueDouble(i) << ", ";
103  return ost;
104  }
105 
106 
107 
108 
109 
110 
111 
112 
113 
120 class NGS_DLL_HEADER EvalFunction
121 {
122 
124  enum EVAL_TOKEN
125  {
126  ADD = '+', SUB = '-', MULT = '*', DIV = '/', LP ='(', RP = ')',
127  COMMA = ',',
128  NEG = 100,
129  VEC_ADD, VEC_SUB, VEC_SCAL_MULT, SCAL_VEC_MULT, VEC_VEC_MULT, VEC_SCAL_DIV, VEC_ELEM, VEC_DIM,
130  AND, OR, NOT, GREATER, LESS, GREATEREQUAL, LESSEQUAL, EQUAL,
131  CONSTANT, IMAG, VARIABLE, FUNCTION, GLOBVAR, GLOBGENVAR, /* COEFF_FUNC,*/ END, STRING,
132  SIN, COS, TAN, ATAN, ATAN2, EXP, LOG, ABS, SIGN, SQRT, STEP,
133  BESSELJ0, BESSELY0, BESSELJ1, BESSELY1
134  };
135 
136 public:
138  EvalFunction ();
140  EvalFunction (istream & aist);
142  EvalFunction (const string & str);
144  EvalFunction (const EvalFunction & eval2);
146  virtual ~EvalFunction ();
147 
149  bool Parse (istream & aist);
151  void DefineConstant (const string & name, double val);
153  void DefineGlobalVariable (const string & name, double * var);
155  void DefineGlobalVariable (const string & name, GenericVariable * var);
157  void DefineArgument (const string & name, int num, int vecdim = 1, bool iscomplex = false);
158 
160  double Eval (const double * x = NULL) const;
162  void Eval (const double * x, double * y, int ydim) const;
163 
165  complex<double> Eval (const complex<double> * x = NULL) const;
167  void Eval (const complex<double> * x, complex<double> * y, int ydim) const;
169  void Eval (const complex<double> * x, double * y, int ydim) const;
170 
171  /*
173  template <typename TIN>
174  void Eval (const TIN * x, complex<double> * y, int ydim) const;
175  */
176  template <typename TIN, typename TCALC>
177  void Eval (const TIN * x, TCALC * stack) const;
178 
179 
181  bool IsComplex () const;
182 
184  bool IsResultComplex () const { return res_type.iscomplex; }
185 
187  bool IsConstant () const;
189  double EvalConstant () const;
190 
192  int Dimension() const { return res_type.vecdim; }
193 
195  void AddConstant (double val)
196  { program.Append (step (val)); }
197 
199  void AddVariable (int varnum)
200  { program.Append (step(varnum)); }
201 
203  void AddGlobVariable (const double * dp)
204  { program.Append (step(dp)); }
205 
208  { program.Append (step(dp)); }
209 
211  void AddOperation (EVAL_TOKEN op)
212  { program.Append (step(op)); }
213 
215  void AddFunction (double (*fun) (double))
216  { program.Append (step(fun)); }
217 
219  void Print (ostream & ost) const;
220 protected:
221 
223  class step
224  {
225  public:
227  EVAL_TOKEN op;
229  union UNION_OP
230  {
232  double val;
234  const double *globvar;
238  int varnum;
240  double (*fun) (double);
241  };
243  UNION_OP operand;
244 
246  short int vecdim;
247 
248  step () { ; }
249 
250  step (EVAL_TOKEN hop)
251  {
252  op = hop;
253  operand.val = 0;
254  }
255 
256  step (double hval)
257  {
258  op = CONSTANT;
259  operand.val = hval;
260  }
261 
262  step (int varnum)
263  {
264  op = VARIABLE;
265  operand.varnum = varnum;
266  }
267 
268  step (const double * aglobvar)
269  {
270  op = GLOBVAR;
271  operand.globvar = aglobvar;
272  }
273 
274  step (const GenericVariable * aglobvar)
275  {
276  op = GLOBGENVAR;
277  operand.globgenvar = aglobvar;
278  }
279 
280  step (double (*fun) (double))
281  {
282  op = FUNCTION;
283  operand.fun = fun;
284  }
285  };
286 
288  Array<step> program;
289 
291  {
292  public:
293  int vecdim;
294  bool isbool;
295  bool iscomplex;
296  ResultType ()
297  : vecdim(1), isbool(false), iscomplex(false)
298  { ; }
299  };
300 
301  ResultType res_type;
302  const double eps;
303 
305  ResultType ParseExpression ();
307  ResultType ParseCommaExpression ();
309  ResultType ParseSubExpression ();
311  ResultType ParseTerm ();
313  ResultType ParsePrimary ();
314 
316  istream * ist;
317 
319  EVAL_TOKEN token;
321  double num_value;
323  char string_value[1000];
325  int var_num, var_dim;
327  bool var_iscomplex;
329  double * globvar;
330  GenericVariable * globgenvar;
331  streampos lastpos;
332 
333  typedef double(*TFUNP) (double);
335  static SymbolTable<TFUNP> functions;
336 
338  SymbolTable<double> constants;
339 
341  SymbolTable<double*> globvariables;
343  SymbolTable<GenericVariable*> genericvariables;
344 
345 public:
347  struct argtype
348  {
349  int argnum;
350  int dim;
351  bool iscomplex;
352  public:
353  argtype ()
354  : argnum(-1), dim(1), iscomplex(false) { ; }
355  argtype (int aanum, int adim = 1, bool acomplex = false)
356  : argnum(aanum), dim(adim), iscomplex(acomplex) { ; }
357  };
358  SymbolTable<argtype> arguments;
359  int num_arguments;
360 
362  EVAL_TOKEN GetToken() const
363  { return token; }
364 
366  double GetNumValue() const
367  { return num_value; }
368 
370  int GetVariableNumber() const
371  { return var_num; }
374  { return var_dim; }
375  bool GetVariableIsComplex() const
376  { return var_iscomplex; }
377 
379  const char * GetStringValue() const
380  { return string_value; }
381 
383  void ReadNext(bool optional = true);
384  void WriteBack();
385 
386  bool ToBool (double x) const { return x > eps; }
387  bool ToBool (complex<double> x) const { return x.real() > eps; }
388  double CheckReal (double x) const { return x; }
389  double CheckReal (complex<double> x) const
390  {
391  if (x.imag() != 0) cerr << "illegal complex value" << endl;
392  return x.real();
393  }
394 
395  double Abs (double x) const { return std::fabs(x); }
396  double Abs (complex<double> x) const { return abs(x); }
397 };
398 
399 
400 }
401 
402 
403 #endif
404 
405 
ngstd::EvalFunction::ResultType
Definition: evalfunc.hpp:290
ngstd::EvalFunction::AddGlobVariable
void AddGlobVariable(const GenericVariable *dp)
push pointer to global double value.
Definition: evalfunc.hpp:207
ngstd::EvalFunction::IsResultComplex
bool IsResultComplex() const
is expression complex valued ?
Definition: evalfunc.hpp:184
ngstd::EvalFunction::step::vecdim
short int vecdim
dimension of vector
Definition: evalfunc.hpp:246
ngstd::EvalFunction::GetStringValue
const char * GetStringValue() const
returns identifier of last token
Definition: evalfunc.hpp:379
ngstd::EvalFunction::step::UNION_OP::globvar
const double * globvar
a pointer to a global variable
Definition: evalfunc.hpp:234
ngstd::EvalFunction::argtype
the arguments passed to the function
Definition: evalfunc.hpp:347
ngstd::EvalFunction::AddGlobVariable
void AddGlobVariable(const double *dp)
push pointer to global double value.
Definition: evalfunc.hpp:203
ngstd::EvalFunction::GetVariableNumber
int GetVariableNumber() const
returns variable number of last token
Definition: evalfunc.hpp:370
ngstd::EvalFunction::step::UNION_OP::varnum
int varnum
the input argument number varnum
Definition: evalfunc.hpp:238
ngstd::EvalFunction::Dimension
int Dimension() const
vector dimension of result
Definition: evalfunc.hpp:192
ngstd::EvalFunction::ist
istream * ist
parse from stream
Definition: evalfunc.hpp:316
ngstd::EvalFunction::globvariables
SymbolTable< double * > globvariables
registered variables
Definition: evalfunc.hpp:341
ngstd::EvalFunction::AddVariable
void AddVariable(int varnum)
push variable x[varnum-1].
Definition: evalfunc.hpp:199
ngstd::EvalFunction::step::UNION_OP::globgenvar
const GenericVariable * globgenvar
a pointer to a global variable
Definition: evalfunc.hpp:236
ngstd::EvalFunction::step::UNION_OP::fun
double(* fun)(double)
a pointer to a unary function
Definition: evalfunc.hpp:240
ngstd::EvalFunction::step
one step of evaluation
Definition: evalfunc.hpp:223
ngstd::EvalFunction::GetNumValue
double GetNumValue() const
returns num_value of last token
Definition: evalfunc.hpp:366
ngstd::EvalFunction::functions
static SymbolTable< TFUNP > functions
registered functions
Definition: evalfunc.hpp:335
ngstd::EvalFunction::step::UNION_OP::val
double val
a constant value
Definition: evalfunc.hpp:232
ngstd::EvalFunction::program
Array< step > program
the evaluation sequence
Definition: evalfunc.hpp:288
ngstd::EvalFunction::step::UNION_OP
the data
Definition: evalfunc.hpp:229
ngstd::EvalFunction::AddOperation
void AddOperation(EVAL_TOKEN op)
push operation.
Definition: evalfunc.hpp:211
ngstd::EvalFunction
Numerical expression parser.
Definition: evalfunc.hpp:120
ngstd::GenericVariable
Definition: evalfunc.hpp:17
ngstd::EvalFunction::constants
SymbolTable< double > constants
registered constants
Definition: evalfunc.hpp:338
ngstd
namespace for standard data types and algorithms.
Definition: ngstd.hpp:55
ngstd::EvalFunction::GetVariableDimension
int GetVariableDimension() const
returns dimension of variable of last token
Definition: evalfunc.hpp:373
ngstd::EvalFunction::genericvariables
SymbolTable< GenericVariable * > genericvariables
registered variables
Definition: evalfunc.hpp:343
ngstd::operator<<
ostream & operator<<(ostream &ost, const AutoDiffDiff< D, SCAL > &x)
Prints AudoDiffDiff.
Definition: autodiffdiff.hpp:256
ngstd::EvalFunction::AddFunction
void AddFunction(double(*fun)(double))
push function call.
Definition: evalfunc.hpp:215
ngstd::EvalFunction::GetToken
EVAL_TOKEN GetToken() const
returns last token
Definition: evalfunc.hpp:362
ngstd::EvalFunction::AddConstant
void AddConstant(double val)
push constant on stack.
Definition: evalfunc.hpp:195