Skip to main content

ad_from_vector

Function ad_from_vector 

Source
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
Hide additional 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}