CppADCodeGen  2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
time_diff.hpp
1 #ifndef CPPAD_CG_TIME_DIFF_INCLUDED
2 #define CPPAD_CG_TIME_DIFF_INCLUDED
3 /* --------------------------------------------------------------------------
4  * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5  * Copyright (C) 2012 Ciengis
6  *
7  * CppADCodeGen is distributed under multiple licenses:
8  *
9  * - Eclipse Public License Version 1.0 (EPL1), and
10  * - GNU General Public License Version 3 (GPL3).
11  *
12  * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
13  * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
14  * ----------------------------------------------------------------------------
15  * Author: Joao Leal
16  */
17 
18 namespace CppAD {
19 namespace cg {
20 
21 // ----------------------------------------------------------------------
22 // forward mode routine called by CppAD for y = f(x, dxdt, t)
23 
24 template<class Base>
25 bool time_diff_forward(size_t id,
26  size_t order,
27  size_t n,
28  size_t m,
29  const CppAD::vector<bool>& vx,
31  const CppAD::vector<CG<Base> >& tx,
32  CppAD::vector<CG<Base> >& tzy) {
33  CPPADCG_ASSERT_UNKNOWN(n == 3); // [x, dxdt, t]
34  CPPADCG_ASSERT_UNKNOWN(m == 1);
35  CPPADCG_ASSERT_UNKNOWN(tx.size() >= (order + 1) * n);
36  CPPADCG_ASSERT_UNKNOWN(tzy.size() >= (order + 1) * m);
37 
38  size_t n_order = order + 1;
39  const size_t xIndex = 0; // index of the variable in the argument list
40  const size_t dxdtIndex = 1; // index of the time derivative variable in the argument list
41  const size_t timeIndex = 2; // index of the time variable in the argument list
42 
43  // check if this is during the call to time_var(id, ax, ay)
44  if (vx.size() > 0) {
45  CPPADCG_ASSERT_UNKNOWN(vx.size() >= n);
46  CPPADCG_ASSERT_UNKNOWN(vzy.size() >= m);
47 
48  vzy[0] = vx[0] || vx[1] || vx[2];
49  }
50 
51  if (order == 0) {
52  tzy[0] = tx[0];
53  } else if (order == 1) {
54  const CG<Base>& ttime = tx[timeIndex * n_order + order]; //
55  const CG<Base>& txx = tx[xIndex * n_order + order]; //
56  CPPADCG_ASSERT_UNKNOWN(ttime.isParameter());
57  CPPADCG_ASSERT_UNKNOWN(txx.isParameter());
58  if (ttime.getValue() > 0) {
59  CPPADCG_ASSERT_UNKNOWN(txx.getValue() == 0);
60  tzy[1] = ttime * tx[dxdtIndex * n_order + 0]; // transform x(t) into dx(t)/dt
61  } else {
62  tzy[1] = txx; // do nothing
63  }
64 
65  } else {
66  return false; // not implemented
67  }
68 
69  // All orders are implemented and there are no possible errors
70  return true;
71 }
72 // ----------------------------------------------------------------------
73 // reverse mode routine called by CppAD for y = f(x, dxdt, t)
74 
75 template<class Base>
76 bool time_diff_reverse(size_t id,
77  size_t order,
78  size_t n,
79  size_t m,
80  const CppAD::vector<CG<Base> >& tx,
81  const CppAD::vector<CG<Base> >& tzy,
82  CppAD::vector<CG<Base> >& px,
83  const CppAD::vector<CG<Base> >& pzy) {
84 
85  CPPADCG_ASSERT_UNKNOWN(n == 3); // [x, dxdt, t]
86  CPPADCG_ASSERT_UNKNOWN(m == 1);
87  CPPADCG_ASSERT_UNKNOWN(tx.size() >= (order + 1) * n);
88  CPPADCG_ASSERT_UNKNOWN(tzy.size() >= (order + 1) * m);
89  CPPADCG_ASSERT_UNKNOWN(px.size() >= (order + 1) * n);
90 
91  CG<Base>* pxx = &px[0];
92  CG<Base>* pdxdt = &px[order + 1];
93  CG<Base>* pt = &px[2 * (order + 1)];
94 
95  //const CG<Base>* txx = &tx[0];
96  const CG<Base>* tdxdt = &tx[order + 1];
97  //const CG<Base>* tt = &tx[2 * (order + 1)];
98 
99  if (order == 0) {
100  pxx[0] = pzy[0] * 1.0;
101  pdxdt[0] = 0.0;
102  pt[0] = pzy[0] * tdxdt[0];
103  return true;
104  }
105 
106  return false; // not implemented yet
107 }
108 // ----------------------------------------------------------------------
109 // forward Jacobian sparsity routine called by CppAD
110 
111 template<class Base>
112 bool time_diff_for_jac_sparse(size_t id,
113  size_t n,
114  size_t m,
115  size_t q,
116  const CppAD::vector< std::set<size_t> >& r,
117  CppAD::vector< std::set<size_t> >& s) {
118  CPPADCG_ASSERT_UNKNOWN(n == 3);
119  CPPADCG_ASSERT_UNKNOWN(m == 1);
120  CPPADCG_ASSERT_UNKNOWN(r.size() >= n);
121  CPPADCG_ASSERT_UNKNOWN(s.size() >= m);
122 
123  // sparsity for z and y are the same as for x
124  s[0] = r[0]; // x
125  s[0].insert(r[1].begin(), r[1].end()); // dxdt
126  s[0].insert(r[2].begin(), r[2].end()); // t
127 
128  return true;
129 }
130 // ----------------------------------------------------------------------
131 // reverse Jacobian sparsity routine called by CppAD
132 
133 template<class Base>
134 bool time_diff_rev_jac_sparse(size_t id,
135  size_t n,
136  size_t m,
137  size_t q,
138  CppAD::vector< std::set<size_t> >& r,
139  const CppAD::vector< std::set<size_t> >& s) {
140  CPPADCG_ASSERT_UNKNOWN(n == 3);
141  CPPADCG_ASSERT_UNKNOWN(m == 1);
142  CPPADCG_ASSERT_UNKNOWN(r.size() >= n);
143  CPPADCG_ASSERT_UNKNOWN(s.size() >= m);
144 
145  r[0] = s[0];
146  r[2] = s[0];
147 
148  return false;
149 }
150 // ----------------------------------------------------------------------
151 // reverse Hessian sparsity routine called by CppAD
152 
153 template<class Base>
154 bool time_diff_rev_hes_sparse(size_t id,
155  size_t n,
156  size_t m,
157  size_t q,
158  const CppAD::vector< std::set<size_t> >& r,
159  const CppAD::vector<bool>& s,
161  const CppAD::vector< std::set<size_t> >& u,
162  CppAD::vector< std::set<size_t> >& v) {
163  return false;
164 }
165 // ---------------------------------------------------------------------
166 // Declare the AD<CG<Base> > routine time_var(id, ax, ay)
167 template<class Base>
168 CPPAD_USER_ATOMIC(time_var,
169  std::vector,
170  cg::CG<Base>,
171  CppAD::cg::time_diff_forward<Base>,
172  CppAD::cg::time_diff_reverse<Base>,
173  CppAD::cg::time_diff_for_jac_sparse<Base>,
174  CppAD::cg::time_diff_rev_jac_sparse<Base>,
175  CppAD::cg::time_diff_rev_hes_sparse<Base>)
176 
177 } // END cg namespace
178 } // END CppAD namespace
179 
180 #endif
CppAD::vector
Definition: declare_cg.hpp:22
CppAD
Definition: abstract_atomic_fun.hpp:19