Struct varpro::solvers::levmar::LevMarProblemBuilder

source ·
pub struct LevMarProblemBuilder<Model, const MRHS: bool>{ /* private fields */ }
Expand description

A builder structure to create a LevMarProblem, which can be used for fitting a separable model to data.

§Example

The following code shows how to create an unweighted least squares problem to fit the separable model $\vec{f}(\vec{x},\vec{\alpha},\vec{c})$ given by model to data $\vec{y}$ (given as y) using the independent variable $\vec{x}$ (given as x). Furthermore we need an initial guess params for the nonlinear model parameters $\vec{\alpha}$

  let problem = LevMarProblemBuilder::new(model)
                .observations(y)
                .build()
                .unwrap();

§Building a Model

A new builder is constructed with the new constructor. It must be filled with content using the methods described in the following. After all mandatory fields have been filled, the build method can be called. This returns a Result type that contains the finished model iff all mandatory fields have been set with valid values. Otherwise it contains an error variant.

§Multiple Right Hand Sides

We can also construct a problem with multiple right hand sides, using the mrhs constructor, see LevMarProblem for additional details.

Implementations§

source§

impl<Model> LevMarProblemBuilder<Model, false>

source

pub fn new(model: Model) -> Self

Create a new builder based on the given model for a problem with a single right hand side. This is the standard use case, where the data is a vector that is fitted by the model.

source

pub fn observations(self, observed: OVector<Model::ScalarType, Dyn>) -> Self

Mandatory: Set the data which we want to fit: since this is called on a model builder for problems with single right hand sides, this is a column vector $\vec{y}=\vec{y}(\vec{x})$ containing the values we want to fit with the model.

The length of $\vec{y} and the output dimension of the model must be the same.

source§

impl<Model> LevMarProblemBuilder<Model, true>

source

pub fn mrhs(model: Model) -> Self

Create a new builder based on the given model for a problem with multiple right hand sides and perform a global fit.

That means the observations are expected to be a matrix, where the columns correspond to the individual observations. The nonlinear parameters will be optimized across all the observations, but the linear coefficients are calculated for each observation individually. Hence, they also become a matrix where the columns correspond to the linear coefficients of the observation in the same column.

source

pub fn observations( self, observed: OMatrix<Model::ScalarType, Dyn, Dyn> ) -> Self

Mandatory: Set the data which we want to fit: This is either a single vector $\vec{y}=\vec{y}(\vec{x})$ or a matrix $\boldsymbol{Y}$ of multiple vectors. In the former case this corresponds to fitting a single right hand side, in the latter case, this corresponds to global fitting of a problem with multiple right hand sides. The length of $\vec{x}$ and the number of rows in the data must be the same.

source§

impl<Model, const MRHS: bool> LevMarProblemBuilder<Model, MRHS>

source

pub fn epsilon( self, eps: <Model::ScalarType as ComplexField>::RealField ) -> Self

Optional This value is relevant for the solver, because it uses singular value decomposition internally. This method sets a value \epsilon for which smaller (i.e. absolute - wise) singular values are considered zero. In essence this gives a truncation of the SVD. This might be helpful if two basis functions become linear dependent when the nonlinear model parameters align in an unfortunate way. In this case a higher epsilon might increase the robustness of the fitting process.

If this value is not given, it will be set to machine epsilon.

The given epsilon is automatically converted to a non-negative number.

source

pub fn weights(self, weights: OVector<Model::ScalarType, Dyn>) -> Self

Optional Add diagonal weights to the problem (meaning data points are statistically independent). If this is not given, the problem is unweighted, i.e. each data point has unit weight.

Note The weighted residual is calculated as $||W(\vec{y}-\vec{f}(\vec{\alpha})||^2$, so to make weights that have a statistical meaning, the diagonal elements of the weight matrix should be set to w_{jj} = 1/\sigma_j where $\sigma_j$ is the (estimated) standard deviation associated with data point $y_j$.

source

pub fn build(self) -> Result<LevMarProblem<Model, MRHS>, LevMarBuilderError>

build the least squares problem from the builder.

§Prerequisites
  • All mandatory parameters have been set (see individual builder methods for details)
  • $\vec{x}$ and $\vec{y}$ have the same number of elements
  • $\vec{x}$ and $\vec{y}$ have a nonzero number of elements
  • the length of the initial guesses vector is the same as the number of model parameters
§Returns

If all prerequisites are fulfilled, returns a LevMarProblem with the given content and the parameters set to the initial guess. Otherwise returns an error variant.

Trait Implementations§

source§

impl<Model, const MRHS: bool> Clone for LevMarProblemBuilder<Model, MRHS>

source§

fn clone(&self) -> LevMarProblemBuilder<Model, MRHS>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<Model, const MRHS: bool> Freeze for LevMarProblemBuilder<Model, MRHS>

§

impl<Model, const MRHS: bool> RefUnwindSafe for LevMarProblemBuilder<Model, MRHS>

§

impl<Model, const MRHS: bool> Send for LevMarProblemBuilder<Model, MRHS>

§

impl<Model, const MRHS: bool> Sync for LevMarProblemBuilder<Model, MRHS>

§

impl<Model, const MRHS: bool> Unpin for LevMarProblemBuilder<Model, MRHS>

§

impl<Model, const MRHS: bool> UnwindSafe for LevMarProblemBuilder<Model, MRHS>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.