1 /* --------------------------------------------------------------------------
2 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell
3 
4 CppAD is distributed under the terms of the
5              Eclipse Public License Version 2.0.
6 
7 This Source Code may also be made available under the following
8 Secondary License when the conditions for such availability set forth
9 in the Eclipse Public License, Version 2.0 are satisfied:
10       GNU General Public License, Version 2.0 or later.
11 ---------------------------------------------------------------------------- */
12 
13 /*
14 $begin code_gen_fun_jac_as_fun.cpp$$
15 $spell
16     jacobian
17 $$
18 
19 $section Pass Jacobian as Code Gen Function: Example and Test$$
20 
21 $srcthisfile%0%// BEGIN C++%// END C++%1%$$
22 
23 $end
24 */
25 // BEGIN C++
26 # include <cppad/example/code_gen_fun.hpp>
27 
jac_as_fun(void)28 bool jac_as_fun(void)
29 {   bool ok = true;
30     //
31     typedef CppAD::cg::CG<double>     c_double;
32     typedef CppAD::AD<c_double>      ac_double;
33     //
34     typedef CppAD::vector<double>     d_vector;
35     typedef CppAD::vector<ac_double> ac_vector;
36     //
37     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
38 
39     // domain space vector
40     size_t n  = 2;
41     ac_vector ac_x(n);
42     for(size_t j = 0; j < n; ++j)
43         ac_x[j] = 1.0 / double(j + 1);
44 
45     // declare independent variables and start tape recording
46     CppAD::Independent(ac_x);
47 
48     // range space vector
49     size_t m = 3;
50     ac_vector ac_y(m);
51     for(size_t i = 0; i < m; ++i)
52         ac_y[i] = double(i + 1) * sin( ac_x[i % n] );
53 
54     // create f: x -> y and stop tape recording
55     CppAD::ADFun<c_double> c_f(ac_x, ac_y);
56 
57     // create a version of f that evalutes using ac_double
58     CppAD::ADFun<ac_double, c_double> ac_f = c_f.base2ad();
59 
60     // Independent varialbes while evaluating Jacobian
61     CppAD::Independent(ac_x);
62 
63     // Evaluate the Jacobian using any CppAD method
64     // (for this example we just use the simpliest thing)
65     ac_vector ac_J = ac_f.Jacobian(ac_x);
66 
67     // create g: x -> f'(x)
68     CppAD::ADFun<c_double> c_g(ac_x, ac_J);
69 
70     // create compiled version of c_g
71     std::string file_name = "example_lib";
72     code_gen_fun g(file_name, c_g);
73 
74     // evaluate the compiled jacobian
75     d_vector x(n), J(m * n);
76     for(size_t j = 0; j < n; ++j)
77         x[j] = 1.0 / double(j + 2);
78     J = g(x);
79 
80     // check Jaociban values
81     for(size_t i = 0; i < m; ++i)
82     {   for(size_t j = 0; j < n; ++j)
83         {   double check = 0.0;
84             if( j == i % n )
85                 check = double(i + 1) * cos( x[i % n] );
86             ok &= CppAD::NearEqual(J[i * n + j] , check, eps99, eps99);
87         }
88     }
89     return ok;
90 }
91 // END C++
92