CppADCodeGen  2.3.0
A C++ Algorithmic Differentiation Package with Source Code Generation
evaluator.hpp
1 #ifndef CPPAD_CG_EVALUATOR_INCLUDED
2 #define CPPAD_CG_EVALUATOR_INCLUDED
3 /* --------------------------------------------------------------------------
4  * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5  * Copyright (C) 2012 Ciengis
6  *
7  * CppADCodeGen is distributed under multiple licenses:
8  *
9  * - Eclipse Public License Version 1.0 (EPL1), and
10  * - GNU General Public License Version 3 (GPL3).
11  *
12  * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
13  * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
14  * ----------------------------------------------------------------------------
15  * Author: Joao Leal
16  */
17 
18 namespace CppAD {
19 namespace cg {
20 
21 // forward declarations
22 template<class ScalarIn, class ScalarOut, class ActiveOut, class FinalEvaluatorType>
24 
25 template<class ScalarIn, class ScalarOut, class ActiveOut, class Operations>
27 
43 template<class ScalarIn, class ScalarOut, class ActiveOut, class FinalEvaluatorType>
44 class EvaluatorBase {
45  friend FinalEvaluatorType;
46 protected:
47  using SourceCodePath = typename CodeHandler<ScalarIn>::SourceCodePath;
48 protected:
49  CodeHandler<ScalarIn>& handler_;
50  const ActiveOut* indep_;
52  std::map<size_t, std::vector<ActiveOut>* > evalsArrays_;
53  std::map<size_t, std::vector<ActiveOut>* > evalsSparseArrays_;
54  bool underEval_;
55  size_t depth_;
56  SourceCodePath path_;
57 public:
58 
63  handler_(handler),
64  indep_(nullptr),
65  evals_(handler),
66  underEval_(false),
67  depth_(0) { // not really required (but it avoids warnings)
68  }
69 
70  inline virtual ~EvaluatorBase() {
71  clear();
72  }
73 
77  inline bool isUnderEvaluation() {
78  return underEval_;
79  }
80 
92  inline std::vector<ActiveOut> evaluate(ArrayView<const ActiveOut> indepNew,
93  ArrayView<const CG<ScalarIn> > depOld) {
94  std::vector<ActiveOut> depNew(depOld.size());
95 
96  evaluate(indepNew.data(), indepNew.size(), depNew.data(), depOld.data(), depNew.size());
97 
98  return depNew;
99  }
100 
113  inline void evaluate(ArrayView<const ActiveOut> indepNew,
114  ArrayView<ActiveOut> depNew,
115  ArrayView<const CG<ScalarIn> > depOld) {
116  if (depNew.size() != depOld.size()) {
117  throw CGException("Dependent array sizes are different.");
118  }
119 
120  evaluate(indepNew.data(), indepNew.size(), depNew.data(), depOld.data(), depNew.size());
121  }
122 
136  inline void evaluate(const ActiveOut* indepNew,
137  size_t indepSize,
138  ActiveOut* depNew,
139  const CG<ScalarIn>* depOld,
140  size_t depSize) {
141  if (handler_.getIndependentVariableSize() != indepSize) {
142  throw CGException("Invalid independent variable size. Expected ", handler_.getIndependentVariableSize(), " but got ", indepSize, ".");
143  }
144 
145  CPPADCG_ASSERT_KNOWN(handler_.getIndependentVariableSize() == indepSize, "Invalid size the array of independent variables");
146 
147  if (underEval_) {
148  throw CGException("The same evaluator cannot be used for simultaneous evaluations. "
149  "Either use a new one or wait for this one to finish its current evaluation.");
150  }
151 
152  underEval_ = true;
153 
154  clear(); // clean-up from any previous call that might have failed
155  evals_.adjustSize();
156 
157  depth_ = 0;
158  path_.clear();
159 
160  if(path_.capacity() == 0) {
161  path_.reserve(30);
162  }
163 
164  FinalEvaluatorType& thisOps = static_cast<FinalEvaluatorType&>(*this);
165 
166  try {
167  thisOps.prepareNewEvaluation();
168 
169  indep_ = indepNew;
170  thisOps.analyzeOutIndeps(indep_, indepSize);
171 
172  for (size_t i = 0; i < depSize; i++) {
173  CPPADCG_ASSERT_UNKNOWN(depth_ == 0);
174  depNew[i] = evalCG(depOld[i]);
175  }
176 
177  thisOps.clear(); // clean-up
178 
179  } catch (...) {
180  underEval_ = false;
181  throw;
182  }
183 
184  underEval_ = false;
185  }
186 
187 protected:
188 
189  inline void prepareNewEvaluation() {
190  // empty
191  }
192 
196  inline void clear() {
197  evals_.clear();
198 
199  for (const auto& p : evalsArrays_) {
200  delete p.second;
201  }
202  evalsArrays_.clear();
203 
204  for (const auto& p : evalsSparseArrays_) {
205  delete p.second;
206  }
207  evalsSparseArrays_.clear();
208  }
209 
210  inline void analyzeOutIndeps(const ActiveOut* indep,
211  size_t n) {
212  // empty
213  }
214 
215  inline ActiveOut evalCG(const CG<ScalarIn>& dep) {
216  if (dep.isParameter()) {
217  // parameter
218  return ActiveOut(dep.getValue());
219  } else {
220  return evalOperations(*dep.getOperationNode());
221  }
222  }
223 
224  inline ActiveOut evalArg(const std::vector<Argument<ScalarIn> >& args,
225  size_t pos) {
226  return evalArg(args[pos], pos);
227  }
228 
229  inline ActiveOut evalArg(const Argument<ScalarIn>& arg,
230  size_t pos) {
231  if (arg.getOperation() != nullptr) {
232  path_.back().argIndex = pos;
233  ActiveOut a = evalOperations(*arg.getOperation());
234  return a;
235  } else {
236  // parameter
237  return ActiveOut(*arg.getParameter());
238  }
239  }
240 
241  inline const ActiveOut& evalOperations(OperationNode<ScalarIn>& node) {
242  CPPADCG_ASSERT_KNOWN(node.getHandlerPosition() < handler_.getManagedNodesCount(), "this node is not managed by the code handler");
243 
244  // check if this node was previously determined
245  if (evals_[node] != nullptr) {
246  return *evals_[node];
247  }
248 
249  // first evaluation of this node
250  FinalEvaluatorType& thisOps = static_cast<FinalEvaluatorType&>(*this);
251 
252  path_.push_back(OperationPathNode<ScalarIn>(&node, -1));
253  depth_++;
254 
255  ActiveOut result = thisOps.evalOperation(node);
256 
257  // save it for reuse
258  ActiveOut* resultPtr = saveEvaluation(node, ActiveOut(result));
259 
260  depth_--;
261  path_.pop_back();
262 
263  return *resultPtr;
264  }
265 
266  inline ActiveOut* saveEvaluation(const OperationNode<ScalarIn>& node,
267  ActiveOut&& result) {
268  std::unique_ptr<ActiveOut>& resultPtr = evals_[node];
269  CPPADCG_ASSERT_UNKNOWN(resultPtr == nullptr); // not supposed to override existing result
270  resultPtr.reset(new ActiveOut(std::move(result)));
271 
272  ActiveOut* resultPtr2 = resultPtr.get(); // do not use a reference (just in case evals_ is resized)
273 
274  FinalEvaluatorType& thisOps = static_cast<FinalEvaluatorType&>(*this);
275  thisOps.processActiveOut(node, *resultPtr2);
276 
277  return resultPtr2;
278  }
279 
280  inline std::vector<ActiveOut>& evalArrayCreationOperation(const OperationNode<ScalarIn>& node) {
281 
282  CPPADCG_ASSERT_KNOWN(node.getOperationType() == CGOpCode::ArrayCreation, "Invalid array creation operation");
283  CPPADCG_ASSERT_KNOWN(node.getHandlerPosition() < handler_.getManagedNodesCount(), "this node is not managed by the code handler");
284 
285  // check if this node was previously determined
286  auto it = evalsArrays_.find(node.getHandlerPosition());
287  if (it != evalsArrays_.end()) {
288  return *it->second;
289  }
290 
291  const std::vector<Argument<ScalarIn> >& args = node.getArguments();
292  std::vector<ActiveOut>* resultArray = new std::vector<ActiveOut>(args.size());
293 
294  // save it for reuse
295  evalsArrays_[node.getHandlerPosition()] = resultArray;
296 
297  // define its elements
298  for (size_t a = 0; a < args.size(); a++) {
299  (*resultArray)[a] = evalArg(args, a);
300  }
301 
302  return *resultArray;
303  }
304 
305  inline std::vector<ActiveOut>& evalSparseArrayCreationOperation(const OperationNode<ScalarIn>& node) {
306 
307  CPPADCG_ASSERT_KNOWN(node.getOperationType() == CGOpCode::SparseArrayCreation, "Invalid array creation operation");
308  CPPADCG_ASSERT_KNOWN(node.getHandlerPosition() < handler_.getManagedNodesCount(), "this node is not managed by the code handler");
309 
310  // check if this node was previously determined
311  auto it = evalsSparseArrays_.find(node.getHandlerPosition());
312  if (it != evalsSparseArrays_.end()) {
313  return *it->second;
314  }
315 
316  const std::vector<Argument<ScalarIn> >& args = node.getArguments();
317  std::vector<ActiveOut>* resultArray = new std::vector<ActiveOut>(args.size());
318 
319  // save it for reuse
320  evalsSparseArrays_[node.getHandlerPosition()] = resultArray;
321 
322  // define its elements
323  for (size_t a = 0; a < args.size(); a++) {
324  (*resultArray)[a] = evalArg(args, a);
325  }
326 
327  return *resultArray;
328  }
329 
330 };
331 
332 
343 template<class ScalarIn, class ScalarOut, class ActiveOut, class FinalEvaluatorType>
344 class EvaluatorOperations : public EvaluatorBase<ScalarIn, ScalarOut, ActiveOut, FinalEvaluatorType> {
349  friend class EvaluatorBase<ScalarIn, ScalarOut, ActiveOut, FinalEvaluatorType>;
350 public:
353  using ArgIn = Argument<ScalarIn>;
354 public:
356  Base(handler) {
357  }
358 
359  virtual ~EvaluatorOperations() { }
360 
361 protected:
362 
363  using Base::evalArg;
364 
373  inline ActiveOut evalOperation(OperationNode<ScalarIn>& node) {
374  FinalEvaluatorType& thisOps = static_cast<FinalEvaluatorType&>(*this);
375 
376  const CGOpCode code = node.getOperationType();
377  switch (code) {
378  case CGOpCode::Assign:
379  return thisOps.evalAssign(node);
380 
381  case CGOpCode::Abs: // abs(variable)
382  return thisOps.evalAbs(node);
383 
384  case CGOpCode::Acos: // acos(variable)
385  return thisOps.evalAcos(node);
386 
387  case CGOpCode::Add: // a + b
388  return thisOps.evalAdd(node);
389 
390  case CGOpCode::Alias:
391  return thisOps.evalAlias(node);
392 
393  //case CGArrayCreationOp: // {a, b, c ...}
394  case CGOpCode::ArrayElement: // x[i]
395  return thisOps.evalArrayElement(node);
396 
397  case CGOpCode::Asin: // asin(variable)
398  return thisOps.evalAsin(node);
399 
400  case CGOpCode::Atan: // atan(variable)
401  return thisOps.evalAtan(node);
402 
403  //CGAtomicForwardOp
404  //CGAtomicReverseOp
405  case CGOpCode::ComLt: // return left < right? trueCase: falseCase
406  return thisOps.evalCompareLt(node);
407 
408  case CGOpCode::ComLe: // return left <= right? trueCase: falseCase
409  return thisOps.evalCompareLe(node);
410 
411  case CGOpCode::ComEq: // return left == right? trueCase: falseCase
412  return thisOps.evalCompareEq(node);
413 
414  case CGOpCode::ComGe: // return left >= right? trueCase: falseCase
415  return thisOps.evalCompareGe(node);
416 
417  case CGOpCode::ComGt: // return left > right? trueCase: falseCase
418  return thisOps.evalCompareGt(node);
419 
420  case CGOpCode::ComNe: // return left != right? trueCase: falseCase
421  return thisOps.evalCompareNe(node);
422 
423  case CGOpCode::Cosh: // cosh(variable)
424  return thisOps.evalCosh(node);
425 
426  case CGOpCode::Cos: // cos(variable)
427  return thisOps.evalCos(node);
428 
429  case CGOpCode::Div: // a / b
430  return thisOps.evalDiv(node);
431 
432  case CGOpCode::Exp: // exp(variable)
433  return thisOps.evalExp(node);
434 
435  case CGOpCode::Inv: // independent variable
436  return thisOps.evalIndependent(node);
437 
438  case CGOpCode::Log: // log(variable)
439  return thisOps.evalLog(node);
440 
441  case CGOpCode::Mul: // a * b
442  return thisOps.evalMul(node);
443 
444  case CGOpCode::Pow: // pow(a, b)
445  return thisOps.evalPow(node);
446 
447  case CGOpCode::Pri: // pow(a, b)
448  return thisOps.evalPrint(node);
449  //case PriOp: // PrintFor(text, parameter or variable, parameter or variable)
450 
451  case CGOpCode::Sign: // return (x > 0)? 1.0:((x == 0)? 0.0:-1)
452  return thisOps.evalSign(node);
453 
454  case CGOpCode::Sinh: // sinh(variable)
455  return thisOps.evalSinh(node);
456 
457  case CGOpCode::Sin: // sin(variable)
458  return thisOps.evalSin(node);
459 
460  case CGOpCode::Sqrt: // sqrt(variable)
461  return thisOps.evalSqrt(node);
462 
463  case CGOpCode::Sub: // a - b
464  return thisOps.evalSub(node);
465 
466  case CGOpCode::Tanh: // tanh(variable)
467  return thisOps.evalTanh(node);
468 
469  case CGOpCode::Tan: // tan(variable)
470  return thisOps.evalTan(node);
471 
472  case CGOpCode::UnMinus: // -(a)
473  return thisOps.evalMinus(node);
474 
475  default:
476  return thisOps.evalUnsupportedOperation(node);
477  }
478  }
479 
480  inline ActiveOut evalAssign(const NodeIn& node) {
481  const std::vector<ArgIn>& args = node.getArguments();
482  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for assign()");
483  return evalArg(args, 0);
484  }
485 
486  inline ActiveOut evalAbs(const NodeIn& node) {
487  const std::vector<ArgIn>& args = node.getArguments();
488  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for abs()");
489  return abs(evalArg(args, 0));
490  }
491 
492  inline ActiveOut evalAcos(const NodeIn& node) {
493  const std::vector<ArgIn>& args = node.getArguments();
494  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for acos()");
495  return acos(evalArg(args, 0));
496  }
497 
498  inline ActiveOut evalAdd(const NodeIn& node) {
499  const std::vector<ArgIn>& args = node.getArguments();
500  CPPADCG_ASSERT_KNOWN(args.size() == 2, "Invalid number of arguments for addition");
501  return evalArg(args, 0) + evalArg(args, 1);
502  }
503 
504  inline ActiveOut evalAlias(const NodeIn& node) {
505  const std::vector<ArgIn>& args = node.getArguments();
506  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for alias");
507  return evalArg(args, 0);
508  }
509 
510  inline ActiveOut evalArrayElement(const NodeIn& node) {
511  const std::vector<ArgIn>& args = node.getArguments();
512  const std::vector<size_t>& info = node.getInfo();
513  CPPADCG_ASSERT_KNOWN(args.size() == 2, "Invalid number of arguments for array element");
514  CPPADCG_ASSERT_KNOWN(args[0].getOperation() != nullptr, "Invalid argument for array element");
515  CPPADCG_ASSERT_KNOWN(args[1].getOperation() != nullptr, "Invalid argument for array element");
516  CPPADCG_ASSERT_KNOWN(info.size() == 1, "Invalid number of information data for array element");
517  size_t index = info[0];
518  std::vector<ActiveOut>& array = this->evalArrayCreationOperation(*args[0].getOperation()); // array creation
519 
520  FinalEvaluatorType& thisOps = static_cast<FinalEvaluatorType&>(*this);
521  thisOps.evalAtomicOperation(*args[1].getOperation()); // atomic operation
522 
523  return array[index];
524  }
525 
526  inline ActiveOut evalAsin(const NodeIn& node) {
527  const std::vector<ArgIn>& args = node.getArguments();
528  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for asin()");
529  return asin(evalArg(args, 0));
530  }
531 
532  inline ActiveOut evalAtan(const NodeIn& node) {
533  const std::vector<ArgIn>& args = node.getArguments();
534  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for atan()");
535  return atan(evalArg(args, 0));
536  }
537 
538  inline ActiveOut evalCompareLt(const NodeIn& node) {
539  const std::vector<ArgIn>& args = node.getArguments();
540  CPPADCG_ASSERT_KNOWN(args.size() == 4, "Invalid number of arguments for CondExpOp(CompareLt, )");
541  return CondExpOp(CompareLt, evalArg(args, 0), evalArg(args, 1), evalArg(args, 2), evalArg(args, 3));
542  }
543 
544  inline ActiveOut evalCompareLe(const NodeIn& node) {
545  const std::vector<ArgIn>& args = node.getArguments();
546  CPPADCG_ASSERT_KNOWN(args.size() == 4, "Invalid number of arguments for CondExpOp(CompareLe, )");
547  return CondExpOp(CompareLe, evalArg(args, 0), evalArg(args, 1), evalArg(args, 2), evalArg(args, 3));
548  }
549 
550  inline ActiveOut evalCompareEq(const NodeIn& node) {
551  const std::vector<ArgIn>& args = node.getArguments();
552  CPPADCG_ASSERT_KNOWN(args.size() == 4, "Invalid number of arguments for CondExpOp(CompareEq, )");
553  return CondExpOp(CompareEq, evalArg(args, 0), evalArg(args, 1), evalArg(args, 2), evalArg(args, 3));
554  }
555 
556  inline ActiveOut evalCompareGe(const NodeIn& node) {
557  const std::vector<ArgIn>& args = node.getArguments();
558  CPPADCG_ASSERT_KNOWN(args.size() == 4, "Invalid number of arguments for CondExpOp(CompareGe, )");
559  return CondExpOp(CompareGe, evalArg(args, 0), evalArg(args, 1), evalArg(args, 2), evalArg(args, 3));
560  }
561 
562  inline ActiveOut evalCompareGt(const NodeIn& node) {
563  const std::vector<ArgIn>& args = node.getArguments();
564  CPPADCG_ASSERT_KNOWN(args.size() == 4, "Invalid number of arguments for CondExpOp(CompareGt, )");
565  return CondExpOp(CompareGt, evalArg(args, 0), evalArg(args, 1), evalArg(args, 2), evalArg(args, 3));
566  }
567 
568  inline ActiveOut evalCompareNe(const NodeIn& node) {
569  const std::vector<ArgIn>& args = node.getArguments();
570  CPPADCG_ASSERT_KNOWN(args.size() == 4, "Invalid number of arguments for CondExpOp(CompareNe, )");
571  return CondExpOp(CompareNe, evalArg(args, 0), evalArg(args, 1), evalArg(args, 2), evalArg(args, 3));
572  }
573 
574  inline ActiveOut evalCosh(const NodeIn& node) {
575  const std::vector<ArgIn>& args = node.getArguments();
576  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for cosh()");
577  return cosh(evalArg(args, 0));
578  }
579 
580  inline ActiveOut evalCos(const NodeIn& node) {
581  const std::vector<ArgIn>& args = node.getArguments();
582  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for cos()");
583  return cos(evalArg(args, 0));
584  }
585 
586  inline ActiveOut evalDiv(const NodeIn& node) {
587  const std::vector<ArgIn>& args = node.getArguments();
588  CPPADCG_ASSERT_KNOWN(args.size() == 2, "Invalid number of arguments for division");
589  return evalArg(args, 0) / evalArg(args, 1);
590  }
591 
592  inline ActiveOut evalExp(const NodeIn& node) {
593  const std::vector<ArgIn>& args = node.getArguments();
594  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for exp()");
595  return exp(evalArg(args, 0));
596  }
597 
598  inline ActiveOut evalIndependent(const NodeIn& node) {
599  size_t index = this->handler_.getIndependentVariableIndex(node);
600  return this->indep_[index];
601  }
602 
603  inline ActiveOut evalLog(const NodeIn& node) {
604  const std::vector<ArgIn>& args = node.getArguments();
605  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for log()");
606  return log(evalArg(args, 0));
607  }
608 
609  inline ActiveOut evalMul(const NodeIn& node) {
610  const std::vector<ArgIn>& args = node.getArguments();
611  CPPADCG_ASSERT_KNOWN(args.size() == 2, "Invalid number of arguments for multiplication");
612  return evalArg(args, 0) * evalArg(args, 1);
613  }
614 
615  inline ActiveOut evalPow(const NodeIn& node) {
616  const std::vector<ArgIn>& args = node.getArguments();
617  CPPADCG_ASSERT_KNOWN(args.size() == 2, "Invalid number of arguments for pow()");
618  return pow(evalArg(args, 0), evalArg(args, 1));
619  }
620 
621  inline ActiveOut evalPrint(const NodeIn& node) {
622  FinalEvaluatorType& thisOps = static_cast<FinalEvaluatorType&>(*this);
623  return thisOps.evalUnsupportedOperation(node);
624  }
625 
626  //case PriOp: // PrintFor(text, parameter or variable, parameter or variable)
627  inline ActiveOut evalSign(const NodeIn& node) {
628  const std::vector<ArgIn>& args = node.getArguments();
629  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for sign()");
630  return sign(evalArg(args, 0));
631  }
632 
633  inline ActiveOut evalSinh(const NodeIn& node) {
634  const std::vector<ArgIn>& args = node.getArguments();
635  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for sinh()");
636  return sinh(evalArg(args, 0));
637  }
638 
639  inline ActiveOut evalSin(const NodeIn& node) {
640  const std::vector<ArgIn>& args = node.getArguments();
641  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for sin()");
642  return sin(evalArg(args, 0));
643  }
644 
645  inline ActiveOut evalSqrt(const NodeIn& node) {
646  const std::vector<ArgIn>& args = node.getArguments();
647  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for sqrt()");
648  return sqrt(evalArg(args, 0));
649  }
650 
651  inline ActiveOut evalSub(const NodeIn& node) {
652  const std::vector<ArgIn>& args = node.getArguments();
653  CPPADCG_ASSERT_KNOWN(args.size() == 2, "Invalid number of arguments for subtraction");
654  return evalArg(args, 0) - evalArg(args, 1);
655  }
656 
657  inline ActiveOut evalTanh(const NodeIn& node) {
658  const std::vector<ArgIn>& args = node.getArguments();
659  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for tanh()");
660  return tanh(evalArg(args, 0));
661  }
662 
663  inline ActiveOut evalTan(const NodeIn& node) {
664  const std::vector<ArgIn>& args = node.getArguments();
665  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for tan()");
666  return tan(evalArg(args, 0));
667  }
668 
669  inline ActiveOut evalMinus(const NodeIn& node) {
670  const std::vector<ArgIn>& args = node.getArguments();
671  CPPADCG_ASSERT_KNOWN(args.size() == 1, "Invalid number of arguments for unary minus");
672  return -evalArg(args, 0);
673  }
674 
675  inline ActiveOut evalUnsupportedOperation(const NodeIn& node) {
676  throw CGException("Unknown operation code '", node.getOperationType(), "'");
677  }
678 
679  inline void evalAtomicOperation(const NodeIn& node) {
680  throw CGException("Evaluator is unable to handle atomic functions for these variable types");
681  }
682 
683  inline void processActiveOut(const NodeIn& node,
684  ActiveOut& a) {
685  }
686 };
687 
692 template<class ScalarIn, class ScalarOut, class ActiveOut = CppAD::AD<ScalarOut> >
693 class Evaluator : public EvaluatorOperations<ScalarIn, ScalarOut, ActiveOut, Evaluator<ScalarIn, ScalarOut, ActiveOut> > {
694 public:
696 public:
697 
698  inline Evaluator(CodeHandler<ScalarIn>& handler) :
699  Base(handler) {
700  }
701 
702  inline virtual ~Evaluator() = default;
703 };
704 
705 } // END cg namespace
706 } // END CppAD namespace
707 
708 #endif
std::vector< ActiveOut > evaluate(ArrayView< const ActiveOut > indepNew, ArrayView< const CG< ScalarIn > > depOld)
Definition: evaluator.hpp:92
pointer data() noexcept
Definition: array_view.hpp:220
const Base & getValue() const
Definition: variable.hpp:45
const std::vector< Argument< Base > > & getArguments() const
ActiveOut evalOperation(OperationNode< ScalarIn > &node)
Definition: evaluator.hpp:373
size_t getHandlerPosition() const
void evaluate(ArrayView< const ActiveOut > indepNew, ArrayView< ActiveOut > depNew, ArrayView< const CG< ScalarIn > > depOld)
Definition: evaluator.hpp:113
cg::CG< Base > pow(const cg::CG< Base > &x, const cg::CG< Base > &y)
Definition: math_other.hpp:21
size_t getIndependentVariableSize() const
CGOpCode getOperationType() const
size_t getManagedNodesCount() const
EvaluatorBase(CodeHandler< ScalarIn > &handler)
Definition: evaluator.hpp:62
void evaluate(const ActiveOut *indepNew, size_t indepSize, ActiveOut *depNew, const CG< ScalarIn > *depOld, size_t depSize)
Definition: evaluator.hpp:136
size_t size() const noexcept
Definition: array_view.hpp:202
bool isParameter() const
Definition: variable.hpp:35
cg::CG< Base > sign(const cg::CG< Base > &x)
Definition: math_other.hpp:74
const std::vector< size_t > & getInfo() const