CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
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
18namespace CppAD {
19namespace cg {
20
21// ----------------------------------------------------------------------
22// forward mode routine called by CppAD for y = f(x, dxdt, t)
23
24template<class Base>
25bool 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
75template<class Base>
76bool 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
111template<class Base>
112bool 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
133template<class Base>
134bool 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
153template<class Base>
154bool 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)
167template<class Base>
168CPPAD_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