TMB Documentation  v1.9.11
global.hpp
1 #ifndef HAVE_GLOBAL_HPP
2 #define HAVE_GLOBAL_HPP
3 // Autogenerated - do not edit by hand !
4 #include <algorithm>
5 #include <cmath>
6 #include <ctime>
7 #include <iomanip>
8 #include <iostream>
9 #include <limits>
10 #include <set>
11 #include <sstream>
12 #include <valarray>
13 #include <vector>
14 #include "config.hpp"
15 #include "radix.hpp"
16 
20 namespace TMBad {
21 
22 typedef TMBAD_HASH_TYPE hash_t;
23 typedef TMBAD_INDEX_TYPE Index;
24 typedef TMBAD_SCALAR_TYPE Scalar;
25 typedef std::pair<Index, Index> IndexPair;
26 typedef TMBAD_INDEX_VECTOR IndexVector;
27 
28 struct global;
31 global *get_glob();
32 
33 template <class T>
34 std::ostream &operator<<(std::ostream &out, const std::vector<T> &v) {
35  out << "{";
36  size_t last = v.size() - 1;
37  for (size_t i = 0; i < v.size(); ++i) {
38  out << v[i];
39  if (i != last) out << ", ";
40  }
41  out << "}";
42  return out;
43 }
44 
46 template <class T>
47 struct intervals {
48  struct ep : std::pair<T, bool> {
49  bool left() const { return !this->second; }
50  ep(T x, bool type) : std::pair<T, bool>(x, type) {}
51  operator T() { return this->first; }
52  };
53  std::set<ep> x;
54  typedef typename std::set<ep>::iterator iterator;
58  bool insert(T a, T b) {
59  ep x1(a, false);
60  ep x2(b, true);
61  iterator it1 = x.upper_bound(x1);
62  iterator it2 = x.lower_bound(x2);
63 
64  bool insert_x1 = (it1 == x.end()) || it1->left();
65  bool insert_x2 = (it2 == x.end()) || it2->left();
66 
67  bool change = (it1 != it2) || insert_x1;
68 
69  if (it1 != it2) {
70  x.erase(it1, it2);
71  }
72 
73  if (insert_x1) x.insert(x1);
74  if (insert_x2) x.insert(x2);
75  return change;
76  }
78  template <class F>
79  F &apply(F &f) const {
80  for (iterator it = x.begin(); it != x.end();) {
81  ep a = *it;
82  ++it;
83  ep b = *it;
84  ++it;
85  f(a, b);
86  }
87  return f;
88  }
89  struct print_interval {
90  void operator()(T a, T b) { Rcout << "[ " << a << " , " << b << " ] "; }
91  };
92  void print() {
93  print_interval f;
94  this->apply(f);
95  Rcout << "\n";
96  }
97 };
98 
99 struct Dependencies : std::vector<Index> {
100  typedef std::vector<Index> Base;
101  std::vector<std::pair<Index, Index> > I;
102  Dependencies();
103  void clear();
104  void add_interval(Index a, Index b);
105  void add_segment(Index start, Index size);
106 
107  void monotone_transform_inplace(const std::vector<Index> &x);
108 
109  template <class F>
110  F &apply(F &f) {
111  for (size_t i = 0; i < this->size(); i++) f((*this)[i]);
112  for (size_t i = 0; i < I.size(); i++) {
113  for (Index j = I[i].first; j <= I[i].second; j++) {
114  f(j);
115  }
116  }
117  return f;
118  }
119 
120  template <class F>
121  F &apply_if_not_visited(F &f, intervals<Index> &visited) {
122  for (size_t i = 0; i < this->size(); i++) f((*this)[i]);
123  for (size_t i = 0; i < I.size(); i++) {
124  if (visited.insert(I[i].first, I[i].second)) {
125  for (Index j = I[i].first; j <= I[i].second; j++) {
126  f(j);
127  }
128  }
129  }
130  return f;
131  }
132 
133  bool any(const std::vector<bool> &x) const;
134 };
135 
138 enum ArrayAccess { x_read, y_read, y_write, dx_read, dx_write, dy_read };
139 template <class Args, ArrayAccess What>
140 struct Accessor {};
141 template <class Args>
142 struct Accessor<Args, x_read> {
143  typename Args::value_type operator()(const Args &args, Index j) const {
144  return args.x(j);
145  }
146 };
147 template <class Args>
148 struct Accessor<Args, y_read> {
149  typename Args::value_type operator()(const Args &args, Index j) const {
150  return args.y(j);
151  }
152 };
153 template <class Args>
154 struct Accessor<Args, y_write> {
155  typename Args::value_type &operator()(Args &args, Index j) {
156  return args.y(j);
157  }
158 };
159 template <class Args>
160 struct Accessor<Args, dx_read> {
161  typename Args::value_type operator()(const Args &args, Index j) const {
162  return args.dx(j);
163  }
164 };
165 template <class Args>
166 struct Accessor<Args, dx_write> {
167  typename Args::value_type &operator()(Args &args, Index j) {
168  return args.dx(j);
169  }
170 };
171 template <class Args>
172 struct Accessor<Args, dy_read> {
173  typename Args::value_type operator()(const Args &args, Index j) const {
174  return args.dy(j);
175  }
176 };
177 
183 template <class T>
185  const std::vector<T> &x;
186  const std::vector<Index> &i;
187  IndirectAccessor(const std::vector<T> &x, const std::vector<Index> &i)
188  : x(x), i(i) {}
189  T operator[](size_t j) const { return x[i[j]]; }
190  size_t size() const { return i.size(); }
191  operator std::vector<T>() const {
192  std::vector<T> ans(i.size());
193  for (size_t j = 0; j < ans.size(); j++) ans[j] = (*this)[j];
194  return ans;
195  }
196 };
197 
205 template <class Args, ArrayAccess What>
206 struct segment_ref {
207  typedef typename Args::value_type Type;
208  Accessor<Args, What> element_access;
209  Args args;
210  Index from, n;
211  segment_ref(const Args &args, Index from, Index n)
212  : args(args), from(from), n(n) {}
213  template <class Other>
214  operator Other() {
215  Other ans(n);
216  for (size_t i = 0; i < n; i++) {
217  ans[i] = element_access(args, from + i);
218  }
219  return ans;
220  }
221  Type operator[](Index i) const { return element_access(args, from + i); }
222  size_t size() const { return n; }
223  template <class Other>
224  segment_ref &operator=(const Other &other) {
225  for (size_t i = 0; i < n; i++) {
226  element_access(args, from + i) = other[i];
227  }
228  return *this;
229  }
230  template <class Other>
231  segment_ref &operator+=(const Other &other) {
232  for (size_t i = 0; i < n; i++) {
233  element_access(args, from + i) += other[i];
234  }
235  return *this;
236  }
237  template <class Other>
238  segment_ref &operator-=(const Other &other) {
239  for (size_t i = 0; i < n; i++) {
240  element_access(args, from + i) -= other[i];
241  }
242  return *this;
243  }
244 };
245 
255 template <class dummy = void>
256 struct Args {
258  const Index *inputs;
263  IndexPair ptr;
265  Index input(Index j) const { return inputs[ptr.first + j]; }
267  Index output(Index j) const { return ptr.second + j; }
268  Args(const IndexVector &inputs) : inputs(inputs.data()) {
269  ptr.first = 0;
270  ptr.second = 0;
271  }
272 };
278 template <class Type>
279 struct ForwardArgs : Args<> {
280  typedef std::vector<Type> TypeVector;
281  typedef Type value_type;
282  Type *values;
283  global *glob_ptr;
285  Type x(Index j) const { return values[input(j)]; }
287  Type &y(Index j) { return values[output(j)]; }
289  Type *x_ptr(Index j) { return &values[input(j)]; }
291  Type *y_ptr(Index j) { return &values[output(j)]; }
293  segment_ref<ForwardArgs, x_read> x_segment(Index from, Index size) {
294  return segment_ref<ForwardArgs, x_read>(*this, from, size);
295  }
298  return segment_ref<ForwardArgs, y_write>(*this, from, size);
299  }
300  ForwardArgs(const IndexVector &inputs, TypeVector &values,
301  global *glob_ptr = NULL)
302  : Args<>(inputs), values(values.data()), glob_ptr(glob_ptr) {}
303 };
310 template <class Type>
311 struct ReverseArgs : Args<> {
312  typedef std::vector<Type> TypeVector;
313  typedef Type value_type;
314  Type *values;
315  Type *derivs;
316  global *glob_ptr;
318  Type x(Index j) const { return values[input(j)]; }
320  Type y(Index j) const { return values[output(j)]; }
323  Type &dx(Index j) { return derivs[input(j)]; }
326  Type dy(Index j) const { return derivs[output(j)]; }
328  Type *x_ptr(Index j) { return &values[input(j)]; }
330  Type *y_ptr(Index j) { return &values[output(j)]; }
332  Type *dx_ptr(Index j) { return &derivs[input(j)]; }
334  Type *dy_ptr(Index j) { return &derivs[output(j)]; }
336  segment_ref<ReverseArgs, x_read> x_segment(Index from, Index size) {
337  return segment_ref<ReverseArgs, x_read>(*this, from, size);
338  }
340  segment_ref<ReverseArgs, y_read> y_segment(Index from, Index size) {
341  return segment_ref<ReverseArgs, y_read>(*this, from, size);
342  }
345  return segment_ref<ReverseArgs, dx_write>(*this, from, size);
346  }
349  return segment_ref<ReverseArgs, dy_read>(*this, from, size);
350  }
351  ReverseArgs(const IndexVector &inputs, TypeVector &values, TypeVector &derivs,
352  global *glob_ptr = NULL)
353  : Args<>(inputs),
354  values(values.data()),
355  derivs(derivs.data()),
356  glob_ptr(glob_ptr) {
357  ptr.first = (Index)inputs.size();
358  ptr.second = (Index)values.size();
359  }
360 };
361 
362 template <>
363 struct ForwardArgs<bool> : Args<> {
364  typedef std::vector<bool> BoolVector;
365  BoolVector &values;
366  intervals<Index> &marked_intervals;
367  bool x(Index j) { return values[input(j)]; }
368  BoolVector::reference y(Index j) { return values[output(j)]; }
369  ForwardArgs(const IndexVector &inputs, BoolVector &values,
370  intervals<Index> &marked_intervals)
371  : Args<>(inputs), values(values), marked_intervals(marked_intervals) {}
373  template <class Operator>
374  bool any_marked_input(const Operator &op) {
375  if (Operator::implicit_dependencies) {
376  Dependencies dep;
377  op.dependencies(*this, dep);
378  return dep.any(values);
379  } else {
380  Index ninput = op.input_size();
381  for (Index j = 0; j < ninput; j++)
382  if (x(j)) return true;
383  }
384  return false;
385  }
387  template <class Operator>
388  void mark_all_output(const Operator &op) {
389  if (Operator::updating && op.output_size() == 0) {
390  Dependencies dep;
391  op.dependencies_updating(*this, dep);
392 
393  for (size_t i = 0; i < dep.size(); i++) values[dep[i]] = true;
394 
395  for (size_t i = 0; i < dep.I.size(); i++) {
396  Index a = dep.I[i].first;
397  Index b = dep.I[i].second;
398  bool insert = marked_intervals.insert(a, b);
399  if (insert) {
400  for (Index j = a; j <= b; j++) {
401  values[j] = true;
402  }
403  }
404  }
405  } else {
406  Index noutput = op.output_size();
407  for (Index j = 0; j < noutput; j++) y(j) = true;
408  }
409  }
411  template <class Operator>
412  bool mark_dense(const Operator &op) {
413  if (any_marked_input(op)) {
414  mark_all_output(op);
415  return true;
416  }
417  return false;
418  }
419 };
420 
421 template <>
422 struct ReverseArgs<bool> : Args<> {
423  typedef std::vector<bool> BoolVector;
424  BoolVector &values;
425  intervals<Index> &marked_intervals;
426  BoolVector::reference x(Index j) { return values[input(j)]; }
427  bool y(Index j) { return values[output(j)]; }
428  ReverseArgs(IndexVector &inputs, BoolVector &values,
429  intervals<Index> &marked_intervals)
430  : Args<>(inputs), values(values), marked_intervals(marked_intervals) {
431  ptr.first = (Index)inputs.size();
432  ptr.second = (Index)values.size();
433  }
435  template <class Operator>
436  bool any_marked_output(const Operator &op) {
437  if (Operator::elimination_protected) return true;
438  if (Operator::updating && op.output_size() == 0) {
439  Dependencies dep;
440  op.dependencies_updating(*this, dep);
441  return dep.any(values);
442  } else {
443  Index noutput = op.output_size();
444  for (Index j = 0; j < noutput; j++)
445  if (y(j)) return true;
446  }
447  return false;
448  }
450  template <class Operator>
451  void mark_all_input(const Operator &op) {
452  if (Operator::implicit_dependencies) {
453  Dependencies dep;
454  op.dependencies(*this, dep);
455 
456  for (size_t i = 0; i < dep.size(); i++) values[dep[i]] = true;
457 
458  for (size_t i = 0; i < dep.I.size(); i++) {
459  Index a = dep.I[i].first;
460  Index b = dep.I[i].second;
461  bool insert = marked_intervals.insert(a, b);
462  if (insert) {
463  for (Index j = a; j <= b; j++) {
464  values[j] = true;
465  }
466  }
467  }
468  } else {
469  Index ninput = op.input_size();
470  for (Index j = 0; j < ninput; j++) x(j) = true;
471  }
472  }
474  template <class Operator>
475  bool mark_dense(const Operator &op) {
476  if (any_marked_output(op)) {
477  mark_all_input(op);
478  return true;
479  }
480  return false;
481  }
482 };
483 
484 std::string tostr(const Index &x);
485 
486 std::string tostr(const Scalar &x);
487 
488 struct Writer : std::string {
489  static std::ostream *cout;
490  Writer(std::string str);
491  Writer(Scalar x);
492  Writer();
493 
494  template <class V>
495  std::string vinit(const V &x) {
496  std::string y = "{";
497  for (size_t i = 0; i < x.size(); i++)
498  y = y + (i == 0 ? "" : ",") + tostr(x[i]);
499  y = y + "}";
500  return y;
501  }
502 
503  std::string p(std::string x);
504  Writer operator+(const Writer &other);
505  Writer operator-(const Writer &other);
506  Writer operator-();
507  Writer operator*(const Writer &other);
508  Writer operator/(const Writer &other);
509 
510  Writer operator*(const Scalar &other);
511  Writer operator+(const Scalar &other);
512 
513  void operator=(const Writer &other);
514  void operator+=(const Writer &other);
515  void operator-=(const Writer &other);
516  void operator*=(const Writer &other);
517  void operator/=(const Writer &other);
518 
519  template <class T>
520  friend Writer &operator<<(Writer &w, const T &v) {
521  *cout << v;
522  return w;
523  }
524  template <class T>
525  friend Writer &operator<<(Writer &w, const std::valarray<T> &x) {
526  *cout << w.vinit(x);
527  return w;
528  }
529 };
530 
531 template <>
532 struct ForwardArgs<Writer> : ForwardArgs<Scalar> {
533  typedef std::vector<Scalar> ScalarVector;
534  typedef ForwardArgs<Scalar> Base;
536  bool const_literals;
538  bool indirect;
539  void set_indirect() {
540  indirect = true;
541  ptr.first = 0;
542  ptr.second = 0;
543  }
544  Writer xd(Index j) { return "v[" + tostr(input(j)) + "]"; }
545  Writer yd(Index j) { return "v[" + tostr(output(j)) + "]"; }
546  Writer xi(Index j) { return "v[i[" + tostr(Index(ptr.first + j)) + "]]"; }
547  Writer yi(Index j) { return "v[o[" + tostr(Index(ptr.second + j)) + "]]"; }
548  Writer x(Index j) { return (indirect ? xi(j) : xd(j)); }
549  Writer y(Index j) { return (indirect ? yi(j) : yd(j)); }
550  Writer y_const(Index j) {
551  TMBAD_ASSERT2(!indirect, "Attempt to write constants within loop?");
552  return tostr(Base::y(j));
553  }
554  ForwardArgs(IndexVector &inputs, ScalarVector &values)
555  : ForwardArgs<Scalar>(inputs, values) {
556  const_literals = false;
557  indirect = false;
558  }
559 };
560 
561 template <>
562 struct ReverseArgs<Writer> : Args<> {
563  typedef std::vector<Scalar> ScalarVector;
565  bool const_literals;
567  bool indirect;
568  void set_indirect() {
569  indirect = true;
570  ptr.first = 0;
571  ptr.second = 0;
572  }
573  Writer dxd(Index j) { return "d[" + tostr(input(j)) + "]"; }
574  Writer dyd(Index j) { return "d[" + tostr(output(j)) + "]"; }
575  Writer xd(Index j) { return "v[" + tostr(input(j)) + "]"; }
576  Writer yd(Index j) { return "v[" + tostr(output(j)) + "]"; }
577  Writer dxi(Index j) { return "d[i[" + tostr(Index(ptr.first + j)) + "]]"; }
578  Writer dyi(Index j) { return "d[o[" + tostr(Index(ptr.second + j)) + "]]"; }
579  Writer xi(Index j) { return "v[i[" + tostr(Index(ptr.first + j)) + "]]"; }
580  Writer yi(Index j) { return "v[o[" + tostr(Index(ptr.second + j)) + "]]"; }
581  Writer x(Index j) { return (indirect ? xi(j) : xd(j)); }
582  Writer y(Index j) { return (indirect ? yi(j) : yd(j)); }
583  Writer dx(Index j) { return (indirect ? dxi(j) : dxd(j)); }
584  Writer dy(Index j) { return (indirect ? dyi(j) : dyd(j)); }
585 
586  ReverseArgs(IndexVector &inputs, ScalarVector &values) : Args<>(inputs) {
587  const_literals = false;
588  indirect = false;
589  ptr.first = (Index)inputs.size();
590  ptr.second = (Index)values.size();
591  }
592 };
593 
594 struct Position {
595  Position(Index node, Index first, Index second);
596  Position();
597  Index node;
598  IndexPair ptr;
599  bool operator<(const Position &other) const;
600 };
601 
603 template <class T>
604 void sort_inplace(std::vector<T> &x) {
605  std::sort(x.begin(), x.end());
606 }
607 
609 template <class T>
610 void sort_unique_inplace(std::vector<T> &x) {
611  std::sort(x.begin(), x.end());
612  typename std::vector<T>::iterator last = std::unique(x.begin(), x.end());
613  x.erase(last, x.end());
614 }
615 
617 struct graph {
618  std::vector<Index> j;
619  std::vector<Index> p;
620  graph();
621  size_t num_neighbors(Index node);
622  Index *neighbors(Index node);
623  bool empty();
624  size_t num_nodes();
625  void print();
628  std::vector<bool> mark;
630  std::vector<Index> inv2op;
632  std::vector<Index> dep2op;
634  std::vector<Index> rowcounts();
636  std::vector<Index> colcounts();
646  void bfs(const std::vector<Index> &start, std::vector<bool> &visited,
647  std::vector<Index> &result);
660  void search(std::vector<Index> &start, bool sort_input = true,
661  bool sort_output = true);
669  void search(std::vector<Index> &start, std::vector<bool> &visited,
670  bool sort_input = true, bool sort_output = true);
676  std::vector<Index> boundary(const std::vector<Index> &subgraph);
681  graph(size_t num_nodes, const std::vector<IndexPair> &edges);
682 };
683 
684 namespace {
685 template <class CompleteOperator, bool dynamic>
686 struct constructOperator {};
687 template <class CompleteOperator>
688 struct constructOperator<CompleteOperator, false> {
689  CompleteOperator *operator()() {
690  static CompleteOperator *pOp = new CompleteOperator();
691  return pOp;
692  }
693 };
694 template <class CompleteOperator>
695 struct constructOperator<CompleteOperator, true> {
696  CompleteOperator *operator()() {
697  CompleteOperator *pOp = new CompleteOperator();
698  return pOp;
699  }
700 
701  template <class T1>
702  CompleteOperator *operator()(const T1 &x1) {
703  CompleteOperator *pOp = new CompleteOperator(x1);
704  return pOp;
705  }
706 
707  template <class T1, class T2>
708  CompleteOperator *operator()(const T1 &x1, const T2 &x2) {
709  CompleteOperator *pOp = new CompleteOperator(x1, x2);
710  return pOp;
711  }
712 
713  template <class T1, class T2, class T3>
714  CompleteOperator *operator()(const T1 &x1, const T2 &x2, const T3 &x3) {
715  CompleteOperator *pOp = new CompleteOperator(x1, x2, x3);
716  return pOp;
717  }
718 
719  template <class T1, class T2, class T3, class T4>
720  CompleteOperator *operator()(const T1 &x1, const T2 &x2, const T3 &x3,
721  const T4 &x4) {
722  CompleteOperator *pOp = new CompleteOperator(x1, x2, x3, x4);
723  return pOp;
724  }
725 };
726 } // namespace
727 
732 struct op_info {
734  typedef int IntRep;
736  IntRep code;
738  enum op_flag {
758  op_flag_count
759  };
760  template <class T>
761  IntRep get_flags(T op) {
762  return
763 
764  (op.dynamic * (1 << dynamic)) |
765  (op.smart_pointer * (1 << smart_pointer)) |
766  (op.is_linear * (1 << is_linear)) |
767  (op.is_constant * (1 << is_constant)) |
768  (op.independent_variable * (1 << independent_variable)) |
769  (op.dependent_variable * (1 << dependent_variable)) |
770  (op.allow_remap * (1 << allow_remap)) |
771  (op.elimination_protected * (1 << elimination_protected)) |
772  (op.updating * (1 << updating));
773  }
774  op_info();
775  op_info(op_flag f);
776 
777  template <class T>
778  op_info(T op) : code(get_flags(op)) {}
780  bool test(op_flag f) const;
781  op_info &operator|=(const op_info &other);
782  op_info &operator&=(const op_info &other);
783 };
784 
797 struct global {
798  struct ad_plain;
799  struct ad_aug;
800  typedef TMBAD_REPLAY_TYPE Replay;
801  struct ad_segment;
802  struct print_config;
811  struct OperatorPure {
814  virtual void increment(IndexPair &ptr) = 0;
817  virtual void decrement(IndexPair &ptr) = 0;
819  virtual void forward(ForwardArgs<Scalar> &args) = 0;
821  virtual void reverse(ReverseArgs<Scalar> &args) = 0;
823  virtual void forward_incr(ForwardArgs<Scalar> &args) = 0;
825  virtual void reverse_decr(ReverseArgs<Scalar> &args) = 0;
827  virtual Index input_size() = 0;
829  virtual Index output_size() = 0;
834  virtual void forward(ForwardArgs<bool> &args) = 0;
839  virtual void reverse(ReverseArgs<bool> &args) = 0;
841  virtual void forward_incr(ForwardArgs<bool> &args) = 0;
843  virtual void reverse_decr(ReverseArgs<bool> &args) = 0;
845  virtual void forward_incr_mark_dense(ForwardArgs<bool> &args) = 0;
859  virtual void dependencies(Args<> &args, Dependencies &dep) = 0;
863  virtual void dependencies_updating(Args<> &args, Dependencies &dep) = 0;
865  virtual void forward(ForwardArgs<Replay> &args) = 0;
867  virtual void reverse(ReverseArgs<Replay> &args) = 0;
869  virtual void forward_incr(ForwardArgs<Replay> &args) = 0;
871  virtual void reverse_decr(ReverseArgs<Replay> &args) = 0;
873  virtual void forward(ForwardArgs<Writer> &args) = 0;
875  virtual void reverse(ReverseArgs<Writer> &args) = 0;
877  virtual void forward_incr(ForwardArgs<Writer> &args) = 0;
879  virtual void reverse_decr(ReverseArgs<Writer> &args) = 0;
881  virtual const char *op_name() { return "NoName"; }
885  virtual OperatorPure *self_fuse() = 0;
889  virtual OperatorPure *other_fuse(OperatorPure *other) = 0;
891  virtual OperatorPure *copy() = 0;
893  virtual void deallocate() = 0;
895  virtual op_info info() = 0;
897  virtual void *operator_data() = 0;
902  virtual void *identifier() = 0;
904  virtual void print(print_config cfg) = 0;
907  virtual void *incomplete() = 0;
908  virtual ~OperatorPure() {}
909  };
910 
917  struct operation_stack : std::vector<OperatorPure *> {
918  typedef std::vector<OperatorPure *> Base;
922  operation_stack();
924  operation_stack(const operation_stack &other);
927  void push_back(OperatorPure *x);
929  operation_stack &operator=(const operation_stack &other);
930  ~operation_stack();
932  void clear();
933  void copy_from(const operation_stack &other);
934  };
935 
940  std::vector<Scalar> values;
943  std::vector<Scalar> derivs;
945  IndexVector inputs;
948  std::vector<Index> inv_index;
951  std::vector<Index> dep_index;
952 
953  mutable std::vector<IndexPair> subgraph_ptr;
954  std::vector<Index> subgraph_seq;
956  void (*forward_compiled)(Scalar *);
958  void (*reverse_compiled)(Scalar *, Scalar *);
959 
960  global();
963  void clear();
964 
980  void shrink_to_fit(double tol = .9);
981 
985  void clear_deriv(Position start = Position(0, 0, 0));
986 
988  Scalar &value_inv(Index i);
990  Scalar &deriv_inv(Index i);
992  Scalar &value_dep(Index i);
994  Scalar &deriv_dep(Index i);
996  Position begin();
998  Position end();
999 
1001  struct no_filter {
1002  CONSTEXPR bool operator[](size_t i) const;
1003  };
1009  template <class ForwardArgs, class NodeFilter>
1010  void forward_loop(ForwardArgs &args, size_t begin,
1011  const NodeFilter &node_filter) const {
1012  for (size_t i = begin; i < opstack.size(); i++) {
1013  if (node_filter[i])
1014  opstack[i]->forward_incr(args);
1015  else
1016  opstack[i]->increment(args.ptr);
1017  }
1018  }
1020  template <class ForwardArgs>
1021  void forward_loop(ForwardArgs &args, size_t begin = 0) const {
1022  forward_loop(args, begin, no_filter());
1023  }
1028  template <class ReverseArgs, class NodeFilter>
1029  void reverse_loop(ReverseArgs &args, size_t begin,
1030  const NodeFilter &node_filter) const {
1031  for (size_t i = opstack.size(); i > begin;) {
1032  i--;
1033  if (node_filter[i])
1034  opstack[i]->reverse_decr(args);
1035  else
1036  opstack[i]->decrement(args.ptr);
1037  }
1038  }
1040  template <class ReverseArgs>
1041  void reverse_loop(ReverseArgs &args, size_t begin = 0) const {
1042  reverse_loop(args, begin, no_filter());
1043  }
1045  template <class ForwardArgs>
1047  subgraph_cache_ptr();
1048  for (size_t j = 0; j < subgraph_seq.size(); j++) {
1049  Index i = subgraph_seq[j];
1050  args.ptr = subgraph_ptr[i];
1051  opstack[i]->forward(args);
1052  }
1053  }
1055  template <class ReverseArgs>
1057  subgraph_cache_ptr();
1058  for (size_t j = subgraph_seq.size(); j > 0;) {
1059  j--;
1060  Index i = subgraph_seq[j];
1061  args.ptr = subgraph_ptr[i];
1062  opstack[i]->reverse(args);
1063  }
1064  }
1075  template <class Vector>
1077  typename Vector::value_type value =
1078  typename Vector::value_type(0)) const {
1079  if (array.size() != values.size()) {
1080  array.resize(values.size());
1081  std::fill(array.begin(), array.end(), value);
1082  return;
1083  }
1084  subgraph_cache_ptr();
1085  for (size_t j = 0; j < subgraph_seq.size(); j++) {
1086  Index i = subgraph_seq[j];
1087  size_t noutput = opstack[i]->output_size();
1088  for (size_t k = 0; k < noutput; k++)
1089  array[subgraph_ptr[i].second + k] = value;
1090  }
1091  }
1092 
1097  void forward(Position start = Position(0, 0, 0));
1105  void reverse(Position start = Position(0, 0, 0));
1107  void forward_sub();
1109  void reverse_sub();
1110 
1112  void forward(std::vector<bool> &marks);
1114  void reverse(std::vector<bool> &marks);
1119  void forward_sub(std::vector<bool> &marks,
1120  const std::vector<bool> &node_filter = std::vector<bool>());
1125  void reverse_sub(std::vector<bool> &marks,
1126  const std::vector<bool> &node_filter = std::vector<bool>());
1135  void forward_dense(std::vector<bool> &marks);
1136 
1137  intervals<Index> updating_intervals() const;
1138 
1139  intervals<Index> updating_intervals_sub() const;
1140 
1141  struct replay {
1143  std::vector<Replay> values;
1146  std::vector<Replay> derivs;
1148  const global &orig;
1150  global &target;
1152  global *parent_glob;
1154  Replay &value_inv(Index i);
1156  Replay &deriv_inv(Index i);
1158  Replay &value_dep(Index i);
1160  Replay &deriv_dep(Index i);
1164  replay(const global &orig, global &target);
1173  void start();
1178  void stop();
1180  void add_updatable_derivs(const intervals<Index> &I);
1182  void clear_deriv();
1189  void forward(bool inv_tags = true, bool dep_tags = true,
1190  Position start = Position(0, 0, 0),
1191  const std::vector<bool> &node_filter = std::vector<bool>());
1199  void reverse(bool dep_tags = true, bool inv_tags = false,
1200  Position start = Position(0, 0, 0),
1201  const std::vector<bool> &node_filter = std::vector<bool>());
1203  void forward_sub();
1205  void reverse_sub();
1207  void clear_deriv_sub();
1208  };
1209 
1214  void forward_replay(bool inv_tags = true, bool dep_tags = true);
1215 
1221  void subgraph_cache_ptr() const;
1229  void set_subgraph(const std::vector<bool> &marks, bool append = false);
1231  void mark_subgraph(std::vector<bool> &marks);
1233  void unmark_subgraph(std::vector<bool> &marks);
1235  void subgraph_trivial();
1241  void clear_deriv_sub();
1274  global extract_sub(std::vector<Index> &var_remap, global new_glob = global());
1279  void extract_sub_inplace(std::vector<bool> marks);
1283  global extract_sub();
1284 
1293  std::vector<Index> var2op();
1299  std::vector<bool> var2op(const std::vector<bool> &values);
1301  std::vector<Index> op2var(const std::vector<Index> &seq);
1303  std::vector<bool> op2var(const std::vector<bool> &seq_mark);
1312  std::vector<Index> op2idx(const std::vector<Index> &var_subset,
1313  Index NA = (Index)-1);
1315  std::vector<bool> mark_space(size_t n, const std::vector<Index> ind);
1317  std::vector<bool> inv_marks();
1319  std::vector<bool> dep_marks();
1321  std::vector<bool> subgraph_marks();
1322 
1323  struct append_edges {
1324  size_t &i;
1325  const std::vector<bool> &keep_var;
1326  std::vector<Index> &var2op;
1327  std::vector<IndexPair> &edges;
1328 
1329  std::vector<bool> op_marks;
1330  size_t pos;
1331  append_edges(size_t &i, size_t num_nodes, const std::vector<bool> &keep_var,
1332  std::vector<Index> &var2op, std::vector<IndexPair> &edges);
1333  void operator()(Index dep_j);
1334 
1335  void start_iteration();
1336 
1337  void end_iteration();
1338  };
1347  graph build_graph(bool transpose, const std::vector<bool> &keep_var);
1351  graph forward_graph(std::vector<bool> keep_var = std::vector<bool>(0));
1355  graph reverse_graph(std::vector<bool> keep_var = std::vector<bool>(0));
1356 
1361  bool identical(const global &other) const;
1362 
1364  template <class T>
1365  void hash(hash_t &h, T x) const {
1366  static const size_t n =
1367  (sizeof(T) / sizeof(hash_t)) + (sizeof(T) % sizeof(hash_t) != 0);
1368  hash_t buffer[n];
1369  std::fill(buffer, buffer + n, 0);
1370  for (size_t i = 0; i < sizeof(x); i++)
1371  ((char *)buffer)[i] = ((char *)&x)[i];
1372  hash_t A = 54059;
1373  hash_t B = 76963;
1374  for (size_t i = 0; i < n; i++) h = (A * h) ^ (B * buffer[i]);
1375  }
1376 
1385  hash_t hash() const;
1386 
1388  struct hash_config {
1398  bool reduce;
1402  std::vector<Index> inv_seed;
1403  };
1404 
1459  std::vector<hash_t> hash_sweep(hash_config cfg) const;
1461  std::vector<hash_t> hash_sweep(bool weak = true) const;
1462 
1476  void eliminate();
1477 
1479  struct print_config {
1480  std::string prefix, mark;
1481  int depth;
1482  print_config();
1483  };
1485  void print(print_config cfg);
1487  void print();
1488 
1490  template <int ninput_, int noutput_ = 1>
1491  struct Operator {
1493  static const bool dynamic = false;
1495  static const int ninput = ninput_;
1497  static const int noutput = noutput_;
1499  static const int independent_variable = false;
1501  static const int dependent_variable = false;
1503  static const bool have_input_size_output_size = false;
1505  static const bool have_increment_decrement = false;
1507  static const bool have_forward_reverse = true;
1509  static const bool have_forward_incr_reverse_decr = false;
1511  static const bool have_forward_mark_reverse_mark = false;
1513  static const bool have_dependencies = false;
1519  static const bool allow_remap = true;
1530  static const bool implicit_dependencies = false;
1532  static const bool add_static_identifier = false;
1535  static const bool add_forward_replay_copy = false;
1538  static const bool have_eval = false;
1540  static const int max_fuse_depth = 2;
1542  static const bool is_linear = false;
1544  static const bool is_constant = false;
1546  static const bool smart_pointer = false;
1548  static const bool elimination_protected = false;
1574  static const bool updating = false;
1577  void dependencies_updating(Args<> &args, Dependencies &dep) const {}
1580  return NULL;
1581  }
1583  void *operator_data() { return NULL; }
1585  void print(print_config cfg) {}
1586  };
1589  template <int ninput, int noutput>
1590  struct DynamicOperator : Operator<ninput, noutput> {
1592  static const bool dynamic = true;
1594  static const int max_fuse_depth = 0;
1595  };
1598  template <int ninput>
1599  struct DynamicOutputOperator : Operator<ninput, -1> {
1601  static const bool dynamic = true;
1603  static const int max_fuse_depth = 0;
1604  Index noutput;
1605  };
1606  template <int noutput = 1>
1607  struct DynamicInputOperator : Operator<-1, noutput> {
1609  static const bool dynamic = true;
1611  static const int max_fuse_depth = 0;
1612  Index ninput;
1613  };
1614  struct DynamicInputOutputOperator : Operator<-1, -1> {
1616  static const bool dynamic = true;
1618  static const int max_fuse_depth = 0;
1619  Index ninput_, noutput_;
1620  DynamicInputOutputOperator(Index ninput, Index noutput);
1621  Index input_size() const;
1622  Index output_size() const;
1623  static const bool have_input_size_output_size = true;
1624  };
1625  struct UniqueDynamicOperator : Operator<-1, -1> {
1627  static const bool dynamic = true;
1629  static const int max_fuse_depth = 0;
1631  static const bool smart_pointer = false;
1634  static const bool have_input_size_output_size = true;
1635  };
1636  struct SharedDynamicOperator : UniqueDynamicOperator {
1638  static const bool smart_pointer = true;
1639  };
1640 
1643  template <class OperatorBase>
1644  struct AddInputSizeOutputSize : OperatorBase {
1645  INHERIT_CTOR(AddInputSizeOutputSize, OperatorBase)
1646  Index input_size() const { return this->ninput; }
1647  Index output_size() const { return this->noutput; }
1648  static const bool have_input_size_output_size = true;
1649  };
1650 
1653  template <class OperatorBase>
1654  struct AddIncrementDecrement : OperatorBase {
1655  INHERIT_CTOR(AddIncrementDecrement, OperatorBase)
1656  void increment(IndexPair &ptr) {
1657  ptr.first += this->input_size();
1658  ptr.second += this->output_size();
1659  }
1660  void decrement(IndexPair &ptr) {
1661  ptr.first -= this->input_size();
1662  ptr.second -= this->output_size();
1663  }
1664  static const bool have_increment_decrement = true;
1665  };
1666 
1670  template <class OperatorBase>
1671  struct AddForwardReverse : OperatorBase {
1672  INHERIT_CTOR(AddForwardReverse, OperatorBase)
1673 
1674  template <class Type>
1675  void forward(ForwardArgs<Type> &args) {
1676  ForwardArgs<Type> args_cpy(args);
1677  OperatorBase::forward_incr(args_cpy);
1678  }
1679  template <class Type>
1680  void reverse(ReverseArgs<Type> &args) {
1681  ReverseArgs<Type> args_cpy(args);
1682  OperatorBase::increment(args_cpy.ptr);
1683  OperatorBase::reverse_decr(args_cpy);
1684  }
1685  static const bool have_forward_reverse = true;
1686  };
1687 
1691  template <class OperatorBase>
1692  struct AddForwardIncrReverseDecr : OperatorBase {
1693  INHERIT_CTOR(AddForwardIncrReverseDecr, OperatorBase)
1694 
1695  template <class Type>
1696  void forward_incr(ForwardArgs<Type> &args) {
1697  OperatorBase::forward(args);
1698  OperatorBase::increment(args.ptr);
1699  }
1700 
1701  template <class Type>
1702  void reverse_decr(ReverseArgs<Type> &args) {
1703  OperatorBase::decrement(args.ptr);
1704  OperatorBase::reverse(args);
1705  }
1706  static const bool have_forward_incr_reverse_decr = true;
1707  };
1708 
1711  template <class OperatorBase>
1712  struct AddForwardMarkReverseMark : OperatorBase {
1713  INHERIT_CTOR(AddForwardMarkReverseMark, OperatorBase)
1714 
1715  template <class Type>
1716  void forward(ForwardArgs<Type> &args) {
1717  OperatorBase::forward(args);
1718  }
1719  template <class Type>
1720  void reverse(ReverseArgs<Type> &args) {
1721  OperatorBase::reverse(args);
1722  }
1723 
1724  void forward(ForwardArgs<bool> &args) { args.mark_dense(*this); }
1725  void reverse(ReverseArgs<bool> &args) { args.mark_dense(*this); }
1726  static const bool have_forward_mark_reverse_mark = true;
1727  };
1728 
1731  template <class OperatorBase>
1732  struct AddDependencies : OperatorBase {
1733  INHERIT_CTOR(AddDependencies, OperatorBase)
1734  void dependencies(Args<> &args, Dependencies &dep) const {
1735  Index ninput_ = this->input_size();
1736  for (Index j = 0; j < ninput_; j++) dep.push_back(args.input(j));
1737  }
1738  static const bool have_dependencies = true;
1739  };
1740 
1743  template <class OperatorBase, int ninput>
1744  struct AddForwardFromEval : OperatorBase {};
1746  template <class OperatorBase>
1747  struct AddForwardFromEval<OperatorBase, 1> : OperatorBase {
1748  INHERIT_CTOR(AddForwardFromEval, OperatorBase)
1749  template <class Type>
1750  void forward(ForwardArgs<Type> &args) {
1751  args.y(0) = this->eval(args.x(0));
1752  }
1753  };
1755  template <class OperatorBase>
1756  struct AddForwardFromEval<OperatorBase, 2> : OperatorBase {
1757  INHERIT_CTOR(AddForwardFromEval, OperatorBase)
1758  template <class Type>
1759  void forward(ForwardArgs<Type> &args) {
1760  args.y(0) = this->eval(args.x(0), args.x(1));
1761  }
1762  };
1763 
1765  template <bool flag, class dummy>
1767  void increment() {}
1768  void decrement() {}
1769  size_t operator()() const { return 0; }
1770  };
1771  template <class dummy>
1772  struct ReferenceCounter<true, dummy> {
1773  size_t counter;
1774  ReferenceCounter() : counter(0) {}
1775  void increment() { counter++; }
1776  void decrement() { counter--; }
1777  size_t operator()() const { return counter; }
1778  };
1779 
1781  template <bool flag, class Yes, class No>
1782  struct if_else {};
1783  template <class Yes, class No>
1784  struct if_else<true, Yes, No> {
1785  typedef Yes type;
1786  };
1787  template <class Yes, class No>
1788  struct if_else<false, Yes, No> {
1789  typedef No type;
1790  };
1791 
1793  template <class OperatorBase>
1794  struct CPL {
1795  static const bool test1 = !OperatorBase::have_eval;
1797  typedef typename if_else<
1798  test1, OperatorBase,
1800 
1801  static const bool test2 = Result1::have_input_size_output_size;
1803  typedef
1806 
1807  static const bool test3 = !Result2::have_dependencies;
1809  typedef typename if_else<test3, AddDependencies<Result2>, Result2>::type
1811 
1812  static const bool test4 = Result3::have_increment_decrement;
1814  typedef
1817 
1818  static const bool test5 = Result4::have_forward_mark_reverse_mark;
1820  typedef typename if_else<test5, Result4,
1822 
1823  static const bool test6 = Result5::have_forward_reverse &&
1824  !Result5::have_forward_incr_reverse_decr;
1827  Result5>::type Result6;
1828 
1829  static const bool test7 = Result6::have_forward_incr_reverse_decr &&
1830  !Result6::have_forward_reverse;
1832  typedef typename if_else<test7, AddForwardReverse<Result6>, Result6>::type
1834 
1835  typedef Result7 type;
1836  };
1837 
1839  template <class Operator1, class Operator2>
1840  struct Fused : Operator<Operator1::ninput + Operator2::ninput,
1841  Operator1::noutput + Operator2::noutput> {
1842  typename CPL<Operator1>::type Op1;
1843  typename CPL<Operator2>::type Op2;
1845  static const int independent_variable =
1846  Operator1::independent_variable && Operator2::independent_variable;
1848  static const int dependent_variable =
1849  Operator1::dependent_variable && Operator2::dependent_variable;
1851  static const int max_fuse_depth =
1852  (Operator1::max_fuse_depth < Operator2::max_fuse_depth
1853  ? Operator1::max_fuse_depth - 1
1854  : Operator2::max_fuse_depth - 1);
1856  static const bool is_linear = Operator1::is_linear && Operator2::is_linear;
1857  template <class Type>
1858  void forward_incr(ForwardArgs<Type> &args) {
1859  Op1.forward_incr(args);
1860  Op2.forward_incr(args);
1861  }
1862  template <class Type>
1863  void reverse_decr(ReverseArgs<Type> &args) {
1864  Op2.reverse_decr(args);
1865  Op1.reverse_decr(args);
1866  }
1868  static const bool have_forward_incr_reverse_decr = true;
1870  static const bool have_forward_reverse = false;
1871  const char *op_name() { return "Fused"; }
1872  };
1881  template <class Operator1>
1882  struct Rep : DynamicOperator<-1, -1> {
1883  typename CPL<Operator1>::type Op;
1885  static const int independent_variable = Operator1::independent_variable;
1887  static const int dependent_variable = Operator1::dependent_variable;
1889  static const bool is_linear = Operator1::is_linear;
1890  Index n;
1891  Rep(Index n) : n(n) {}
1892  Index input_size() const { return Operator1::ninput * n; }
1893  Index output_size() const { return Operator1::noutput * n; }
1895  static const bool have_input_size_output_size = true;
1896  template <class Type>
1897  void forward_incr(ForwardArgs<Type> &args) {
1898  for (size_t i = 0; i < (size_t)n; i++) Op.forward_incr(args);
1899  }
1900  template <class Type>
1901  void reverse_decr(ReverseArgs<Type> &args) {
1902  for (size_t i = 0; i < (size_t)n; i++) Op.reverse_decr(args);
1903  }
1905  static const bool have_forward_incr_reverse_decr = true;
1907  static const bool have_forward_reverse = false;
1914  TMBAD_ASSERT(false);
1915  std::vector<Index> &inputs = get_glob()->inputs;
1916  size_t k = Op.input_size();
1917  size_t start = inputs.size() - k * n;
1918  std::valarray<Index> increment(k);
1919  if (k > 0) {
1920  for (size_t i = 0; i < (size_t)n - 1; i++) {
1921  std::valarray<Index> v1(&inputs[start + i * k], k);
1922  std::valarray<Index> v2(&inputs[start + (i + 1) * k], k);
1923  if (i == 0) {
1924  increment = v2 - v1;
1925  } else {
1926  bool ok = (increment == (v2 - v1)).min();
1927  if (!ok) return NULL;
1928  }
1929  }
1930  }
1931 
1932  size_t reduction = (n - 1) * k;
1933  inputs.resize(inputs.size() - reduction);
1934  return get_glob()->getOperator<RepCompress<Operator1> >(n, increment);
1935  }
1936  OperatorPure *other_fuse(OperatorPure *self, OperatorPure *other) {
1937  OperatorPure *op1 = get_glob()->getOperator<Operator1>();
1938  if (op1 == other) {
1939  this->n++;
1940  return self;
1941  }
1942  return NULL;
1943  }
1944  const char *op_name() { return "Rep"; }
1945  };
1956  template <class Operator1>
1957  struct RepCompress : DynamicOperator<-1, -1> {
1959  static const int independent_variable = Operator1::independent_variable;
1961  static const int dependent_variable = Operator1::dependent_variable;
1963  static const bool is_linear = Operator1::is_linear;
1964  typename CPL<Operator1>::type Op;
1965  Index n;
1966 
1967  std::valarray<Index> increment_pattern;
1968  RepCompress(Index n, std::valarray<Index> v) : n(n), increment_pattern(v) {}
1969  Index input_size() const { return Operator1::ninput; }
1970  Index output_size() const { return Operator1::noutput * n; }
1972  static const bool have_input_size_output_size = true;
1974  template <class Type>
1976  std::valarray<Index> inputs(input_size());
1977  for (size_t i = 0; i < inputs.size(); i++) inputs[i] = args.input(i);
1978  ForwardArgs<Type> args_cpy = args;
1979  args_cpy.inputs = &inputs[0];
1980  args_cpy.ptr.first = 0;
1981  for (size_t i = 0; i < (size_t)n; i++) {
1982  Op.forward(args_cpy);
1983  inputs += this->increment_pattern;
1984  args_cpy.ptr.second += Op.output_size();
1985  }
1986  }
1988  template <class Type>
1990  std::valarray<Index> inputs(input_size());
1991  for (size_t i = 0; i < inputs.size(); i++) inputs[i] = args.input(i);
1992  inputs += n * this->increment_pattern;
1993  ReverseArgs<Type> args_cpy = args;
1994  args_cpy.inputs = &inputs[0];
1995  args_cpy.ptr.first = 0;
1996  args_cpy.ptr.second += n * Op.output_size();
1997  for (size_t i = 0; i < (size_t)n; i++) {
1998  inputs -= this->increment_pattern;
1999  args_cpy.ptr.second -= Op.output_size();
2000  Op.reverse(args_cpy);
2001  }
2002  }
2004  void dependencies(Args<> &args, Dependencies &dep) const {
2005  std::valarray<Index> inputs(input_size());
2006  for (size_t i = 0; i < inputs.size(); i++) inputs[i] = args.input(i);
2007  for (size_t i = 0; i < (size_t)n; i++) {
2008  dep.insert(dep.end(), &inputs[0], &inputs[0] + inputs.size());
2009  inputs += this->increment_pattern;
2010  }
2011  }
2012  static const bool have_dependencies = true;
2013  void forward(ForwardArgs<Writer> &args) {
2014  std::valarray<Index> inputs(Op.input_size());
2015  for (size_t i = 0; i < (size_t)Op.input_size(); i++)
2016  inputs[i] = args.input(i);
2017  std::valarray<Index> outputs(Op.output_size());
2018  for (size_t i = 0; i < (size_t)Op.output_size(); i++)
2019  outputs[i] = args.output(i);
2020  Writer w;
2021  int ninp = Op.input_size();
2022  int nout = Op.output_size();
2023 
2024  w << "for (int count = 0, "
2025  << "i[" << ninp << "]=" << inputs << ", "
2026  << "di[" << ninp << "]=" << increment_pattern << ", "
2027  << "o[" << nout << "]=" << outputs << "; "
2028  << "count < " << n << "; count++) {\n";
2029 
2030  w << " ";
2031  ForwardArgs<Writer> args_cpy = args;
2032  args_cpy.set_indirect();
2033  Op.forward(args_cpy);
2034  w << "\n";
2035 
2036  w << " ";
2037  w << "for (int k=0; k<" << ninp << "; k++) i[k] += di[k];\n";
2038  w << " ";
2039  w << "for (int k=0; k<" << nout << "; k++) o[k] += " << nout << ";\n";
2040 
2041  w << " ";
2042  w << "}";
2043  }
2044  void reverse(ReverseArgs<Writer> &args) {
2045  std::valarray<Index> inputs(Op.input_size());
2046  for (size_t i = 0; i < (size_t)Op.input_size(); i++)
2047  inputs[i] = args.input(i);
2048  inputs += n * increment_pattern;
2049  std::valarray<Index> outputs(Op.output_size());
2050  for (size_t i = 0; i < (size_t)Op.output_size(); i++)
2051  outputs[i] = args.output(i);
2052  outputs += n * Op.output_size();
2053  Writer w;
2054  int ninp = Op.input_size();
2055  int nout = Op.output_size();
2056 
2057  w << "for (int count = 0, "
2058  << "i[" << ninp << "]=" << inputs << ", "
2059  << "di[" << ninp << "]=" << increment_pattern << ", "
2060  << "o[" << nout << "]=" << outputs << "; "
2061  << "count < " << n << "; count++) {\n";
2062 
2063  w << " ";
2064  w << "for (int k=0; k<" << ninp << "; k++) i[k] -= di[k];\n";
2065  w << " ";
2066  w << "for (int k=0; k<" << nout << "; k++) o[k] -= " << nout << ";\n";
2067 
2068  w << " ";
2069  ReverseArgs<Writer> args_cpy = args;
2070  args_cpy.set_indirect();
2071  Op.reverse(args_cpy);
2072  w << "\n";
2073 
2074  w << " ";
2075  w << "}";
2076  }
2078  static const bool have_forward_incr_reverse_decr = false;
2080  static const bool have_forward_reverse = true;
2082  static const bool have_forward_mark_reverse_mark = true;
2083  const char *op_name() { return "CRep"; }
2084 
2085  struct operator_data_t {
2086  OperatorPure *Op;
2087  Index n;
2088  std::valarray<Index> ip;
2089  operator_data_t(const RepCompress &x)
2090  : Op(get_glob()->getOperator<Operator1>()),
2091  n(x.n),
2092  ip(x.increment_pattern) {}
2093  ~operator_data_t() { Op->deallocate(); }
2094  bool operator==(const operator_data_t &other) {
2095  return (Op == other.Op) && (ip.size() == other.ip.size()) &&
2096  ((ip - other.ip).min() == 0);
2097  }
2098  };
2099  void *operator_data() { return new operator_data_t(*this); }
2100  OperatorPure *other_fuse(OperatorPure *self, OperatorPure *other) {
2101  if (this->op_name() == other->op_name()) {
2102  operator_data_t *p1 =
2103  static_cast<operator_data_t *>(self->operator_data());
2104  operator_data_t *p2 =
2105  static_cast<operator_data_t *>(other->operator_data());
2106  bool match = (*p1 == *p2);
2107  int other_n = p2->n;
2108  delete p1;
2109  delete p2;
2110  if (match) {
2111  std::vector<Index> &inputs = get_glob()->inputs;
2112  size_t reduction = increment_pattern.size();
2113  inputs.resize(inputs.size() - reduction);
2114  this->n += other_n;
2115  other->deallocate();
2116  return self;
2117  }
2118  }
2119  return NULL;
2120  }
2121  };
2122 
2128  template <class OperatorBase>
2130  typename CPL<OperatorBase>::type Op;
2131  INHERIT_CTOR(Complete, Op)
2132  ~Complete() {}
2133  void forward(ForwardArgs<Scalar> &args) { Op.forward(args); }
2134  void reverse(ReverseArgs<Scalar> &args) { Op.reverse(args); }
2135  void forward_incr(ForwardArgs<Scalar> &args) { Op.forward_incr(args); }
2136  void reverse_decr(ReverseArgs<Scalar> &args) { Op.reverse_decr(args); }
2137 
2139  if (Op.add_forward_replay_copy)
2140  forward_replay_copy(args);
2141  else
2142  Op.forward(args);
2143  }
2144  void reverse(ReverseArgs<Replay> &args) { Op.reverse(args); }
2146  if (Op.add_forward_replay_copy) {
2147  forward_replay_copy(args);
2148  increment(args.ptr);
2149  } else
2150  Op.forward_incr(args);
2151  }
2152  void reverse_decr(ReverseArgs<Replay> &args) { Op.reverse_decr(args); }
2153 
2154  void forward(ForwardArgs<bool> &args) { Op.forward(args); }
2155  void reverse(ReverseArgs<bool> &args) { Op.reverse(args); }
2156  void forward_incr(ForwardArgs<bool> &args) { Op.forward_incr(args); }
2157  void reverse_decr(ReverseArgs<bool> &args) { Op.reverse_decr(args); }
2159  args.mark_dense(Op);
2160  Op.increment(args.ptr);
2161  };
2162 
2163  void forward(ForwardArgs<Writer> &args) { Op.forward(args); }
2164  void reverse(ReverseArgs<Writer> &args) { Op.reverse(args); }
2165  void forward_incr(ForwardArgs<Writer> &args) { Op.forward_incr(args); }
2166  void reverse_decr(ReverseArgs<Writer> &args) { Op.reverse_decr(args); }
2171  std::vector<ad_plain> operator()(const std::vector<ad_plain> &x) {
2172  TMBAD_ASSERT2(OperatorBase::dynamic,
2173  "Stack to heap copy only allowed for dynamic operators");
2174  Complete *pOp = new Complete(*this);
2175  TMBAD_ASSERT2(pOp->ref_count() == 0, "Operator already on the heap");
2176  pOp->ref_count.increment();
2177  return get_glob()->add_to_stack<OperatorBase>(pOp, x);
2178  }
2179  ad_segment operator()(const ad_segment &x) {
2180  TMBAD_ASSERT2(OperatorBase::dynamic,
2181  "Stack to heap copy only allowed for dynamic operators");
2182  Complete *pOp = new Complete(*this);
2183  TMBAD_ASSERT2(pOp->ref_count() == 0, "Operator already on the heap");
2184  pOp->ref_count.increment();
2185  return get_glob()->add_to_stack<OperatorBase>(pOp, x);
2186  }
2187  ad_segment operator()(const ad_segment &x, const ad_segment &y) {
2188  TMBAD_ASSERT2(OperatorBase::dynamic,
2189  "Stack to heap copy only allowed for dynamic operators");
2190  Complete *pOp = new Complete(*this);
2191  TMBAD_ASSERT2(pOp->ref_count() == 0, "Operator already on the heap");
2192  pOp->ref_count.increment();
2193  return get_glob()->add_to_stack<OperatorBase>(pOp, x, y);
2194  }
2195  template <class T>
2196  std::vector<T> operator()(const std::vector<T> &x) {
2197  std::vector<ad_plain> x_(x.begin(), x.end());
2198  std::vector<ad_plain> y_ = (*this)(x_);
2199  std::vector<T> y(y_.begin(), y_.end());
2200  return y;
2201  }
2202  void forward_replay_copy(ForwardArgs<Replay> &args) {
2203  std::vector<ad_plain> x(Op.input_size());
2204  for (size_t i = 0; i < x.size(); i++) x[i] = args.x(i);
2205  std::vector<ad_plain> y =
2206  get_glob()->add_to_stack<OperatorBase>(this->copy(), x);
2207  for (size_t i = 0; i < y.size(); i++) args.y(i) = y[i];
2208  }
2209  void dependencies(Args<> &args, Dependencies &dep) {
2210  Op.dependencies(args, dep);
2211  }
2212  void dependencies_updating(Args<> &args, Dependencies &dep) {
2213  Op.dependencies_updating(args, dep);
2214  }
2215  void increment(IndexPair &ptr) { Op.increment(ptr); }
2216  void decrement(IndexPair &ptr) { Op.decrement(ptr); }
2217  Index input_size() { return Op.input_size(); }
2218  Index output_size() { return Op.output_size(); }
2219  const char *op_name() { return Op.op_name(); }
2220  void print(print_config cfg) { Op.print(cfg); }
2221 
2222  template <class Operator_, int depth>
2223  struct SelfFuse {
2224  typedef Rep<Operator_> type;
2225  OperatorPure *operator()() {
2226  return get_glob()->template getOperator<type>(2);
2227  }
2228  };
2229  template <class Operator_>
2230  struct SelfFuse<Operator_, 0> {
2231  OperatorPure *operator()() { return NULL; }
2232  };
2234  return SelfFuse<OperatorBase, OperatorBase::max_fuse_depth>()();
2235  }
2237  return Op.other_fuse(this, other);
2238  }
2241  if (Op.smart_pointer) {
2242  ref_count.increment();
2243  return this;
2244  } else if (Op.dynamic)
2245  return new Complete(*this);
2246  else
2247  return this;
2248  }
2249  void deallocate() {
2250  if (!Op.dynamic) return;
2251  if (Op.smart_pointer) {
2252  if (ref_count() > 1) {
2253  ref_count.decrement();
2254  return;
2255  }
2256  }
2257  delete this;
2258  }
2260  op_info info(Op);
2261  return info;
2262  }
2263  void *identifier() {
2264  if (Op.add_static_identifier) {
2265  static void *id = new char();
2266  return id;
2267  } else
2268  return (void *)this;
2269  }
2270  void *operator_data() { return Op.operator_data(); }
2271  void *incomplete() { return &Op; }
2272  };
2273 
2274  template <class OperatorBase>
2275  Complete<OperatorBase> *getOperator() const {
2276  return constructOperator<Complete<OperatorBase>, OperatorBase::dynamic>()();
2277  }
2278  template <class OperatorBase, class T1>
2279  Complete<OperatorBase> *getOperator(const T1 &x1) const {
2280  return constructOperator<Complete<OperatorBase>, OperatorBase::dynamic>()(
2281  x1);
2282  }
2283  template <class OperatorBase, class T1, class T2>
2284  Complete<OperatorBase> *getOperator(const T1 &x1, const T2 &x2) const {
2285  return constructOperator<Complete<OperatorBase>, OperatorBase::dynamic>()(
2286  x1, x2);
2287  }
2288  template <class OperatorBase, class T1, class T2, class T3>
2289  Complete<OperatorBase> *getOperator(const T1 &x1, const T2 &x2,
2290  const T3 &x3) const {
2291  return constructOperator<Complete<OperatorBase>, OperatorBase::dynamic>()(
2292  x1, x2, x3);
2293  }
2294  template <class OperatorBase, class T1, class T2, class T3, class T4>
2295  Complete<OperatorBase> *getOperator(const T1 &x1, const T2 &x2, const T3 &x3,
2296  const T4 &x4) const {
2297  return constructOperator<Complete<OperatorBase>, OperatorBase::dynamic>()(
2298  x1, x2, x3, x4);
2299  }
2300  struct InvOp : Operator<0> {
2301  static const int independent_variable = true;
2302  template <class Type>
2303  void forward(ForwardArgs<Type> &args) {}
2304  template <class Type>
2305  void reverse(ReverseArgs<Type> &args) {}
2306  const char *op_name();
2307  };
2308 
2309  struct DepOp : Operator<1> {
2310  static const bool is_linear = true;
2311  static const int dependent_variable = true;
2312  static const bool have_eval = true;
2313  template <class Type>
2314  Type eval(Type x0) {
2315  return x0;
2316  }
2317  template <class Type>
2318  void reverse(ReverseArgs<Type> &args) {
2319  args.dx(0) += args.dy(0);
2320  }
2321  const char *op_name();
2322  };
2323 
2324  struct ConstOp : Operator<0, 1> {
2325  static const bool is_linear = true;
2326  static const bool is_constant = true;
2327  template <class Type>
2328  void forward(ForwardArgs<Type> &args) {}
2329  void forward(ForwardArgs<Replay> &args);
2330  template <class Type>
2331  void reverse(ReverseArgs<Type> &args) {}
2332  const char *op_name();
2333  void forward(ForwardArgs<Writer> &args);
2334  };
2335  struct DataOp : DynamicOutputOperator<0> {
2336  typedef DynamicOutputOperator<0> Base;
2337  static const bool is_linear = true;
2338  DataOp(Index n);
2339  template <class Type>
2340  void forward(ForwardArgs<Type> &args) {}
2341  template <class Type>
2342  void reverse(ReverseArgs<Type> &args) {}
2343  const char *op_name();
2344  void forward(ForwardArgs<Writer> &args);
2345  };
2356  static const bool add_forward_replay_copy = true;
2357  ZeroOp(Index n);
2358  template <class Type>
2359  void forward(ForwardArgs<Type> &args) {
2360  for (Index i = 0; i < Base::noutput; i++) args.y(i) = Type(0);
2361  }
2362  template <class Type>
2363  void reverse(ReverseArgs<Type> &args) {}
2364  const char *op_name();
2365  void forward(ForwardArgs<Writer> &args);
2368  void operator()(Replay *x, Index n);
2369  };
2371  struct NullOp : Operator<0, 0> {
2372  NullOp();
2373  const char *op_name();
2374  template <class T>
2375  void forward(ForwardArgs<T> &args) {}
2376  template <class T>
2377  void reverse(ReverseArgs<T> &args) {}
2378  };
2380  struct NullOp2 : DynamicInputOutputOperator {
2381  NullOp2(Index ninput, Index noutput);
2382  const char *op_name();
2383  template <class T>
2384  void forward(ForwardArgs<T> &args) {}
2385  template <class T>
2386  void reverse(ReverseArgs<T> &args) {}
2387  };
2408  struct RefOp : DynamicOperator<0, 1> {
2409  static const bool dynamic = true;
2410  global *glob;
2411  Index i;
2412  RefOp(global *glob, Index i);
2414  void forward(ForwardArgs<Scalar> &args);
2416  void forward(ForwardArgs<Replay> &args);
2419  template <class Type>
2421  TMBAD_ASSERT2(false,
2422  "Reverse mode updates are forbidden until all references "
2423  "are resolved");
2424  }
2426  void reverse(ReverseArgs<Replay> &args);
2427  const char *op_name();
2428  };
2429 
2430  typedef Operator<1> UnaryOperator;
2431  typedef Operator<2> BinaryOperator;
2432 
2433  OperatorPure *Fuse(OperatorPure *Op1, OperatorPure *Op2);
2434 
2435  static bool fuse;
2436 
2441  void set_fuse(bool flag);
2442 
2445  void add_to_opstack(OperatorPure *pOp);
2447  template <class OperatorBase>
2448  ad_plain add_to_stack(Scalar result = 0) {
2449  ad_plain ans;
2450  ans.index = this->values.size();
2451 
2452  this->values.push_back(result);
2453 
2454  Complete<OperatorBase> *pOp = this->template getOperator<OperatorBase>();
2455  add_to_opstack(pOp);
2456 
2457  TMBAD_ASSERT(!TMBAD_INDEX_OVERFLOW(values.size()));
2458  return ans;
2459  }
2461  template <class OperatorBase>
2462  ad_plain add_to_stack(const ad_plain &x) {
2463  ad_plain ans;
2464  ans.index = this->values.size();
2465 
2466  this->values.push_back(OperatorBase().eval(x.Value()));
2467 
2468  this->inputs.push_back(x.index);
2469 
2470  Complete<OperatorBase> *pOp = this->template getOperator<OperatorBase>();
2471  add_to_opstack(pOp);
2472 
2473  TMBAD_ASSERT(!TMBAD_INDEX_OVERFLOW(values.size()));
2474  TMBAD_ASSERT(!TMBAD_INDEX_OVERFLOW(inputs.size()));
2475  return ans;
2476  }
2478  template <class OperatorBase>
2479  ad_plain add_to_stack(const ad_plain &x, const ad_plain &y) {
2480  ad_plain ans;
2481  ans.index = this->values.size();
2482 
2483  this->values.push_back(OperatorBase().eval(x.Value(), y.Value()));
2484 
2485  this->inputs.push_back(x.index);
2486  this->inputs.push_back(y.index);
2487 
2488  Complete<OperatorBase> *pOp = this->template getOperator<OperatorBase>();
2489  add_to_opstack(pOp);
2490 
2491  TMBAD_ASSERT(!TMBAD_INDEX_OVERFLOW(values.size()));
2492  TMBAD_ASSERT(!TMBAD_INDEX_OVERFLOW(inputs.size()));
2493  return ans;
2494  }
2495  template <class OperatorBase>
2496  ad_segment add_to_stack(ad_segment lhs, ad_segment rhs,
2497  ad_segment more = ad_segment()) {
2498  IndexPair ptr((Index)inputs.size(), (Index)values.size());
2499  Complete<OperatorBase> *pOp =
2500  this->template getOperator<OperatorBase>(lhs, rhs);
2501  size_t n = pOp->output_size();
2502  ad_segment ans(values.size(), n);
2503  inputs.push_back(lhs.index());
2504  inputs.push_back(rhs.index());
2505  if (more.size() > 0) inputs.push_back(more.index());
2506  opstack.push_back(pOp);
2507  values.resize(values.size() + n);
2508  ForwardArgs<Scalar> args(inputs, values, this);
2509  args.ptr = ptr;
2510  pOp->forward(args);
2511 
2512  TMBAD_ASSERT(!TMBAD_INDEX_OVERFLOW(values.size()));
2513  TMBAD_ASSERT(!TMBAD_INDEX_OVERFLOW(inputs.size()));
2514  return ans;
2515  }
2516 
2517  template <class OperatorBase>
2518  ad_segment add_to_stack(Complete<OperatorBase> *pOp, ad_segment lhs,
2519  ad_segment rhs = ad_segment()) {
2520  static_assert(
2521  OperatorBase::dynamic,
2522  "Unlikely that you want to use this method for static operators?");
2523  static_assert(
2524  OperatorBase::ninput == 0 || OperatorBase::implicit_dependencies,
2525  "Operators with pointer inputs should always implement "
2526  "'implicit_dependencies'");
2527 
2528  IndexPair ptr((Index)inputs.size(), (Index)values.size());
2529  size_t n = pOp->output_size();
2530  ad_segment ans(values.size(), n);
2531  TMBAD_ASSERT((Index)(lhs.size() > 0) + (Index)(rhs.size() > 0) ==
2532  pOp->input_size());
2533  if (lhs.size() > 0) inputs.push_back(lhs.index());
2534  if (rhs.size() > 0) inputs.push_back(rhs.index());
2535  opstack.push_back(pOp);
2536  values.resize(values.size() + n);
2537  ForwardArgs<Scalar> args(inputs, values, this);
2538  args.ptr = ptr;
2539  pOp->forward(args);
2540 
2541  TMBAD_ASSERT(!TMBAD_INDEX_OVERFLOW(values.size()));
2542  TMBAD_ASSERT(!TMBAD_INDEX_OVERFLOW(inputs.size()));
2543  return ans;
2544  }
2547  template <class OperatorBase>
2548  std::vector<ad_plain> add_to_stack(OperatorPure *pOp,
2549  const std::vector<ad_plain> &x) {
2550  IndexPair ptr((Index)inputs.size(), (Index)values.size());
2551  size_t m = pOp->input_size();
2552  size_t n = pOp->output_size();
2553  ad_segment ans(values.size(), n);
2554  for (size_t i = 0; i < m; i++) inputs.push_back(x[i].index);
2555  opstack.push_back(pOp);
2556  values.resize(values.size() + n);
2557  ForwardArgs<Scalar> args(inputs, values, this);
2558  args.ptr = ptr;
2559  pOp->forward(args);
2560 
2561  TMBAD_ASSERT(!TMBAD_INDEX_OVERFLOW(values.size()));
2562  TMBAD_ASSERT(!TMBAD_INDEX_OVERFLOW(inputs.size()));
2563  std::vector<ad_plain> out(n);
2564  for (size_t i = 0; i < n; i++) out[i].index = ans.index() + i;
2565  return out;
2566  }
2567 
2568  struct ad_plain {
2569  Index index;
2570  static const Index NA = (Index)-1;
2571  bool initialized() const;
2572  bool on_some_tape() const;
2574  void addToTape() const;
2576  global *glob() const;
2580  void override_by(const ad_plain &x) const;
2581 
2586  ad_plain();
2587 
2589  ad_plain(Scalar x);
2591  ad_plain(ad_aug x);
2592 
2594  struct CopyOp : Operator<1> {
2595  static const bool have_eval = true;
2596  template <class Type>
2597  Type eval(Type x0) {
2598  return x0;
2599  }
2600  Replay eval(Replay x0);
2601  template <class Type>
2602  void reverse(ReverseArgs<Type> &args) {
2603  args.dx(0) += args.dy(0);
2604  }
2605  const char *op_name();
2606  };
2614  ad_plain copy() const;
2625  struct ValOp : Operator<1> {
2626  static const bool have_dependencies = true;
2627  static const bool have_eval = true;
2629  template <class Type>
2630  Type eval(Type x0) {
2631  return x0;
2632  }
2633  Replay eval(Replay x0);
2635  template <class Type>
2643  void dependencies(Args<> &args, Dependencies &dep) const;
2644  const char *op_name();
2645  };
2649  ad_plain copy0() const;
2650 
2651  template <bool left_var, bool right_var>
2652  struct AddOp_ : BinaryOperator {
2653  static const bool is_linear = true;
2654  static const bool have_eval = true;
2655  template <class Type>
2656  Type eval(Type x0, Type x1) {
2657  return x0 + x1;
2658  }
2659  template <class Type>
2660  void reverse(ReverseArgs<Type> &args) {
2661  if (left_var) args.dx(0) += args.dy(0);
2662  if (right_var) args.dx(1) += args.dy(0);
2663  }
2664  const char *op_name() { return "AddOp"; }
2665  OperatorPure *other_fuse(OperatorPure *self, OperatorPure *other) {
2666  if (other == get_glob()->getOperator<MulOp>()) {
2667  return get_glob()->getOperator<Fused<AddOp_, MulOp> >();
2668  }
2669  return NULL;
2670  }
2671  };
2672  typedef AddOp_<true, true> AddOp;
2673  ad_plain operator+(const ad_plain &other) const;
2674 
2675  template <bool left_var, bool right_var>
2676  struct SubOp_ : BinaryOperator {
2677  static const bool is_linear = true;
2678  static const bool have_eval = true;
2679  template <class Type>
2680  Type eval(Type x0, Type x1) {
2681  return x0 - x1;
2682  }
2683  template <class Type>
2684  void reverse(ReverseArgs<Type> &args) {
2685  if (left_var) args.dx(0) += args.dy(0);
2686  if (right_var) args.dx(1) -= args.dy(0);
2687  }
2688  const char *op_name() { return "SubOp"; }
2689  };
2690  typedef SubOp_<true, true> SubOp;
2691  ad_plain operator-(const ad_plain &other) const;
2692 
2693  template <bool left_var, bool right_var>
2694  struct MulOp_ : BinaryOperator {
2695  static const bool have_eval = true;
2696  static const bool is_linear = !left_var || !right_var;
2697  template <class Type>
2698  Type eval(Type x0, Type x1) {
2699  return x0 * x1;
2700  }
2701  template <class Type>
2702  void reverse(ReverseArgs<Type> &args) {
2703  if (left_var) args.dx(0) += args.x(1) * args.dy(0);
2704  if (right_var) args.dx(1) += args.x(0) * args.dy(0);
2705  }
2706  const char *op_name() { return "MulOp"; }
2707  };
2708  typedef MulOp_<true, true> MulOp;
2709  ad_plain operator*(const ad_plain &other) const;
2710  ad_plain operator*(const Scalar &other) const;
2711 
2712  template <bool left_var, bool right_var>
2713  struct DivOp_ : BinaryOperator {
2714  static const bool have_eval = true;
2715  template <class Type>
2716  Type eval(Type x0, Type x1) {
2717  return x0 / x1;
2718  }
2719  template <class Type>
2720  void reverse(ReverseArgs<Type> &args) {
2721  Type tmp0 = args.dy(0) / args.x(1);
2722  if (left_var) args.dx(0) += tmp0;
2723  if (right_var) args.dx(1) -= args.y(0) * tmp0;
2724  }
2725  const char *op_name() { return "DivOp"; }
2726  };
2727  typedef DivOp_<true, true> DivOp;
2728  ad_plain operator/(const ad_plain &other) const;
2729 
2730  struct NegOp : UnaryOperator {
2731  static const bool is_linear = true;
2732  static const bool have_eval = true;
2733  template <class Type>
2734  Type eval(Type x0) {
2735  return -x0;
2736  }
2737  template <class Type>
2738  void reverse(ReverseArgs<Type> &args) {
2739  args.dx(0) -= args.dy(0);
2740  }
2741  const char *op_name();
2742  };
2743  ad_plain operator-() const;
2744 
2745  ad_plain &operator+=(const ad_plain &other);
2746  ad_plain &operator-=(const ad_plain &other);
2747  ad_plain &operator*=(const ad_plain &other);
2748  ad_plain &operator/=(const ad_plain &other);
2749 
2750  void Dependent();
2751 
2752  void Independent();
2753  Scalar &Value();
2754  Scalar Value() const;
2755  Scalar Value(global *glob) const;
2756  Scalar &Deriv();
2757  };
2765  bool in_use;
2769  void ad_start();
2771  void ad_stop();
2772  void Independent(std::vector<ad_plain> &x);
2780  struct ad_segment {
2781  ad_plain x;
2782  size_t n;
2783  size_t c;
2785  ad_segment();
2787  ad_segment(ad_plain x, size_t n);
2789  ad_segment(ad_aug x);
2791  ad_segment(Scalar x);
2793  ad_segment(Index idx, size_t n);
2795  ad_segment(ad_plain x, size_t r, size_t c);
2798  ad_segment(Replay *x, size_t n, bool zero_check = false);
2799  bool identicalZero();
2800  bool all_on_active_tape(Replay *x, size_t n);
2801  bool is_contiguous(Replay *x, size_t n);
2802  bool all_zero(Replay *x, size_t n);
2803  bool all_constant(Replay *x, size_t n);
2804  size_t size() const;
2805  size_t rows() const;
2806  size_t cols() const;
2807 
2808  ad_plain operator[](size_t i) const;
2809  ad_plain offset() const;
2810  Index index() const;
2811  };
2831  struct ad_aug {
2834  mutable ad_plain taped_value;
2838  TMBAD_UNION_OR_STRUCT {
2839  Scalar value;
2840  mutable global *glob;
2841  }
2842  data;
2844  bool on_some_tape() const;
2846  bool on_active_tape() const;
2848  bool ontape() const;
2852  bool constant() const;
2853  Index index() const;
2859  global *glob() const;
2861  Scalar Value() const;
2865  ad_aug();
2869  ad_aug(Scalar x);
2871  ad_aug(ad_plain x);
2876  void addToTape() const;
2880  void override_by(const ad_plain &x) const;
2882  bool in_context_stack(global *glob) const;
2885  ad_aug copy() const;
2887  ad_aug copy0() const;
2890  bool identicalZero() const;
2893  bool identicalOne() const;
2897  bool bothConstant(const ad_aug &other) const;
2901  bool identical(const ad_aug &other) const;
2906  ad_aug operator+(const ad_aug &other) const;
2912  ad_aug operator-(const ad_aug &other) const;
2914  ad_aug operator-() const;
2921  ad_aug operator*(const ad_aug &other) const;
2926  ad_aug operator/(const ad_aug &other) const;
2929  ad_aug &operator+=(const ad_aug &other);
2932  ad_aug &operator-=(const ad_aug &other);
2935  ad_aug &operator*=(const ad_aug &other);
2938  ad_aug &operator/=(const ad_aug &other);
2940  void Dependent();
2942  void Independent();
2943  Scalar &Value();
2944  Scalar &Deriv();
2945  };
2946  void Independent(std::vector<ad_aug> &x);
2947 };
2948 
2949 template <class S, class T>
2950 std::ostream &operator<<(std::ostream &os, const std::pair<S, T> &x) {
2951  os << "(" << x.first << ", " << x.second << ")";
2952  return os;
2953 }
2954 
2955 std::ostream &operator<<(std::ostream &os, const global::ad_plain &x);
2956 std::ostream &operator<<(std::ostream &os, const global::ad_aug &x);
2957 
2968 template <class T>
2969 struct adaptive : T {
2970  INHERIT_CTOR(adaptive, T)
2971  bool operator==(const T &other) const {
2972  return this->Value() == other.Value();
2973  }
2974  bool operator!=(const T &other) const {
2975  return this->Value() != other.Value();
2976  }
2977  bool operator>=(const T &other) const {
2978  return this->Value() >= other.Value();
2979  }
2980  bool operator<=(const T &other) const {
2981  return this->Value() <= other.Value();
2982  }
2983  bool operator<(const T &other) const { return this->Value() < other.Value(); }
2984  bool operator>(const T &other) const { return this->Value() > other.Value(); }
2985 
2986  adaptive operator+(const T &other) const {
2987  return adaptive(T(*this) + other);
2988  }
2989  adaptive operator-(const T &other) const {
2990  return adaptive(T(*this) - other);
2991  }
2992  adaptive operator*(const T &other) const {
2993  return adaptive(T(*this) * other);
2994  }
2995  adaptive operator/(const T &other) const {
2996  return adaptive(T(*this) / other);
2997  }
2998 
2999  adaptive operator-() const { return adaptive(-(T(*this))); }
3000 };
3001 
3002 typedef global::ad_plain ad_plain;
3003 typedef global::ad_aug ad_aug;
3004 typedef global::Replay Replay;
3005 typedef adaptive<ad_aug> ad_adapt;
3014 struct ad_plain_index : ad_plain {
3015  ad_plain_index(const Index &i);
3016  ad_plain_index(const ad_plain &x);
3017 };
3018 struct ad_aug_index : ad_aug {
3019  ad_aug_index(const Index &i);
3020  ad_aug_index(const ad_aug &x);
3021  ad_aug_index(const ad_plain &x);
3022 };
3023 
3024 template <class T>
3025 void Independent(std::vector<T> &x) {
3026  for (size_t i = 0; i < x.size(); i++) x[i].Independent();
3027 }
3028 template <class T>
3029 void Dependent(std::vector<T> &x) {
3030  for (size_t i = 0; i < x.size(); i++) x[i].Dependent();
3031 }
3032 template <class T>
3033 Scalar Value(T x) {
3034  return x.Value();
3035 }
3036 Scalar Value(Scalar x);
3037 
3044 template <class V>
3045 bool isContiguous(V &x) {
3046  bool ok = true;
3047  Index j_previous;
3048  for (size_t i = 0; i < (size_t)x.size(); i++) {
3049  if (!x[i].on_some_tape()) {
3050  ok = false;
3051  break;
3052  }
3053  Index j = ad_plain(x[i]).index;
3054  if (i > 0) {
3055  if (j != j_previous + 1) {
3056  ok = false;
3057  break;
3058  }
3059  }
3060  j_previous = j;
3061  }
3062  return ok;
3063 }
3070 template <class V>
3071 V getContiguous(const V &x) {
3072  V y(x.size());
3073  for (size_t i = 0; i < (size_t)x.size(); i++) y[i] = x[i].copy();
3074  return y;
3075 }
3082 template <class V>
3083 void forceContiguous(V &x) {
3084  if (!isContiguous(x)) x = getContiguous(x);
3085 }
3086 ad_aug operator+(const double &x, const ad_aug &y);
3087 ad_aug operator-(const double &x, const ad_aug &y);
3088 ad_aug operator*(const double &x, const ad_aug &y);
3089 ad_aug operator/(const double &x, const ad_aug &y);
3090 
3091 bool operator<(const double &x, const ad_adapt &y);
3092 bool operator<=(const double &x, const ad_adapt &y);
3093 bool operator>(const double &x, const ad_adapt &y);
3094 bool operator>=(const double &x, const ad_adapt &y);
3095 bool operator==(const double &x, const ad_adapt &y);
3096 bool operator!=(const double &x, const ad_adapt &y);
3097 using ::round;
3098 using ::trunc;
3099 using std::ceil;
3100 using std::floor;
3101 Writer floor(const Writer &x);
3102 struct FloorOp : global::UnaryOperator {
3103  static const bool have_eval = true;
3104  template <class Type>
3105  Type eval(Type x) {
3106  return floor(x);
3107  }
3108  template <class Type>
3109  void reverse(ReverseArgs<Type> &args) {}
3110  const char *op_name();
3111 };
3112 ad_plain floor(const ad_plain &x);
3113 ad_aug floor(const ad_aug &x);
3114 Writer ceil(const Writer &x);
3115 struct CeilOp : global::UnaryOperator {
3116  static const bool have_eval = true;
3117  template <class Type>
3118  Type eval(Type x) {
3119  return ceil(x);
3120  }
3121  template <class Type>
3122  void reverse(ReverseArgs<Type> &args) {}
3123  const char *op_name();
3124 };
3125 ad_plain ceil(const ad_plain &x);
3126 ad_aug ceil(const ad_aug &x);
3127 Writer trunc(const Writer &x);
3128 struct TruncOp : global::UnaryOperator {
3129  static const bool have_eval = true;
3130  template <class Type>
3131  Type eval(Type x) {
3132  return trunc(x);
3133  }
3134  template <class Type>
3135  void reverse(ReverseArgs<Type> &args) {}
3136  const char *op_name();
3137 };
3138 ad_plain trunc(const ad_plain &x);
3139 ad_aug trunc(const ad_aug &x);
3140 Writer round(const Writer &x);
3141 struct RoundOp : global::UnaryOperator {
3142  static const bool have_eval = true;
3143  template <class Type>
3144  Type eval(Type x) {
3145  return round(x);
3146  }
3147  template <class Type>
3148  void reverse(ReverseArgs<Type> &args) {}
3149  const char *op_name();
3150 };
3151 ad_plain round(const ad_plain &x);
3152 ad_aug round(const ad_aug &x);
3153 
3154 double sign(const double &x);
3155 Writer sign(const Writer &x);
3156 struct SignOp : global::UnaryOperator {
3157  static const bool have_eval = true;
3158  template <class Type>
3159  Type eval(Type x) {
3160  return sign(x);
3161  }
3162  template <class Type>
3163  void reverse(ReverseArgs<Type> &args) {}
3164  const char *op_name();
3165 };
3166 ad_plain sign(const ad_plain &x);
3167 ad_aug sign(const ad_aug &x);
3168 
3169 double ge0(const double &x);
3170 double lt0(const double &x);
3171 Writer ge0(const Writer &x);
3172 struct Ge0Op : global::UnaryOperator {
3173  static const bool have_eval = true;
3174  template <class Type>
3175  Type eval(Type x) {
3176  return ge0(x);
3177  }
3178  template <class Type>
3179  void reverse(ReverseArgs<Type> &args) {}
3180  const char *op_name();
3181 };
3182 ad_plain ge0(const ad_plain &x);
3183 ad_aug ge0(const ad_aug &x);
3184 Writer lt0(const Writer &x);
3185 struct Lt0Op : global::UnaryOperator {
3186  static const bool have_eval = true;
3187  template <class Type>
3188  Type eval(Type x) {
3189  return lt0(x);
3190  }
3191  template <class Type>
3192  void reverse(ReverseArgs<Type> &args) {}
3193  const char *op_name();
3194 };
3195 ad_plain lt0(const ad_plain &x);
3196 ad_aug lt0(const ad_aug &x);
3197 using ::expm1;
3198 using ::fabs;
3199 using ::log1p;
3200 using std::acos;
3201 using std::acosh;
3202 using std::asin;
3203 using std::asinh;
3204 using std::atan;
3205 using std::atanh;
3206 using std::cos;
3207 using std::cosh;
3208 using std::exp;
3209 using std::log;
3210 using std::sin;
3211 using std::sinh;
3212 using std::sqrt;
3213 using std::tan;
3214 using std::tanh;
3215 
3216 Writer fabs(const Writer &x);
3217 struct AbsOp : global::UnaryOperator {
3218  static const bool have_eval = true;
3219  template <class Type>
3220  Type eval(Type x) {
3221  return fabs(x);
3222  }
3223  template <class Type>
3224  void reverse(ReverseArgs<Type> &args) {
3225  args.dx(0) += args.dy(0) * sign(args.x(0));
3226  }
3227  void reverse(ReverseArgs<Scalar> &args);
3228  const char *op_name();
3229 };
3230 ad_plain fabs(const ad_plain &x);
3231 ad_aug fabs(const ad_aug &x);
3232 ad_adapt fabs(const ad_adapt &x);
3233 Writer cos(const Writer &x);
3234 ad_aug cos(const ad_aug &x);
3235 Writer sin(const Writer &x);
3236 struct SinOp : global::UnaryOperator {
3237  static const bool have_eval = true;
3238  template <class Type>
3239  Type eval(Type x) {
3240  return sin(x);
3241  }
3242  template <class Type>
3243  void reverse(ReverseArgs<Type> &args) {
3244  args.dx(0) += args.dy(0) * cos(args.x(0));
3245  }
3246  void reverse(ReverseArgs<Scalar> &args);
3247  const char *op_name();
3248 };
3249 ad_plain sin(const ad_plain &x);
3250 ad_aug sin(const ad_aug &x);
3251 ad_adapt sin(const ad_adapt &x);
3252 Writer cos(const Writer &x);
3253 struct CosOp : global::UnaryOperator {
3254  static const bool have_eval = true;
3255  template <class Type>
3256  Type eval(Type x) {
3257  return cos(x);
3258  }
3259  template <class Type>
3260  void reverse(ReverseArgs<Type> &args) {
3261  args.dx(0) += args.dy(0) * -sin(args.x(0));
3262  }
3263  void reverse(ReverseArgs<Scalar> &args);
3264  const char *op_name();
3265 };
3266 ad_plain cos(const ad_plain &x);
3267 ad_aug cos(const ad_aug &x);
3268 ad_adapt cos(const ad_adapt &x);
3269 Writer exp(const Writer &x);
3270 struct ExpOp : global::UnaryOperator {
3271  static const bool have_eval = true;
3272  template <class Type>
3273  Type eval(Type x) {
3274  return exp(x);
3275  }
3276  template <class Type>
3277  void reverse(ReverseArgs<Type> &args) {
3278  args.dx(0) += args.dy(0) * args.y(0);
3279  }
3280  void reverse(ReverseArgs<Scalar> &args);
3281  const char *op_name();
3282 };
3283 ad_plain exp(const ad_plain &x);
3284 ad_aug exp(const ad_aug &x);
3285 ad_adapt exp(const ad_adapt &x);
3286 Writer log(const Writer &x);
3287 struct LogOp : global::UnaryOperator {
3288  static const bool have_eval = true;
3289  template <class Type>
3290  Type eval(Type x) {
3291  return log(x);
3292  }
3293  template <class Type>
3294  void reverse(ReverseArgs<Type> &args) {
3295  args.dx(0) += args.dy(0) * Type(1.) / args.x(0);
3296  }
3297  void reverse(ReverseArgs<Scalar> &args);
3298  const char *op_name();
3299 };
3300 ad_plain log(const ad_plain &x);
3301 ad_aug log(const ad_aug &x);
3302 ad_adapt log(const ad_adapt &x);
3303 Writer sqrt(const Writer &x);
3304 struct SqrtOp : global::UnaryOperator {
3305  static const bool have_eval = true;
3306  template <class Type>
3307  Type eval(Type x) {
3308  return sqrt(x);
3309  }
3310  template <class Type>
3311  void reverse(ReverseArgs<Type> &args) {
3312  args.dx(0) += args.dy(0) * Type(0.5) / args.y(0);
3313  }
3314  void reverse(ReverseArgs<Scalar> &args);
3315  const char *op_name();
3316 };
3317 ad_plain sqrt(const ad_plain &x);
3318 ad_aug sqrt(const ad_aug &x);
3319 ad_adapt sqrt(const ad_adapt &x);
3320 Writer tan(const Writer &x);
3321 struct TanOp : global::UnaryOperator {
3322  static const bool have_eval = true;
3323  template <class Type>
3324  Type eval(Type x) {
3325  return tan(x);
3326  }
3327  template <class Type>
3328  void reverse(ReverseArgs<Type> &args) {
3329  args.dx(0) += args.dy(0) * Type(1.) / (cos(args.x(0)) * cos(args.x(0)));
3330  }
3331  void reverse(ReverseArgs<Scalar> &args);
3332  const char *op_name();
3333 };
3334 ad_plain tan(const ad_plain &x);
3335 ad_aug tan(const ad_aug &x);
3336 ad_adapt tan(const ad_adapt &x);
3337 Writer cosh(const Writer &x);
3338 ad_aug cosh(const ad_aug &x);
3339 Writer sinh(const Writer &x);
3340 struct SinhOp : global::UnaryOperator {
3341  static const bool have_eval = true;
3342  template <class Type>
3343  Type eval(Type x) {
3344  return sinh(x);
3345  }
3346  template <class Type>
3347  void reverse(ReverseArgs<Type> &args) {
3348  args.dx(0) += args.dy(0) * cosh(args.x(0));
3349  }
3350  void reverse(ReverseArgs<Scalar> &args);
3351  const char *op_name();
3352 };
3353 ad_plain sinh(const ad_plain &x);
3354 ad_aug sinh(const ad_aug &x);
3355 ad_adapt sinh(const ad_adapt &x);
3356 Writer cosh(const Writer &x);
3357 struct CoshOp : global::UnaryOperator {
3358  static const bool have_eval = true;
3359  template <class Type>
3360  Type eval(Type x) {
3361  return cosh(x);
3362  }
3363  template <class Type>
3364  void reverse(ReverseArgs<Type> &args) {
3365  args.dx(0) += args.dy(0) * sinh(args.x(0));
3366  }
3367  void reverse(ReverseArgs<Scalar> &args);
3368  const char *op_name();
3369 };
3370 ad_plain cosh(const ad_plain &x);
3371 ad_aug cosh(const ad_aug &x);
3372 ad_adapt cosh(const ad_adapt &x);
3373 Writer tanh(const Writer &x);
3374 struct TanhOp : global::UnaryOperator {
3375  static const bool have_eval = true;
3376  template <class Type>
3377  Type eval(Type x) {
3378  return tanh(x);
3379  }
3380  template <class Type>
3381  void reverse(ReverseArgs<Type> &args) {
3382  args.dx(0) += args.dy(0) * Type(1.) / (cosh(args.x(0)) * cosh(args.x(0)));
3383  }
3384  void reverse(ReverseArgs<Scalar> &args);
3385  const char *op_name();
3386 };
3387 ad_plain tanh(const ad_plain &x);
3388 ad_aug tanh(const ad_aug &x);
3389 ad_adapt tanh(const ad_adapt &x);
3390 Writer expm1(const Writer &x);
3391 struct Expm1 : global::UnaryOperator {
3392  static const bool have_eval = true;
3393  template <class Type>
3394  Type eval(Type x) {
3395  return expm1(x);
3396  }
3397  template <class Type>
3398  void reverse(ReverseArgs<Type> &args) {
3399  args.dx(0) += args.dy(0) * args.y(0) + Type(1.);
3400  }
3401  void reverse(ReverseArgs<Scalar> &args);
3402  const char *op_name();
3403 };
3404 ad_plain expm1(const ad_plain &x);
3405 ad_aug expm1(const ad_aug &x);
3406 ad_adapt expm1(const ad_adapt &x);
3407 Writer log1p(const Writer &x);
3408 struct Log1p : global::UnaryOperator {
3409  static const bool have_eval = true;
3410  template <class Type>
3411  Type eval(Type x) {
3412  return log1p(x);
3413  }
3414  template <class Type>
3415  void reverse(ReverseArgs<Type> &args) {
3416  args.dx(0) += args.dy(0) * Type(1.) / (args.x(0) + Type(1.));
3417  }
3418  void reverse(ReverseArgs<Scalar> &args);
3419  const char *op_name();
3420 };
3421 ad_plain log1p(const ad_plain &x);
3422 ad_aug log1p(const ad_aug &x);
3423 ad_adapt log1p(const ad_adapt &x);
3424 Writer asin(const Writer &x);
3425 struct AsinOp : global::UnaryOperator {
3426  static const bool have_eval = true;
3427  template <class Type>
3428  Type eval(Type x) {
3429  return asin(x);
3430  }
3431  template <class Type>
3432  void reverse(ReverseArgs<Type> &args) {
3433  args.dx(0) +=
3434  args.dy(0) * Type(1.) / sqrt(Type(1.) - args.x(0) * args.x(0));
3435  }
3436  void reverse(ReverseArgs<Scalar> &args);
3437  const char *op_name();
3438 };
3439 ad_plain asin(const ad_plain &x);
3440 ad_aug asin(const ad_aug &x);
3441 ad_adapt asin(const ad_adapt &x);
3442 Writer acos(const Writer &x);
3443 struct AcosOp : global::UnaryOperator {
3444  static const bool have_eval = true;
3445  template <class Type>
3446  Type eval(Type x) {
3447  return acos(x);
3448  }
3449  template <class Type>
3450  void reverse(ReverseArgs<Type> &args) {
3451  args.dx(0) +=
3452  args.dy(0) * Type(-1.) / sqrt(Type(1.) - args.x(0) * args.x(0));
3453  }
3454  void reverse(ReverseArgs<Scalar> &args);
3455  const char *op_name();
3456 };
3457 ad_plain acos(const ad_plain &x);
3458 ad_aug acos(const ad_aug &x);
3459 ad_adapt acos(const ad_adapt &x);
3460 Writer atan(const Writer &x);
3461 struct AtanOp : global::UnaryOperator {
3462  static const bool have_eval = true;
3463  template <class Type>
3464  Type eval(Type x) {
3465  return atan(x);
3466  }
3467  template <class Type>
3468  void reverse(ReverseArgs<Type> &args) {
3469  args.dx(0) += args.dy(0) * Type(1.) / (Type(1.) + args.x(0) * args.x(0));
3470  }
3471  void reverse(ReverseArgs<Scalar> &args);
3472  const char *op_name();
3473 };
3474 ad_plain atan(const ad_plain &x);
3475 ad_aug atan(const ad_aug &x);
3476 ad_adapt atan(const ad_adapt &x);
3477 Writer asinh(const Writer &x);
3478 struct AsinhOp : global::UnaryOperator {
3479  static const bool have_eval = true;
3480  template <class Type>
3481  Type eval(Type x) {
3482  return asinh(x);
3483  }
3484  template <class Type>
3485  void reverse(ReverseArgs<Type> &args) {
3486  args.dx(0) +=
3487  args.dy(0) * Type(1.) / sqrt(args.x(0) * args.x(0) + Type(1.));
3488  }
3489  void reverse(ReverseArgs<Scalar> &args);
3490  const char *op_name();
3491 };
3492 ad_plain asinh(const ad_plain &x);
3493 ad_aug asinh(const ad_aug &x);
3494 ad_adapt asinh(const ad_adapt &x);
3495 Writer acosh(const Writer &x);
3496 struct AcoshOp : global::UnaryOperator {
3497  static const bool have_eval = true;
3498  template <class Type>
3499  Type eval(Type x) {
3500  return acosh(x);
3501  }
3502  template <class Type>
3503  void reverse(ReverseArgs<Type> &args) {
3504  args.dx(0) +=
3505  args.dy(0) * Type(1.) / sqrt(args.x(0) * args.x(0) - Type(1.));
3506  }
3507  void reverse(ReverseArgs<Scalar> &args);
3508  const char *op_name();
3509 };
3510 ad_plain acosh(const ad_plain &x);
3511 ad_aug acosh(const ad_aug &x);
3512 ad_adapt acosh(const ad_adapt &x);
3513 Writer atanh(const Writer &x);
3514 struct AtanhOp : global::UnaryOperator {
3515  static const bool have_eval = true;
3516  template <class Type>
3517  Type eval(Type x) {
3518  return atanh(x);
3519  }
3520  template <class Type>
3521  void reverse(ReverseArgs<Type> &args) {
3522  args.dx(0) += args.dy(0) * Type(1.) / (Type(1) - args.x(0) * args.x(0));
3523  }
3524  void reverse(ReverseArgs<Scalar> &args);
3525  const char *op_name();
3526 };
3527 ad_plain atanh(const ad_plain &x);
3528 ad_aug atanh(const ad_aug &x);
3529 ad_adapt atanh(const ad_adapt &x);
3530 
3531 template <class T>
3532 T abs(const T &x) {
3533  return fabs(x);
3534 }
3535 using std::pow;
3536 Writer pow(const Writer &x1, const Writer &x2);
3537 struct PowOp : global::BinaryOperator {
3538  static const bool have_eval = true;
3539  template <class Type>
3540  Type eval(Type x1, Type x2) {
3541  return pow(x1, x2);
3542  }
3543  template <class Type>
3544  void reverse(ReverseArgs<Type> &args) {
3545  args.dx(0) += args.dy(0) * args.x(1) * pow(args.x(0), args.x(1) - Type(1.));
3546  args.dx(1) += args.dy(0) * args.y(0) * log(args.x(0));
3547  }
3548  const char *op_name();
3549 };
3550 ad_plain pow(const ad_plain &x1, const ad_plain &x2);
3551 ad_aug pow(const ad_aug &x1, const ad_aug &x2);
3552 ad_adapt pow(const ad_adapt &x1, const ad_adapt &x2);
3553 using std::atan2;
3554 Writer atan2(const Writer &x1, const Writer &x2);
3555 struct Atan2 : global::BinaryOperator {
3556  static const bool have_eval = true;
3557  template <class Type>
3558  Type eval(Type x1, Type x2) {
3559  return atan2(x1, x2);
3560  }
3561  template <class Type>
3562  void reverse(ReverseArgs<Type> &args) {
3563  args.dx(0) += args.dy(0) * args.x(1) /
3564  (args.x(0) * args.x(0) + args.x(1) * args.x(1));
3565  args.dx(1) += args.dy(0) * -args.x(0) /
3566  (args.x(0) * args.x(0) + args.x(1) * args.x(1));
3567  }
3568  const char *op_name();
3569 };
3570 ad_plain atan2(const ad_plain &x1, const ad_plain &x2);
3571 ad_aug atan2(const ad_aug &x1, const ad_aug &x2);
3572 ad_adapt atan2(const ad_adapt &x1, const ad_adapt &x2);
3573 using std::max;
3574 Writer max(const Writer &x1, const Writer &x2);
3575 struct MaxOp : global::BinaryOperator {
3576  static const bool have_eval = true;
3577  template <class Type>
3578  Type eval(Type x1, Type x2) {
3579  return max(x1, x2);
3580  }
3581  template <class Type>
3582  void reverse(ReverseArgs<Type> &args) {
3583  args.dx(0) += args.dy(0) * ge0(args.x(0) - args.x(1));
3584  args.dx(1) += args.dy(0) * lt0(args.x(0) - args.x(1));
3585  }
3586  const char *op_name();
3587 };
3588 ad_plain max(const ad_plain &x1, const ad_plain &x2);
3589 ad_aug max(const ad_aug &x1, const ad_aug &x2);
3590 ad_adapt max(const ad_adapt &x1, const ad_adapt &x2);
3591 
3592 using std::min;
3593 Writer min(const Writer &x1, const Writer &x2);
3594 struct MinOp : global::BinaryOperator {
3595  static const bool have_eval = true;
3596  template <class Type>
3597  Type eval(Type x1, Type x2) {
3598  return min(x1, x2);
3599  }
3600  template <class Type>
3601  void reverse(ReverseArgs<Type> &args) {
3602  args.dx(0) += args.dy(0) * ge0(args.x(1) - args.x(0));
3603  args.dx(1) += args.dy(0) * lt0(args.x(1) - args.x(0));
3604  }
3605  const char *op_name();
3606 };
3607 ad_plain min(const ad_plain &x1, const ad_plain &x2);
3608 ad_aug min(const ad_aug &x1, const ad_aug &x2);
3609 ad_adapt min(const ad_adapt &x1, const ad_adapt &x2);
3610 Replay CondExpEq(const Replay &x0, const Replay &x1, const Replay &x2,
3611  const Replay &x3);
3612 struct CondExpEqOp : global::Operator<4, 1> {
3613  void forward(ForwardArgs<Scalar> &args);
3614  void reverse(ReverseArgs<Scalar> &args);
3615  void forward(ForwardArgs<Replay> &args);
3616  void reverse(ReverseArgs<Replay> &args);
3617  void forward(ForwardArgs<Writer> &args);
3618  void reverse(ReverseArgs<Writer> &args);
3619  template <class Type>
3620  void forward(ForwardArgs<Type> &args) {
3621  TMBAD_ASSERT(false);
3622  }
3623  template <class Type>
3624  void reverse(ReverseArgs<Type> &args) {
3625  TMBAD_ASSERT(false);
3626  }
3627  const char *op_name();
3628 };
3629 Scalar CondExpEq(const Scalar &x0, const Scalar &x1, const Scalar &x2,
3630  const Scalar &x3);
3631 ad_plain CondExpEq(const ad_plain &x0, const ad_plain &x1, const ad_plain &x2,
3632  const ad_plain &x3);
3633 ad_aug CondExpEq(const ad_aug &x0, const ad_aug &x1, const ad_aug &x2,
3634  const ad_aug &x3);
3635 Replay CondExpNe(const Replay &x0, const Replay &x1, const Replay &x2,
3636  const Replay &x3);
3637 struct CondExpNeOp : global::Operator<4, 1> {
3638  void forward(ForwardArgs<Scalar> &args);
3639  void reverse(ReverseArgs<Scalar> &args);
3640  void forward(ForwardArgs<Replay> &args);
3641  void reverse(ReverseArgs<Replay> &args);
3642  void forward(ForwardArgs<Writer> &args);
3643  void reverse(ReverseArgs<Writer> &args);
3644  template <class Type>
3645  void forward(ForwardArgs<Type> &args) {
3646  TMBAD_ASSERT(false);
3647  }
3648  template <class Type>
3649  void reverse(ReverseArgs<Type> &args) {
3650  TMBAD_ASSERT(false);
3651  }
3652  const char *op_name();
3653 };
3654 Scalar CondExpNe(const Scalar &x0, const Scalar &x1, const Scalar &x2,
3655  const Scalar &x3);
3656 ad_plain CondExpNe(const ad_plain &x0, const ad_plain &x1, const ad_plain &x2,
3657  const ad_plain &x3);
3658 ad_aug CondExpNe(const ad_aug &x0, const ad_aug &x1, const ad_aug &x2,
3659  const ad_aug &x3);
3660 Replay CondExpGt(const Replay &x0, const Replay &x1, const Replay &x2,
3661  const Replay &x3);
3662 struct CondExpGtOp : global::Operator<4, 1> {
3663  void forward(ForwardArgs<Scalar> &args);
3664  void reverse(ReverseArgs<Scalar> &args);
3665  void forward(ForwardArgs<Replay> &args);
3666  void reverse(ReverseArgs<Replay> &args);
3667  void forward(ForwardArgs<Writer> &args);
3668  void reverse(ReverseArgs<Writer> &args);
3669  template <class Type>
3670  void forward(ForwardArgs<Type> &args) {
3671  TMBAD_ASSERT(false);
3672  }
3673  template <class Type>
3674  void reverse(ReverseArgs<Type> &args) {
3675  TMBAD_ASSERT(false);
3676  }
3677  const char *op_name();
3678 };
3679 Scalar CondExpGt(const Scalar &x0, const Scalar &x1, const Scalar &x2,
3680  const Scalar &x3);
3681 ad_plain CondExpGt(const ad_plain &x0, const ad_plain &x1, const ad_plain &x2,
3682  const ad_plain &x3);
3683 ad_aug CondExpGt(const ad_aug &x0, const ad_aug &x1, const ad_aug &x2,
3684  const ad_aug &x3);
3685 Replay CondExpLt(const Replay &x0, const Replay &x1, const Replay &x2,
3686  const Replay &x3);
3687 struct CondExpLtOp : global::Operator<4, 1> {
3688  void forward(ForwardArgs<Scalar> &args);
3689  void reverse(ReverseArgs<Scalar> &args);
3690  void forward(ForwardArgs<Replay> &args);
3691  void reverse(ReverseArgs<Replay> &args);
3692  void forward(ForwardArgs<Writer> &args);
3693  void reverse(ReverseArgs<Writer> &args);
3694  template <class Type>
3695  void forward(ForwardArgs<Type> &args) {
3696  TMBAD_ASSERT(false);
3697  }
3698  template <class Type>
3699  void reverse(ReverseArgs<Type> &args) {
3700  TMBAD_ASSERT(false);
3701  }
3702  const char *op_name();
3703 };
3704 Scalar CondExpLt(const Scalar &x0, const Scalar &x1, const Scalar &x2,
3705  const Scalar &x3);
3706 ad_plain CondExpLt(const ad_plain &x0, const ad_plain &x1, const ad_plain &x2,
3707  const ad_plain &x3);
3708 ad_aug CondExpLt(const ad_aug &x0, const ad_aug &x1, const ad_aug &x2,
3709  const ad_aug &x3);
3710 Replay CondExpGe(const Replay &x0, const Replay &x1, const Replay &x2,
3711  const Replay &x3);
3712 struct CondExpGeOp : global::Operator<4, 1> {
3713  void forward(ForwardArgs<Scalar> &args);
3714  void reverse(ReverseArgs<Scalar> &args);
3715  void forward(ForwardArgs<Replay> &args);
3716  void reverse(ReverseArgs<Replay> &args);
3717  void forward(ForwardArgs<Writer> &args);
3718  void reverse(ReverseArgs<Writer> &args);
3719  template <class Type>
3720  void forward(ForwardArgs<Type> &args) {
3721  TMBAD_ASSERT(false);
3722  }
3723  template <class Type>
3724  void reverse(ReverseArgs<Type> &args) {
3725  TMBAD_ASSERT(false);
3726  }
3727  const char *op_name();
3728 };
3729 Scalar CondExpGe(const Scalar &x0, const Scalar &x1, const Scalar &x2,
3730  const Scalar &x3);
3731 ad_plain CondExpGe(const ad_plain &x0, const ad_plain &x1, const ad_plain &x2,
3732  const ad_plain &x3);
3733 ad_aug CondExpGe(const ad_aug &x0, const ad_aug &x1, const ad_aug &x2,
3734  const ad_aug &x3);
3735 Replay CondExpLe(const Replay &x0, const Replay &x1, const Replay &x2,
3736  const Replay &x3);
3737 struct CondExpLeOp : global::Operator<4, 1> {
3738  void forward(ForwardArgs<Scalar> &args);
3739  void reverse(ReverseArgs<Scalar> &args);
3740  void forward(ForwardArgs<Replay> &args);
3741  void reverse(ReverseArgs<Replay> &args);
3742  void forward(ForwardArgs<Writer> &args);
3743  void reverse(ReverseArgs<Writer> &args);
3744  template <class Type>
3745  void forward(ForwardArgs<Type> &args) {
3746  TMBAD_ASSERT(false);
3747  }
3748  template <class Type>
3749  void reverse(ReverseArgs<Type> &args) {
3750  TMBAD_ASSERT(false);
3751  }
3752  const char *op_name();
3753 };
3754 Scalar CondExpLe(const Scalar &x0, const Scalar &x1, const Scalar &x2,
3755  const Scalar &x3);
3756 ad_plain CondExpLe(const ad_plain &x0, const ad_plain &x1, const ad_plain &x2,
3757  const ad_plain &x3);
3758 ad_aug CondExpLe(const ad_aug &x0, const ad_aug &x1, const ad_aug &x2,
3759  const ad_aug &x3);
3760 
3761 template <class Info>
3762 struct InfoOp : global::DynamicOperator<-1, 0> {
3763  Index n;
3764  Info info;
3765  InfoOp(Index n, Info info) : n(n), info(info) {}
3766  static const bool elimination_protected = true;
3767  static const bool add_forward_replay_copy = true;
3768  static const bool have_input_size_output_size = true;
3769  template <class Type>
3770  void forward(ForwardArgs<Type> &args) {}
3771  template <class Type>
3772  void reverse(ReverseArgs<Type> &args) {}
3773  Index input_size() const { return n; }
3774  Index output_size() const { return 0; }
3775  const char *op_name() { return "InfoOp"; }
3776  void print(global::print_config cfg) {
3777  Rcout << cfg.prefix << info << std::endl;
3778  }
3779  void *operator_data() { return &info; }
3780 };
3781 template <class Info>
3782 void addInfo(const std::vector<ad_aug> &x, const Info &info) {
3783  global::Complete<InfoOp<Info> >(x.size(), info)(x);
3784 }
3785 template <class Info>
3786 void addInfo(const std::vector<double> &x, const Info &info) {}
3787 
3788 struct SumOp : global::DynamicOperator<-1, 1> {
3789  static const bool is_linear = true;
3790  static const bool have_input_size_output_size = true;
3791  static const bool add_forward_replay_copy = true;
3792  size_t n;
3793  Index input_size() const;
3794  Index output_size() const;
3795  SumOp(size_t n);
3796  template <class Type>
3797  void forward(ForwardArgs<Type> &args) {
3798  args.y(0) = 0;
3799  for (size_t i = 0; i < n; i++) {
3800  args.y(0) += args.x(i);
3801  }
3802  }
3803  template <class Type>
3804  void reverse(ReverseArgs<Type> &args) {
3805  for (size_t i = 0; i < n; i++) {
3806  args.dx(i) += args.dy(0);
3807  }
3808  }
3809  const char *op_name();
3810 };
3811 template <class T>
3812 T sum(const std::vector<T> &x) {
3813  return global::Complete<SumOp>(x.size())(x)[0];
3814 }
3815 
3816 ad_plain logspace_sum(const std::vector<ad_plain> &x);
3817 struct LogSpaceSumOp : global::DynamicOperator<-1, 1> {
3818  size_t n;
3819  static const bool have_input_size_output_size = true;
3820  Index input_size() const;
3821  Index output_size() const;
3822  LogSpaceSumOp(size_t n);
3823  void forward(ForwardArgs<Scalar> &args);
3824  void forward(ForwardArgs<Replay> &args);
3825  template <class Type>
3826  void reverse(ReverseArgs<Type> &args) {
3827  for (size_t i = 0; i < n; i++) {
3828  args.dx(i) += exp(args.x(i) - args.y(0)) * args.dy(0);
3829  }
3830  }
3831  const char *op_name();
3832 };
3833 ad_plain logspace_sum(const std::vector<ad_plain> &x);
3834 template <class T>
3835 T logspace_sum(const std::vector<T> &x_) {
3836  std::vector<ad_plain> x(x_.begin(), x_.end());
3837  return logspace_sum(x);
3838 }
3839 
3840 ad_plain logspace_sum_stride(const std::vector<ad_plain> &x,
3841  const std::vector<Index> &stride, size_t n);
3842 struct LogSpaceSumStrideOp : global::DynamicOperator<-1, 1> {
3843  std::vector<Index> stride;
3844  size_t n;
3845  static const bool have_input_size_output_size = true;
3846 
3847  Index number_of_terms() const;
3848  template <class Type>
3849  Type &entry(Type **px, size_t i, size_t j) const {
3850  return px[j][0 + i * stride[j]];
3851  }
3852  template <class Type>
3853  Type rowsum(Type **px, size_t i) const {
3854  size_t m = stride.size();
3855  Type s = (Scalar)(0);
3856  for (size_t j = 0; j < m; j++) {
3857  s += entry(px, i, j);
3858  }
3859  return s;
3860  }
3861  Index input_size() const;
3862  Index output_size() const;
3863  LogSpaceSumStrideOp(std::vector<Index> stride, size_t n);
3864  void forward(ForwardArgs<Scalar> &args);
3865  void forward(ForwardArgs<Replay> &args);
3866  template <class Type>
3867  void reverse(ReverseArgs<Type> &args) {
3868  size_t m = stride.size();
3869  std::vector<Type *> wrk1(m);
3870  std::vector<Type *> wrk2(m);
3871  Type **px = &(wrk1[0]);
3872  Type **pdx = &(wrk2[0]);
3873  for (size_t i = 0; i < m; i++) {
3874  px[i] = args.x_ptr(i);
3875  pdx[i] = args.dx_ptr(i);
3876  }
3877  for (size_t i = 0; i < n; i++) {
3878  Type s = rowsum(px, i);
3879  Type tmp = exp(s - args.y(0)) * args.dy(0);
3880  for (size_t j = 0; j < m; j++) {
3881  entry(pdx, i, j) += tmp;
3882  }
3883  }
3884  }
3889  void dependencies(Args<> &args, Dependencies &dep) const;
3891  static const bool have_dependencies = true;
3893  static const bool implicit_dependencies = true;
3895  static const bool allow_remap = false;
3896  const char *op_name();
3897 
3898  void forward(ForwardArgs<Writer> &args);
3899  void reverse(ReverseArgs<Writer> &args);
3900 };
3901 ad_plain logspace_sum_stride(const std::vector<ad_plain> &x,
3902  const std::vector<Index> &stride, size_t n);
3903 template <class T>
3904 T logspace_sum_stride(const std::vector<T> &x_,
3905  const std::vector<Index> &stride, size_t n) {
3906  std::vector<ad_plain> x(x_.begin(), x_.end());
3907  return logspace_sum_stride(x, stride, n);
3908 }
3909 } // namespace TMBad
3910 #endif // HAVE_GLOBAL_HPP
Automatic differentiation library designed for TMB.
Definition: TMB.hpp:157
segment_ref< ReverseArgs, dx_write > dx_segment(Index from, Index size)
segment version
Definition: global.hpp:344
Add zero allocated workspace to the tape.
Definition: global.hpp:2354
void reverse_decr(ReverseArgs< Writer > &args)
Source code writer.
Definition: global.hpp:2166
virtual Index output_size()=0
Number of outputs from this OperatorPure.
Is this a linear operator ?
Definition: global.hpp:744
bool in_use
Is this glob present in the context stack?
Definition: global.hpp:2765
Does this operator require dynamic allocation ?
Definition: global.hpp:740
Type y(Index j) const
j&#39;th output variable of this operator
Definition: global.hpp:320
Reference counting.
Definition: global.hpp:1766
segment_ref< ReverseArgs, x_read > x_segment(Index from, Index size)
segment version
Definition: global.hpp:336
segment_ref< ForwardArgs, x_read > x_segment(Index from, Index size)
segment version
Definition: global.hpp:293
Index output_size()
Number of outputs from this OperatorPure.
Definition: global.hpp:2218
void reverse(ReverseArgs< Scalar > &args)
Update input derivs of this OperatorPure.
Definition: global.hpp:2134
IntRep code
Internal integer representation.
Definition: global.hpp:736
Operator with input/output dimension known at compile time.
Definition: global.hpp:1491
ad_plain add_to_stack(const ad_plain &x, const ad_plain &y)
Add binary operator to the stack based on its two arguments
Definition: global.hpp:2479
virtual void * operator_data()=0
Optional operator_data.
void * operator_data()
Return operator specific dynamic information (optional)
Definition: global.hpp:1583
std::vector< Index > inv_seed
Optionally control seeding of InvOp in case strong_inv=true
Definition: global.hpp:1402
operation_stack opstack
Operation stack.
Definition: global.hpp:937
void sort_inplace(std::vector< T > &x)
Utility: sort inplace.
Definition: global.hpp:604
void deallocate()
Deallocate this OperatorPure.
Definition: global.hpp:2249
Replicate an operator and apply input compression.
Definition: global.hpp:1957
Add default implementation of mandatory member: forward from optional member eval ...
Definition: global.hpp:1744
const Index * inputs
Array for indirect access of operator inputs.
Definition: global.hpp:258
segment_ref< ForwardArgs, y_write > y_segment(Index from, Index size)
segment version
Definition: global.hpp:297
void dependencies_updating(Args<> &args, Dependencies &dep) const
Default implementation of OperatorPure::dependencies_updating()
Definition: global.hpp:1577
IndexVector inputs
Pointers into global::values determining operator inputs.
Definition: global.hpp:945
global * get_glob()
Get pointer to current global AD context (or NULL if no context is active).
Definition: TMBad.cpp:690
ad_plain add_to_stack(Scalar result=0)
Add nullary operator to the stack based on its result
Definition: global.hpp:2448
void * incomplete()
Get pointer to operator before it was completed.
Definition: global.hpp:2271
void reverse_loop_subgraph(ReverseArgs &args) const
Generic reverse sweep along global::subgraph_seq.
Definition: global.hpp:1056
Access input/output values and derivatives during a reverse pass. Write access granted for the input ...
Definition: global.hpp:311
F & apply(F &f) const
Apply a functor to each interval.
Definition: global.hpp:79
void increment(IndexPair &ptr)
Increment input/output pointers to prepare for the next OperatorPure in the stack.
Definition: global.hpp:2215
std::vector< Scalar > values
Contiguous workspace for taped variables (same length as global::derivs)
Definition: global.hpp:940
void dependencies_updating(Args<> &args, Dependencies &dep)
Get the indices of variables updated by this operator.
Definition: global.hpp:2212
Is this a constant operator ?
Definition: global.hpp:746
void forward(ForwardArgs< Replay > &args)
Replay operation sequence.
Definition: global.hpp:2138
Generate all mandatory members.
Definition: global.hpp:1794
Contiguous set of variables on the current tape.
Definition: global.hpp:2780
void dependencies(Args<> &args, Dependencies &dep) const
Calculate all inputs.
Definition: global.hpp:2004
void reverse_loop(ReverseArgs &args, size_t begin=0) const
Generic reverse sweep.
Definition: global.hpp:1041
Provide inplace read access to value or derivative arrays.
Definition: global.hpp:184
void forward_loop(ForwardArgs &args, size_t begin=0) const
Generic forward sweep.
Definition: global.hpp:1021
Access input/output values during a forward pass. Write access granted for the output value only...
Definition: global.hpp:279
OperatorPure * compress()
Attempt to apply input compression to this Rep operator.
Definition: global.hpp:1913
void reverse(ReverseArgs< Replay > &args)
Replay operation sequence.
Definition: global.hpp:2144
void forceContiguous(V &x)
Make contiguous ad vector.
Definition: global.hpp:3083
void forward(ForwardArgs< bool > &args)
Mark forward dependencies.
Definition: global.hpp:2154
void * identifier()
Operator identifier.
Definition: global.hpp:2263
if_else< test3, AddDependencies< Result2 >, Result2 >::type Result3
Add default implementation of mandatory member: dependencies
Definition: global.hpp:1810
Type * x_ptr(Index j)
pointer version - use with caution.
Definition: global.hpp:328
void forward_loop(ForwardArgs &args, size_t begin, const NodeFilter &node_filter) const
Generic forward sweep.
Definition: global.hpp:1010
Enable weak comparison operators of an ad type.
Definition: global.hpp:2969
void forward_loop_subgraph(ForwardArgs &args) const
Generic forward sweep along global::subgraph_seq.
Definition: global.hpp:1046
bool deterministic
Deterministic hash codes?
Definition: global.hpp:1400
void forward_incr(ForwardArgs< Scalar > &args)
Fast equivalent of combined forward() and increment()
Definition: global.hpp:2135
bool insert(T a, T b)
Insert new interval [a,b].
Definition: global.hpp:58
Operator that requires dynamic allocation. Compile time known input size.
Definition: global.hpp:1599
void hash(hash_t &h, T x) const
Simple hash code of scalar.
Definition: global.hpp:1365
vector< Type > operator*(matrix< Type > A, vector< Type > x)
Definition: convenience.hpp:42
void forward_incr(ForwardArgs< Writer > &args)
Source code writer.
Definition: global.hpp:2165
Configuration of print method.
Definition: global.hpp:1479
segment_ref< ReverseArgs, dy_read > dy_segment(Index from, Index size)
segment version
Definition: global.hpp:348
V getContiguous(const V &x)
Get contiguous (deep) copy of this vector.
Definition: global.hpp:3071
std::vector< Index > inv2op
Used to lookup operator (node) of an independent variable.
Definition: global.hpp:630
The abstract operator for the operation stack global::opstack
Definition: global.hpp:811
Type min(const vector< Type > &x)
Augmented AD type.
Definition: global.hpp:2831
Type x(Index j) const
j&#39;th input variable of this operator
Definition: global.hpp:285
void forward(ForwardArgs< Writer > &args)
Source code writer.
Definition: global.hpp:2163
void * operator_data()
Optional operator_data.
Definition: global.hpp:2270
if_else< test6, AddForwardIncrReverseDecr< Result5 >, Result5 >::type Result6
Add default implementation of mandatory members: forward_incr and reverse_decr from forward and rever...
Definition: global.hpp:1827
bool strong_inv
Use unique code for each independent variable? (see hash_sweep)
Definition: global.hpp:1391
void reverse_decr(ReverseArgs< Replay > &args)
Replay operation sequence.
Definition: global.hpp:2152
virtual void forward(ForwardArgs< Scalar > &args)=0
Update output values of this OperatorPure.
std::vector< Index > inv_index
Pointers into global::values determining independent variables.
Definition: global.hpp:948
Type & y(Index j)
j&#39;th output variable of this operator
Definition: global.hpp:287
bool strong_output
Use unique hash code for each output of an operator?
Definition: global.hpp:1396
Substitute of std::vector<bool> with all elements true
Definition: global.hpp:1001
if_else< test5, Result4, AddForwardMarkReverseMark< Result4 > >::type Result5
Add default implementation of mandatory members: forward_mark and reverse_mark
Definition: global.hpp:1821
Type x(Index j) const
j&#39;th input variable of this operator
Definition: global.hpp:318
op_info any
Bitwise max of operator flags in this stack.
Definition: global.hpp:920
void sort_unique_inplace(std::vector< T > &x)
Utility: sort unique inplace.
Definition: global.hpp:610
Construct ad_plain from index.
Definition: global.hpp:3014
void reverse(ReverseArgs< Type > &args)
Reverse method applicable for Scalar and bool case.
Definition: global.hpp:1989
virtual const char * op_name()
Name of this OperatorPure.
Definition: global.hpp:881
Protect this operator from elimination by the tape optimizer ?
Definition: global.hpp:754
Empty operator with inputs and outputs.
Definition: global.hpp:2380
Copy value and set derivative to zero.
Definition: global.hpp:2625
void decrement(IndexPair &ptr)
Decrement input/output pointers to prepare for the previous OperatorPure in the stack.
Definition: global.hpp:2216
OperatorPure * self_fuse()
Lookup table for operator fusion. Merge this OperatorPure with an identical copy. If no match return ...
Definition: global.hpp:2233
std::vector< size_t > match(const std::vector< T > &x, const std::vector< T > &y)
Match x vector in y vector.
Replicate an operator.
Definition: global.hpp:1882
Type * dx_ptr(Index j)
pointer version - use with caution.
Definition: global.hpp:332
const char * op_name()
Name of this OperatorPure.
Definition: global.hpp:2219
Array class used by TMB.
Definition: array.hpp:22
Struct defining the main AD context.
Definition: global.hpp:797
Provide read/write access to an array segment.
Definition: global.hpp:206
Add default implementation of mandatory members: forward and reverse from forward_incr and reverse_de...
Definition: global.hpp:1671
void reverse_loop(ReverseArgs &args, size_t begin, const NodeFilter &node_filter) const
Generic reverse sweep.
Definition: global.hpp:1029
ad_plain taped_value
If taped_value is initialized (see ad_plain::initialize) this is the value of ad_aug.
Definition: global.hpp:2834
void print(print_config cfg)
Print this operator (optional)
Definition: global.hpp:1585
This operator may update existing variables ?
Definition: global.hpp:756
op_flag
Enumeration of selected boolean flags in global::Operator
Definition: global.hpp:738
Add default implementation of mandatory members: forward_mark and reverse_mark
Definition: global.hpp:1712
void push_back(OperatorPure *x)
Add new operator to this stack and update bitwise operator information.
Definition: TMBad.cpp:923
void reverse(ReverseArgs< bool > &args)
Mark reverse dependencies.
Definition: global.hpp:2155
virtual void deallocate()=0
Deallocate this OperatorPure.
segment_ref< ReverseArgs, y_read > y_segment(Index from, Index size)
segment version
Definition: global.hpp:340
std::vector< Index > dep2op
Used to lookup operator (node) of a dependent variable.
Definition: global.hpp:632
op_info info()
Get operator info.
Definition: global.hpp:2259
Type dy(Index j) const
Partial derivative of end result wrt. j&#39;th output variable of this operator.
Definition: global.hpp:326
Utility for member completion.
Definition: global.hpp:1782
Empty operator without inputs or outputs.
Definition: global.hpp:2371
int IntRep
Type used for internal integer representation.
Definition: global.hpp:734
void reverse_decr(ReverseArgs< bool > &args)
Fast equivalent of combined decrement() and reverse()
Definition: global.hpp:2157
virtual Index input_size()=0
Number of inputs to this OperatorPure.
Is output of this operator an independent variable ?
Definition: global.hpp:748
Operator auto-completion.
Definition: global.hpp:2129
Reference a variable on another tape.
Definition: global.hpp:2408
Add default implementation of mandatory members: increment and decrement
Definition: global.hpp:1654
Operator that requires dynamic allocation. Compile time known input/output size.
Definition: global.hpp:1590
OperatorPure * other_fuse(OperatorPure *other)
Lookup table for operator fusion. Merge this OperatorPure with another operator. If no match return N...
Definition: global.hpp:2236
Index output(Index j) const
Get variable index of j&#39;th output of current operator.
Definition: global.hpp:267
OperatorPure * copy()
Return a copy of this OperatorPure.
Definition: global.hpp:2240
Is this operator a &#39;smart pointer&#39; (with reference counting) ?
Definition: global.hpp:742
bool reduce
Reduce returned hash values to one per dependent variable?
Definition: global.hpp:1398
OperatorPure * other_fuse(OperatorPure *self, OperatorPure *other)
How to fuse this operator (self) with another (other)
Definition: global.hpp:1579
bool strong_const
Include numerical value as part of hash code for constants? (see hash_sweep)
Definition: global.hpp:1394
if_else< test4, Result3, AddIncrementDecrement< Result3 > >::type Result4
Add default implementation of mandatory members: increment and decrement
Definition: global.hpp:1816
Type sum(Vector< Type > x)
Definition: convenience.hpp:33
std::vector< bool > mark
Private workspace used by graph::search. Must either be empty or filled with false when not in use...
Definition: global.hpp:628
Fuse two operators.
Definition: global.hpp:1840
std::vector< Scalar > derivs
Contiguous workspace for derivatives (same length as global::values)
Definition: global.hpp:943
global * parent_glob
Previous ad context to be restored then this context ends.
Definition: global.hpp:2763
void clear_array_subgraph(Vector &array, typename Vector::value_type value=typename Vector::value_type(0)) const
Generic clear array along global::subgraph.
Definition: global.hpp:1076
Configuration of hash_sweep.
Definition: global.hpp:1388
Add default implementation of mandatory members: input_size ans output_size
Definition: global.hpp:1644
void forward_incr(ForwardArgs< bool > &args)
Fast equivalent of combined forward() and increment()
Definition: global.hpp:2156
if_else< test7, AddForwardReverse< Result6 >, Result6 >::type Result7
Add default implementation of mandatory members: forward and reverse from forward_incr and reverse_de...
Definition: global.hpp:1833
double value(T x)
Namespace with utility functions for adaptive numerical integration.
void print(print_config cfg)
Optional print method.
Definition: global.hpp:2220
Index input_size()
Number of inputs to this OperatorPure.
Definition: global.hpp:2217
bool isContiguous(V &x)
Is this ad vector available as a contiguous block on the tape?
Definition: global.hpp:3045
IndexPair ptr
Input/output pointers.
Definition: global.hpp:263
void reverse(ReverseArgs< Type > &args)
Reverse mode updates are forbidden until all references are resolved.
Definition: global.hpp:2420
Type & dx(Index j)
Partial derivative of end result wrt. j&#39;th input variable of this operator.
Definition: global.hpp:323
Union of closed intervals.
Definition: global.hpp:47
Operator graph in compressed row storage.
Definition: global.hpp:617
Is output of this operator a dependent variable ?
Definition: global.hpp:750
void reverse(ReverseArgs< Type > &args)
Derivatives in the dense case are zero.
Definition: global.hpp:2636
void forward(ForwardArgs< Scalar > &args)
Update output values of this OperatorPure.
Definition: global.hpp:2133
Index input(Index j) const
Get variable index of j&#39;th input to current operator.
Definition: global.hpp:265
void forward_incr_mark_dense(ForwardArgs< bool > &args)
Conditionally mark all outputs.
Definition: global.hpp:2158
void forward_incr(ForwardArgs< Replay > &args)
Replay operation sequence.
Definition: global.hpp:2145
Bitwise collection of selected operator flags.
Definition: global.hpp:732
ArrayAccess
Define segment_ref array to access inside ForwardArgs or ReverseArgs
Definition: global.hpp:138
if_else< test1, OperatorBase, AddForwardFromEval< OperatorBase, OperatorBase::ninput > >::type Result1
Add default implementation of mandatory member: forward from optional member eval ...
Definition: global.hpp:1799
void reverse_decr(ReverseArgs< Scalar > &args)
Fast equivalent of combined decrement() and reverse()
Definition: global.hpp:2136
Add default implementation of mandatory members: forward_incr and reverse_decr from forward and rever...
Definition: global.hpp:1692
void reverse(ReverseArgs< Writer > &args)
Source code writer.
Definition: global.hpp:2164
std::vector< ad_plain > add_to_stack(OperatorPure *pOp, const std::vector< ad_plain > &x)
Add vector operator to the stack based on its vector argument
Definition: global.hpp:2548
Is it safe to remap the inputs of this operator?
Definition: global.hpp:752
void forward(ForwardArgs< Type > &args)
Forward method applicable for Scalar and bool case.
Definition: global.hpp:1975
std::vector< Index > dep_index
Pointers into global::values determining dependent variables.
Definition: global.hpp:951
ad_plain add_to_stack(const ad_plain &x)
Add unary operator to the stack based on its argument
Definition: global.hpp:2462
if_else< test2, Result1, AddInputSizeOutputSize< Result1 > >::type Result2
Add default implementation of mandatory members: input_size ans output_size
Definition: global.hpp:1805
Add default implementation of mandatory member: dependencies
Definition: global.hpp:1732
void dependencies(Args<> &args, Dependencies &dep)
Get the indices of variables required by this operator.
Definition: global.hpp:2209
std::vector< ad_plain > operator()(const std::vector< ad_plain > &x)
Move a stack allocated instance to the heap and let the operation_stack manage the memory...
Definition: global.hpp:2171
Type max(const vector< Type > &x)
License: GPL v2