Objective

Trait Objective 

Source
pub trait Objective<const N: usize> {
    type EvalArgs;

    // Required method
    fn eval(&self, variables: &advec<N, N>, args: &Self::EvalArgs) -> Ad<N>;

    // Provided methods
    fn evaluate_for_indices(
        &self,
        global_inds: [usize; N],
        x: &Col<f64>,
        args: &Self::EvalArgs,
    ) -> Ad<N> { ... }
    fn compute(
        &self,
        x: &Col<f64>,
        operand_indices: &[[usize; N]],
        args: &Self::EvalArgs,
    ) -> ComputedObjective<N> { ... }
    fn value(
        &self,
        x: &Col<f64>,
        operand_indices: &[[usize; N]],
        args: &Self::EvalArgs,
    ) -> f64 { ... }
    fn grad(
        &self,
        x: &Col<f64>,
        operand_indices: &[[usize; N]],
        args: &Self::EvalArgs,
    ) -> Col<f64> { ... }
    fn hess_trips(
        &self,
        x: &Col<f64>,
        operand_indices: &[[usize; N]],
        args: &Self::EvalArgs,
    ) -> Vec<(usize, usize, f64)> { ... }
    fn hess(
        &self,
        x: &Col<f64>,
        operand_indices: &[[usize; N]],
        args: &Self::EvalArgs,
    ) -> Result<SparseColMat<usize, f64>, CreationError> { ... }
}
Expand description

Defines the interface for sparse objective functions

§Type Parameters

  • N: The problem size/dimension of a single objective

§Associated Types

  • EvalArgs: Additional arguments needed for objective evaluation

§Example

struct MyObjective;

impl Objective<3> for MyObjective {
    type EvalArgs = f64; // Example args type
     
    fn eval(&self, variables: &advec<3, 3>, args: &f64) -> Ad<3> {
        todo!("Your implementation")
    }
}

Required Associated Types§

Required Methods§

Source

fn eval(&self, variables: &advec<N, N>, args: &Self::EvalArgs) -> Ad<N>

Evaluates the objective function for given variables

§Arguments
  • variables: The input variables as an advec
  • args: Additional evaluation arguments
§Returns

An Ad<N> containing the function value, gradient and Hessian

Provided Methods§

Source

fn evaluate_for_indices( &self, global_inds: [usize; N], x: &Col<f64>, args: &Self::EvalArgs, ) -> Ad<N>

Helper method to evaluate objective for given indices

§Arguments
  • global_inds: Global indices of variables to evaluate
  • x: The full variable vector
  • args: Additional evaluation arguments
§Returns

An Ad<N> containing the local evaluation results

Source

fn compute( &self, x: &Col<f64>, operand_indices: &[[usize; N]], args: &Self::EvalArgs, ) -> ComputedObjective<N>

Computes value, gradient and Hessian triplets in one operation

§Arguments
  • x: The full variable vector, may be large
  • operand_indices: Slice of indices of variables to evaluate
  • args: Additional evaluation arguments
§Returns

A ComputedObjective<N> containing all computed results

Source

fn value( &self, x: &Col<f64>, operand_indices: &[[usize; N]], args: &Self::EvalArgs, ) -> f64

Computes just the objective function value

§Arguments
  • x: The full variable vector
  • operand_indices: Slice of indices of variables to evaluate
  • args: Additional evaluation arguments
§Returns

The computed objective function value

