1 | // $Id$ |
---|

2 | /* -------------------------------------------------------------------------- |
---|

3 | CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell |
---|

4 | |
---|

5 | CppAD is distributed under multiple licenses. This distribution is under |
---|

6 | the terms of the |
---|

7 | Eclipse Public License Version 1.0. |
---|

8 | |
---|

9 | A copy of this license is included in the COPYING file of this distribution. |
---|

10 | Please visit http://www.coin-or.org/CppAD/ for information on other licenses. |
---|

11 | -------------------------------------------------------------------------- */ |
---|

12 | # include <iostream> |
---|

13 | # include <cppad/cppad.hpp> |
---|

14 | |
---|

15 | // Test multiple level conditional skip where value of comparision is |
---|

16 | // uncertain during forward mode base Base value can be a variable. |
---|

17 | bool mul_cskip(void) |
---|

18 | { bool ok = true; |
---|

19 | using namespace CppAD; |
---|

20 | using CppAD::vector; |
---|

21 | |
---|

22 | typedef AD<double> a1type; |
---|

23 | typedef AD<a1type> a2type; |
---|

24 | |
---|

25 | size_t n = 2; |
---|

26 | size_t m = 1; |
---|

27 | vector<double> x(n), y(m); |
---|

28 | x[0] = 0.0; |
---|

29 | x[1] = 1.0; |
---|

30 | |
---|

31 | // start recording a2type operations |
---|

32 | vector<a2type> a2x(n), a2y(m); |
---|

33 | for (size_t j = 0; j < n; j++) |
---|

34 | a2x[j] = a2type( a1type(x[j]) ); |
---|

35 | Independent(a2x); |
---|

36 | |
---|

37 | // a1f(x) = x_0 * x_1 if x[0] == 1 |
---|

38 | // 0.0 otherwise |
---|

39 | a2type a2zero = a2type(0.0); |
---|

40 | a2type a2one = a2type(1.0); |
---|

41 | a2type a2p = a2x[0] * a2x[1]; |
---|

42 | a2y[0] = CondExpEq(a2x[0], a2one, a2p, a2zero); |
---|

43 | ADFun<a1type> a1f(a2x, a2y); |
---|

44 | |
---|

45 | // Optimization will check to see if we can skip part of conditional |
---|

46 | // expression that is not used. |
---|

47 | a1f.optimize(); |
---|

48 | |
---|

49 | // f(x) = x_0 * x_1 if x[0] == 1 |
---|

50 | // 0.0 otherwise |
---|

51 | vector<a1type> a1x(n), a1y(m); |
---|

52 | for (size_t j = 0; j < n; j++) |
---|

53 | a1x[j] = a1type(x[j]); |
---|

54 | Independent(a1x); |
---|

55 | a1y = a1f.Forward(0, a1x); |
---|

56 | CppAD::ADFun<double> f(a1x, a1y); |
---|

57 | |
---|

58 | // check case where x[0] == 1 |
---|

59 | x[0] = 1.0; |
---|

60 | x[1] = 2.0; |
---|

61 | y = f.Forward(0, x); |
---|

62 | ok &= y[0] == x[1]; |
---|

63 | |
---|

64 | // check case where x[0] != 1 |
---|

65 | x[0] = 3.0; |
---|

66 | x[1] = 2.0; |
---|

67 | y = f.Forward(0, x); |
---|

68 | ok &= y[0] == 0.0; |
---|

69 | |
---|

70 | return ok; |
---|

71 | } |
---|