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