pub fn ad_from_vector<V>(vec: Vec<V>) -> Vec<AD<V>>Expand description
Convert a vector to an vector of AD objects with no variable information; i.e., a vector of constants.
See Also : example in ad_from_value
ยงExample
use rustad::AD;
use rustad::ad_from_vector;
let x : Vec<f64> = vec![ 3.0, 4.0 ];
let ax = ad_from_vector(x);
assert_eq!( ax[0].clone().to_value(), 3.0 );
assert_eq!( ax[1].clone().to_value(), 4.0 );Examples found in repository?
examples/atom/tests.rs (line 103)
90pub fn callback_forward_one_ad(
91 sumsq_atom_id : IndexT , call_info : IndexT, trace : bool
92) {
93 //
94 // f
95 let f = value_callback_f(sumsq_atom_id, call_info, trace);
96 //
97 // av, dx1, adx1
98 let x : Vec<V> = vec![ 3.0 , 4.0 ];
99 let ax = start_recording(x);
100 let mut av : Vec< AD<V> > = Vec::new();
101 f.forward_zero_ad(&mut av , ax, trace);
102 let dx1 : Vec<V> = vec![ 5.0, 6.0 ];
103 let adx1 = ad_from_vector(dx1.clone());
104 //
105 // g
106 // callback to sumsq_forward_one_ad
107 // g(x) = f'(x) * dx1 = 2 * ( x[0] * dx1[0] + x[2] * dx1[2] + ... )
108 let ady = f.forward_one_ad(&av, adx1, trace);
109 let g = stop_recording(ady);
110 //
111 // x, v, y
112 // check forward_zero_value
113 let x : Vec<V> = vec![ 3.0 , 4.0 ];
114 let mut v : Vec<V> = Vec::new();
115 let y = g.forward_zero_value(&mut v , x.clone(), trace);
116 assert_eq!( y[0], 2.0 * ( x[0] * dx1[0] + x[1] * dx1[1] ) );
117 //
118 // check forward_one_value
119 let dx2 : Vec<V> = vec![ 7.0, 8.0 ];
120 let dy = g.forward_one_value(&v , dx2.clone(), trace);
121 assert_eq!( dy[0], 2.0 * ( dx2[0] * dx1[0] + dx2[1] * dx1[1] ) );
122 //
123 // check reverse_one_value
124 let dy : Vec<V> = vec![ 9.0 ];
125 let dx = g.reverse_one_value(&v , dy.clone(), trace);
126 assert_eq!( dx[0], 2.0 * dy[0] * dx1[0] );
127 assert_eq!( dx[1], 2.0 * dy[0] * dx1[1] );
128}
129//
130// callback_reverse_one_value
131pub fn callback_reverse_one_value(
132 sumsq_atom_id : IndexT , call_info : IndexT, trace : bool
133) {
134 //
135 // f
136 let f = value_callback_f(sumsq_atom_id, call_info, trace);
137 //
138 // x, dy, dx
139 let x : Vec<V> = vec![ 3.0 , 4.0 ];
140 let mut v : Vec<V> = Vec::new();
141 f.forward_zero_value(&mut v , x.clone(), trace);
142 let dy : Vec<V> = vec![ 5.0 ];
143 let dx = f.reverse_one_value(&v , dy.clone(), trace);
144 assert_eq!( dx[0], 2.0 * x[0]*dy[0] );
145 assert_eq!( dx[1], 2.0 * x[1]*dy[0] );
146}
147//
148// callback_reverse_one_ad
149pub fn callback_reverse_one_ad(
150 sumsq_atom_id : IndexT , call_info : IndexT, trace : bool
151) {
152 //
153 // f
154 let f = value_callback_f(sumsq_atom_id, call_info, trace);
155 //
156 // av, dy1, ady1
157 let x : Vec<V> = vec![ 3.0 , 4.0 ];
158 let ax = start_recording(x);
159 let mut av : Vec< AD<V> > = Vec::new();
160 f.forward_zero_ad(&mut av , ax, trace);
161 let dy1 : Vec<V> = vec![ 5.0 ];
162 let ady1 = ad_from_vector(dy1.clone());
163 //
164 // g
165 // callback to sumsq_reverse_one_ad
166 // g(x) = dy1 * f'(x) = 2 * ( dy1[0] * x[0], dy1[0] * x[1], ... )
167 let adx = f.reverse_one_ad(&av, ady1, trace);
168 let g = stop_recording(adx);
169 //
170 // x, v
171 // check forward_zero_value
172 let x : Vec<V> = vec![ 3.0 , 4.0 ];
173 let mut v : Vec<V> = Vec::new();
174 let y = g.forward_zero_value(&mut v , x.clone(), trace);
175 assert_eq!( y[0], 2.0 * dy1[0] * x[0] );
176 assert_eq!( y[1], 2.0 * dy1[0] * x[1] );
177 //
178 // check forward_one_value
179 let dx : Vec<V> = vec![ 6.0, 7.0 ];
180 let dy = g.forward_one_value(&v, dx.clone(), trace);
181 assert_eq!( dy[0], 2.0 * dy1[0] * dx[0] );
182 assert_eq!( dy[1], 2.0 * dy1[0] * dx[1] );
183 //
184 // check reverse_one_value
185 let dy2 : Vec<V> = vec![ 8.0, 9.0 ];
186 let dx = g.reverse_one_value(&v, dy2.clone(), trace);
187 assert_eq!( dx[0], 2.0 * dy1[0] * dy2[0] );
188 assert_eq!( dx[1], 2.0 * dy1[0] * dy2[1] );
189}More examples
examples/hessian.rs (line 50)
18fn example_hessian () {
19 //
20 type V = f32;
21 let nx = 3;
22 let trace = false;
23 //
24 // x
25 let x : Vec<V> = vec![ 2.0 as V; nx ];
26 //
27 // ax
28 let ax = start_recording(x.clone());
29 //
30 // asum
31 let mut asum : AD<V> = ad_from_value( 0.0 as V );
32 for j in 0 .. nx {
33 let cubed = &( &ax[j] * &ax[j] ) * &ax[j];
34 asum += &cubed;
35 }
36 //
37 // f
38 // f(x) = x[0] * x[0] * x[0] + ... + x[nx-1] * x[nx-1] * x[nx-1]
39 let ay = vec![ asum ];
40 let f = stop_recording(ay);
41 //
42 // av
43 let ax = start_recording(x);
44 let mut av : Vec< AD<V> > = Vec::new();
45 f.forward_zero_ad(&mut av, ax, trace);
46 //
47 // g
48 // g(x) = df/dx = [ 3 * x[0] * x[0], ..., 3 * x[nx-1] * x[nx-1] ]
49 let dy : Vec<V> = vec![ 1.0 as V ];
50 let ady = ad_from_vector(dy);
51 let adx = f.reverse_one_ad(&av, ady, trace);
52 let g = stop_recording(adx);
53 //
54 // x
55 // x[j] = j+2
56 let mut x : Vec<V> = Vec::new();
57 for j in 0 .. nx {
58 x.push( (j+2) as V );
59 }
60 //
61 // v, y
62 let mut v : Vec<V> = Vec::new();
63 let y = g.forward_zero_value(&mut v, x, trace);
64 for j in 0 .. nx {
65 let check = 3 * (j+2) * (j+2);
66 assert_eq!( y[j], check as V );
67 }
68 //
69 // dy
70 // dy[i] = partial g[i] w.r.t x[j] = 6 * x[j]
71 for j in 0 .. nx {
72 let mut dx : Vec<V> = vec![ 0.0 as V; nx ];
73 dx[j] = 1.0 as V;
74 let dy = g.forward_one_value(&v, dx, trace);
75 for i in 0 .. nx {
76 if i == j {
77 let check = 6 * (j+2);
78 assert_eq!( dy[i], check as V );
79 } else {
80 assert_eq!( dy[i], 0.0 as V );
81 }
82 }
83 }
84}
85//
86// example_numvec_hessian
87// Same function where V = NumVec<f64>
88fn example_numvec_hessian () {
89 //
90 type F = f64;
91 type V = NumVec<F>;
92 let nx = 3;
93 let trace = false;
94 //
95 // x
96 let mut x : Vec<V> = Vec::new();
97 for _j in 0 .. nx {
98 x.push( NumVec::new( vec![ 2.0 as F ] ) );
99 }
100 //
101 // ax
102 let ax = start_recording(x.clone());
103 //
104 // asum
105 let mut asum : AD<V> = ad_from_value( NumVec::from( 0.0 as F ) );
106 for j in 0 .. nx {
107 let cubed = &( &ax[j] * &ax[j] ) * &ax[j];
108 asum += &cubed;
109 }
110 //
111 // f
112 // f(x) = x[0] * x[0] * x[0] + ... + x[nx-1] * x[nx-1] * x[nx-1]
113 let ay = vec![ asum ];
114 let f = stop_recording(ay);
115 //
116 // av
117 let ax = start_recording(x);
118 let mut av : Vec< AD<V> > = Vec::new();
119 f.forward_zero_ad(&mut av, ax, trace);
120 //
121 // g
122 // g(x) = df/dx = [ 3 * x[0] * x[0], ..., 3 * x[nx-1] * x[nx-1] ]
123 let dy : Vec<V> = vec![ NumVec::from( 1.0 as F ) ];
124 let ady = ad_from_vector(dy);
125 let adx = f.reverse_one_ad(&av, ady, trace);
126 let g = stop_recording(adx);
127 //
128 // x
129 // x[j] = [ j+1, j+2 ]
130 let mut x : Vec<V> = Vec::new();
131 for j in 0 .. nx {
132 x.push( NumVec::new( vec![ (j+1) as F, (j+2) as F ] ) );
133 }
134 //
135 // v, y
136 let mut v : Vec<V> = Vec::new();
137 let y = g.forward_zero_value(&mut v, x, trace);
138 for j in 0 .. nx {
139 //
140 let check = 3 * (j+1) * (j+1);
141 assert_eq!( y[j].get(0), check as F );
142 //
143 let check = 3 * (j+2) * (j+2);
144 assert_eq!( y[j].get(1), check as F );
145 }
146 //
147 // dy
148 // dy[i] = partial g[i] w.r.t x[j] = 6 * x[j]
149 for j in 0 .. nx {
150 let mut dx : Vec<V> = vec![ NumVec::from( 0.0 as F ); nx ];
151 dx[j] = NumVec::from( 1.0 as F );
152 let dy = g.forward_one_value(&v, dx, trace);
153 for i in 0 .. nx {
154 if i == j {
155 //
156 let check = 6 * (j+1);
157 assert_eq!( dy[i].get(0), check as F );
158 //
159 let check = 6 * (j+2);
160 assert_eq!( dy[i].get(1), check as F );
161 } else {
162 for k in 0 .. dy[i].len() {
163 assert_eq!( dy[i].get(k) , 0.0 as F );
164 }
165 }
166 }
167 }
168}