Expand description
§ceres-solver-rs
§Safe Rust bindings for Ceres Solver
Solve large and small non-linear optimization problems in Rust. See NllsProblem for general non-linear least squares problem and CurveFitProblem1D for a multiparametric 1-D curve fitting.
§Examples
Let’s solve min[(x - 2)^2] problem
use ceres_solver::{CostFunctionType, NllsProblem, SolverOptions};
// parameters vector consists of vector parameters, here we have a single 1-D parameter.
let true_parameters = vec![vec![2.0]];
let initial_parameters = vec![vec![0.0]];
// You can skip type annotations in the closure definition, we use them for verbosity only.
let cost: CostFunctionType = Box::new(
move |parameters: &[&[f64]],
residuals: &mut [f64],
mut jacobians: Option<&mut [Option<&mut [&mut [f64]]>]>| {
// residuals have the size of your data set, in our case it is just 1
residuals[0] = parameters[0][0] - 2.0;
// jacobians can be None, then you don't need to provide them
if let Some(jacobians) = jacobians {
// The size of the jacobians array is equal to the number of parameters,
// each element is Option<&mut [&mut [f64]]>
if let Some(d_dx) = &mut jacobians[0] {
// Each element in the jacobians array is slice of slices:
// the first index is for different residuals components,
// the second index is for different components of the parameter vector
d_dx[0][0] = 1.0;
}
}
true
},
);
let solution = NllsProblem::new()
.residual_block_builder() // create a builder for residual block
.set_cost(cost, 1) // 1 is the number of residuals
.set_parameters(initial_parameters)
.build_into_problem()
.unwrap()
.0 // build_into_problem returns a tuple (NllsProblem, ResidualBlockId)
// You can repeat .residual_block_builder() and .build_into_problem() calls to add more
// residual blocks
.solve(&SolverOptions::default()) // SolverOptions can be customized
.unwrap(); // Err should happen only if we added no residual blocks
// Print the full solver report
println!("{}", solution.summary.full_report());
// The solution is a vector of parameter vectors, here we have a single 1-D parameter.
assert!(f64::abs(solution.parameters[0][0] - true_parameters[0][0]) < 1e-8);
See more details and examples in nlls_problem module documentation.
We also provide a lighter interface for 1-D multiparameter curve fit problems via CurveFitProblem1D. Let’s generate data points and fit them for a quadratic function.
use ceres_solver::{CurveFitProblem1D, CurveFunctionType, SolverOptions};
// A model to use for the cost function.
fn model(
x: f64,
parameters: &[f64],
y: &mut f64,
jacobians: Option<&mut [Option<f64>]>,
) -> bool {
let &[a, b, c]: &[f64; 3] = parameters.try_into().unwrap();
*y = a * x.powi(2) + b * x + c;
if let Some(jacobians) = jacobians {
let [d_da, d_db, d_dc]: &mut [Option<f64>; 3] = jacobians.try_into().unwrap();
if let Some(d_da) = d_da {
*d_da = x.powi(2);
}
if let Some(d_db) = d_db {
*d_db = x;
}
if let Some(d_dc) = d_dc {
*d_dc = 1.0;
}
}
true
}
let true_parameters = [1.0, 2.0, 3.0];
// Generate data points.
let x: Vec<_> = (0..100).map(|i| i as f64 * 0.01).collect();
let y: Vec<_> = x
.iter()
.map(|&x| {
let mut y = 0.0;
model(x, &true_parameters, &mut y, None);
// True value + "noise"
y + 0.001 + f64::sin(1e6 * x)
})
.collect();
// Wrap the model to be a cost function.
let cost: CurveFunctionType = Box::new(model);
// Create and solve the problem.
let initial_guess = [0.0, 0.0, 0.0];
let solution =
CurveFitProblem1D::new(cost, &x, &y, &initial_guess).solve(&SolverOptions::default());
// Print the brief report
print!("{:?}", solution.summary);
// Check the results.
for (true_value, actual_value) in true_parameters
.into_iter()
.zip(solution.parameters.into_iter())
{
assert!(f64::abs(true_value - actual_value) < 0.1);
}
See more examples in curve_fit::CurveFitProblem1DBuilder’s documentation.
Re-exports§
pub use cost::CostFunctionType;
pub use curve_fit::CurveFitProblem1D;
pub use curve_fit::CurveFunctionType;
pub use loss::LossFunction;
pub use loss::LossFunctionType;
pub use nlls_problem::NllsProblem;
pub use parameter_block::ParameterBlock;
pub use parameter_block::ParameterBlockOrIndex;
pub use solver::SolverOptions;
Modules§
- cost
- Cost function wrapper for NllsProblem.
- curve_
fit - Wrapping NllsProblem for 1-D curve fit problems.
- error
- Error enums.
- loss
- Loss functions for NllsProblem and CurveFitProblem1D.
- nlls_
problem - Non-Linear Least Squares problem builder and solver.
- parameter_
block - Parameter block and related structures for NllsProblem.
- residual_
block - Residual-block related structures.
- solver
- Structures for solver configuration and report.
- types
- Various helper types.