• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geo-ant / varpro / 10126064836

27 Jul 2024 08:02PM CUT coverage: 82.236%. Remained the same
10126064836

Pull #36

github

web-flow
Merge 14f457c27 into 70eb1d40c
Pull Request #36: Feature/bump version

824 of 1002 relevant lines covered (82.24%)

1268.26 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.21
/shared_test_code/src/lib.rs
1
#![warn(missing_docs)]
2
//! a helper crate which carries common code used by the benchtests and the
3
//! integration tests.
4
use std::ops::Range;
5

6
use nalgebra::{ComplexField, DVector, DefaultAllocator, Dyn, OMatrix, OVector, Scalar};
7
use num_traits::Float;
8
use rand::{Rng, SeedableRng};
9
use varpro::model::builder::SeparableModelBuilder;
10
use varpro::model::SeparableModel;
11
use varpro::prelude::SeparableNonlinearModel;
12

13
/// multiple right hand sides for for levenberg marquardt
14
pub mod levmar_mrhs;
15
/// contains models both for the levmar crate as well as the
16
/// varpro crate
17
pub mod models;
18

19
/// create holding `count` the elements from range [first,last] with linear spacing. (equivalent to matlabs linspace)
20
pub fn linspace<ScalarType: Float + Scalar>(
8✔
21
    first: ScalarType,
22
    last: ScalarType,
23
    count: usize,
24
) -> DVector<ScalarType> {
25
    let n_minus_one = ScalarType::from(count - 1).expect("Could not convert usize to Float");
8✔
26
    let lin: Vec<ScalarType> = (0..count)
8✔
27
        .map(|n| {
4,184✔
28
            first
4,176✔
29
                + (first - last) / (n_minus_one)
4,176✔
30
                    * ScalarType::from(n).expect("Could not convert usize to Float")
4,176✔
31
        })
32
        .collect();
33
    DVector::from(lin)
8✔
34
}
35

36
/// create a random matrix with coefficients in the given range
37
pub fn create_random_dmatrix(
×
38
    (rows, cols): (usize, usize),
39
    seed: u64,
40
    range: Range<f64>,
41
) -> nalgebra::DMatrix<f64> {
42
    let mut rng = rand::rngs::StdRng::seed_from_u64(seed);
×
43
    nalgebra::DMatrix::from_fn(rows, cols, move |_, _| rng.gen_range(range.clone()))
×
44
}
45

46
/// evaluete the vector valued function of a model by evaluating the model at the given location
47
/// `x` with (nonlinear) parameters `params` and by calculating the linear superposition of the basisfunctions
48
/// with the given linear coefficients `linear_coeffs`.
49
pub fn evaluate_complete_model_at_params<Model>(
4✔
50
    model: &'_ mut Model,
51
    params: OVector<Model::ScalarType, Dyn>,
52
    linear_coeffs: &OVector<Model::ScalarType, Dyn>,
53
) -> OVector<Model::ScalarType, Dyn>
54
where
55
    Model::ScalarType: Scalar + ComplexField,
56
    Model: SeparableNonlinearModel,
57
    DefaultAllocator: nalgebra::allocator::Allocator<Dyn, Dyn>,
58
    DefaultAllocator: nalgebra::allocator::Allocator<Dyn>,
59
{
60
    let original_params = model.params();
4✔
61
    model
4✔
62
        .set_params(params)
4✔
63
        .expect("Setting params must not fail");
64
    let eval = (&model
4✔
65
        .eval()
4✔
66
        .expect("Evaluating model must not produce error"))
4✔
67
        * linear_coeffs;
4✔
68
    model
4✔
69
        .set_params(original_params)
4✔
70
        .expect("Setting params must not fail");
71
    eval
4✔
72
}
73

74
/// evaluate the model for multiple right hand sides
75
pub fn evaluate_complete_model_at_params_mrhs<Model>(
×
76
    model: &'_ mut Model,
77
    params: OVector<Model::ScalarType, Dyn>,
78
    linear_coeffs: &OMatrix<Model::ScalarType, Dyn, Dyn>,
79
) -> OMatrix<Model::ScalarType, Dyn, Dyn>
80
where
81
    Model::ScalarType: Scalar + ComplexField,
82
    Model: SeparableNonlinearModel,
83
    DefaultAllocator: nalgebra::allocator::Allocator<Dyn, Dyn>,
84
    DefaultAllocator: nalgebra::allocator::Allocator<Dyn>,
85
{
86
    let original_params = model.params();
×
87
    model
×
88
        .set_params(params)
×
89
        .expect("Setting params must not fail");
90
    let eval = (&model
×
91
        .eval()
×
92
        .expect("Evaluating model must not produce error"))
×
93
        * linear_coeffs;
×
94
    model
×
95
        .set_params(original_params)
×
96
        .expect("Setting params must not fail");
97
    eval
×
98
}
99

100
/// exponential decay f(t,tau) = exp(-t/tau)
101
pub fn exp_decay<ScalarType: Float + Scalar>(
60✔
102
    tvec: &DVector<ScalarType>,
103
    tau: ScalarType,
104
) -> DVector<ScalarType> {
105
    tvec.map(|t| (-t / tau).exp())
61,560✔
106
}
107

108
/// derivative of exp decay with respect to tau
109
pub fn exp_decay_dtau<ScalarType: Scalar + Float>(
28✔
110
    tvec: &DVector<ScalarType>,
111
    tau: ScalarType,
112
) -> DVector<ScalarType> {
113
    tvec.map(|t| (-t / tau).exp() * t / (tau * tau))
28,728✔
114
}
115

116
/// A helper function that returns a double exponential decay model
117
/// f(x,tau1,tau2) = c1*exp(-x/tau1)+c2*exp(-x/tau2)+c3
118
/// Model parameters are: tau1, tau2
119
pub fn get_double_exponential_model_with_constant_offset(
3✔
120
    x: DVector<f64>,
121
    initial_params: Vec<f64>,
122
) -> SeparableModel<f64> {
123
    let ones = |t: &DVector<_>| DVector::from_element(t.len(), 1.);
33✔
124

125
    SeparableModelBuilder::new(&["tau1", "tau2"])
3✔
126
        .initial_parameters(initial_params)
3✔
127
        .function(&["tau1"], exp_decay)
3✔
128
        .partial_deriv("tau1", exp_decay_dtau)
3✔
129
        .function(&["tau2"], exp_decay)
3✔
130
        .partial_deriv("tau2", exp_decay_dtau)
3✔
131
        .invariant_function(ones)
3✔
132
        .independent_variable(x)
3✔
133
        .build()
134
        .expect("double exponential model builder should produce a valid model")
135
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc