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