Nektar++
AnalyticExpressionEvaluator.hpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File AnalyticExpressionEvaluator.hpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: Parser and evaluator of analytic expressions.
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
36 #ifndef _ANALYTIC_EXPRESSION_EVALUATOR_HPP
37 #define _ANALYTIC_EXPRESSION_EVALUATOR_HPP
38 
42 
43 #include <boost/version.hpp>
44 #include <boost/random/mersenne_twister.hpp> // for mt19937
45 #include <boost/random/variate_generator.hpp> // for variate_generator
46 #include <boost/random/normal_distribution.hpp>
47 
48 #define BOOST_SPIRIT_THREADSAFE
49 #if( BOOST_VERSION / 100 % 1000 >= 36 )
50 #include <boost/spirit/include/classic_core.hpp>
51 #include <boost/spirit/include/classic_ast.hpp>
52 #include <boost/spirit/include/classic_symbols.hpp>
53 #include <boost/spirit/include/classic_assign_actor.hpp>
54 #include <boost/spirit/include/classic_push_back_actor.hpp>
55 
56 namespace boost_spirit = boost::spirit::classic;
57 #else
58 #include <boost/spirit/core.hpp>
59 #include <boost/spirit/tree/ast.hpp>
60 #include <boost/spirit/symbols/symbols.hpp>
61 #include <boost/spirit/actor/assign_actor.hpp>
62 #include <boost/spirit/actor/push_back_actor.hpp>
63 
64 namespace boost_spirit = boost::spirit;
65 #endif
66 
67 #include <string>
68 #include <vector>
69 #include <map>
70 #if defined(__INTEL_COMPILER)
71 #include <mathimf.h>
72 #else
73 #include <cmath>
74 #endif
75 
76 namespace Nektar
77 {
78  namespace LibUtilities
79  {
81  {
82  if (x != 0. || y != 0.)
83  return sqrt (x*x + y*y);
84  else
85  return 0.;
86  }
87 
89  {
90  NekDouble theta = 0.;
91  if ((x != 0.) || (y != 0.))
92  theta = atan2 (y,x);
93  return theta;
94  }
95 
96  /// This class defines evaluator of analytic (symbolic)
97  /// mathematical expressions. Expressions are allowed to
98  /// depend on a number of spatial-time variables and
99  /// parameters. Pre-processing and evaluation stages are
100  /// split. At evaluation stage one specifies values for
101  /// each variable, resulting expression value is returned.
102  /// Vectorized evaluator (evaluate expression at a set of
103  /// points) is available.
104  ///
105  /// Internally this class uses boost::spirit to parse analytic
106  /// expressions and unrolls their recursive bracketing structure
107  /// into a sequence of evaluation steps (aka execution stack)
108  /// with resolved data dependencies. Once an expression is
109  /// pre-processed, its execution stack is stored internally
110  /// in order to be re-used.
111 
113  {
114 
115  private:
116 
118 
119  public:
120 
121 
122  typedef std::map<std::string, int> VariableMap;
123  typedef std::map<std::string, int> ConstantMap;
124  typedef std::map<std::string, int> ParameterMap;
125  typedef std::map<std::string, int> ExpressionMap;
126  typedef std::map<std::string, int> FunctionNameMap;
127  typedef std::vector<EvaluationStep*> ExecutionStack;
128  typedef std::pair<bool, NekDouble> PrecomputedValue;
131 
132  typedef boost_spirit::tree_parse_info<
133  std::string::const_iterator,
134  boost_spirit::node_val_data_factory<NekDouble>
136  typedef boost_spirit::tree_match<
137  std::string::const_iterator,
138  boost_spirit::node_val_data_factory<NekDouble>
139  >::tree_iterator ParsedTreeIterator;
140 
141  typedef std::vector<const Array<OneD, const NekDouble>* > VariableArray;
142 
143  typedef boost::mt19937 RandomGeneratorType;
144 
145 
146  // ======================================
147  // Methods
148  // ======================================
149 
150 
151  /// Initializes the evaluator to a state where it is ready to accept input
152  /// from the #DefineFunction function.
154 
155  /// Destroys the execution stack.
157 
158 
159  // ======================================
160  // Setting up methods
161  // ======================================
162 
163 
164  LIB_UTILITIES_EXPORT void SetRandomSeed(unsigned int seed = 123u);
165 
166  /// Constants are evaluated and inserted into the function at the time it is parsed
167  /// when calling the #DefineFunction function. After parsing, if a constant is
168  /// changed, it will not be reflected in the function when Evaluate is called. This
169  /// also means that if a function with an unknown constant is added, and then the
170  /// constant is added, the function will not see the added constant and through an
171  /// exception. This function will add all of the constants in the map argument to
172  /// the global internal constants. If a constant was already loaded previously, it will
173  /// throw an exception stating which constants in the map had this issue. It will add
174  /// all of the constants it can and output the constants it couldn't add in the string
175  /// exception.
176  LIB_UTILITIES_EXPORT void AddConstants(std::map<std::string, NekDouble> const& constants);
177 
178  /// This function behaves in the same way as #AddConstants, but it only adds one
179  /// constant at a time. If the constant existed previously, an exception will be thrown
180  /// stating the fact. If it did not exist previously, it will be added to the global
181  /// constants and will be used the next time #DefineFunction is called.
182  LIB_UTILITIES_EXPORT int AddConstant(std::string const& name, NekDouble value);
183 
184  /// If a constant with the specified name exists, it returns the NekDouble value that the
185  /// constant stores. If the constant doesn't exist, it throws an exception.
186  LIB_UTILITIES_EXPORT NekDouble GetConstant(std::string const& name);
187 
188  /// Parameters are like constants, but they are inserted into the function at the time
189  /// #Evaluate is called instead of when the function is parsed. This function can
190  /// be called at any time, and it will take effect in the next call to #Evaluate.
191  /// This function will delete all of the parameters, and replace all of them with only
192  /// the ones in the map argument.
193  LIB_UTILITIES_EXPORT void SetParameters(std::map<std::string, NekDouble> const& params);
194 
195  /// This function behaves in the same way as #SetParameters, but it only adds one
196  /// parameter and it does not delete the others. If the parameter existed previously,
197  /// it will be overridden and replaced with the new value. If it did not exist previously,
198  /// it will be added to the current parameters.
199  LIB_UTILITIES_EXPORT void SetParameter(std::string const& name, NekDouble value);
200 
201  /// If a parameter with the specified name exists, it returns the NekDouble value that the
202  /// parameter stores. If the parameter doesn't exist, it throws an exception.
203  LIB_UTILITIES_EXPORT NekDouble GetParameter(std::string const& name);
204 
205  /// Returns the total time spent in evaluation procedures, seconds.
206  LIB_UTILITIES_EXPORT NekDouble GetTime() const;
207 
208 
209  // ======================================================
210  // Parsing and evaluation methods
211  // ======================================================
212 
213 
214  /// This function allows one to define a function to evaluate. The first argument (vlist)
215  /// is a list of variables (separated by spaces) that the second argument (function)
216  /// depends on. For example, if function = "x + y", then vlist should most likely be
217  /// "x y", unless you are defining x or y as parameters with #SetParameters.
218  /// \output parsed expression ID. You will need this expression id to call evaluation
219  /// methods below.
220  LIB_UTILITIES_EXPORT int DefineFunction(const std::string& vlist, const std::string& function);
221 
222 
223  /// Evaluation method for expressions depending on parameters only.
224  LIB_UTILITIES_EXPORT NekDouble Evaluate(const int AnalyticExpression_id);
225 
226  /// Evaluation method for expressions depending on 4 variables (+parameters).
227  LIB_UTILITIES_EXPORT NekDouble Evaluate(
228  const int AnalyticExpression_id,
229  const NekDouble,
230  const NekDouble,
231  const NekDouble,
232  const NekDouble);
233 
234  /// Evaluation method for expressions depending on unspecified number of variables.
235  /// This suitable for expressions depending on more than 4 variables or for the dynamic
236  /// setting some variables as parameters (there is currently no interface method
237  /// for removing a variable from parameter map though).
239  const int AnalyticExpression_id,
240  std::vector<NekDouble> point);
241 
242  /// Vectorized evaluation method for expressions depending on 4 variables.
244  const int expression_id,
249  Array<OneD, NekDouble>& result);
250 
251 
252 
253  /// Vectorized evaluation method for expressions depending on unspecified
254  /// number of variables.
256  const int expression_id,
257  const std::vector<Array<OneD, const NekDouble> > points,
258  Array<OneD, NekDouble>& result);
259 
260  private:
261 
262  // ======================================================
263  // Private parsing and partial evaluation method
264  // ======================================================
265 
266  /// This method prepares the execution stack (an ordered sequence of
267  /// operators that perform the evaluation) for the parsed evaluation tree.
268  ///
269  /// In order to do this, it unrolls binary tree representing
270  /// the recursive evaluation into an ordered sequence of commands.
271  /// That ordered sequence of commands is equivalent to bottom-up
272  /// walk up the evaluation tree, but this allows not to form tree explicitly.
273  ///
274  /// This approach requires to introduce explicitly an execution state
275  /// (memory) shared by commands in the evaluation sequence: recursively
276  /// dependent commands need to pass data between each other. Such state
277  /// for the recursive evaluation is passed via return values of a recursive
278  /// evaluation function --- which is bad if one wants to implement vectorized
279  /// evaluator.
280  ///
281  /// On the other hand, to run through a sequential container of
282  /// functors is faster than to walk the tree and at each node to check
283  /// the node type.
284  ///
285  /// \input root - iterator generated by boost::spirit;
286  /// stack - initially empty sequential container of evaluation steps;
287  /// varMap - maps variable names to their ids;
288  /// stateIndex - an index in state[] array where an evaluation
289  /// step corresponding to the current tree node
290  /// is allowed to write.
291  /// \output an std::pair<bool, NekDouble> which encodes fully pre-evaluated
292  /// NekDouble value as pair <true, value> if all sub-tree down the
293  /// current node evaluates to constant, or flags the opposite
294  /// via pair <false,0>.
296  const ParsedTreeIterator& root,
297  ExecutionStack& stack,
298  VariableMap &varMap,
299  int stateIndex);
300 
301 
302  // ======================================================
303  // Boost::spirit related data structures
304  // ======================================================
305 
306 
307  /** This is a parser for spirit that parses the CONSTANT values. The default
308  constants are those that are in math.h without the M_ prefix and they are
309  initialized in the AnalyticExpressionEvaluator constructor. **/
310 
311  boost_spirit::symbols<NekDouble> m_constantsParser;
312 
313 
314  /** This is the class that is used as the grammar parser for the spirit engine. **/
315  class AnalyticExpression : public boost_spirit::grammar<AnalyticExpression>
316  {
317  private:
318  const boost_spirit::symbols<NekDouble>* constants_p;
319 
320  /** Variables is a customized parser that will match the variables that the function
321  depends on (the first argument of #DefineFunction). **/
322  struct variables : boost_spirit::symbols<NekDouble*>
323  {
324  variables(std::vector<std::string> const& vars)
325  {
326  for (std::vector<std::string>::const_iterator it = vars.begin(); it != vars.end(); it++)
327  add(it->c_str(), 0);
328  }
329  } variables_p;
330 
331  public:
332  /** These constants are used to determine what parser was used to parse what value,
333  which allows for type identification when analyzing the parsed AST. **/
334  static const int constantID = 1;
335  static const int numberID = 2;
336  static const int variableID = 3;
337  static const int parameterID = 4;
338  static const int functionID = 5;
339  static const int factorID = 6;
340  static const int operatorID = 7;
341 
342  AnalyticExpression(const boost_spirit::symbols<NekDouble>* constants, const std::vector<std::string>& variables) :
343  boost_spirit::grammar<AnalyticExpression>(), constants_p(constants), variables_p(variables) {}
344 
345  // Trivial constructor to avoid compiler warning with
346  // constants_p.
348  {
349  constants_p = NULL;
350  }
351 
352  template <typename ScannerT>
353  struct definition
354  {
355  /** This function specifies the grammar of the MathAnalyticExpression parser. **/
356  definition(AnalyticExpression const& self);
357 
358  /** This holds the NekDouble value that is parsed by spirit so it can be stored in the AST. **/
359  NekDouble ParsedDouble;
360 
361  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<constantID> > constant;
362  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<numberID> > number;
363  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<variableID> > variable;
364  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<parameterID> > parameter;
365  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<functionID> > function;
366  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<factorID> > factor;
367  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<operatorID> > exponential;
368  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<operatorID> > mult_div;
369  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<operatorID> > add_sub;
370  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<operatorID> > lt_gt;
371  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<operatorID> > equality;
372  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<operatorID> > logical_and;
373  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<operatorID> > logical_or;
374  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<operatorID> > expression;
375  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<operatorID> > op;
376 
377  boost_spirit::rule<ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag<operatorID> > const&
378  start() const { return expression; }
379  };
380  }; // class AnalyticExpression
381 
382 
383 
384  // ======================================================
385  // Pre-processed expressions
386  // ======================================================
387 
388  /// These vector and map store pre-processed evaluation sequences
389  /// for the analytic expressions. Each ExecutionStack is an ordered
390  /// container of steps of sequential execution process which
391  /// evaluates an analytic expression.
392 
394  std::vector<ExecutionStack> m_executionStack;
395 
396  /// Keeping map of variables individually per each analytic expression
397  /// allows correctly handling expressions which depend on different
398  /// number of variables.
399 
400  std::vector<VariableMap> m_stackVariableMap;
401 
402  // ======================================================
403  // Execution state and data
404  // ======================================================
405 
406  /// The following data structures hold input data to be used on evaluation
407  /// stage. There are three types of input data:
408  /// - constants (never change their value)
409  /// - parameters are allowed to change their values between evaluations
410  /// (compared to constants)
411  /// - variables always change their values at every evaluation call.
412  /// First map looks like <parameter_name, parameter_id> while the second is
413  /// <parameter_id, parameter_value>. The map is used at a preparation
414  /// stage when the analytic expression is parsed. This associates an integer
415  /// id with a parameter name in its string form. On evaluation stage the id
416  /// and a std::vector constant lookup time make evaluation faster compared
417  /// to permanent std::map<std::string, NekDouble> lookup.
418 
422 
423  std::vector<NekDouble> m_parameter;
424  std::vector<NekDouble> m_constant;
425  std::vector<NekDouble> m_variable;
426 
427 
428  /// This vector stores the execution state (memory) used by the
429  /// sequential execution process.
430  std::vector<NekDouble> m_state;
431 
432  /// Vector of state sizes per each
433  std::vector<int> m_state_sizes;
434 
435  /// This counter is used by PrepareExecutionAsYouParse for finding
436  /// the minimal state size necessary for evaluation of function parsed.
438 
439 
440  /// Timer and sum of evaluation times
442  NekDouble m_total_eval_time;
443 
444 
445  RandomGeneratorType m_generator;
446  // boost::variate_generator<RandomGeneratorType&, boost::normal_distribution<> >
447  // m_normal;
448 
449 
450 
451  // ======================================================
452  // A map of (external) mathematical functions
453  // ======================================================
454 
455 
457  std::map<int, OneArgFunc> m_function;
458  std::map<int, TwoArgFunc> m_function2;
459 
460 
461  // ======================================================
462  // Internal representation of evaluation step
463  // ======================================================
464 
465  /// Short names to minimise the infractructural code mess in defining functors below.
466  typedef std::vector<NekDouble>& vr;
467  typedef const std::vector<NekDouble>& cvr;
468  typedef const int ci;
469  typedef RandomGeneratorType& rgt;
470 
471  /// Factory method which makes code little less messy
472  template<typename StepType>
473  EvaluationStep* makeStep(ci dest, ci src_left = 0, ci src_right = 0)
474  {
475  return ( new StepType ( m_generator,m_state,m_constant,m_parameter,m_variable,dest,src_left,src_right ) );
476  }
477 
479  {
484  };
485 
486 
487 
488  /// Function objects (functors)
490  {
491  /// reference to random number generator
492  rgt rng;
493 
494  /// references to arrays holding the common state
495  vr state;
496  cvr consts;
497  cvr params;
498  cvr vars;
499 
500  /// indices in the above arrays uniquely defining actual command arguments
504 
505  EvaluationStep(rgt rn, ci i, ci l, ci r, vr s, cvr c, cvr p, cvr v):
506  rng(rn), state(s), consts(c), params(p), vars(v), storeIdx(i), argIdx1(l), argIdx2(r) {};
507 
508  virtual ~EvaluationStep() {}
509 
510  /// declaring this guy pure virtual shortens virtual table. It saves some execution time.
511  virtual void run_many(ci n) = 0;
512  virtual void run_once() = 0;
513  };
514  struct CopyState: public EvaluationStep
515  {
516  CopyState(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
517  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = state[argIdx1]; }
518  virtual void run_once() { state[storeIdx] = state[argIdx1]; }
519  };
520  struct StoreConst: public EvaluationStep
521  {
522  StoreConst(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
523  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = consts[argIdx1]; }
524  virtual void run_once() { state[storeIdx] = consts[argIdx1]; }
525  };
526  struct StoreVar: public EvaluationStep
527  {
528  StoreVar(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
529  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = vars[argIdx1*n+i]; }
530  virtual void run_once() { state[storeIdx] = vars[argIdx1]; }
531  };
532  struct StorePrm: public EvaluationStep
533  {
534  StorePrm(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
535  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = params[argIdx1]; }
536  virtual void run_once() { state[storeIdx] = params[argIdx1]; }
537  };
538  struct EvalSum: public EvaluationStep
539  {
540  EvalSum(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
541  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = state[argIdx1*n+i] + state[argIdx2*n+i]; }
542  virtual void run_once() { state[storeIdx] = state[argIdx1] + state[argIdx2]; }
543  };
544  struct EvalSub: public EvaluationStep
545  {
546  EvalSub(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
547  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = state[argIdx1*n+i] - state[argIdx2*n+i]; }
548  virtual void run_once() { state[storeIdx] = state[argIdx1] - state[argIdx2]; }
549  };
550  struct EvalMul: public EvaluationStep
551  {
552  EvalMul(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
553  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = state[argIdx1*n+i] * state[argIdx2*n+i]; }
554  virtual void run_once() { state[storeIdx] = state[argIdx1] * state[argIdx2]; }
555  };
556  struct EvalDiv: public EvaluationStep
557  {
558  EvalDiv(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
559  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = state[argIdx1*n+i] / state[argIdx2*n+i]; }
560  virtual void run_once() { state[storeIdx] = state[argIdx1] / state[argIdx2]; }
561  };
562  struct EvalPow: public EvaluationStep
563  {
564  EvalPow(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
565  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::pow( state[argIdx1*n+i], state[argIdx2*n+i] ); }
566  virtual void run_once() { state[storeIdx] = std::pow( state[argIdx1], state[argIdx2] ); }
567  };
568  struct EvalNeg: public EvaluationStep
569  {
570  EvalNeg(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
571  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = - state[argIdx1*n+i]; }
572  virtual void run_once() { state[storeIdx] = - state[argIdx1]; }
573  };
575  {
576  EvalLogicalEqual(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
577  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = ( state[argIdx1*n+i] == state[argIdx2*n+i] ); }
578  virtual void run_once() { state[storeIdx] = ( state[argIdx1] == state[argIdx2] ); }
579  };
581  {
582  EvalLogicalLeq(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
583  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = ( state[argIdx1*n+i] <= state[argIdx2*n+i] ); }
584  virtual void run_once() { state[storeIdx] = ( state[argIdx1] <= state[argIdx2] ); }
585  };
587  {
588  EvalLogicalLess(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
589  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = ( state[argIdx1*n+i] < state[argIdx2*n+i] ); }
590  virtual void run_once() { state[storeIdx] = ( state[argIdx1] < state[argIdx2] ); }
591  };
593  {
594  EvalLogicalGeq(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
595  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = ( state[argIdx1*n+i] >= state[argIdx2*n+i] ); }
596  virtual void run_once() { state[storeIdx] = ( state[argIdx1] >= state[argIdx2] ); }
597  };
599  {
600  EvalLogicalGreater(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
601  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = ( state[argIdx1*n+i] > state[argIdx2*n+i] ); }
602  virtual void run_once() { state[storeIdx] = ( state[argIdx1] > state[argIdx2] ); }
603  };
604  struct EvalAbs: public EvaluationStep
605  {
606  EvalAbs(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
607  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::abs( state[argIdx1*n+i] ); }
608  virtual void run_once() { state[storeIdx] = std::abs( state[argIdx1] ); }
609  };
610  struct EvalSign: public EvaluationStep
611  {
612  EvalSign(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
613  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = ((state[argIdx1*n+i] > 0.0) - (state[argIdx1*n+i] < 0.0)); }
614  virtual void run_once() { state[storeIdx] = ((state[argIdx1] > 0.0) - (state[argIdx1] < 0.0)); }
615  };
616  struct EvalAsin: public EvaluationStep
617  {
618  EvalAsin(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
619  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::asin( state[argIdx1*n+i] ); }
620  virtual void run_once() { state[storeIdx] = std::asin( state[argIdx1] ); }
621  };
622  struct EvalAcos: public EvaluationStep
623  {
624  EvalAcos(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
625  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::acos( state[argIdx1*n+i] ); }
626  virtual void run_once() { state[storeIdx] = std::acos( state[argIdx1] ); }
627  };
628  struct EvalAtan: public EvaluationStep
629  {
630  EvalAtan(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
631  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::atan( state[argIdx1*n+i] ); }
632  virtual void run_once() { state[storeIdx] = std::atan( state[argIdx1] ); }
633  };
634  struct EvalAtan2: public EvaluationStep
635  {
636  EvalAtan2(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
637  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::atan2( state[argIdx1*n+i], state[argIdx2*n+i] ); }
638  virtual void run_once() { state[storeIdx] = std::atan2( state[argIdx1], state[argIdx2] ); }
639  };
640  struct EvalAng: public EvaluationStep
641  {
642  EvalAng(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
643  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = ang( state[argIdx1*n+i], state[argIdx2*n+i] ); }
644  virtual void run_once() { state[storeIdx] = ang( state[argIdx1], state[argIdx2] ); }
645  };
646  struct EvalCeil: public EvaluationStep
647  {
648  EvalCeil(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
649  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::ceil( state[argIdx1*n+i] ); }
650  virtual void run_once() { state[storeIdx] = std::ceil( state[argIdx1] ); }
651  };
652  struct EvalCos: public EvaluationStep
653  {
654  EvalCos(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
655  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::cos( state[argIdx1*n+i] ); }
656  virtual void run_once() { state[storeIdx] = std::cos( state[argIdx1] ); }
657  };
658  struct EvalCosh: public EvaluationStep
659  {
660  EvalCosh(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
661  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::cosh( state[argIdx1*n+i] ); }
662  virtual void run_once() { state[storeIdx] = std::cosh( state[argIdx1] ); }
663  };
664  struct EvalExp: public EvaluationStep
665  {
666  EvalExp(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
667  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::exp( state[argIdx1*n+i] ); }
668  virtual void run_once() { state[storeIdx] = std::exp( state[argIdx1] ); }
669  };
670  struct EvalFabs: public EvaluationStep
671  {
672  EvalFabs(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
673  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::fabs( state[argIdx1*n+i] ); }
674  virtual void run_once() { state[storeIdx] = std::fabs( state[argIdx1] ); }
675  };
676  struct EvalFloor: public EvaluationStep
677  {
678  EvalFloor(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
679  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::floor( state[argIdx1*n+i] ); }
680  virtual void run_once() { state[storeIdx] = std::floor( state[argIdx1] ); }
681  };
682  struct EvalLog: public EvaluationStep
683  {
684  EvalLog(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
685  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::log( state[argIdx1*n+i] ); }
686  virtual void run_once() { state[storeIdx] = std::log( state[argIdx1] ); }
687  };
688  struct EvalLog10: public EvaluationStep
689  {
690  EvalLog10(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
691  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::log10( state[argIdx1*n+i] ); }
692  virtual void run_once() { state[storeIdx] = std::log10( state[argIdx1] ); }
693  };
694  struct EvalRad: public EvaluationStep
695  {
696  EvalRad(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
697  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = rad( state[argIdx1*n+i], state[argIdx2*n+i] ); }
698  virtual void run_once() { state[storeIdx] = rad( state[argIdx1], state[argIdx2] ); }
699  };
700  struct EvalSin: public EvaluationStep
701  {
702  EvalSin(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
703  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::sin( state[argIdx1*n+i] ); }
704  virtual void run_once() { state[storeIdx] = std::sin( state[argIdx1] ); }
705  };
706  struct EvalSinh: public EvaluationStep
707  {
708  EvalSinh(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
709  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::sinh( state[argIdx1*n+i] ); }
710  virtual void run_once() { state[storeIdx] = std::sinh( state[argIdx1] ); }
711  };
712  struct EvalSqrt: public EvaluationStep
713  {
714  EvalSqrt(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
715  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::sqrt( state[argIdx1*n+i] ); }
716  virtual void run_once() { state[storeIdx] = std::sqrt( state[argIdx1] ); }
717  };
718  struct EvalTan: public EvaluationStep
719  {
720  EvalTan(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
721  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::tan( state[argIdx1*n+i] ); }
722  virtual void run_once() { state[storeIdx] = std::tan( state[argIdx1] ); }
723  };
724  struct EvalTanh: public EvaluationStep
725  {
726  EvalTanh(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
727  virtual void run_many(ci n) { for(int i=0;i<n;i++) state[storeIdx*n+i] = std::tanh( state[argIdx1*n+i] ); }
728  virtual void run_once() { state[storeIdx] = std::tanh( state[argIdx1] ); }
729  };
730  struct EvalAWGN: public EvaluationStep
731  {
732  EvalAWGN(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r): EvaluationStep(rn,i,l,r,s,c,p,v) {}
733  virtual void run_many(ci n)
734  {
735  // assuming the argument to AWGN does not depend on spatial variables =>
736  boost::variate_generator<RandomGeneratorType&, boost::normal_distribution<> >
737  _normal(rng, boost::normal_distribution<>(0, state[storeIdx*n]) );
738  for(int i=0;i<n;i++) { state[storeIdx*n+i] = _normal(); }
739  }
740  virtual void run_once()
741  {
742  boost::variate_generator<RandomGeneratorType&, boost::normal_distribution<> >
743  _normal(rng, boost::normal_distribution<>(0, state[storeIdx]) );
744  state[storeIdx] = _normal();
745  }
746  };
747 
748  };
749  };
750 };
751 
752 #endif // _ANALYTIC_EXPRESSION_EVALUATOR_HPP
static NekDouble ang(NekDouble x, NekDouble y)
EvalLogicalGreater(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
NekDouble GetTime() const
Returns the total time spent in evaluation procedures, seconds.
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< operatorID > > logical_or
std::vector< NekDouble > & vr
Short names to minimise the infractructural code mess in defining functors below. ...
void AddConstants(std::map< std::string, NekDouble > const &constants)
Constants are evaluated and inserted into the function at the time it is parsed when calling the Defi...
boost_spirit::tree_parse_info< std::string::const_iterator, boost_spirit::node_val_data_factory< NekDouble > > ParsedTreeInfo
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
ExpressionMap m_parsedMapExprToExecStackId
These vector and map store pre-processed evaluation sequences for the analytic expressions. Each ExecutionStack is an ordered container of steps of sequential execution process which evaluates an analytic expression.
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< operatorID > > exponential
EvalTanh(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
EvalLogicalLess(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
StorePrm(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
EvalSinh(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< operatorID > > const & start() const
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
std::vector< VariableMap > m_stackVariableMap
Keeping map of variables individually per each analytic expression allows correctly handling expressi...
AnalyticExpression(const boost_spirit::symbols< NekDouble > *constants, const std::vector< std::string > &variables)
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< operatorID > > op
EvalLog(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
void SetParameter(std::string const &name, NekDouble value)
This function behaves in the same way as SetParameters, but it only adds one parameter and it does no...
std::vector< const Array< OneD, const NekDouble > * > VariableArray
EvalFloor(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
int AddConstant(std::string const &name, NekDouble value)
This function behaves in the same way as AddConstants, but it only adds one constant at a time...
EvalExp(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
StoreConst(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
EvalCos(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< parameterID > > parameter
EvalAsin(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
EvaluationStep * makeStep(ci dest, ci src_left=0, ci src_right=0)
Factory method which makes code little less messy.
NekDouble Evaluate(const int AnalyticExpression_id)
Evaluation method for expressions depending on parameters only.
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
std::vector< NekDouble > m_state
This vector stores the execution state (memory) used by the sequential execution process.
EvalRad(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
EvalNeg(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
EvalTan(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
EvalAbs(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
AnalyticExpressionEvaluator(void)
Initializes the evaluator to a state where it is ready to accept input from the DefineFunction functi...
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
NekDouble EvaluateAtPoint(const int AnalyticExpression_id, std::vector< NekDouble > point)
Evaluation method for expressions depending on unspecified number of variables. This suitable for exp...
EvalDiv(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
EvalAtan2(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< operatorID > > mult_div
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
Nektar::LibUtilities::AnalyticExpressionEvaluator::AnalyticExpression::variables variables_p
PrecomputedValue PrepareExecutionAsYouParse(const ParsedTreeIterator &root, ExecutionStack &stack, VariableMap &varMap, int stateIndex)
This method prepares the execution stack (an ordered sequence of operators that perform the evaluatio...
NekDouble GetConstant(std::string const &name)
If a constant with the specified name exists, it returns the NekDouble value that the constant stores...
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
int m_state_size
This counter is used by PrepareExecutionAsYouParse for finding the minimal state size necessary for e...
ParameterMap m_parameterMapNameToId
The following data structures hold input data to be used on evaluation stage. There are three types o...
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
EvalCosh(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< constantID > > constant
StoreVar(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)=0
declaring this guy pure virtual shortens virtual table. It saves some execution time.
#define LIB_UTILITIES_EXPORT
EvalAWGN(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< variableID > > variable
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
EvalAcos(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
double NekDouble
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
EvalLogicalEqual(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
EvalPow(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< operatorID > > equality
EvalMul(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
This class defines evaluator of analytic (symbolic) mathematical expressions. Expressions are allowed...
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< factorID > > factor
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< operatorID > > expression
EvalFabs(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
static NekDouble rad(NekDouble x, NekDouble y)
EvalCeil(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
int DefineFunction(const std::string &vlist, const std::string &function)
This function allows one to define a function to evaluate. The first argument (vlist) is a list of va...
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< numberID > > number
EvalSin(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
EvalLog10(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
std::vector< int > m_state_sizes
Vector of state sizes per each.
EvalLogicalLeq(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
EvalAng(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
NekDouble GetParameter(std::string const &name)
If a parameter with the specified name exists, it returns the NekDouble value that the parameter stor...
EvalSub(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
EvalSum(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
EvalAtan(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
EvalSign(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
EvalLogicalGeq(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< operatorID > > add_sub
CopyState(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
~AnalyticExpressionEvaluator(void)
Destroys the execution stack.
boost_spirit::tree_match< std::string::const_iterator, boost_spirit::node_val_data_factory< NekDouble > >::tree_iterator ParsedTreeIterator
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
EvaluationStep(rgt rn, ci i, ci l, ci r, vr s, cvr c, cvr p, cvr v)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< operatorID > > logical_and
void SetParameters(std::map< std::string, NekDouble > const &params)
Parameters are like constants, but they are inserted into the function at the time Evaluate is called...
EvalSqrt(rgt rn, vr s, cvr c, cvr p, cvr v, ci i, ci l, ci r)
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.
boost_spirit::rule< ScannerT, boost_spirit::parser_context<>, boost_spirit::parser_tag< operatorID > > lt_gt
ci storeIdx
indices in the above arrays uniquely defining actual command arguments
virtual void run_many(ci n)
declaring this guy pure virtual shortens virtual table. It saves some execution time.