File: cond_exp_rev.cpp

package info (click to toggle)
cppad 2026.00.00.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,584 kB
  • sloc: cpp: 112,960; sh: 6,146; ansic: 179; python: 71; sed: 12; makefile: 10
file content (132 lines) | stat: -rw-r--r-- 3,430 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>
// SPDX-FileContributor: 2003-22 Bradley M. Bell
// ----------------------------------------------------------------------------

// Test that reverse mode handles conditional expressions properly
// in that infinity and nans do not propagate thouh un-used case.

# include <cppad/cppad.hpp>

bool cond_exp_rev(void)
{  bool ok = true;
   using CppAD::vector;
   using CppAD::AD;

   AD<double> anan  = std::numeric_limits<double>::quiet_NaN();
   AD<double> azero = 0.0;


   size_t n = 2;
   vector< AD<double> > ax(n), ay;
   ax[0] = 1.0;
   ax[1] = anan;
   Independent(ax);

   // AbsOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], fabs(ax[1]) ));

   // AcosOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], acos(ax[1]) ));

   // AddvvOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], ax[0] + ax[1] ));

   // AddpvOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], 1.0 + ax[1] ));

   // AsinOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], asin(ax[1]) ));

   // AtanOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], atan(ax[1]) ));

   // CosOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], cos(ax[1]) ));

   // CoshOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], cosh(ax[1]) ));

   // DivvvOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], ax[0] / ax[1] ));

   // DivpvOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], 1.0 / ax[1] ));

   // DivvpOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], ax[1] / 2.0 ));

   // ErfOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], erf(ax[1]) ));

   // ExpOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], exp(ax[1]) ));

   // LogOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], log(ax[1]) ));

   // MulvvOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], ax[0] * ax[1] ));

   // MulpvOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], 2.0 * ax[1] ));

   // PowvvOP
   // uses check in log, mul, and exp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], pow(ax[1], ax[1]) ));

   // PowvpOP
   // uses check in log, mul, and exp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], pow(ax[1], 2.0) ));

   // PowpvOP
   // uses check in log, mul, and exp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], pow(2.0, ax[1]) ));

   // SignOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], sign(ax[1]) ));

   // SinOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], sin(ax[1]) ));

   // SinhOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], sinh(ax[1]) ));

   // SqrtOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], sqrt(ax[1]) ));

   // SubvvOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], ax[0] - ax[1] ));

   // SubpvOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], 1.0 - ax[1] ));

   // SubvpOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], ax[1] - 1.0 ));

   // TanOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], tan(ax[1]) ));

   // TanhOp
   ay.push_back( CondExpGt(ax[0], azero, ax[0], tanh(ax[1]) ));

   // create f : x -> y
   size_t m = ay.size();
   CppAD::ADFun<double> f(ax, ay);

   // weighting vector and reverse mode derivative
   vector<double> w(m), dw(n);
   for(size_t i = 0; i < m; i++)
      w[i] = 0.0;

   // check DivvOp
   for(size_t i = 0; i < m; i++)
   {  w[i] = 1.0;
      dw = f.Reverse(1, w);
      ok &= dw[0] == 1.0;
      ok &= dw[1] == 0.0;
      w[i] = 0.0;
   }

   return ok;
}