Expand description
§Least Squares
Compute a least-squares solution to the equation Ax = b.
Compute a vector x such that the 2-norm |b - A x|
is minimized.
Finding the least squares solutions is implemented as traits, meaning
that to solve A x = b
for a matrix A
and a RHS b
, we call
let result = A.least_squares(&b);
. This returns a result
of
type LeastSquaresResult
, the solution for the least square problem
is in result.solution
.
There are three traits, LeastSquaresSvd
with the method least_squares
,
which operates on immutable references, LeastSquaresInto
with the method
least_squares_into
, which takes ownership over both the array A
and the
RHS b
and LeastSquaresSvdInPlace
with the method least_squares_in_place
,
which operates on mutable references for A
and b
and destroys these when
solving the least squares problem. LeastSquaresSvdInto
and
LeastSquaresSvdInPlace
avoid an extra allocation for A
and b
which
LeastSquaresSvd
has do perform to preserve the values in A
and b
.
All methods use the Lapacke family of methods *gelsd
which solves the least
squares problem using the SVD with a divide-and-conquer strategy.
The traits are implemented for value types f32
, f64
, c32
and c64
and vector or matrix right-hand-sides (ArrayBase<S, Ix1>
or ArrayBase<S, Ix2>
).
§Example
use approx::AbsDiffEq; // for abs_diff_eq
use ndarray::{array, Array1, Array2};
use ndarray_linalg::{LeastSquaresSvd, LeastSquaresSvdInto, LeastSquaresSvdInPlace};
let a: Array2<f64> = array![
[1., 1., 1.],
[2., 3., 4.],
[3., 5., 2.],
[4., 2., 5.],
[5., 4., 3.]
];
// solving for a single right-hand side
let b: Array1<f64> = array![-10., 12., 14., 16., 18.];
let expected: Array1<f64> = array![2., 1., 1.];
let result = a.least_squares(&b).unwrap();
assert!(result.solution.abs_diff_eq(&expected, 1e-12));
// solving for two right-hand sides at once
let b_2: Array2<f64> =
array![[-10., -3.], [12., 14.], [14., 12.], [16., 16.], [18., 16.]];
let expected_2: Array2<f64> = array![[2., 1.], [1., 1.], [1., 2.]];
let result_2 = a.least_squares(&b_2).unwrap();
assert!(result_2.solution.abs_diff_eq(&expected_2, 1e-12));
// using `least_squares_in_place` which overwrites its arguments
let mut a_3 = a.clone();
let mut b_3 = b.clone();
let result_3 = a_3.least_squares_in_place(&mut b_3).unwrap();
// using `least_squares_into` which consumes its arguments
let result_4 = a.least_squares_into(b).unwrap();
// `a` and `b` have been moved, no longer valid
Structs§
- Result of a LeastSquares computation
Traits§
- Solve least squares for immutable references
- Solve least squares for mutable references, overwriting the input fields in the process
- Solve least squares for owned matrices