svZeroDSolver
Loading...
Searching...
No Matches
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 */
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::Model source file
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
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 of 0D elements.
Definition Model.h:55