// Note: directions do not need to be normalized.
// (The ranges are in units of these norms)
directions do not need to be normalized.
(The ranges are in units of these norms)
directions do not need to be normalized . ( The ranges are in units of these norms )
pub fn integrate_two_directions<E, F>(
    // dims must be greater than 1
    dims: [usize; 2],
    init_pos: &[V3],
    ranges: [Range<f64>; 2],
    extend_borders: [bool; 2],
    directions: [&[V3]; 2],
    mut compute_grad: F,
) -> Result<TwoDeeIntegrated, E>
where
    F: FnMut(&[V3]) -> Result<Vec<V3>, E>,
{
    let (ixs, xs) = linspace(ranges[0].clone(), dims[0], extend_borders[0]);
    let (iys, ys) = linspace(ranges[1].clone(), dims[1], extend_borders[1]);
    let indices = iproduct!(ixs, iys).map(|(ix, iy)| [ix, iy]).collect();
    let coords = iproduct!(&xs, &ys).map(|(&x, &y)| [x, y]).collect();
    let values = integrate_grid_random(
        (dims[0], dims[1]),
        |(x, y)| {Ok::<_,E>({
            let V(pos) = v(init_pos.flat())
                + xs[x] * v(directions[0].flat())
                + ys[y] * v(directions[1].flat());
            let pos = pos.to_vec();
            let grad = compute_grad(pos.nest())?.flat().to_vec();
            (pos, grad)
        })},
        |(_, (pos1, grad1)), (_, (pos2, grad2))| {Ok({
            // trapezoid
            let V(grad) = 0.5 * (v(grad1) + v(grad2));
            let V(d_pos) = v(pos2) - v(pos1);
            vdot(&grad[..], &d_pos)
        })},
    )?;
    Ok(TwoDeeIntegrated { indices, values, coords })
}
pub fn integrate_two_directions < E , F > ( // dims must be greater than 1 dims : [ usize ; 2 ] , init_pos : & [ V3 ] , ranges : [ Range < f64 > ; 2 ] , extend_borders : [ bool ; 2 ] , directions : [ & [ V3 ] ; 2 ] , mut compute_grad : F , ) -> Result < TwoDeeIntegrated , E > where F : FnMut ( & [ V3 ] ) -> Result < Vec < V3 > , E > , { let ( ixs , xs ) = linspace ( ranges [ 0 ] . clone ( ) , dims [ 0 ] , extend_borders [ 0 ] ) ; let ( iys , ys ) = linspace ( ranges [ 1 ] . clone ( ) , dims [ 1 ] , extend_borders [ 1 ] ) ; let indices = iproduct ! ( ixs iys ) . map ( | ( ix , iy ) | [ ix , iy ] ) . collect ( ) ; let coords = iproduct ! ( xs ys ) . map ( | ( & x , & y ) | [ x , y ] ) . collect ( ) ; let values = integrate_grid_random ( ( dims [ 0 ] , dims [ 1 ] ) , | ( x , y ) | { Ok :: < _ , E > ( { let V ( pos ) = v ( init_pos . flat ( ) ) + xs [ x ] * v ( directions [ 0 ] . flat ( ) ) + ys [ y ] * v ( directions [ 1 ] . flat ( ) ) ; let pos = pos . to_vec ( ) ; let grad = compute_grad ( pos . nest ( ) ) ? . flat ( ) . to_vec ( ) ; ( pos , grad ) } ) } , | ( _ , ( pos1 , grad1 ) ) , ( _ , ( pos2 , grad2 ) ) | { Ok ( { // trapezoid let V ( grad ) = 0.5 * ( v ( grad1 ) + v ( grad2 ) ) ; let V ( d_pos ) = v ( pos2 ) - v ( pos1 ) ; vdot ( & grad [ .. ] , & d_pos ) } ) } , ) ? ; Ok ( TwoDeeIntegrated { indices , values , coords } ) }
Note: directions do not need to be normalized.
Note : directions do not need to be normalized .
dims
[usize; 2]
init_pos
&[V3]
ranges
[Range<f64>; 2]
extend_borders
[bool; 2]
directions
[&[V3]; 2]
compute_grad
F