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 # include <cppad/cppad.hpp>
13 
14 namespace { // BEGIN_EMPTY_NAMESPACE
15 // ---------------------------------------------------------------------------
comp_op_dyn_dyn(void)16 bool comp_op_dyn_dyn(void)
17 {   bool ok = true;
18     using CppAD::vector;
19     using CppAD::AD;
20     //
21     // AD graph example
22     // node[0:4] : p[0], p[1], p[2], p[3], p[4]
23     // node_5    : x[0]
24     //           : p[0] == p[1]
25     //           : p[0] <= p[2]
26     //           : p[0] <  p[3]
27     //           : p[0] != p[4]
28     // y[0]      = p[0]
29     std::string json =
30         "{\n"
31         "   'function_name'  : 'comp_op example',\n"
32         "   'op_define_vec'  : [ 4, [\n"
33         "       { 'op_code':1, 'name':'comp_eq'            } ,\n"
34         "       { 'op_code':2, 'name':'comp_le'            } ,\n"
35         "       { 'op_code':3, 'name':'comp_lt'            } ,\n"
36         "       { 'op_code':4, 'name':'comp_ne'            } ]\n"
37         "   ],\n"
38         "   'n_dynamic_ind'  : 5,\n"
39         "   'n_variable_ind' : 1,\n"
40         "   'constant_vec'   : [ 0, [ ] ],\n"
41         "   'op_usage_vec'   : [ 4, [\n"
42         "       [ 1, 0, 2, [1, 2 ] ] ,\n" // p[0] == p[1]
43         "       [ 2, 0, 2, [1, 3 ] ] ,\n" // p[0] <= p[2]
44         "       [ 3, 0, 2, [1, 4 ] ] ,\n" // p[0] <  p[3]
45         "       [ 4, 0, 2, [1, 5 ] ] ]\n" // p[0] != p[4]
46         "   ],\n"
47         "   'dependent_vec' : [ 1, [1] ] \n"
48         "}\n";
49     // Convert the single quote to double quote
50     for(size_t i = 0; i < json.size(); ++i)
51         if( json[i] == '\'' ) json[i] = '"';
52     //
53     // f(x, p) = p[0]
54     CppAD::ADFun<double> f;
55     f.from_json(json);
56     //
57     ok &= f.Domain() == 1;
58     ok &= f.Range() == 1;
59     ok &= f.size_dyn_ind() == 5;
60     //
61     // set independent variables and parameters so all comparisons true
62     vector<double> x(1), p(5);
63     x[0] = 1.0;
64     p[0] = 3.0;
65     p[1] = p[0];
66     p[2] = p[0] + 1.0;
67     p[3] = p[0] + 1.0;
68     p[4] = p[0] + 1.0;
69     //
70     // compute y = f(x; p)
71     f.new_dynamic(p);
72     vector<double> y = f.Forward(0, x);
73     //
74     // check that all comparisons are true
75     ok &= f.compare_change_number() == 0;
76     //
77     // case where all the comparisons are false
78     p[1] = p[0] - 1.0;
79     p[2] = p[0] - 1.0;
80     p[3] = p[0] - 1.0;
81     p[4] = p[0];
82     f.new_dynamic(p);
83     y = f.Forward(0, x);
84     y = f.Forward(0, x);
85     ok &= f.compare_change_number() == 4;
86     //
87     // -----------------------------------------------------------------------
88     // Convert to Json graph and back again
89     json = f.to_json();
90     f.from_json(json);
91     // -----------------------------------------------------------------------
92     //
93     ok &= f.Domain() == 1;
94     ok &= f.Range() == 1;
95     ok &= f.size_dyn_ind() == 5;
96     //
97     // set independent variables and parameters so all comparisons true
98     p[0] = 3.0;
99     p[1] = p[0];
100     p[2] = p[0] + 1.0;
101     p[3] = p[0] + 1.0;
102     p[4] = p[0] + 1.0;
103     //
104     // compute y = f(x)
105     f.new_dynamic(p);
106     y = f.Forward(0, x);
107     //
108     // check that all comparisons are true
109     ok &= f.compare_change_number() == 0;
110     //
111     // case where all the comparisons are false
112     p[1] = p[0] - 1.0;
113     p[2] = p[0] - 1.0;
114     p[3] = p[0] - 1.0;
115     p[4] = p[0];
116     f.new_dynamic(p);
117     y = f.Forward(0, x);
118     ok &= f.compare_change_number() == 4;
119     //
120     return ok;
121 }
122 // ---------------------------------------------------------------------------
comp_op_var_var(void)123 bool comp_op_var_var(void)
124 {   bool ok = true;
125     using CppAD::vector;
126     using CppAD::AD;
127     //
128     // AD graph example
129     // node[1:5] : x[0], x[1], x[2], x[3], x[4]
130     //           : x[0] == x[1]
131     //           : x[0] <= x[2]
132     //           : x[0] <  x[3]
133     //           : x[0] != x[4]
134     // y[0]      = x[0]
135     std::string json =
136         "{\n"
137         "   'function_name'  : 'comp_op example',\n"
138         "   'op_define_vec'  : [ 4, [\n"
139         "       { 'op_code':1, 'name':'comp_eq'            } ,\n"
140         "       { 'op_code':2, 'name':'comp_le'            } ,\n"
141         "       { 'op_code':3, 'name':'comp_lt'            } ,\n"
142         "       { 'op_code':4, 'name':'comp_ne'            } ]\n"
143         "   ],\n"
144         "   'n_dynamic_ind'  : 0,\n"
145         "   'n_variable_ind' : 5,\n"
146         "   'constant_vec'   : [ 0, [ ] ],\n"
147         "   'op_usage_vec'   : [ 4, [\n"
148         "       [ 1, 0, 2, [1, 2 ] ] ,\n" // x[0] == x[1]
149         "       [ 2, 0, 2, [1, 3 ] ] ,\n" // x[0] <= x[2]
150         "       [ 3, 0, 2, [1, 4 ] ] ,\n" // x[0] <  x[3]
151         "       [ 4, 0, 2, [1, 5 ] ] ]\n" // x[0] != x[4]
152         "   ],\n"
153         "   'dependent_vec' : [ 1, [1] ] \n"
154         "}\n";
155     // Convert the single quote to double quote
156     for(size_t i = 0; i < json.size(); ++i)
157         if( json[i] == '\'' ) json[i] = '"';
158     //
159     // f(x, p) = p[0]
160     CppAD::ADFun<double> f;
161     f.from_json(json);
162     //
163     ok &= f.Domain() == 5;
164     ok &= f.Range() == 1;
165     ok &= f.size_dyn_ind() == 0;
166     //
167     // set independent variables and parameters so all comparisons true
168     vector<double> x(5);
169     x[0] = 3.0;
170     x[1] = x[0];
171     x[2] = x[0] + 1.0;
172     x[3] = x[0] + 1.0;
173     x[4] = x[0] + 1.0;
174     //
175     // compute y = f(x)
176     vector<double> y = f.Forward(0, x);
177     //
178     // check that all comparisons are true
179     ok &= f.compare_change_number() == 0;
180     //
181     // case where all the comparisons are false
182     x[1] = x[0] - 1.0;
183     x[2] = x[0] - 1.0;
184     x[3] = x[0] - 1.0;
185     x[4] = x[0];
186     y = f.Forward(0, x);
187     ok &= f.compare_change_number() == 4;
188     //
189     // -----------------------------------------------------------------------
190     // Convert to Json graph and back again
191     json = f.to_json();
192     f.from_json(json);
193     // -----------------------------------------------------------------------
194     //
195     ok &= f.Domain() == 5;
196     ok &= f.Range() == 1;
197     ok &= f.size_dyn_ind() == 0;
198     //
199     // set independent variables and parameters so all comparisons true
200     x[0] = 3.0;
201     x[1] = x[0];
202     x[2] = x[0] + 1.0;
203     x[3] = x[0] + 1.0;
204     x[4] = x[0] + 1.0;
205     //
206     // compute y = f(x)
207     y = f.Forward(0, x);
208     //
209     // check that all comparisons are true
210     ok &= f.compare_change_number() == 0;
211     //
212     // case where all the comparisons are false
213     x[1] = x[0] - 1.0;
214     x[2] = x[0] - 1.0;
215     x[3] = x[0] - 1.0;
216     x[4] = x[0];
217     y = f.Forward(0, x);
218     ok &= f.compare_change_number() == 4;
219     //
220     return ok;
221 }
222 // ---------------------------------------------------------------------------
comp_op_dyn_var(void)223 bool comp_op_dyn_var(void)
224 {   bool ok = true;
225     using CppAD::vector;
226     using CppAD::AD;
227     //
228     // AD graph example
229     // node_1    : p[0]
230     // node[2:5] : x[0], x[1], x[2], x[3]
231     //           : p[0] == x[0]
232     //           : p[0] <= x[1]
233     //           : p[0] <  x[2]
234     //           : p[0] != x[3]
235     // y[0]      = p[0]
236     std::string json =
237         "{\n"
238         "   'function_name'  : 'comp_op example',\n"
239         "   'op_define_vec'  : [ 4, [\n"
240         "       { 'op_code':1, 'name':'comp_eq'            } ,\n"
241         "       { 'op_code':2, 'name':'comp_le'            } ,\n"
242         "       { 'op_code':3, 'name':'comp_lt'            } ,\n"
243         "       { 'op_code':4, 'name':'comp_ne'            } ]\n"
244         "   ],\n"
245         "   'n_dynamic_ind'  : 1,\n"
246         "   'n_variable_ind' : 4,\n"
247         "   'constant_vec'   : [ 0, [ ] ],\n"
248         "   'op_usage_vec'   : [ 4, [\n"
249         "       [ 1, 0, 2, [1, 2 ] ] ,\n" // p[0] == x[0]
250         "       [ 2, 0, 2, [1, 3 ] ] ,\n" // p[0] <= x[1]
251         "       [ 3, 0, 2, [1, 4 ] ] ,\n" // p[0] <  x[2]
252         "       [ 4, 0, 2, [1, 5 ] ] ]\n" // p[0] != x[3]
253         "   ],\n"
254         "   'dependent_vec' : [ 1, [1] ] \n"
255         "}\n";
256     // Convert the single quote to double quote
257     for(size_t i = 0; i < json.size(); ++i)
258         if( json[i] == '\'' ) json[i] = '"';
259     //
260     // f(x, p) = p[0]
261     CppAD::ADFun<double> f;
262     f.from_json(json);
263     //
264     ok &= f.Domain() == 4;
265     ok &= f.Range() == 1;
266     ok &= f.size_dyn_ind() == 1;
267     //
268     // set independent variables and parameters so all comparisons true
269     vector<double> x(4), p(1);
270     p[0] = 3.0;
271     x[0] = p[0];
272     x[1] = p[0] + 1.0;
273     x[2] = p[0] + 1.0;
274     x[3] = p[0] + 1.0;
275     //
276     // compute y = f(x, p)
277     f.new_dynamic(p);
278     vector<double> y = f.Forward(0, x);
279     //
280     // check that all comparisons are true
281     ok &= f.compare_change_number() == 0;
282     //
283     // case where all the comparisons are false
284     x[0] = p[0] - 1.0;
285     x[1] = p[0] - 1.0;
286     x[2] = p[0] - 1.0;
287     x[3] = p[0];
288     f.new_dynamic(p);
289     y = f.Forward(0, x);
290     ok &= f.compare_change_number() == 4;
291     //
292     // -----------------------------------------------------------------------
293     // Convert to Json graph and back again
294     json = f.to_json();
295     f.from_json(json);
296     // -----------------------------------------------------------------------
297     //
298     ok &= f.Domain() == 4;
299     ok &= f.Range() == 1;
300     ok &= f.size_dyn_ind() == 1;
301     //
302     // set independent variables and parameters so all comparisons true
303     p[0] = 3.0;
304     x[0] = p[0];
305     x[1] = p[0] + 1.0;
306     x[2] = p[0] + 1.0;
307     x[3] = p[0] + 1.0;
308     //
309     // compute y = f(x, p)
310     f.new_dynamic(p);
311     y = f.Forward(0, x);
312     //
313     // check that all comparisons are true
314     ok &= f.compare_change_number() == 0;
315     //
316     // case where all the comparisons are false
317     x[0] = p[0] - 1.0;
318     x[1] = p[0] - 1.0;
319     x[2] = p[0] - 1.0;
320     x[3] = p[0];
321     f.new_dynamic(p);
322     y = f.Forward(0, x);
323     ok &= f.compare_change_number() == 4;
324     //
325     return ok;
326 }
327 // ---------------------------------------------------------------------------
comp_op_var_dyn(void)328 bool comp_op_var_dyn(void)
329 {   bool ok = true;
330     using CppAD::vector;
331     using CppAD::AD;
332     //
333     // AD graph example
334     // node[1:4] : p[0], p[1], p[2], p[3]
335     // node_5    : x[0]
336     //           : x[0] == p[0]
337     //           : x[0] <= p[1]
338     //           : x[0] <  p[2]
339     //           : x[0] != p[3]
340     // y[0]      = p[0]
341     std::string json =
342         "{\n"
343         "   'function_name'  : 'comp_op example',\n"
344         "   'op_define_vec'  : [ 4, [\n"
345         "       { 'op_code':1, 'name':'comp_eq'            } ,\n"
346         "       { 'op_code':2, 'name':'comp_le'            } ,\n"
347         "       { 'op_code':3, 'name':'comp_lt'            } ,\n"
348         "       { 'op_code':4, 'name':'comp_ne'            } ]\n"
349         "   ],\n"
350         "   'n_dynamic_ind'  : 4,\n"
351         "   'n_variable_ind' : 1,\n"
352         "   'constant_vec'   : [ 0, [ ] ],\n"
353         "   'op_usage_vec'   : [ 4, [\n"
354         "       [ 1, 0, 2, [5, 1 ] ] ,\n" // x[0] == p[0]
355         "       [ 2, 0, 2, [5, 2 ] ] ,\n" // x[0] <= p[1]
356         "       [ 3, 0, 2, [5, 3 ] ] ,\n" // x[0] <  p[2]
357         "       [ 4, 0, 2, [5, 4 ] ] ]\n" // x[0] != p[3]
358         "   ],\n"
359         "   'dependent_vec' : [ 1, [1] ] \n"
360         "}\n";
361     // Convert the single quote to double quote
362     for(size_t i = 0; i < json.size(); ++i)
363         if( json[i] == '\'' ) json[i] = '"';
364     //
365     // f(x, p) = p[0]
366     CppAD::ADFun<double> f;
367     f.from_json(json);
368     //
369     ok &= f.Domain() == 1;
370     ok &= f.Range() == 1;
371     ok &= f.size_dyn_ind() == 4;
372     //
373     // set independent variables and parameters so all comparisons true
374     vector<double> x(1), p(4);
375     x[0] = 3.0;
376     p[0] = x[0];
377     p[1] = x[0] + 1.0;
378     p[2] = x[0] + 1.0;
379     p[3] = x[0] + 1.0;
380     //
381     // compute y = f(x, p)
382     f.new_dynamic(p);
383     vector<double> y = f.Forward(0, x);
384     //
385     // check that all comparisons are true
386     ok &= f.compare_change_number() == 0;
387     //
388     // case where all the comparisons are false
389     p[0] = x[0] - 1.0;
390     p[1] = x[0] - 1.0;
391     p[2] = x[0] - 1.0;
392     p[3] = x[0];
393     f.new_dynamic(p);
394     y = f.Forward(0, x);
395     ok &= f.compare_change_number() == 4;
396     //
397     // -----------------------------------------------------------------------
398     // Convert to Json graph and back again
399     json = f.to_json();
400     f.from_json(json);
401     // -----------------------------------------------------------------------
402     //
403     ok &= f.Domain() == 1;
404     ok &= f.Range() == 1;
405     ok &= f.size_dyn_ind() == 4;
406     //
407     // set independent variables and parameters so all comparisons true
408     x[0] = 3.0;
409     p[0] = x[0];
410     p[1] = x[0] + 1.0;
411     p[2] = x[0] + 1.0;
412     p[3] = x[0] + 1.0;
413     //
414     // compute y = f(x, p)
415     f.new_dynamic(p);
416     y = f.Forward(0, x);
417     //
418     // check that all comparisons are true
419     ok &= f.compare_change_number() == 0;
420     //
421     // case where all the comparisons are false
422     p[0] = x[0] - 1.0;
423     p[1] = x[0] - 1.0;
424     p[2] = x[0] - 1.0;
425     p[3] = x[0];
426     f.new_dynamic(p);
427     y = f.Forward(0, x);
428     ok &= f.compare_change_number() == 4;
429     //
430     return ok;
431 }
432 // ===========================================================================
acosh_op(void)433 bool acosh_op(void)
434 {   bool ok = true;
435     using CppAD::vector;
436     using CppAD::AD;
437     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
438     //
439     // AD graph example
440     // node_1 : p[0]
441     // node_2 : x[0]
442     // node_3 : c[0]
443     // node_4 : acosh(p[0])
444     // node_5 : acosh(x[0])
445     // node_6 : acosh(c[0])
446     // node_7 : acosh(p[0]) + acosh(x[0]) + acosh(c[0])
447     // y[0]   = acosh(p[0]) + acosh(x[0]) + acosh(c[0])
448     // use single quote to avoid having to escape double quote
449     std::string json =
450         "{\n"
451         "   'function_name'  : 'acosh_op example',\n"
452         "   'op_define_vec'  : [ 2, [\n"
453         "       { 'op_code':1, 'name':'acosh', 'n_arg':1 } ,\n"
454         "       { 'op_code':2, 'name':'sum'              } ]\n"
455         "   ],\n"
456         "   'n_dynamic_ind'  : 1,\n"
457         "   'n_variable_ind' : 1,\n"
458         "   'constant_vec'   : [ 1, [ 1.3 ] ],\n" // c[0]
459         "   'op_usage_vec'   : [ 4, [\n"
460         "       [ 1, 1]                ,\n" // acosh(p0)
461         "       [ 1, 2]                ,\n" // acosh(x0)
462         "       [ 1, 3]                ,\n" // acosh(c0)
463         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // acosh(p0)+acosh(x0)+acosh(c0)
464         "   ],\n"
465         "   'dependent_vec' : [ 1, [7] ] \n"
466         "}\n";
467     // Convert the single quote to double quote
468     for(size_t i = 0; i < json.size(); ++i)
469         if( json[i] == '\'' ) json[i] = '"';
470     //
471     // f(x, p) = acosh(p0) + acosh(x0) + acosh(c0)
472     CppAD::ADFun<double> f;
473     f.from_json(json);
474     ok &= f.Domain() == 1;
475     ok &= f.Range() == 1;
476     ok &= f.size_dyn_ind() == 1;
477     //
478     // value of constant in function
479     vector<double> c(1);
480     c[0] = 1.3;
481     //
482     // set independent variables and parameters
483     vector<double> p(1), x(1);
484     p[0] = 1.1;
485     x[0] = 1.2;
486     //
487     // compute y = f(x, p)
488     f.new_dynamic(p);
489     vector<double> y = f.Forward(0, x);
490     //
491     // check result
492     double check = CppAD::acosh(p[0]) + CppAD::acosh(x[0]) + CppAD::acosh(c[0]);
493     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
494     //
495     // Convert to Json graph and back again
496     json = f.to_json();
497     f.from_json(json);
498     //
499     // compute y = f(x, p)
500     f.new_dynamic(p);
501     y = f.Forward(0, x);
502     //
503     // check result
504     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
505     //
506     return ok;
507 }
508 // ---------------------------------------------------------------------------
log1p_op(void)509 bool log1p_op(void)
510 {   bool ok = true;
511     using CppAD::vector;
512     using CppAD::AD;
513     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
514     //
515     // AD graph example
516     // node_1 : p[0]
517     // node_2 : x[0]
518     // node_3 : c[0]
519     // node_4 : log1p(p[0])
520     // node_5 : log1p(x[0])
521     // node_6 : log1p(c[0])
522     // node_7 : log1p(p[0]) + log1p(x[0]) + log1p(c[0])
523     // y[0]   = log1p(p[0]) + log1p(x[0]) + log1p(c[0])
524     // use single quote to avoid having to escape double quote
525     std::string json =
526         "{\n"
527         "   'function_name'  : 'log1p_op example',\n"
528         "   'op_define_vec'  : [ 2, [\n"
529         "       { 'op_code':1, 'name':'log1p', 'n_arg':1 } ,\n"
530         "       { 'op_code':2, 'name':'sum'               } ]\n"
531         "   ],\n"
532         "   'n_dynamic_ind'  : 1,\n"
533         "   'n_variable_ind' : 1,\n"
534         "   'constant_vec'   : [ 1, [ 0.3 ] ],\n" // c[0]
535         "   'op_usage_vec'   : [ 4, [\n"
536         "       [ 1, 1]                ,\n" // log1p(p0)
537         "       [ 1, 2]                ,\n" // log1p(x0)
538         "       [ 1, 3]                ,\n" // log1p(c0)
539         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // log1p(p0)+log1p(x0)+log1p(c0)
540         "   ],\n"
541         "   'dependent_vec' : [ 1, [7] ] \n"
542         "}\n";
543     // Convert the single quote to double quote
544     for(size_t i = 0; i < json.size(); ++i)
545         if( json[i] == '\'' ) json[i] = '"';
546     //
547     // f(x, p) = log1p(p0) + log1p(x0) + log1p(c0)
548     CppAD::ADFun<double> f;
549     f.from_json(json);
550     ok &= f.Domain() == 1;
551     ok &= f.Range() == 1;
552     ok &= f.size_dyn_ind() == 1;
553     //
554     // value of constant in function
555     vector<double> c(1);
556     c[0] = 0.3;
557     //
558     // set independent variables and parameters
559     vector<double> p(1), x(1);
560     p[0] = -0.1;
561     x[0] = 0.2;
562     //
563     // compute y = f(x, p)
564     f.new_dynamic(p);
565     vector<double> y = f.Forward(0, x);
566     //
567     // check result
568     double check = CppAD::log1p(p[0]) + CppAD::log1p(x[0]) + CppAD::log1p(c[0]);
569     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
570     //
571     // Convert to Json graph and back again
572     json = f.to_json();
573     f.from_json(json);
574     //
575     // compute y = f(x, p)
576     f.new_dynamic(p);
577     y = f.Forward(0, x);
578     //
579     // check result
580     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
581     //
582     return ok;
583 }
584 // ---------------------------------------------------------------------------
expm1_op(void)585 bool expm1_op(void)
586 {   bool ok = true;
587     using CppAD::vector;
588     using CppAD::AD;
589     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
590     //
591     // AD graph example
592     // node_1 : p[0]
593     // node_2 : x[0]
594     // node_3 : c[0]
595     // node_4 : expm1(p[0])
596     // node_5 : expm1(x[0])
597     // node_6 : expm1(c[0])
598     // node_7 : expm1(p[0]) + expm1(x[0]) + expm1(c[0])
599     // y[0]   = expm1(p[0]) + expm1(x[0]) + expm1(c[0])
600     // use single quote to avoid having to escape double quote
601     std::string json =
602         "{\n"
603         "   'function_name'  : 'expm1_op example',\n"
604         "   'op_define_vec'  : [ 2, [\n"
605         "       { 'op_code':1, 'name':'expm1', 'n_arg':1 } ,\n"
606         "       { 'op_code':2, 'name':'sum'              } ]\n"
607         "   ],\n"
608         "   'n_dynamic_ind'  : 1,\n"
609         "   'n_variable_ind' : 1,\n"
610         "   'constant_vec'   : [ 1, [ 0.3 ] ],\n" // c[0]
611         "   'op_usage_vec'   : [ 4, [\n"
612         "       [ 1, 1]                ,\n" // expm1(p0)
613         "       [ 1, 2]                ,\n" // expm1(x0)
614         "       [ 1, 3]                ,\n" // expm1(c0)
615         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // expm1(p0)+expm1(x0)+expm1(c0)
616         "   ],\n"
617         "   'dependent_vec' : [ 1, [7] ] \n"
618         "}\n";
619     // Convert the single quote to double quote
620     for(size_t i = 0; i < json.size(); ++i)
621         if( json[i] == '\'' ) json[i] = '"';
622     //
623     // f(x, p) = expm1(p0) + expm1(x0) + expm1(c0)
624     CppAD::ADFun<double> f;
625     f.from_json(json);
626     ok &= f.Domain() == 1;
627     ok &= f.Range() == 1;
628     ok &= f.size_dyn_ind() == 1;
629     //
630     // value of constant in function
631     vector<double> c(1);
632     c[0] = 0.3;
633     //
634     // set independent variables and parameters
635     vector<double> p(1), x(1);
636     p[0] = -0.1;
637     x[0] = 0.2;
638     //
639     // compute y = f(x, p)
640     f.new_dynamic(p);
641     vector<double> y = f.Forward(0, x);
642     //
643     // check result
644     double check = CppAD::expm1(p[0]) + CppAD::expm1(x[0]) + CppAD::expm1(c[0]);
645     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
646     //
647     // Convert to Json graph and back again
648     json = f.to_json();
649     f.from_json(json);
650     //
651     // compute y = f(x, p)
652     f.new_dynamic(p);
653     y = f.Forward(0, x);
654     //
655     // check result
656     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
657     //
658     return ok;
659 }
660 // ---------------------------------------------------------------------------
erfc_op(void)661 bool erfc_op(void)
662 {   bool ok = true;
663     using CppAD::vector;
664     using CppAD::AD;
665     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
666     //
667     // AD graph example
668     // node_1 : p[0]
669     // node_2 : x[0]
670     // node_3 : c[0]
671     // node_4 : erfc(p[0])
672     // node_5 : erfc(x[0])
673     // node_6 : erfc(c[0])
674     // node_7 : erfc(p[0]) + erfc(x[0]) + erfc(c[0])
675     // y[0]   = erfc(p[0]) + erfc(x[0]) + erfc(c[0])
676     // use single quote to avoid having to escape double quote
677     std::string json =
678         "{\n"
679         "   'function_name'  : 'erfc_op example',\n"
680         "   'op_define_vec'  : [ 2, [\n"
681         "       { 'op_code':1, 'name':'erfc', 'n_arg':1 } ,\n"
682         "       { 'op_code':2, 'name':'sum'             } ]\n"
683         "   ],\n"
684         "   'n_dynamic_ind'  : 1,\n"
685         "   'n_variable_ind' : 1,\n"
686         "   'constant_vec'   : [ 1, [ 0.3 ] ],\n" // c[0]
687         "   'op_usage_vec'   : [ 4, [\n"
688         "       [ 1, 1]                ,\n" // erfc(p0)
689         "       [ 1, 2]                ,\n" // erfc(x0)
690         "       [ 1, 3]                ,\n" // erfc(c0)
691         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // erfc(p0)+erfc(x0)+erfc(c0)
692         "   ],\n"
693         "   'dependent_vec' : [ 1, [7] ] \n"
694         "}\n";
695     // Convert the single quote to double quote
696     for(size_t i = 0; i < json.size(); ++i)
697         if( json[i] == '\'' ) json[i] = '"';
698     //
699     // f(x, p) = erfc(p0) + erfc(x0) + erfc(c0)
700     CppAD::ADFun<double> f;
701     f.from_json(json);
702     ok &= f.Domain() == 1;
703     ok &= f.Range() == 1;
704     ok &= f.size_dyn_ind() == 1;
705     //
706     // value of constant in function
707     vector<double> c(1);
708     c[0] = 0.3;
709     //
710     // set independent variables and parameters
711     vector<double> p(1), x(1);
712     p[0] = -0.1;
713     x[0] = 0.2;
714     //
715     // compute y = f(x, p)
716     f.new_dynamic(p);
717     vector<double> y = f.Forward(0, x);
718     //
719     // check result
720     double check = CppAD::erfc(p[0]) + CppAD::erfc(x[0]) + CppAD::erfc(c[0]);
721     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
722     //
723     // Convert to Json graph and back again
724     json = f.to_json();
725     f.from_json(json);
726     //
727     // compute y = f(x, p)
728     f.new_dynamic(p);
729     y = f.Forward(0, x);
730     //
731     // check result
732     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
733     //
734     return ok;
735 }
736 // ---------------------------------------------------------------------------
erf_op(void)737 bool erf_op(void)
738 {   bool ok = true;
739     using CppAD::vector;
740     using CppAD::AD;
741     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
742     //
743     // AD graph example
744     // node_1 : p[0]
745     // node_2 : x[0]
746     // node_3 : c[0]
747     // node_4 : erf(p[0])
748     // node_5 : erf(x[0])
749     // node_6 : erf(c[0])
750     // node_7 : erf(p[0]) + erf(x[0]) + erf(c[0])
751     // y[0]   = erf(p[0]) + erf(x[0]) + erf(c[0])
752     // use single quote to avoid having to escape double quote
753     std::string json =
754         "{\n"
755         "   'function_name'  : 'erf_op example',\n"
756         "   'op_define_vec'  : [ 2, [\n"
757         "       { 'op_code':1, 'name':'erf', 'n_arg':1 } ,\n"
758         "       { 'op_code':2, 'name':'sum'            } ]\n"
759         "   ],\n"
760         "   'n_dynamic_ind'  : 1,\n"
761         "   'n_variable_ind' : 1,\n"
762         "   'constant_vec'   : [ 1, [ 0.3 ] ],\n" // c[0]
763         "   'op_usage_vec'   : [ 4, [\n"
764         "       [ 1, 1]                ,\n" // erf(p0)
765         "       [ 1, 2]                ,\n" // erf(x0)
766         "       [ 1, 3]                ,\n" // erf(c0)
767         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // erf(p0)+erf(x0)+erf(c0)
768         "   ],\n"
769         "   'dependent_vec' : [ 1, [7] ] \n"
770         "}\n";
771     // Convert the single quote to double quote
772     for(size_t i = 0; i < json.size(); ++i)
773         if( json[i] == '\'' ) json[i] = '"';
774     //
775     // f(x, p) = erf(p0) + erf(x0) + erf(c0)
776     CppAD::ADFun<double> f;
777     f.from_json(json);
778     ok &= f.Domain() == 1;
779     ok &= f.Range() == 1;
780     ok &= f.size_dyn_ind() == 1;
781     //
782     // value of constant in function
783     vector<double> c(1);
784     c[0] = 0.3;
785     //
786     // set independent variables and parameters
787     vector<double> p(1), x(1);
788     p[0] = -0.1;
789     x[0] = 0.2;
790     //
791     // compute y = f(x, p)
792     f.new_dynamic(p);
793     vector<double> y = f.Forward(0, x);
794     //
795     // check result
796     double check = CppAD::erf(p[0]) + CppAD::erf(x[0]) + CppAD::erf(c[0]);
797     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
798     //
799     // Convert to Json graph and back again
800     json = f.to_json();
801     f.from_json(json);
802     //
803     // compute y = f(x, p)
804     f.new_dynamic(p);
805     y = f.Forward(0, x);
806     //
807     // check result
808     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
809     //
810     return ok;
811 }
812 // ---------------------------------------------------------------------------
atanh_op(void)813 bool atanh_op(void)
814 {   bool ok = true;
815     using CppAD::vector;
816     using CppAD::AD;
817     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
818     //
819     // AD graph example
820     // node_1 : p[0]
821     // node_2 : x[0]
822     // node_3 : c[0]
823     // node_4 : atanh(p[0])
824     // node_5 : atanh(x[0])
825     // node_6 : atanh(c[0])
826     // node_7 : atanh(p[0]) + atanh(x[0]) + atanh(c[0])
827     // y[0]   = atanh(p[0]) + atanh(x[0]) + atanh(c[0])
828     // use single quote to avoid having to escape double quote
829     std::string json =
830         "{\n"
831         "   'function_name'  : 'atanh_op example',\n"
832         "   'op_define_vec'  : [ 2, [\n"
833         "       { 'op_code':1, 'name':'atanh', 'n_arg':1 } ,\n"
834         "       { 'op_code':2, 'name':'sum'              } ]\n"
835         "   ],\n"
836         "   'n_dynamic_ind'  : 1,\n"
837         "   'n_variable_ind' : 1,\n"
838         "   'constant_vec'   : [ 1, [ 0.3 ] ],\n" // c[0]
839         "   'op_usage_vec'   : [ 4, [\n"
840         "       [ 1, 1]                ,\n" // atanh(p0)
841         "       [ 1, 2]                ,\n" // atanh(x0)
842         "       [ 1, 3]                ,\n" // atanh(c0)
843         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // atanh(p0)+atanh(x0)+atanh(c0)
844         "   ],\n"
845         "   'dependent_vec' : [ 1, [7] ] \n"
846         "}\n";
847     // Convert the single quote to double quote
848     for(size_t i = 0; i < json.size(); ++i)
849         if( json[i] == '\'' ) json[i] = '"';
850     //
851     // f(x, p) = atanh(p0) + atanh(x0) + atanh(c0)
852     CppAD::ADFun<double> f;
853     f.from_json(json);
854     ok &= f.Domain() == 1;
855     ok &= f.Range() == 1;
856     ok &= f.size_dyn_ind() == 1;
857     //
858     // value of constant in function
859     vector<double> c(1);
860     c[0] = 0.3;
861     //
862     // set independent variables and parameters
863     vector<double> p(1), x(1);
864     p[0] = -0.1;
865     x[0] = 0.2;
866     //
867     // compute y = f(x, p)
868     f.new_dynamic(p);
869     vector<double> y = f.Forward(0, x);
870     //
871     // check result
872     double check = CppAD::atanh(p[0]) + CppAD::atanh(x[0]) + CppAD::atanh(c[0]);
873     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
874     //
875     // Convert to Json graph and back again
876     json = f.to_json();
877     f.from_json(json);
878     //
879     // compute y = f(x, p)
880     f.new_dynamic(p);
881     y = f.Forward(0, x);
882     //
883     // check result
884     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
885     //
886     return ok;
887 }
888 // ---------------------------------------------------------------------------
asinh_op(void)889 bool asinh_op(void)
890 {   bool ok = true;
891     using CppAD::vector;
892     using CppAD::AD;
893     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
894     //
895     // AD graph example
896     // node_1 : p[0]
897     // node_2 : x[0]
898     // node_3 : c[0]
899     // node_4 : asinh(p[0])
900     // node_5 : asinh(x[0])
901     // node_6 : asinh(c[0])
902     // node_7 : asinh(p[0]) + asinh(x[0]) + asinh(c[0])
903     // y[0]   = asinh(p[0]) + asinh(x[0]) + asinh(c[0])
904     // use single quote to avoid having to escape double quote
905     std::string json =
906         "{\n"
907         "   'function_name'  : 'asinh_op example',\n"
908         "   'op_define_vec'  : [ 2, [\n"
909         "       { 'op_code':1, 'name':'asinh', 'n_arg':1 } ,\n"
910         "       { 'op_code':2, 'name':'sum'              } ]\n"
911         "   ],\n"
912         "   'n_dynamic_ind'  : 1,\n"
913         "   'n_variable_ind' : 1,\n"
914         "   'constant_vec'   : [ 1, [ 0.3 ] ],\n" // c[0]
915         "   'op_usage_vec'   : [ 4, [\n"
916         "       [ 1, 1]                ,\n" // asinh(p0)
917         "       [ 1, 2]                ,\n" // asinh(x0)
918         "       [ 1, 3]                ,\n" // asinh(c0)
919         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // asinh(p0)+asinh(x0)+asinh(c0)
920         "   ],\n"
921         "   'dependent_vec' : [ 1, [7] ] \n"
922         "}\n";
923     // Convert the single quote to double quote
924     for(size_t i = 0; i < json.size(); ++i)
925         if( json[i] == '\'' ) json[i] = '"';
926     //
927     // f(x, p) = asinh(p0) + asinh(x0) + asinh(c0)
928     CppAD::ADFun<double> f;
929     f.from_json(json);
930     ok &= f.Domain() == 1;
931     ok &= f.Range() == 1;
932     ok &= f.size_dyn_ind() == 1;
933     //
934     // value of constant in function
935     vector<double> c(1);
936     c[0] = 0.3;
937     //
938     // set independent variables and parameters
939     vector<double> p(1), x(1);
940     p[0] = -0.1;
941     x[0] = 0.2;
942     //
943     // compute y = f(x, p)
944     f.new_dynamic(p);
945     vector<double> y = f.Forward(0, x);
946     //
947     // check result
948     double check = CppAD::asinh(p[0]) + CppAD::asinh(x[0]) + CppAD::asinh(c[0]);
949     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
950     //
951     // Convert to Json graph and back again
952     json = f.to_json();
953     f.from_json(json);
954     //
955     // compute y = f(x, p)
956     f.new_dynamic(p);
957     y = f.Forward(0, x);
958     //
959     // check result
960     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
961     //
962     return ok;
963 }
964 // ===========================================================================
tan_op(void)965 bool tan_op(void)
966 {   bool ok = true;
967     using CppAD::vector;
968     using CppAD::AD;
969     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
970     //
971     // AD graph example
972     // node_1 : p[0]
973     // node_2 : x[0]
974     // node_3 : c[0]
975     // node_4 : tan(p[0])
976     // node_5 : tan(x[0])
977     // node_6 : tan(c[0])
978     // node_7 : tan(p[0]) + tan(x[0]) + tan(c[0])
979     // y[0]   = tan(p[0]) + tan(x[0]) + tan(c[0])
980     // use single quote to avoid having to escape double quote
981     std::string json =
982         "{\n"
983         "   'function_name'  : 'tan_op example',\n"
984         "   'op_define_vec'  : [ 2, [\n"
985         "       { 'op_code':1, 'name':'tan', 'n_arg':1 } ,\n"
986         "       { 'op_code':2, 'name':'sum'            } ]\n"
987         "   ],\n"
988         "   'n_dynamic_ind'  : 1,\n"
989         "   'n_variable_ind' : 1,\n"
990         "   'constant_vec'   : [ 1, [ -0.1 ] ],\n" // c[0]
991         "   'op_usage_vec'   : [ 4, [\n"
992         "       [ 1, 1]                ,\n" // tan(p[0])
993         "       [ 1, 2]                ,\n" // tan(x[0])
994         "       [ 1, 3]                ,\n" // tan(c[0])
995         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // tan(p[0])+tan(x[0])+tan(c[0])
996         "   ],\n"
997         "   'dependent_vec' : [ 1, [7] ] \n"
998         "}\n";
999     // Convert the single quote to double quote
1000     for(size_t i = 0; i < json.size(); ++i)
1001         if( json[i] == '\'' ) json[i] = '"';
1002     //
1003     // f(x, p) = tan(p_0) + tan(x_0) + tan(c_0)
1004     CppAD::ADFun<double> f;
1005     f.from_json(json);
1006     ok &= f.Domain() == 1;
1007     ok &= f.Range() == 1;
1008     ok &= f.size_dyn_ind() == 1;
1009     //
1010     // value of constant that is in function
1011     vector<double> c(1);
1012     c[0] = -0.1;
1013     //
1014     // set independent variables and parameters
1015     vector<double> p(1), x(1);
1016     p[0] = 0.2;
1017     x[0] = 0.3;
1018     //
1019     // compute y = f(x, p)
1020     f.new_dynamic(p);
1021     vector<double> y = f.Forward(0, x);
1022     //
1023     // check result
1024     double check = std::tan(p[0]) + std::tan(x[0]) + std::tan(c[0]);
1025     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1026     //
1027     // Convert to Json graph and back again
1028     json = f.to_json();
1029     f.from_json(json);
1030     //
1031     // compute y = f(x, p)
1032     f.new_dynamic(p);
1033     y = f.Forward(0, x);
1034     //
1035     // check result
1036     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1037     //
1038     return ok;
1039 }
1040 // ---------------------------------------------------------------------------
tanh_op(void)1041 bool tanh_op(void)
1042 {   bool ok = true;
1043     using CppAD::vector;
1044     using CppAD::AD;
1045     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
1046     //
1047     // AD graph example
1048     // node_1 : p[0]
1049     // node_2 : x[0]
1050     // node_3 : c[0]
1051     // node_4 : tanh(p[0])
1052     // node_5 : tanh(x[0])
1053     // node_6 : tanh(c[0])
1054     // node_7 : tanh(p[0]) + tanh(x[0]) + tanh(c[0])
1055     // y[0]   = tanh(p[0]) + tanh(x[0]) + tanh(c[0])
1056     // use single quote to avoid having to escape double quote
1057     std::string json =
1058         "{\n"
1059         "   'function_name'  : 'tanh_op example',\n"
1060         "   'op_define_vec'  : [ 2, [\n"
1061         "       { 'op_code':1, 'name':'tanh', 'n_arg':1 } ,\n"
1062         "       { 'op_code':2, 'name':'sum'             } ]\n"
1063         "   ],\n"
1064         "   'n_dynamic_ind'  : 1,\n"
1065         "   'n_variable_ind' : 1,\n"
1066         "   'constant_vec'   : [ 1, [ -0.1 ] ],\n" // c[0]
1067         "   'op_usage_vec'   : [ 4, [\n"
1068         "       [ 1, 1]                ,\n" // tanh(p[0])
1069         "       [ 1, 2]                ,\n" // tanh(x[0])
1070         "       [ 1, 3]                ,\n" // tanh(c[0])
1071         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // tanh(p[0])+tanh(x[0])+tanh(c[0])
1072         "   ],\n"
1073         "   'dependent_vec' : [ 1, [7] ] \n"
1074         "}\n";
1075     // Convert the single quote to double quote
1076     for(size_t i = 0; i < json.size(); ++i)
1077         if( json[i] == '\'' ) json[i] = '"';
1078     //
1079     // f(x, p) = tanh(p_0) + tanh(x_0) + tanh(c_0)
1080     CppAD::ADFun<double> f;
1081     f.from_json(json);
1082     ok &= f.Domain() == 1;
1083     ok &= f.Range() == 1;
1084     ok &= f.size_dyn_ind() == 1;
1085     //
1086     // value of constant in function
1087     vector<double> c(1);
1088     c[0] = -0.1;
1089     //
1090     // set independent variables and parameters
1091     vector<double> p(1), x(1);
1092     p[0] = 0.2;
1093     x[0] = 0.3;
1094     //
1095     // compute y = f(x, p)
1096     f.new_dynamic(p);
1097     vector<double> y = f.Forward(0, x);
1098     //
1099     // check result
1100     double check = std::tanh(p[0]) + std::tanh(x[0]) + std::tanh(c[0]);
1101     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1102     //
1103     // Convert to Json graph and back again
1104     json = f.to_json();
1105     f.from_json(json);
1106     //
1107     // compute y = f(x, p)
1108     f.new_dynamic(p);
1109     y = f.Forward(0, x);
1110     //
1111     // check result
1112     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1113     //
1114     return ok;
1115 }
1116 // ---------------------------------------------------------------------------
sqrt_op(void)1117 bool sqrt_op(void)
1118 {   bool ok = true;
1119     using CppAD::vector;
1120     using CppAD::AD;
1121     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
1122     //
1123     // AD graph example
1124     // node_1 : p[0]
1125     // node_2 : x[0]
1126     // node_3 : c[0]
1127     // node_4 : sqrt(p[0])
1128     // node_5 : sqrt(x[0])
1129     // node_6 : sqrt(c[0])
1130     // node_7 : sqrt(p[0]) + sqrt(x[0]) + sqrt(c[0])
1131     // y[0]   = sqrt(p[0]) + sqrt(x[0]) + sqrt(c[0])
1132     // use single quote to avoid having to escape double quote
1133     std::string json =
1134         "{\n"
1135         "   'function_name'  : 'sqrt_op example',\n"
1136         "   'op_define_vec'  : [ 2, [\n"
1137         "       { 'op_code':1, 'name':'sqrt', 'n_arg':1 } ,\n"
1138         "       { 'op_code':2, 'name':'sum'             } ]\n"
1139         "   ],\n"
1140         "   'n_dynamic_ind'  : 1,\n"
1141         "   'n_variable_ind' : 1,\n"
1142         "   'constant_vec'   : [ 1, [ +0.1 ] ],\n" // c[0]
1143         "   'op_usage_vec'   : [ 4, [\n"
1144         "       [ 1, 1]                ,\n" // sqrt(p[0])
1145         "       [ 1, 2]                ,\n" // sqrt(x[0])
1146         "       [ 1, 3]                ,\n" // sqrt(c[0])
1147         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // sqrt(p[0])+sqrt(x[0])+sqrt(c[0])
1148         "   ],\n"
1149         "   'dependent_vec' : [ 1, [7] ] \n"
1150         "}\n";
1151     // Convert the single quote to double quote
1152     for(size_t i = 0; i < json.size(); ++i)
1153         if( json[i] == '\'' ) json[i] = '"';
1154     //
1155     // f(x, p) = sqrt(p_0) + sqrt(x_0) + sqrt(c_0)
1156     CppAD::ADFun<double> f;
1157     f.from_json(json);
1158     ok &= f.Domain() == 1;
1159     ok &= f.Range() == 1;
1160     ok &= f.size_dyn_ind() == 1;
1161     //
1162     // value of constant in function
1163     vector<double> c(1);
1164     c[0] = +0.1;
1165     //
1166     // set independent variables and parameters
1167     vector<double> p(1), x(1);
1168     p[0] = 0.2;
1169     x[0] = 0.3;
1170     //
1171     // compute y = f(x, p)
1172     f.new_dynamic(p);
1173     vector<double> y = f.Forward(0, x);
1174     //
1175     // check result
1176     double check = std::sqrt(p[0]) + std::sqrt(x[0]) + std::sqrt(c[0]);
1177     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1178     //
1179     // Convert to Json graph and back again
1180     json = f.to_json();
1181     f.from_json(json);
1182     //
1183     // compute y = f(x, p)
1184     f.new_dynamic(p);
1185     y = f.Forward(0, x);
1186     //
1187     // check result
1188     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1189     //
1190     return ok;
1191 }
1192 // ---------------------------------------------------------------------------
sin_op(void)1193 bool sin_op(void)
1194 {   bool ok = true;
1195     using CppAD::vector;
1196     using CppAD::AD;
1197     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
1198     //
1199     // AD graph example
1200     // node_1 : p[0]
1201     // node_2 : x[0]
1202     // node_3 : c[0]
1203     // node_4 : sin(p[0])
1204     // node_5 : sin(x[0])
1205     // node_6 : sin(c[0])
1206     // node_7 : sin(p[0]) + sin(x[0]) + sin(c[0])
1207     // y[0]   = sin(p[0]) + sin(x[0]) + sin(c[0])
1208     // use single quote to avoid having to escape double quote
1209     std::string json =
1210         "{\n"
1211         "   'function_name'  : 'sin_op example',\n"
1212         "   'op_define_vec'  : [ 2, [\n"
1213         "       { 'op_code':1, 'name':'sin', 'n_arg':1 } ,\n"
1214         "       { 'op_code':2, 'name':'sum'            } ]\n"
1215         "   ],\n"
1216         "   'n_dynamic_ind'  : 1,\n"
1217         "   'n_variable_ind' : 1,\n"
1218         "   'constant_vec'   : [ 1, [ -0.1 ] ],\n" // c[0]
1219         "   'op_usage_vec'   : [ 4, [\n"
1220         "       [ 1, 1]                ,\n" // sin(p[0])
1221         "       [ 1, 2]                ,\n" // sin(x[0])
1222         "       [ 1, 3]                ,\n" // sin(c[0])
1223         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // sin(p[0])+sin(x[0])+sin(c[0])
1224         "   ],\n"
1225         "   'dependent_vec' : [ 1, [7] ] \n"
1226         "}\n";
1227     // Convert the single quote to double quote
1228     for(size_t i = 0; i < json.size(); ++i)
1229         if( json[i] == '\'' ) json[i] = '"';
1230     //
1231     // f(x, p) = sin(p_0) + sin(x_0) + sin(c_0)
1232     CppAD::ADFun<double> f;
1233     f.from_json(json);
1234     ok &= f.Domain() == 1;
1235     ok &= f.Range() == 1;
1236     ok &= f.size_dyn_ind() == 1;
1237     //
1238     // value of constant in function
1239     vector<double> c(1);
1240     c[0] = -0.1;
1241     //
1242     // set independent variables and parameters
1243     vector<double> p(1), x(1);
1244     p[0] = 0.2;
1245     x[0] = 0.3;
1246     //
1247     // compute y = f(x, p)
1248     f.new_dynamic(p);
1249     vector<double> y = f.Forward(0, x);
1250     //
1251     // check result
1252     double check = std::sin(p[0]) + std::sin(x[0]) + std::sin(c[0]);
1253     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1254     //
1255     // Convert to Json graph and back again
1256     json = f.to_json();
1257     f.from_json(json);
1258     //
1259     // compute y = f(x, p)
1260     f.new_dynamic(p);
1261     y = f.Forward(0, x);
1262     //
1263     // check result
1264     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1265     //
1266     return ok;
1267 }
1268 // ---------------------------------------------------------------------------
sinh_op(void)1269 bool sinh_op(void)
1270 {   bool ok = true;
1271     using CppAD::vector;
1272     using CppAD::AD;
1273     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
1274     //
1275     // AD graph example
1276     // node_1 : p[0]
1277     // node_2 : x[0]
1278     // node_3 : c[0]
1279     // node_4 : sinh(p[0])
1280     // node_5 : sinh(x[0])
1281     // node_6 : sinh(c[0])
1282     // node_7 : sinh(p[0]) + sinh(x[0]) + sinh(c[0])
1283     // y[0]   = sinh(p[0]) + sinh(x[0]) + sinh(c[0])
1284     // use single quote to avoid having to escape double quote
1285     std::string json =
1286         "{\n"
1287         "   'function_name'  : 'sinh_op example',\n"
1288         "   'op_define_vec'  : [ 2, [\n"
1289         "       { 'op_code':1, 'name':'sinh', 'n_arg':1 } ,\n"
1290         "       { 'op_code':2, 'name':'sum'             } ]\n"
1291         "   ],\n"
1292         "   'n_dynamic_ind'  : 1,\n"
1293         "   'n_variable_ind' : 1,\n"
1294         "   'constant_vec'   : [ 1, [ -0.1 ] ],\n" // c[0]
1295         "   'op_usage_vec'   : [ 4, [\n"
1296         "       [ 1, 1]                ,\n" // sinh(p[0])
1297         "       [ 1, 2]                ,\n" // sinh(x[0])
1298         "       [ 1, 3]                ,\n" // sinh(c[0])
1299         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // sinh(p[0])+sinh(x[0])+sinh(c[0])
1300         "   ],\n"
1301         "   'dependent_vec' : [ 1, [7] ] \n"
1302         "}\n";
1303     // Convert the single quote to double quote
1304     for(size_t i = 0; i < json.size(); ++i)
1305         if( json[i] == '\'' ) json[i] = '"';
1306     //
1307     // f(x, p) = sinh(p_0) + sinh(x_0) + sinh(c_0)
1308     CppAD::ADFun<double> f;
1309     f.from_json(json);
1310     ok &= f.Domain() == 1;
1311     ok &= f.Range() == 1;
1312     ok &= f.size_dyn_ind() == 1;
1313     //
1314     // value of constant in function
1315     vector<double> c(1);
1316     c[0] = -0.1;
1317     //
1318     // set independent variables and parameters
1319     vector<double> p(1), x(1);
1320     p[0] = 0.2;
1321     x[0] = 0.3;
1322     //
1323     // compute y = f(x, p)
1324     f.new_dynamic(p);
1325     vector<double> y = f.Forward(0, x);
1326     //
1327     // check result
1328     double check = std::sinh(p[0]) + std::sinh(x[0]) + std::sinh(c[0]);
1329     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1330     //
1331     // Convert to Json graph and back again
1332     json = f.to_json();
1333     f.from_json(json);
1334     //
1335     // compute y = f(x, p)
1336     f.new_dynamic(p);
1337     y = f.Forward(0, x);
1338     //
1339     // check result
1340     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1341     //
1342     return ok;
1343 }
1344 // ---------------------------------------------------------------------------
sign_op(void)1345 bool sign_op(void)
1346 {   bool ok = true;
1347     using CppAD::vector;
1348     using CppAD::AD;
1349     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
1350     //
1351     // AD graph example
1352     // node_1 : p[0]
1353     // node_2 : x[0]
1354     // node_3 : c[0]
1355     // node_4 : sign(p[0])
1356     // node_5 : sign(x[0])
1357     // node_6 : sign(c[0])
1358     // node_7 : sign(p[0]) + sign(x[0]) + sign(c[0])
1359     // y[0]   = sign(p[0]) + sign(x[0]) + sign(c[0])
1360     // use single quote to avoid having to escape double quote
1361     std::string json =
1362         "{\n"
1363         "   'function_name'  : 'sign_op example',\n"
1364         "   'op_define_vec'  : [ 2, [\n"
1365         "       { 'op_code':1, 'name':'sign', 'n_arg':1 } ,\n"
1366         "       { 'op_code':2, 'name':'sum'             } ]\n"
1367         "   ],\n"
1368         "   'n_dynamic_ind'  : 1,\n"
1369         "   'n_variable_ind' : 1,\n"
1370         "   'constant_vec'   : [ 1, [ -0.1 ] ],\n" // c[0]
1371         "   'op_usage_vec'   : [ 4, [\n"
1372         "       [ 1, 1]                ,\n" // sign(p[0])
1373         "       [ 1, 2]                ,\n" // sign(x[0])
1374         "       [ 1, 3]                ,\n" // sign(c[0])
1375         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // sign(p[0])+sign(x[0])+sign(c[0])
1376         "   ],\n"
1377         "   'dependent_vec' : [ 1, [7] ] \n"
1378         "}\n";
1379     // Convert the single quote to double quote
1380     for(size_t i = 0; i < json.size(); ++i)
1381         if( json[i] == '\'' ) json[i] = '"';
1382     //
1383     // f(x, p) = sign(p_0) + sign(x_0) + sign(c_0)
1384     CppAD::ADFun<double> f;
1385     f.from_json(json);
1386     ok &= f.Domain() == 1;
1387     ok &= f.Range() == 1;
1388     ok &= f.size_dyn_ind() == 1;
1389     //
1390     // value of constant in function
1391     vector<double> c(1);
1392     c[0] = -0.1;
1393     //
1394     // set independent variables and parameters
1395     vector<double> p(1), x(1);
1396     p[0] = 0.2;
1397     x[0] = 0.3;
1398     //
1399     // compute y = f(x, p)
1400     f.new_dynamic(p);
1401     vector<double> y = f.Forward(0, x);
1402     //
1403     // check result
1404     double check = CppAD::sign(p[0]) + CppAD::sign(x[0]) + CppAD::sign(c[0]);
1405     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1406     //
1407     // Convert to Json graph and back again
1408     json = f.to_json();
1409     f.from_json(json);
1410     //
1411     // compute y = f(x, p)
1412     f.new_dynamic(p);
1413     y = f.Forward(0, x);
1414     //
1415     // check result
1416     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1417     //
1418     return ok;
1419 }
1420 // ---------------------------------------------------------------------------
log_op(void)1421 bool log_op(void)
1422 {   bool ok = true;
1423     using CppAD::vector;
1424     using CppAD::AD;
1425     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
1426     //
1427     // AD graph example
1428     // node_1 : p[0]
1429     // node_2 : x[0]
1430     // node_3 : c[0]
1431     // node_4 : log(p[0])
1432     // node_5 : log(x[0])
1433     // node_6 : log(c[0])
1434     // node_7 : log(p[0]) + log(x[0]) + log(c[0])
1435     // y[0]   = log(p[0]) + log(x[0]) + log(c[0])
1436     // use single quote to avoid having to escape double quote
1437     std::string json =
1438         "{\n"
1439         "   'function_name'  : 'log_op example',\n"
1440         "   'op_define_vec'  : [ 2, [\n"
1441         "       { 'op_code':1, 'name':'log', 'n_arg':1 } ,\n"
1442         "       { 'op_code':2, 'name':'sum'            } ]\n"
1443         "   ],\n"
1444         "   'n_dynamic_ind'  : 1,\n"
1445         "   'n_variable_ind' : 1,\n"
1446         "   'constant_vec'   : [ 1, [ +0.1 ] ],\n" // c[0]
1447         "   'op_usage_vec'   : [ 4, [\n"
1448         "       [ 1, 1]                ,\n" // log(p[0])
1449         "       [ 1, 2]                ,\n" // log(x[0])
1450         "       [ 1, 3]                ,\n" // log(c[0])
1451         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // log(p[0])+log(x[0])+log(c[0])
1452         "   ],\n"
1453         "   'dependent_vec' : [ 1, [7] ] \n"
1454         "}\n";
1455     // Convert the single quote to double quote
1456     for(size_t i = 0; i < json.size(); ++i)
1457         if( json[i] == '\'' ) json[i] = '"';
1458     //
1459     // f(x, p) = log(p_0) + log(x_0) + log(c_0)
1460     CppAD::ADFun<double> f;
1461     f.from_json(json);
1462     ok &= f.Domain() == 1;
1463     ok &= f.Range() == 1;
1464     ok &= f.size_dyn_ind() == 1;
1465     //
1466     // value of constant in function
1467     vector<double> c(1);
1468     c[0] = +0.1;
1469     //
1470     // set independent variables and parameters
1471     vector<double> p(1), x(1);
1472     p[0] = 0.2;
1473     x[0] = 0.3;
1474     //
1475     // compute y = f(x, p)
1476     f.new_dynamic(p);
1477     vector<double> y = f.Forward(0, x);
1478     //
1479     // check result
1480     double check = std::log(p[0]) + std::log(x[0]) + std::log(c[0]);
1481     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1482     //
1483     // Convert to Json graph and back again
1484     json = f.to_json();
1485     f.from_json(json);
1486     //
1487     // compute y = f(x, p)
1488     f.new_dynamic(p);
1489     y = f.Forward(0, x);
1490     //
1491     // check result
1492     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1493     //
1494     return ok;
1495 }
1496 // ---------------------------------------------------------------------------
exp_op(void)1497 bool exp_op(void)
1498 {   bool ok = true;
1499     using CppAD::vector;
1500     using CppAD::AD;
1501     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
1502     //
1503     // AD graph example
1504     // node_1 : p[0]
1505     // node_2 : x[0]
1506     // node_3 : c[0]
1507     // node_4 : exp(p[0])
1508     // node_5 : exp(x[0])
1509     // node_6 : exp(c[0])
1510     // node_7 : exp(p[0]) + exp(x[0]) + exp(c[0])
1511     // y[0]   = exp(p[0]) + exp(x[0]) + exp(c[0])
1512     // use single quote to avoid having to escape double quote
1513     std::string json =
1514         "{\n"
1515         "   'function_name'  : 'exp_op example',\n"
1516         "   'op_define_vec'  : [ 2, [\n"
1517         "       { 'op_code':1, 'name':'exp', 'n_arg':1 } ,\n"
1518         "       { 'op_code':2, 'name':'sum'            } ]\n"
1519         "   ],\n"
1520         "   'n_dynamic_ind'  : 1,\n"
1521         "   'n_variable_ind' : 1,\n"
1522         "   'constant_vec'   : [ 1, [ -0.1 ] ],\n" // c[0]
1523         "   'op_usage_vec'   : [ 4, [\n"
1524         "       [ 1, 1]                ,\n" // exp(p[0])
1525         "       [ 1, 2]                ,\n" // exp(x[0])
1526         "       [ 1, 3]                ,\n" // exp(c[0])
1527         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // exp(p[0])+exp(x[0])+exp(c[0])
1528         "   ],\n"
1529         "   'dependent_vec' : [ 1, [7] ] \n"
1530         "}\n";
1531     // Convert the single quote to double quote
1532     for(size_t i = 0; i < json.size(); ++i)
1533         if( json[i] == '\'' ) json[i] = '"';
1534     //
1535     // f(x, p) = exp(p_0) + exp(x_0) + exp(c_0)
1536     CppAD::ADFun<double> f;
1537     f.from_json(json);
1538     ok &= f.Domain() == 1;
1539     ok &= f.Range() == 1;
1540     ok &= f.size_dyn_ind() == 1;
1541     //
1542     // value of constant in function
1543     vector<double> c(1);
1544     c[0] = -0.1;
1545     //
1546     // set independent variables and parameters
1547     vector<double> p(1), x(1);
1548     p[0] = 0.2;
1549     x[0] = 0.3;
1550     //
1551     // compute y = f(x, p)
1552     f.new_dynamic(p);
1553     vector<double> y = f.Forward(0, x);
1554     //
1555     // check result
1556     double check = std::exp(p[0]) + std::exp(x[0]) + std::exp(c[0]);
1557     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1558     //
1559     // Convert to Json graph and back again
1560     json = f.to_json();
1561     f.from_json(json);
1562     //
1563     // compute y = f(x, p)
1564     f.new_dynamic(p);
1565     y = f.Forward(0, x);
1566     //
1567     // check result
1568     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1569     //
1570     return ok;
1571 }
1572 // ---------------------------------------------------------------------------
cos_op(void)1573 bool cos_op(void)
1574 {   bool ok = true;
1575     using CppAD::vector;
1576     using CppAD::AD;
1577     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
1578     //
1579     // AD graph example
1580     // node_1 : p[0]
1581     // node_2 : x[0]
1582     // node_3 : c[0]
1583     // node_4 : cos(p[0])
1584     // node_5 : cos(x[0])
1585     // node_6 : cos(c[0])
1586     // node_7 : cos(p[0]) + cos(x[0]) + cos(c[0])
1587     // y[0]   = cos(p[0]) + cos(x[0]) + cos(c[0])
1588     // use single quote to avoid having to escape double quote
1589     std::string json =
1590         "{\n"
1591         "   'function_name'  : 'cos_op example',\n"
1592         "   'op_define_vec'  : [ 2, [\n"
1593         "       { 'op_code':1, 'name':'cos', 'n_arg':1 } ,\n"
1594         "       { 'op_code':2, 'name':'sum'            } ]\n"
1595         "   ],\n"
1596         "   'n_dynamic_ind'  : 1,\n"
1597         "   'n_variable_ind' : 1,\n"
1598         "   'constant_vec'   : [ 1, [ -0.1 ] ],\n" // c[0]
1599         "   'op_usage_vec'   : [ 4, [\n"
1600         "       [ 1, 1]                ,\n" // cos(p[0])
1601         "       [ 1, 2]                ,\n" // cos(x[0])
1602         "       [ 1, 3]                ,\n" // cos(c[0])
1603         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // cos(p[0])+cos(x[0])+cos(c[0])
1604         "   ],\n"
1605         "   'dependent_vec' : [ 1, [7] ] \n"
1606         "}\n";
1607     // Convert the single quote to double quote
1608     for(size_t i = 0; i < json.size(); ++i)
1609         if( json[i] == '\'' ) json[i] = '"';
1610     //
1611     // f(x, p) = cos(p_0) + cos(x_0) + cos(c_0)
1612     CppAD::ADFun<double> f;
1613     f.from_json(json);
1614     ok &= f.Domain() == 1;
1615     ok &= f.Range() == 1;
1616     ok &= f.size_dyn_ind() == 1;
1617     //
1618     // value of constant in function
1619     vector<double> c(1);
1620     c[0] = -0.1;
1621     //
1622     // set independent variables and parameters
1623     vector<double> p(1), x(1);
1624     p[0] = 0.2;
1625     x[0] = 0.3;
1626     //
1627     // compute y = f(x, p)
1628     f.new_dynamic(p);
1629     vector<double> y = f.Forward(0, x);
1630     //
1631     // check result
1632     double check = std::cos(p[0]) + std::cos(x[0]) + std::cos(c[0]);
1633     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1634     //
1635     // Convert to Json graph and back again
1636     json = f.to_json();
1637     f.from_json(json);
1638     //
1639     // compute y = f(x, p)
1640     f.new_dynamic(p);
1641     y = f.Forward(0, x);
1642     //
1643     // check result
1644     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1645     //
1646     return ok;
1647 }
1648 // ---------------------------------------------------------------------------
cosh_op(void)1649 bool cosh_op(void)
1650 {   bool ok = true;
1651     using CppAD::vector;
1652     using CppAD::AD;
1653     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
1654     //
1655     // AD graph example
1656     // node_1 : p[0]
1657     // node_2 : x[0]
1658     // node_3 : c[0]
1659     // node_4 : cosh(p[0])
1660     // node_5 : cosh(x[0])
1661     // node_6 : cosh(c[0])
1662     // node_7 : cosh(p[0]) + cosh(x[0]) + cosh(c[0])
1663     // y[0]   = cosh(p[0]) + cosh(x[0]) + cosh(c[0])
1664     // use single quote to avoid having to escape double quote
1665     std::string json =
1666         "{\n"
1667         "   'function_name'  : 'cosh_op example',\n"
1668         "   'op_define_vec'  : [ 2, [\n"
1669         "       { 'op_code':1, 'name':'cosh', 'n_arg':1 } ,\n"
1670         "       { 'op_code':2, 'name':'sum'             } ]\n"
1671         "   ],\n"
1672         "   'n_dynamic_ind'  : 1,\n"
1673         "   'n_variable_ind' : 1,\n"
1674         "   'constant_vec'   : [ 1, [ -0.1 ] ],\n" // c[0]
1675         "   'op_usage_vec'   : [ 4, [\n"
1676         "       [ 1, 1]                ,\n" // cosh(p[0])
1677         "       [ 1, 2]                ,\n" // cosh(x[0])
1678         "       [ 1, 3]                ,\n" // cosh(c[0])
1679         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // cosh(p[0])+cosh(x[0])+cosh(c[0])
1680         "   ],\n"
1681         "   'dependent_vec' : [ 1, [7] ] \n"
1682         "}\n";
1683     // Convert the single quote to double quote
1684     for(size_t i = 0; i < json.size(); ++i)
1685         if( json[i] == '\'' ) json[i] = '"';
1686     //
1687     // f(x, p) = cosh(p_0) + cosh(x_0) + cosh(c_0)
1688     CppAD::ADFun<double> f;
1689     f.from_json(json);
1690     ok &= f.Domain() == 1;
1691     ok &= f.Range() == 1;
1692     ok &= f.size_dyn_ind() == 1;
1693     //
1694     // value of constant in function
1695     vector<double> c(1);
1696     c[0] = -0.1;
1697     //
1698     // set independent variables and parameters
1699     vector<double> p(1), x(1);
1700     p[0] = 0.2;
1701     x[0] = 0.3;
1702     //
1703     // compute y = f(x, p)
1704     f.new_dynamic(p);
1705     vector<double> y = f.Forward(0, x);
1706     //
1707     // check result
1708     double check = std::cosh(p[0]) + std::cosh(x[0]) + std::cosh(c[0]);
1709     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1710     //
1711     // Convert to Json graph and back again
1712     json = f.to_json();
1713     f.from_json(json);
1714     //
1715     // compute y = f(x, p)
1716     f.new_dynamic(p);
1717     y = f.Forward(0, x);
1718     //
1719     // check result
1720     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1721     //
1722     return ok;
1723 }
1724 // ---------------------------------------------------------------------------
atan_op(void)1725 bool atan_op(void)
1726 {   bool ok = true;
1727     using CppAD::vector;
1728     using CppAD::AD;
1729     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
1730     //
1731     // AD graph example
1732     // node_1 : p[0]
1733     // node_2 : x[0]
1734     // node_3 : c[0]
1735     // node_4 : atan(p[0])
1736     // node_5 : atan(x[0])
1737     // node_6 : atan(c[0])
1738     // node_7 : atan(p[0]) + atan(x[0]) + atan(c[0])
1739     // y[0]   = atan(p[0]) + atan(x[0]) + atan(c[0])
1740     // use single quote to avoid having to escape double quote
1741     std::string json =
1742         "{\n"
1743         "   'function_name'  : 'atan_op example',\n"
1744         "   'op_define_vec'  : [ 2, [\n"
1745         "       { 'op_code':1, 'name':'atan', 'n_arg':1 } ,\n"
1746         "       { 'op_code':2, 'name':'sum'             } ]\n"
1747         "   ],\n"
1748         "   'n_dynamic_ind'  : 1,\n"
1749         "   'n_variable_ind' : 1,\n"
1750         "   'constant_vec'   : [ 1, [ -0.1 ] ],\n" // c[0]
1751         "   'op_usage_vec'   : [ 4, [\n"
1752         "       [ 1, 1]                ,\n" // atan(p[0])
1753         "       [ 1, 2]                ,\n" // atan(x[0])
1754         "       [ 1, 3]                ,\n" // atan(c[0])
1755         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // atan(p[0])+atan(x[0])+atan(c[0])
1756         "   ],\n"
1757         "   'dependent_vec' : [ 1, [7] ] \n"
1758         "}\n";
1759     // Convert the single quote to double quote
1760     for(size_t i = 0; i < json.size(); ++i)
1761         if( json[i] == '\'' ) json[i] = '"';
1762     //
1763     // f(x, p) = atan(p_0) + atan(x_0) + atan(c_0)
1764     CppAD::ADFun<double> f;
1765     f.from_json(json);
1766     ok &= f.Domain() == 1;
1767     ok &= f.Range() == 1;
1768     ok &= f.size_dyn_ind() == 1;
1769     //
1770     // value of constant in function
1771     vector<double> c(1);
1772     c[0] = -0.1;
1773     //
1774     // set independent variables and parameters
1775     vector<double> p(1), x(1);
1776     p[0] = 0.2;
1777     x[0] = 0.3;
1778     //
1779     // compute y = f(x, p)
1780     f.new_dynamic(p);
1781     vector<double> y = f.Forward(0, x);
1782     //
1783     // check result
1784     double check = std::atan(p[0]) + std::atan(x[0]) + std::atan(c[0]);
1785     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1786     //
1787     // Convert to Json graph and back again
1788     json = f.to_json();
1789     f.from_json(json);
1790     //
1791     // compute y = f(x, p)
1792     f.new_dynamic(p);
1793     y = f.Forward(0, x);
1794     //
1795     // check result
1796     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1797     //
1798     return ok;
1799 }
1800 // ---------------------------------------------------------------------------
asin_op(void)1801 bool asin_op(void)
1802 {   bool ok = true;
1803     using CppAD::vector;
1804     using CppAD::AD;
1805     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
1806     //
1807     // AD graph example
1808     // node_1 : p[0]
1809     // node_2 : x[0]
1810     // node_3 : c[0]
1811     // node_4 : asin(p[0])
1812     // node_5 : asin(x[0])
1813     // node_6 : asin(c[0])
1814     // node_7 : asin(p[0]) + asin(x[0]) + asin(c[0])
1815     // y[0]   = asin(p[0]) + asin(x[0]) + asin(c[0])
1816     // use single quote to avoid having to escape double quote
1817     std::string json =
1818         "{\n"
1819         "   'function_name'  : 'asin_op example',\n"
1820         "   'op_define_vec'  : [ 2, [\n"
1821         "       { 'op_code':1, 'name':'asin', 'n_arg':1 } ,\n"
1822         "       { 'op_code':2, 'name':'sum'             } ]\n"
1823         "   ],\n"
1824         "   'n_dynamic_ind'  : 1,\n"
1825         "   'n_variable_ind' : 1,\n"
1826         "   'constant_vec'   : [ 1, [ -0.1 ] ],\n" // c[0]
1827         "   'op_usage_vec'   : [ 4, [\n"
1828         "       [ 1, 1]                ,\n" // asin(p[0])
1829         "       [ 1, 2]                ,\n" // asin(x[0])
1830         "       [ 1, 3]                ,\n" // asin(c[0])
1831         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // asin(p[0])+asin(x[0])+asin(c[0])
1832         "   ],\n"
1833         "   'dependent_vec' : [ 1, [7] ] \n"
1834         "}\n";
1835     // Convert the single quote to double quote
1836     for(size_t i = 0; i < json.size(); ++i)
1837         if( json[i] == '\'' ) json[i] = '"';
1838     //
1839     // f(x, p) = asin(p_0) + asin(x_0) + asin(c_0)
1840     CppAD::ADFun<double> f;
1841     f.from_json(json);
1842     ok &= f.Domain() == 1;
1843     ok &= f.Range() == 1;
1844     ok &= f.size_dyn_ind() == 1;
1845     //
1846     // value of constant in function
1847     vector<double> c(1);
1848     c[0] = -0.1;
1849     //
1850     // set independent variables and parameters
1851     vector<double> p(1), x(1);
1852     p[0] = 0.2;
1853     x[0] = 0.3;
1854     //
1855     // compute y = f(x, p)
1856     f.new_dynamic(p);
1857     vector<double> y = f.Forward(0, x);
1858     //
1859     // check result
1860     double check = std::asin(p[0]) + std::asin(x[0]) + std::asin(c[0]);
1861     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1862     //
1863     // Convert to Json graph and back again
1864     json = f.to_json();
1865     f.from_json(json);
1866     //
1867     // compute y = f(x, p)
1868     f.new_dynamic(p);
1869     y = f.Forward(0, x);
1870     //
1871     // check result
1872     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1873     //
1874     return ok;
1875 }
1876 // ---------------------------------------------------------------------------
acos_op(void)1877 bool acos_op(void)
1878 {   bool ok = true;
1879     using CppAD::vector;
1880     using CppAD::AD;
1881     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
1882     //
1883     // AD graph example
1884     // node_1 : p[0]
1885     // node_2 : x[0]
1886     // node_3 : c[0]
1887     // node_4 : acos(p[0])
1888     // node_5 : acos(x[0])
1889     // node_6 : acos(c[0])
1890     // node_7 : acos(p[0]) + acos(x[0]) + acos(c[0])
1891     // y[0]   = acos(p[0]) + acos(x[0]) + acos(c[0])
1892     // use single quote to avoid having to escape double quote
1893     std::string json =
1894         "{\n"
1895         "   'function_name'  : 'acos_op example',\n"
1896         "   'op_define_vec'  : [ 2, [\n"
1897         "       { 'op_code':1, 'name':'acos', 'n_arg':1 } ,\n"
1898         "       { 'op_code':2, 'name':'sum'             } ]\n"
1899         "   ],\n"
1900         "   'n_dynamic_ind'  : 1,\n"
1901         "   'n_variable_ind' : 1,\n"
1902         "   'constant_vec'   : [ 1, [ -0.1 ] ],\n" // c[0]
1903         "   'op_usage_vec'   : [ 4, [\n"
1904         "       [ 1, 1]                ,\n" // acos(p[0])
1905         "       [ 1, 2]                ,\n" // acos(x[0])
1906         "       [ 1, 3]                ,\n" // acos(c[0])
1907         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // acos(p[0])+acos(x[0])+acos(c[0])
1908         "   ],\n"
1909         "   'dependent_vec' : [ 1, [7] ] \n"
1910         "}\n";
1911     // Convert the single quote to double quote
1912     for(size_t i = 0; i < json.size(); ++i)
1913         if( json[i] == '\'' ) json[i] = '"';
1914     //
1915     // f(x, p) = acos(p_0) + acos(x_0) + acos(c_0)
1916     CppAD::ADFun<double> f;
1917     f.from_json(json);
1918     ok &= f.Domain() == 1;
1919     ok &= f.Range() == 1;
1920     ok &= f.size_dyn_ind() == 1;
1921     //
1922     // value of constant in function
1923     vector<double> c(1);
1924     c[0] = -0.1;
1925     //
1926     // set independent variables and parameters
1927     vector<double> p(1), x(1);
1928     p[0] = 0.2;
1929     x[0] = 0.3;
1930     //
1931     // compute y = f(x, p)
1932     f.new_dynamic(p);
1933     vector<double> y = f.Forward(0, x);
1934     //
1935     // check result
1936     double check = std::acos(p[0]) + std::acos(x[0]) + std::acos(c[0]);
1937     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1938     //
1939     // Convert to Json graph and back again
1940     json = f.to_json();
1941     f.from_json(json);
1942     //
1943     // compute y = f(x, p)
1944     f.new_dynamic(p);
1945     y = f.Forward(0, x);
1946     //
1947     // check result
1948     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
1949     //
1950     return ok;
1951 }
1952 // ---------------------------------------------------------------------------
abs_op(void)1953 bool abs_op(void)
1954 {   bool ok = true;
1955     using CppAD::vector;
1956     using CppAD::AD;
1957     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
1958     //
1959     // AD graph example
1960     // node_1 : p[0]
1961     // node_2 : x[0]
1962     // node_3 : c[0]
1963     // node_4 : abs(p[0])
1964     // node_5 : abs(x[0])
1965     // node_6 : abs(c[0])
1966     // node_7 : abs(p[0]) + abs(x[0]) + abs(c[0])
1967     // y[0]   = abs(p[0]) + abs(x[0]) + abs(c[0])
1968     // use single quote to avoid having to escape double quote
1969     std::string json =
1970         "{\n"
1971         "   'function_name'  : 'abs_op example',\n"
1972         "   'op_define_vec'  : [ 2, [\n"
1973         "       { 'op_code':1, 'name':'abs', 'n_arg':1 } ,\n"
1974         "       { 'op_code':2, 'name':'sum'            } ]\n"
1975         "   ],\n"
1976         "   'n_dynamic_ind'  : 1,\n"
1977         "   'n_variable_ind' : 1,\n"
1978         "   'constant_vec'   : [ 1, [ -0.1 ] ],\n" // c[0]
1979         "   'op_usage_vec'   : [ 4, [\n"
1980         "       [ 1, 1]                ,\n" // abs(p[0])
1981         "       [ 1, 2]                ,\n" // abs(x[0])
1982         "       [ 1, 3]                ,\n" // abs(c[0])
1983         "       [ 2, 1, 3, [4, 5, 6] ] ]\n" // abs(p[0])+abs(x[0])+abs(c[0])
1984         "   ],\n"
1985         "   'dependent_vec' : [ 1, [7] ] \n"
1986         "}\n";
1987     // Convert the single quote to double quote
1988     for(size_t i = 0; i < json.size(); ++i)
1989         if( json[i] == '\'' ) json[i] = '"';
1990     //
1991     // f(x, p) = abs(p_0) + abs(x_0) + abs(c_0)
1992     CppAD::ADFun<double> f;
1993     f.from_json(json);
1994     ok &= f.Domain() == 1;
1995     ok &= f.Range() == 1;
1996     ok &= f.size_dyn_ind() == 1;
1997     //
1998     // value of constant in function
1999     vector<double> c(1);
2000     c[0] = -0.1;
2001     //
2002     // set independent variables and parameters
2003     vector<double> p(1), x(1);
2004     p[0] = 0.2;
2005     x[0] = 0.3;
2006     //
2007     // compute y = f(x, p)
2008     f.new_dynamic(p);
2009     vector<double> y = f.Forward(0, x);
2010     //
2011     // check result
2012     double check = std::fabs(p[0]) + std::fabs(x[0]) + std::fabs(c[0]);
2013     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
2014     //
2015     // Convert to Json graph and back again
2016     json = f.to_json();
2017     // std::cout << graph;
2018     f.from_json(json);
2019     //
2020     // compute y = f(x, p)
2021     f.new_dynamic(p);
2022     y = f.Forward(0, x);
2023     //
2024     // check result
2025     ok &= CppAD::NearEqual(y[0], check, eps99, eps99);
2026     //
2027     return ok;
2028 }
2029 // ---------------------------------------------------------------------------
2030 // Test conditonal expression
cexp_lt_variable(void)2031 bool cexp_lt_variable(void)
2032 {   bool ok = true;
2033     using CppAD::vector;
2034     //
2035     // An AD graph example
2036     // node_1 : x[0]
2037     // node_2 : x[1]
2038     // node_3 : cexp_lt(x[0], x[1], x[1], x[0])
2039     // y[0]   = max(x[0], x[1])
2040     // use single quote to avoid having to escape double quote
2041     std::string json =
2042         "{\n"
2043         "   'function_name'  : 'cexp_lt test',\n"
2044         "   'op_define_vec'  : [ 1, [\n"
2045         "       { 'op_code':1, 'name':'cexp_lt', 'n_arg':4 } ]\n"
2046         "   ],\n"
2047         "   'n_dynamic_ind'  : 0,\n"
2048         "   'n_variable_ind' : 2,\n"
2049         "   'constant_vec'   : [ 0, [] ],\n"
2050         "   'op_usage_vec'   : [ 1, [\n"
2051         "       [ 1, 1, 2, 2, 1 ] ] \n"
2052         "   ],\n"
2053         "   'dependent_vec'   : [ 1, [3] ] \n"
2054         "}\n";
2055     // Convert the single quote to double quote
2056     for(size_t i = 0; i < json.size(); ++i)
2057         if( json[i] == '\'' ) json[i] = '"';
2058     //
2059     CppAD::ADFun<double> f;
2060     f.from_json(json);
2061     // ---------------------------------------------------------------------
2062     ok &= f.Domain() == 2;
2063     ok &= f.Range() == 1;
2064     ok &= f.size_dyn_ind() == 0;
2065     //
2066     vector<double> x(2), y(1);
2067     x[0] = 2.0;
2068     x[1] = 3.0;
2069     y = f.Forward(0, x);
2070     ok &= y[0] == std::max(x[0], x[1]);
2071     //
2072     x[0] = 3.0;
2073     x[1] = 2.0;
2074     y = f.Forward(0, x);
2075     ok &= y[0] == std::max(x[0], x[1]);
2076     // ---------------------------------------------------------------------
2077     json = f.to_json();
2078     f.from_json(json);
2079     // ---------------------------------------------------------------------
2080     ok &= f.Domain() == 2;
2081     ok &= f.Range() == 1;
2082     ok &= f.size_dyn_ind() == 0;
2083     //
2084     x[0] = 2.0;
2085     x[1] = 3.0;
2086     y = f.Forward(0, x);
2087     ok &= y[0] == std::max(x[0], x[1]);
2088     //
2089     x[0] = 3.0;
2090     x[1] = 2.0;
2091     y = f.Forward(0, x);
2092     ok &= y[0] == std::max(x[0], x[1]);
2093     //
2094     // std::cout << graph;
2095     return ok;
2096 }
2097 // Test conditonal expression
cexp_lt_constant(void)2098 bool cexp_lt_constant(void)
2099 {   bool ok = true;
2100     using CppAD::vector;
2101     //
2102     // An AD graph example
2103     // node_1 : x[0]
2104     // node_2 : c[0]
2105     // node_3 : c[1]
2106     // node_4 : cexp_lt(c[0], c[1], c[1], c[0])
2107     // y[0]   = max(c[0], c[1])
2108     // use single quote to avoid having to escape double quote
2109     std::string json =
2110         "{\n"
2111         "   'function_name'  : 'cexp_lt test',\n"
2112         "   'op_define_vec'  : [ 1, [\n"
2113         "       { 'op_code':1, 'name':'cexp_lt', 'n_arg':4 } ]\n"
2114         "   ],\n"
2115         "   'n_dynamic_ind'  : 0,\n"
2116         "   'n_variable_ind' : 1,\n"
2117         "   'constant_vec'   : [ 2, [ 5.0, -5.0 ] ],\n"
2118         "   'op_usage_vec'   : [ 1, [\n"
2119         "       [ 1, 2, 3,  3, 2 ] ] \n"
2120         "   ],\n"
2121         "   'dependent_vec'   : [ 1, [4] ] \n"
2122         "}\n";
2123     // Convert the single quote to double quote
2124     for(size_t i = 0; i < json.size(); ++i)
2125         if( json[i] == '\'' ) json[i] = '"';
2126     //
2127     CppAD::ADFun<double> f;
2128     f.from_json(json);
2129     // ---------------------------------------------------------------------
2130     ok &= f.Domain() == 1;
2131     ok &= f.Range() == 1;
2132     ok &= f.size_dyn_ind() == 0;
2133     //
2134     vector<double> c(2), x(1), y(1);
2135     c[0] = 5.0;
2136     c[1] = -5.0;
2137     y = f.Forward(0, x);
2138     ok &= y[0] == std::max(c[0], c[1]);
2139     // ---------------------------------------------------------------------
2140     json = f.to_json();
2141     f.from_json(json);
2142     // ---------------------------------------------------------------------
2143     ok &= f.Domain() == 1;
2144     ok &= f.Range() == 1;
2145     ok &= f.size_dyn_ind() == 0;
2146     //
2147     ok &= y[0] == std::max(c[0], c[1]);
2148     // ---------------------------------------------------------------------
2149     // std::cout << graph;
2150     return ok;
2151 }
cexp_lt_dynamic(void)2152 bool cexp_lt_dynamic(void)
2153 {   bool ok = true;
2154     using CppAD::vector;
2155     //
2156     // An AD graph example
2157     // node_1 : p[0]
2158     // node_2 : p[1]
2159     // node_3 : x[0]
2160     // node_4 : cexp_lt(p[0], p[1], p[1], p[0])
2161     // y[0]   = max(p[0], p[1])
2162     // use single quote to avoid having to escape double quote
2163     std::string json =
2164         "{\n"
2165         "   'function_name'  : 'cexp_lt test',\n"
2166         "   'op_define_vec'  : [ 1, [\n"
2167         "       { 'op_code':1, 'name':'cexp_lt', 'n_arg':4 } ]\n"
2168         "   ],\n"
2169         "   'n_dynamic_ind'  : 2,\n"
2170         "   'n_variable_ind' : 1,\n"
2171         "   'constant_vec'   : [ 0, [ ] ],\n"
2172         "   'op_usage_vec'   : [ 1, [\n"
2173         "       [ 1, 1, 2, 2, 1 ] ] \n"
2174         "   ],\n"
2175         "   'dependent_vec'   : [ 1, [4] ] \n"
2176         "}\n";
2177     // Convert the single quote to double quote
2178     for(size_t i = 0; i < json.size(); ++i)
2179         if( json[i] == '\'' ) json[i] = '"';
2180     //
2181     CppAD::ADFun<double> f;
2182     f.from_json(json);
2183     // ---------------------------------------------------------------------
2184     ok &= f.Domain() == 1;
2185     ok &= f.Range() == 1;
2186     ok &= f.size_dyn_ind() == 2;
2187     //
2188     vector<double> p(2), x(1), y(1);
2189     p[0] = 3.0;
2190     p[1] = 2.0;
2191     f.new_dynamic(p);
2192     y = f.Forward(0, x);
2193     ok &= y[0] == std::max(p[0], p[1]);
2194     // ---------------------------------------------------------------------
2195     json = f.to_json();
2196     // std::cout << graph;
2197     f.from_json(json);
2198     // ---------------------------------------------------------------------
2199     ok &= f.Domain() == 1;
2200     ok &= f.Range() == 1;
2201     ok &= f.size_dyn_ind() == 2;
2202     //
2203     p[0] = 2.0;
2204     p[1] = 3.0;
2205     f.new_dynamic(p);
2206     y = f.Forward(0, x);
2207     ok &= y[0] == std::max(p[0], p[1]);
2208     // ---------------------------------------------------------------------
2209     // std::cout << graph;
2210     return ok;
2211 }
2212 // ---------------------------------------------------------------------------
2213 // Test atomic function that gets passed both variables and dynamic parameters
atomic_both(void)2214 bool atomic_both(void)
2215 {   bool ok = true;
2216     using CppAD::vector;
2217     using CppAD::AD;
2218     //
2219     // y[0] = p[0] * x[0]
2220     vector< AD<double> > ap(1), ax(1), ay(1);
2221     ap[0] = 2.0;
2222     ax[0] = 3.0;
2223     size_t abort_op_index = 0;
2224     bool   record_compare = false;
2225     CppAD::Independent(ax, abort_op_index, record_compare, ap);
2226     ay[0] = ap[0] * ax[0];
2227     CppAD::ADFun<double> f(ax, ay);
2228     //
2229     // Create a ckhpoint_two with name f(x; p).
2230     // (This also creates an atomic_three fucntion with same name.)
2231     bool internal_bool    = false;
2232     bool use_hes_sparsity = false;
2233     bool use_base2ad      = false;
2234     bool use_in_parallel  = false;
2235     CppAD::chkpoint_two<double> chk_f(f, "f(x; p)",
2236         internal_bool, use_hes_sparsity, use_base2ad, use_in_parallel
2237     );
2238     // -----------------------------------------------------------------------
2239     // g(u; p)
2240     vector< AD<double> > au(2), av(1);
2241     au[0] = 5.0;
2242     au[1] = 6.0;
2243     CppAD::Independent(au);
2244     ax[0] = au[0];
2245     chk_f(ax, av);          // v[0] = p[0] * u[0]
2246     ay[0] = au[1] + av[0];  // y[0] = u[1] + p[0] * u[0]
2247     CppAD::ADFun<double> g(au, ay);
2248     // ---------------------------------------------------------------------
2249     ok &= g.Domain() == 2;
2250     ok &= g.Range() == 1;
2251     ok &= g.size_dyn_ind() == 0;
2252     //
2253     // evalute g(u; p)
2254     vector<double> p(1), u(2), y(1);
2255     p[0] = 3.0;
2256     u[0] = 4.0;
2257     u[1] = 5.0;
2258     chk_f.new_dynamic(p);
2259     y    = g.Forward(0, u);
2260     //
2261     // check value
2262     double check = u[1] + p[0] * u[0];
2263     ok &= y[0] == check;
2264     // ---------------------------------------------------------------------
2265     std::string json = g.to_json();
2266     // std::cout << json;
2267     g.from_json(json);
2268     // ---------------------------------------------------------------------
2269     ok &= g.Domain() == 2;
2270     ok &= g.Range() == 1;
2271     ok &= g.size_dyn_ind() == 0;
2272     //
2273     // evalute g(u; p)
2274     p[0] = 4.0;
2275     u[0] = 5.0;
2276     u[1] = 6.0;
2277     chk_f.new_dynamic(p);
2278     y    = g.Forward(0, u);
2279     //
2280     // check value
2281     check = u[1] + p[0] * u[0];
2282     ok &= y[0] == check;
2283 
2284     // -----------------------------------------------------------------------
2285     // std::cout << graph;
2286     return ok;
2287 }
2288 // ---------------------------------------------------------------------------
2289 // Test atomic function that only gets passed dynamic parameters
atomic_dynamic(void)2290 bool atomic_dynamic(void)
2291 {   bool ok = true;
2292     using CppAD::vector;
2293     using CppAD::AD;
2294     //
2295     // y[0] = x[0] * x[1]
2296     vector< AD<double> > ax(2), ay(1);
2297     ax[0] = 2.0;
2298     ax[1] = 3.0;
2299     CppAD::Independent(ax);
2300     ay[0] = ax[0] * ax[1];
2301     CppAD::ADFun<double> f(ax, ay);
2302     //
2303     // Create a ckhpoint_two with name f(x).
2304     // (This also creates an atomic_three fucntion with same name.)
2305     bool internal_bool    = false;
2306     bool use_hes_sparsity = false;
2307     bool use_base2ad      = false;
2308     bool use_in_parallel  = false;
2309     CppAD::chkpoint_two<double> chk_f(f, "f(x)",
2310         internal_bool, use_hes_sparsity, use_base2ad, use_in_parallel
2311     );
2312     // -----------------------------------------------------------------------
2313     vector< AD<double> > au(1), aq(2), av(1);
2314     aq[0] = 4.0;
2315     aq[1] = 5.0;
2316     au[0] = 6.0;
2317     size_t abort_op_index = 0;
2318     bool   record_compare = false;
2319     CppAD::Independent(au, abort_op_index, record_compare, aq);
2320     chk_f(aq, av);          // v[0] = q[0] * q[1]
2321     ay[0] = au[0] + av[0];  // y[0] = u[0] + q[0] * q[1]
2322     CppAD::ADFun<double> g(au, ay);
2323     //
2324     // ---------------------------------------------------------------------
2325     ok &= g.Domain() == 1;
2326     ok &= g.Range() == 1;
2327     ok &= g.size_dyn_ind() == 2;
2328     //
2329     // set q in g(u; q)
2330     vector<double> q(2);
2331     q[0] = 2.0;
2332     q[1] = 3.0;
2333     g.new_dynamic(q);
2334     //
2335     // evalute g(u; q)
2336     vector<double> u(1), y(1);
2337     u[0] = 4.0;
2338     y    = g.Forward(0, u);
2339     //
2340     // check value
2341     double check = u[0] + q[0] * q[1];
2342     ok &= y[0] == check;
2343     // ---------------------------------------------------------------------
2344     std::string json = g.to_json();
2345     // std::cout << graph;
2346     g.from_json(json);
2347     //
2348     ok &= g.Domain() == 1;
2349     ok &= g.Range() == 1;
2350     ok &= g.size_dyn_ind() == 2;
2351     //
2352     // set q in g(u; q)
2353     q[0] = 3.0;
2354     q[1] = 4.0;
2355     g.new_dynamic(q);
2356     //
2357     // evalute g(u; q)
2358     u[0] = 5.0;
2359     y    = g.Forward(0, u);
2360     //
2361     // check value
2362     check = u[0] + q[0] * q[1];
2363     ok &= y[0] == check;
2364     // ----------------------------------------------------------------------
2365     // std::cout << graph;
2366     return ok;
2367 }
2368 // ---------------------------------------------------------------------------
2369 // Test transforming to Json and back to a function
to_json_and_back(void)2370 bool to_json_and_back(void)
2371 {   bool ok = true;
2372     using CppAD::vector;
2373     //
2374     // An AD graph example
2375     // node_1 : p[0]
2376     // node_2 : x[0]
2377     // node_3 : x[1]
2378     // node_4 : -2.0
2379     // node_5 : p[0] + x[0] + x[1]
2380     // node_6 : (p[0] + x[0] + x[1]) * (p[0] + x[0] + x[1])
2381     // y[0]   = (p[0] + x[0] + x[1]) * (p[0] + x[0] + x[1])
2382     // use single quote to avoid having to escape double quote
2383     std::string json =
2384         "{\n"
2385         "   'function_name'  : 'to_json_and_back test',\n"
2386         "   'op_define_vec'  : [ 3, [\n"
2387         "       { 'op_code':1, 'name':'add', 'n_arg':2 } ,\n"
2388         "       { 'op_code':2, 'name':'mul', 'n_arg':2 } ,\n"
2389         "       { 'op_code':3, 'name':'sum'            } ]\n"
2390         "   ],\n"
2391         "   'n_dynamic_ind'  : 1,\n"
2392         "   'n_variable_ind' : 2,\n"
2393         "   'constant_vec'   : [ 1, [ -2.0 ] ],\n"
2394         "   'op_usage_vec'   : [ 2, [\n"
2395         "       [ 3, 1, 3, [1, 2, 3 ] ] ,\n"
2396         "       [ 2, 5, 5             ] ] \n"
2397         "   ],\n"
2398         "   'dependent_vec'   : [ 1, [6] ] \n"
2399         "}\n";
2400     // Convert the single quote to double quote
2401     for(size_t i = 0; i < json.size(); ++i)
2402         if( json[i] == '\'' ) json[i] = '"';
2403     //
2404     CppAD::ADFun<double> fun;
2405     fun.from_json(json);
2406     json = fun.to_json();
2407     // For debugging
2408     // std::cout << "json = " << json;
2409     fun.from_json(json);
2410     //
2411     // Compute function value
2412     vector<double> p(1), x(2);
2413     p[0] = 1.0;
2414     x[0] = 2.0;
2415     x[1] = 3.0;
2416     fun.new_dynamic(p);
2417     vector<double> y = fun.Forward(0, x);
2418     ok  &= y[0] ==  (p[0] + x[0] + x[1]) * (p[0] + x[0] + x[1]);
2419     //
2420     // Conpute derivative value
2421     vector<double> jac = fun.Jacobian(x);
2422     ok &= jac[0] == 2.0 * (p[0] + x[0] + x[1]);
2423     ok &= jac[1] == 2.0 * (p[0] + x[0] + x[1]);
2424     //
2425     // Uncomment statement below to see the graph
2426     // std::cout << graph;
2427     //
2428     return ok;
2429 }
2430 // ---------------------------------------------------------------------------
2431 // Test binary operators that should be implemented
binary_operators(void)2432 bool binary_operators(void)
2433 {   bool ok   = true;
2434     using CppAD::AD;
2435     //
2436     size_t np = 1;
2437     size_t nx = 2;
2438     size_t ny = 10;
2439     CPPAD_TESTVECTOR(double)       p(np),   x(nx);
2440     CPPAD_TESTVECTOR( AD<double> ) ap(np), ax(nx), ay(ny);
2441     for(size_t i = 0; i < np; ++i)
2442     {   ap[i] = 0.5;
2443         p[i]  = double(i + 1);
2444     }
2445     for(size_t i = 0; i < nx; ++i)
2446     {   ax[i] = 0.25;
2447         x[i]  = double(2 * i + 1);
2448     }
2449     CppAD::Independent(ax, ap);
2450     //
2451     size_t j = 0;
2452     ay[j++] = ap[0] + 2.0;    // dynamic + constant (and ParOp)
2453     ay[j++] = 2.0 + ap[0];    // constant + dynamic (and ParOp)
2454     ay[j++] = ax[0] + ap[0];  // variable + dynamic
2455     ay[j++] = ap[0] + ax[0];  // dynamic + variable
2456     ay[j++] = ax[0] + ax[1];  // variable + variable
2457     //
2458     ay[j++] = ap[0] * 2.0;    // dynamic * constant (and ParOp)
2459     ay[j++] = 2.0 * ap[0];    // constant * dynamic (and ParOp)
2460     ay[j++] = ax[0] * ap[0];  // variable * dynamic
2461     ay[j++] = ap[0] * ax[0];  // dynamic * variable
2462     ay[j++] = ax[0] * ax[1];  // variable * variable
2463     //
2464     ok &= j == ny;
2465     //
2466     // Create function
2467     CppAD::ADFun<double> f(ax, ay);
2468     //
2469     // Evaluate function at x before
2470     f.new_dynamic(p);
2471     CPPAD_TESTVECTOR(double) y_before = f.Forward(0, x);
2472     //
2473     // Convert to Json and back again
2474     std::string json = f.to_json();
2475     // std::cout << graph;
2476     f.from_json(json);
2477     //
2478     // Evaluate function at x after
2479     f.new_dynamic(p);
2480     CPPAD_TESTVECTOR(double) y_after = f.Forward(0, x);
2481     //
2482     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
2483     for(size_t i = 0; i < ny; ++i)
2484         ok &= CppAD::NearEqual( y_before[i], y_after[i], eps99, eps99 );
2485     //
2486     // Uncomment statement below to see the graph
2487     // std::cout << graph;
2488     return ok;
2489 }
2490 // ---------------------------------------------------------------------------
2491 // Test cumulative sum operator
cumulative_sum(void)2492 bool cumulative_sum(void)
2493 {   bool ok   = true;
2494     using CppAD::AD;
2495     //
2496     size_t np = 2;
2497     size_t nx = 2;
2498     size_t ny = 1;
2499     CPPAD_TESTVECTOR(double)       p(np),   x(nx);
2500     CPPAD_TESTVECTOR( AD<double> ) ap(np), ax(nx), ay(ny);
2501     for(size_t i = 0; i < np; ++i)
2502     {   ap[i] = 0.5;
2503         p[i]  = double(i + 1);
2504     }
2505     for(size_t i = 0; i < nx; ++i)
2506     {   ax[i] = 0.25;
2507         x[i]  = double(2 * i + 1);
2508     }
2509     CppAD::Independent(ax, ap);
2510     //
2511     AD<double> asum = 0.0;
2512     asum +=  1.0 + ap[0];
2513     asum += ap[1] + 1.0;
2514     asum -= ap[1] + ap[0];
2515     //
2516     asum +=  1.0 + ax[0];
2517     asum += ax[1] + 1.0;
2518     asum -= ax[1] + ax[0];
2519     //
2520     asum += ap[0] + ax[0];
2521     asum += ax[1] + ap[1];
2522     //
2523     ay[0] = asum;
2524     //
2525     // Create function
2526     CppAD::ADFun<double> f(ax, ay);
2527     f.optimize();
2528     //
2529     // Evaluate function at x before
2530     f.new_dynamic(p);
2531     CPPAD_TESTVECTOR(double) y_before = f.Forward(0, x);
2532     //
2533     // Convert to Json and back again
2534     std::string json = f.to_json();
2535     // std::cout << graph;
2536     f.from_json(json);
2537     //
2538     // Evaluate function at x after
2539     f.new_dynamic(p);
2540     CPPAD_TESTVECTOR(double) y_after = f.Forward(0, x);
2541     //
2542     double eps99 = 99.0 * std::numeric_limits<double>::epsilon();
2543     for(size_t i = 0; i < ny; ++i)
2544         ok &= CppAD::NearEqual( y_before[i], y_after[i], eps99, eps99 );
2545     //
2546     // Uncomment statement below to see the graph
2547     // std::cout << graph;
2548     return ok;
2549 }
2550 
2551 // ---------------------------------------------------------------------------
2552 } // END_EMPTY_NAMESPACE
2553 
2554 
json_graph(void)2555 bool json_graph(void)
2556 {   bool ok = true;
2557     ok     &= comp_op_dyn_dyn();
2558     ok     &= comp_op_var_var();
2559     ok     &= comp_op_dyn_var();
2560     ok     &= comp_op_var_dyn();
2561     ok     &= acosh_op();
2562     ok     &= log1p_op();
2563     ok     &= expm1_op();
2564     ok     &= erfc_op();
2565     ok     &= erf_op();
2566     ok     &= atanh_op();
2567     ok     &= asinh_op();
2568     ok     &= tan_op();
2569     ok     &= tanh_op();
2570     ok     &= sqrt_op();
2571     ok     &= sin_op();
2572     ok     &= sinh_op();
2573     ok     &= sign_op();
2574     ok     &= log_op();
2575     ok     &= exp_op();
2576     ok     &= cos_op();
2577     ok     &= cosh_op();
2578     ok     &= atan_op();
2579     ok     &= asin_op();
2580     ok     &= acos_op();
2581     ok     &= abs_op();
2582     ok     &= cexp_lt_variable();
2583     ok     &= cexp_lt_constant();
2584     ok     &= cexp_lt_dynamic();
2585     ok     &= atomic_both();
2586     ok     &= atomic_dynamic();
2587     ok     &= to_json_and_back();
2588     ok     &= binary_operators();
2589     ok     &= cumulative_sum();
2590     //
2591     return ok;
2592 }
2593