svZeroDSolver
Toggle main menu visibility
Loading...
Searching...
No Matches
optimize
LevenbergMarquardtOptimizer.h
Go to the documentation of this file.
1
// SPDX-FileCopyrightText: Copyright (c) Stanford University, The Regents of the
2
// University of California, and others. SPDX-License-Identifier: BSD-3-Clause
3
/**
4
* @file LevenbergMarquardtOptimizer.h
5
* @brief opt::LevenbergMarquardtOptimizer source file
6
*/
7
#ifndef SVZERODSOLVER_OPTIMIZE_LEVENBERGMARQUARDT_HPP_
8
#define SVZERODSOLVER_OPTIMIZE_LEVENBERGMARQUARDT_HPP_
9
10
#include <Eigen/Dense>
11
#include <Eigen/Sparse>
12
13
#include "
Model.h
"
14
15
/**
16
* @brief Levenberg-Marquardt optimization class
17
*
18
* The 0D residual (assuming no time-dependency in parameters) is
19
*
20
* \f[
21
* \boldsymbol{r}(\boldsymbol{\alpha}, \boldsymbol{y}, \boldsymbol{\dot{y}}) =
22
* \boldsymbol{E}(\boldsymbol{\alpha}, \boldsymbol{y}) \cdot
23
* \dot{\boldsymbol{y}}+\boldsymbol{F}(\boldsymbol{\alpha}, \boldsymbol{y})
24
* \cdot \boldsymbol{y}+\boldsymbol{c}(\boldsymbol{\alpha}, \boldsymbol{y}) \f]
25
*
26
* with solution vector \f$\boldsymbol{y} \in \mathbb{R}^{N}\f$ (flow and
27
* pressure at nodes), LPN parameters \f$\boldsymbol{\alpha} \in
28
* \mathbb{R}^{P}\f$, system matrices \f$\boldsymbol{E},\boldsymbol{F} \in
29
* \mathbb{R}^{NxN}\f$, and system vector \f$\boldsymbol{c} \in
30
* \mathbb{R}^{N}\f$.
31
*
32
* The least squares problem can be formulated as
33
*
34
* \f[
35
* \min _\alpha S, \quad \mathrm { with } \quad S=\sum_i^D
36
* r_i^2\left(\boldsymbol{\alpha}, y_i, \dot{y}_i\right) \f]
37
*
38
* with given solution vectors \f$\boldsymbol{y}\f$, \f$\boldsymbol{\dot{y}}\f$
39
* at all datapoints \f$D\f$. The parameter vector is iteratively improved
40
* according to
41
*
42
* \f[
43
* \boldsymbol{\alpha}^{i+1}=\boldsymbol{\alpha}^{i}+\Delta
44
* \boldsymbol{\alpha}^{i+1} \f]
45
*
46
* wherein the increment \f$\Delta \boldsymbol{\alpha}^{i+1} \f$ is determined
47
* by solving the following system:
48
*
49
* \f[
50
* \left[\mathbf{J}^{\mathrm{T}} \mathbf{J}+\lambda
51
* \operatorname{diag}\left(\mathbf{J}^{\mathrm{T}} \mathbf{J}\right)\right]^{i}
52
* \cdot \Delta \boldsymbol{\alpha}^{i+1}=-\left[\mathbf{J}^{\mathrm{T}}
53
* \mathbf{r}\right]^{i}, \quad \lambda^{i}=\lambda^{i-1}
54
* \cdot\left\|\left[\mathbf{J}^{\mathrm{T}} \mathbf{r}\right]^{i}\right\|_2
55
* /\left\|\left[\mathbf{J}^{\mathrm{T}} \mathbf{r}\right]^{i-1}\right\|_2. \f]
56
*
57
* The algorithm terminates when the following tolerance thresholds are reached
58
*
59
* \f[
60
* \left\|\left[\mathbf{J}^{\mathrm{T}}
61
* \mathbf{r}\right]^{\mathrm{i}}\right\|_2<\operatorname{tol}_{\text {grad
62
* }}^\alpha \text { and }\left\|\Delta
63
* \boldsymbol{\alpha}^{\mathrm{i}+1}\right\|_2<\mathrm{tol}_{\text {inc
64
* }}^\alpha, \f]
65
*
66
* The Jacobian is derived from the residual as
67
*
68
* \f[
69
* J = \frac{\partial \boldsymbol{r}}{\partial \boldsymbol{\alpha}} =
70
* \frac{\partial \mathbf{E}}{\partial \boldsymbol{\alpha}} \cdot
71
* \dot{\mathbf{y}}+\frac{\partial \mathbf{F}}{\partial \boldsymbol{\alpha}}
72
* \cdot \mathbf{y}+\frac{\partial \mathbf{c}}{\partial \boldsymbol{\alpha}} \f]
73
*
74
*
75
*/
76
class
LevenbergMarquardtOptimizer
{
77
public
:
78
/**
79
* @brief Construct a new LevenbergMarquardtOptimizer object
80
*
81
* @param model The 0D model
82
* @param num_obs Number of observations in optimization
83
* @param num_params Total number of parameters in alpha
84
* @param active_param_ids Indices into alpha of parameters that should be
85
* optimized. Parameters not listed are held constant at their initial value.
86
* @param lambda0 Initial damping factor
87
* @param tol_grad Gradient tolerance
88
* @param tol_inc Parameter increment tolerance
89
* @param max_iter Maximum iterations
90
*/
91
LevenbergMarquardtOptimizer
(
Model
* model,
int
num_obs,
int
num_params,
92
const
std::vector<int>& active_param_ids,
93
double
lambda0,
double
tol_grad,
double
tol_inc,
94
int
max_iter);
95
96
/**
97
* @brief Run the optimization algorithm
98
*
99
* @param alpha Initial parameter vector alpha
100
* @param y_obs Matrix (num_obs x n) with all observations for y
101
* @param dy_obs Matrix (num_obs x n) with all observations for dy
102
* @return Eigen::Matrix<double, Eigen::Dynamic, 1> Optimized parameter vector
103
* alpha
104
*/
105
Eigen::Matrix<double, Eigen::Dynamic, 1>
run
(
106
Eigen::Matrix<double, Eigen::Dynamic, 1> alpha,
107
std::vector<std::vector<double>>& y_obs,
108
std::vector<std::vector<double>>& dy_obs);
109
110
private
:
111
Eigen::SparseMatrix<double> jacobian;
112
Eigen::Matrix<double, Eigen::Dynamic, 1> residual;
113
Eigen::Matrix<double, Eigen::Dynamic, 1> delta;
114
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> mat;
115
Eigen::Matrix<double, Eigen::Dynamic, 1> vec;
116
std::vector<int> active_param_ids;
117
Model
* model;
118
double
lambda;
119
120
int
num_obs;
121
int
num_params;
122
int
num_active;
123
int
num_eqns;
124
int
num_vars;
125
int
num_dpoints;
126
127
double
tol_grad;
128
double
tol_inc;
129
int
max_iter;
130
131
void
update_gradient(Eigen::Matrix<double, Eigen::Dynamic, 1>& alpha,
132
std::vector<std::vector<double>>& y_obs,
133
std::vector<std::vector<double>>& dy_obs);
134
135
void
update_delta(
bool
first_step);
136
};
137
138
#endif
// SVZERODSOLVER_OPTIMIZE_LEVENBERGMARQUARDT_HPP_
Model.h
model::Model source file
LevenbergMarquardtOptimizer::LevenbergMarquardtOptimizer
LevenbergMarquardtOptimizer(Model *model, int num_obs, int num_params, const std::vector< int > &active_param_ids, double lambda0, double tol_grad, double tol_inc, int max_iter)
Construct a new LevenbergMarquardtOptimizer object.
Definition
LevenbergMarquardtOptimizer.cpp:7
LevenbergMarquardtOptimizer::run
Eigen::Matrix< double, Eigen::Dynamic, 1 > run(Eigen::Matrix< double, Eigen::Dynamic, 1 > alpha, std::vector< std::vector< double > > &y_obs, std::vector< std::vector< double > > &dy_obs)
Run the optimization algorithm.
Definition
LevenbergMarquardtOptimizer.cpp:31
Model
Model of 0D elements.
Definition
Model.h:55
Generated by
1.17.0