Examples found in repository?
src/examples/mass_spring.rs (line 68)
26fn main() {
27    // todo!("This example is undone");
28
29    let springs = vec![[0, 1, 2, 3], [2, 3, 4, 5], [0, 1, 4, 5]];
30    let x0 = faer::col::from_slice(&[0.0, 0.0, 0.001, 0.0, 0.001, 0.01]).to_owned();
31
32    let obj = SpringEnergy {
33        k: 10000.0,
34        restlen: 1.0,
35    };
36
37    let mut i = 0;
38    let mut x = x0.clone();
39    let mut dir: Col<f64>;
40    // Newton Raphson
41    while {
42        let grad = obj.grad(&x, &springs, &());
43        let mut hesstrip = obj.hess_trips(&x, &springs, &());
44        for i in 0..6 {
45            hesstrip.push((i, i, 1.0));
46        }
47        let hess = SparseColMat::try_new_from_triplets(6, 6, &hesstrip).unwrap();
48
49        // wtf matrix is not invertible?
50        dir = hess.sp_lu().unwrap().solve(-&grad);
51
52        dir.norm_l2() > 1e-8
53    } {
54        x += dir;
55
56        i += 1;
57
58        let p1 = SVector::<f64, 2>::new(x[0], x[1]);
59        let p2 = SVector::<f64, 2>::new(x[2], x[3]);
60        let p3 = SVector::<f64, 2>::new(x[4], x[5]);
61
62        println!("\nIter {}", i);
63        println!("Len 1 = {}", (p2 - p1).norm());
64        println!("Len 2 = {}", (p3 - p2).norm());
65        println!("Len 3 = {}", (p3 - p1).norm());
66    }
67
68    println!("\nFinal potential: {}", obj.value(&x, &springs, &()));
69    let p1 = SVector::<f64, 2>::new(x[0], x[1]);
70    let p2 = SVector::<f64, 2>::new(x[2], x[3]);
71    let p3 = SVector::<f64, 2>::new(x[4], x[5]);
72
73    assert_abs_diff_eq!((p2 - p1).norm(), 1.0, epsilon = 1e-4);
74    assert_abs_diff_eq!((p3 - p2).norm(), 1.0, epsilon = 1e-4);
75    assert_abs_diff_eq!((p3 - p1).norm(), 1.0, epsilon = 1e-4);
76}
Source

fn grad( &self, x: &Col<f64>, operand_indices: &[[usize; N]], args: &Self::EvalArgs, ) -> Col<f64>

Computes just the gradient vector

§Arguments
  • x: The full variable vector
  • operand_indices: Slice of indices of variables to evaluate
  • args: Additional evaluation arguments
§Returns

The computed gradient vector

Examples found in repository?
src/examples/mass_spring.rs (line 42)
26fn main() {
27    // todo!("This example is undone");
28
29    let springs = vec![[0, 1, 2, 3], [2, 3, 4, 5], [0, 1, 4, 5]];
30    let x0 = faer::col::from_slice(&[0.0, 0.0, 0.001, 0.0, 0.001, 0.01]).to_owned();
31
32    let obj = SpringEnergy {
33        k: 10000.0,
34        restlen: 1.0,
35    };
36
37    let mut i = 0;
38    let mut x = x0.clone();
39    let mut dir: Col<f64>;
40    // Newton Raphson
41    while {
42        let grad = obj.grad(&x, &springs, &());
43        let mut hesstrip = obj.hess_trips(&x, &springs, &());
44        for i in 0..6 {
45            hesstrip.push((i, i, 1.0));
46        }
47        let hess = SparseColMat::try_new_from_triplets(6, 6, &hesstrip).unwrap();
48
49        // wtf matrix is not invertible?
50        dir = hess.sp_lu().unwrap().solve(-&grad);
51
52        dir.norm_l2() > 1e-8
53    } {
54        x += dir;
55
56        i += 1;
57
58        let p1 = SVector::<f64, 2>::new(x[0], x[1]);
59        let p2 = SVector::<f64, 2>::new(x[2], x[3]);
60        let p3 = SVector::<f64, 2>::new(x[4], x[5]);
61
62        println!("\nIter {}", i);
63        println!("Len 1 = {}", (p2 - p1).norm());
64        println!("Len 2 = {}", (p3 - p2).norm());
65        println!("Len 3 = {}", (p3 - p1).norm());
66    }
67
68    println!("\nFinal potential: {}", obj.value(&x, &springs, &()));
69    let p1 = SVector::<f64, 2>::new(x[0], x[1]);
70    let p2 = SVector::<f64, 2>::new(x[2], x[3]);
71    let p3 = SVector::<f64, 2>::new(x[4], x[5]);
72
73    assert_abs_diff_eq!((p2 - p1).norm(), 1.0, epsilon = 1e-4);
74    assert_abs_diff_eq!((p3 - p2).norm(), 1.0, epsilon = 1e-4);
75    assert_abs_diff_eq!((p3 - p1).norm(), 1.0, epsilon = 1e-4);
76}
Source

