1
1
use crate :: model:: SeparableModel ;
2
2
use levenberg_marquardt:: LeastSquaresProblem ;
3
3
use nalgebra:: storage:: Owned ;
4
- use nalgebra:: { ComplexField , DMatrix , DVector , Dynamic , Matrix , Scalar , Vector , SVD } ;
4
+ use nalgebra:: { ComplexField , DMatrix , DVector , Dyn , Matrix , Scalar , Vector , SVD } ;
5
5
6
6
mod builder;
7
7
#[ cfg( test) ]
@@ -21,7 +21,7 @@ struct CachedCalculations<ScalarType: Scalar + ComplexField> {
21
21
/// The current residual of model function values belonging to the current parameters
22
22
current_residuals : DVector < ScalarType > ,
23
23
/// Singular value decomposition of the current function value matrix
24
- current_svd : SVD < ScalarType , Dynamic , Dynamic > ,
24
+ current_svd : SVD < ScalarType , Dyn , Dyn > ,
25
25
/// the linear coefficients `$\vec{c}$` providing the current best fit
26
26
linear_coefficients : DVector < ScalarType > ,
27
27
}
@@ -80,22 +80,21 @@ impl<'a, ScalarType: Scalar + ComplexField + Copy> LevMarProblem<'a, ScalarType>
80
80
}
81
81
}
82
82
83
- impl < ' a , ScalarType > LeastSquaresProblem < ScalarType , Dynamic , Dynamic >
84
- for LevMarProblem < ' a , ScalarType >
83
+ impl < ' a , ScalarType > LeastSquaresProblem < ScalarType , Dyn , Dyn > for LevMarProblem < ' a , ScalarType >
85
84
where
86
85
ScalarType : Scalar + ComplexField + Copy ,
87
86
ScalarType :: RealField : Mul < ScalarType , Output = ScalarType > + Float ,
88
87
{
89
- type ResidualStorage = Owned < ScalarType , Dynamic > ;
90
- type JacobianStorage = Owned < ScalarType , Dynamic , Dynamic > ;
91
- type ParameterStorage = Owned < ScalarType , Dynamic > ;
88
+ type ResidualStorage = Owned < ScalarType , Dyn > ;
89
+ type JacobianStorage = Owned < ScalarType , Dyn , Dyn > ;
90
+ type ParameterStorage = Owned < ScalarType , Dyn > ;
92
91
93
92
#[ allow( non_snake_case) ]
94
93
/// Set the (nonlinear) model parameters `$\vec{\alpha}$` and update the internal state of the
95
94
/// problem accordingly. The parameters are expected in the same order that the parameter
96
95
/// names were provided in at model creation. So if we gave `&["tau","beta"]` as parameters at
97
96
/// model creation, the function expects the layout of the parameter vector to be `$\vec{\alpha}=(\tau,\beta)^T$`.
98
- fn set_params ( & mut self , params : & Vector < ScalarType , Dynamic , Self :: ParameterStorage > ) {
97
+ fn set_params ( & mut self , params : & Vector < ScalarType , Dyn , Self :: ParameterStorage > ) {
99
98
self . model_parameters = params. iter ( ) . cloned ( ) . collect ( ) ;
100
99
// matrix of weighted model function values
101
100
let Phi_w = self
@@ -135,7 +134,7 @@ where
135
134
/// names given on model creation. E.g. if the parameters at model creation where given as
136
135
/// `&["tau","beta"]`, then the returned vector is `$\vec{\alpha} = (\tau,\beta)^T$`, i.e.
137
136
/// the value of parameter `$\tau$` is at index `0` and the value of `$\beta$` at index `1`.
138
- fn params ( & self ) -> Vector < ScalarType , Dynamic , Self :: ParameterStorage > {
137
+ fn params ( & self ) -> Vector < ScalarType , Dyn , Self :: ParameterStorage > {
139
138
DVector :: from ( self . model_parameters . clone ( ) )
140
139
}
141
140
@@ -146,7 +145,7 @@ where
146
145
/// algorithm calculates `$\vec{c}(\vec{\alpha})$` as the coefficients that provide the best linear least squares
147
146
/// fit, given the current `$\vec{\alpha}$`. For more info on the math of VarPro, see
148
147
/// e.g. [here](https://geo-ant.github.io/blog/2020/variable-projection-part-1-fundamentals/).
149
- fn residuals ( & self ) -> Option < Vector < ScalarType , Dynamic , Self :: ResidualStorage > > {
148
+ fn residuals ( & self ) -> Option < Vector < ScalarType , Dyn , Self :: ResidualStorage > > {
150
149
self . cached
151
150
. as_ref ( )
152
151
. map ( |cached| cached. current_residuals . clone ( ) )
@@ -156,7 +155,7 @@ where
156
155
/// Calculate the Jacobian matrix of the *weighted* residuals `$\vec{r}_w(\vec{\alpha})$`.
157
156
/// For more info on how the Jacobian is calculated in the VarPro algorithm, see
158
157
/// e.g. [here](https://geo-ant.github.io/blog/2020/variable-projection-part-1-fundamentals/).
159
- fn jacobian ( & self ) -> Option < Matrix < ScalarType , Dynamic , Dynamic , Self :: JacobianStorage > > {
158
+ fn jacobian ( & self ) -> Option < Matrix < ScalarType , Dyn , Dyn , Self :: JacobianStorage > > {
160
159
// TODO (Performance): make this more efficient by parallelizing
161
160
162
161
if let Some ( CachedCalculations {
@@ -168,11 +167,8 @@ where
168
167
// this is not a great pattern, but the trait bounds on copy_from
169
168
// as of now prevent us from doing something more idiomatic
170
169
let mut jacobian_matrix = unsafe {
171
- DMatrix :: uninit (
172
- Dynamic :: new ( self . y_w . len ( ) ) ,
173
- Dynamic :: new ( self . model . parameter_count ( ) ) ,
174
- )
175
- . assume_init ( )
170
+ DMatrix :: uninit ( Dyn ( self . y_w . len ( ) ) , Dyn ( self . model . parameter_count ( ) ) )
171
+ . assume_init ( )
176
172
} ;
177
173
178
174
let U = current_svd. u . as_ref ( ) ?; // will return None if this was not calculated
0 commit comments