fn hess_trips( &self, x: &Col<f64>, operand_indices: &[[usize; N]], args: &Self::EvalArgs, ) -> Vec<(usize, usize, f64)>

Computes Hessian matrix entries as triplets

§Arguments
  • x: The full variable vector
  • operand_indices: Slice of indices of variables to evaluate
  • args: Additional evaluation arguments
§Returns

Vector of (row, col, value) triplets representing the Hessian matrix

Examples found in repository?
src/examples/mass_spring.rs (line 43)
26fn main() {
27    // todo!("This example is undone");
28
29    let springs = vec![[0, 1, 2, 3], [2, 3, 4, 5], [0, 1, 4, 5]];
30    let x0 = faer::col::from_slice(&[0.0, 0.0, 0.001, 0.0, 0.001, 0.01]).to_owned();
31
32    let obj = SpringEnergy {
33        k: 10000.0,
34        restlen: 1.0,
35    };
36
37    let mut i = 0;
38    let mut x = x0.clone();
39    let mut dir: Col<f64>;
40    // Newton Raphson
41    while {
42        let grad = obj.grad(&x, &springs, &());
43        let mut hesstrip = obj.hess_trips(&x, &springs, &());
44        for i in 0..6 {
45            hesstrip.push((i, i, 1.0));
46        }
47        let hess = SparseColMat::try_new_from_triplets(6, 6, &hesstrip).unwrap();
48
49        // wtf matrix is not invertible?
50        dir = hess.sp_lu().unwrap().solve(-&grad);
51
52        dir.norm_l2() > 1e-8
53    } {
54        x += dir;
55
56        i += 1;
57
58        let p1 = SVector::<f64, 2>::new(x[0], x[1]);
59        let p2 = SVector::<f64, 2>::new(x[2], x[3]);
60        let p3 = SVector::<f64, 2>::new(x[4], x[5]);
61
62        println!("\nIter {}", i);
63        println!("Len 1 = {}", (p2 - p1).norm());
64        println!("Len 2 = {}", (p3 - p2).norm());
65        println!("Len 3 = {}", (p3 - p1).norm());
66    }
67
68    println!("\nFinal potential: {}", obj.value(&x, &springs, &()));
69    let p1 = SVector::<f64, 2>::new(x[0], x[1]);
70    let p2 = SVector::<f64, 2>::new(x[2], x[3]);
71    let p3 = SVector::<f64, 2>::new(x[4], x[5]);
72
73    assert_abs_diff_eq!((p2 - p1).norm(), 1.0, epsilon = 1e-4);
74    assert_abs_diff_eq!((p3 - p2).norm(), 1.0, epsilon = 1e-4);
75    assert_abs_diff_eq!((p3 - p1).norm(), 1.0, epsilon = 1e-4);
76}
Source

fn hess( &self, x: &Col<f64>, operand_indices: &[[usize; N]], args: &Self::EvalArgs, ) -> Result<SparseColMat<usize, f64>, CreationError>

Computes the Hessian matrix as a sparse matrix

§Arguments
  • x: The full variable vector
  • operand_indices: Slice of indices of variables to evaluate
  • args: Additional evaluation arguments
§Returns

A sparse matrix representation of the Hessian

Implementors§