opm-simulators
linearleastsquares.hpp
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 
19  Consult the COPYING file in the top-level source directory of this
20  module for the precise wording of the license and the list of
21  copyright holders.
22 */
23 #ifndef LINEAR_LEAST_SQUARES_HPP
24 #define LINEAR_LEAST_SQUARES_HPP
25 
26 #include <dune/common/dynmatrix.hh>
27 #include <dune/common/dynvector.hh>
28 
29 #include <opm/common/ErrorMacros.hpp>
30 
31 #include <opm/simulators/linalg/SmallDenseMatrixUtils.hpp>
32 
33 #include <stdexcept>
34 
35 namespace Opm
36 {
37 
43 template <class Scalar>
45 {
46  using Matrix = Dune::DynamicMatrix<Scalar>;
47  using Vector = Dune::DynamicVector<Scalar>;
48 
49 public:
56  LinearLeastSquares(const Matrix& A, const Vector& b)
57  : A_(A), b_(b), x_(A.M())
58  {
59  }
60 
66  void solve()
67  {
68  solveNormalEquations_();
69  }
70 
76  const Vector& x() const
77  {
78  return x_;
79  }
80 
87  Scalar evaluate(const Vector& x) const
88  {
89  return x_ * x;
90  }
91 
97  Scalar residualSumOfSquares() const
98  {
99  Vector r(b_);
100  A_.mmv(x_, r);
101  return r.two_norm2();
102  }
103 
109  Scalar explainedSumOfSquares() const
110  {
111  Scalar ymean = 0.0;
112  const auto ndata = b_.N();
113  for (size_t i = 0; i < ndata; ++i) {
114  ymean += b_[i];
115  }
116  ymean /= ndata;
117 
118  Vector r(ndata, ymean);
119  A_.mmv(x_, r);
120 
121  return r.two_norm2();
122  }
123 
131  Scalar totalSumOfSquares() const
132  {
133  Scalar ymean = 0.0;
134  const auto ndata = b_.N();
135  for (size_t i = 0; i < ndata; ++i) {
136  ymean += b_[i];
137  }
138  ymean /= ndata;
139 
140  Vector r(ndata, ymean);
141  r -= b_;
142 
143  return r.two_norm2();
144  }
145 
153  Scalar RSquared() const
154  {
155  const auto tss = totalSumOfSquares();
156  if (tss < 1e-16) {
157  OPM_THROW(std::runtime_error,
158  "Total sum of squares is close to zero, hence R^2 is undefined!");
159  }
160  return explainedSumOfSquares() / tss;
161  }
162 
163 private:
167  void solveNormalEquations_()
168  {
169  // Right-hand side, bhat = A^T*b
170  Vector bhat(A_.M());
171  A_.mtv(b_, bhat);
172 
173  // Normal matrix Ahat = A^T*A
174  Matrix Ahat(A_.M(), A_.M());
175  detail::multMatrixTransposed(A_, A_, Ahat);
176 
177  // Solve normal equations x = Ahat^{-1}*bhat
178  Ahat.solve(x_, bhat, /*doPivoting=*/true);
179  }
180 
181  Matrix A_{};
182  Vector b_{};
183  Vector x_{};
184 };
185 
186 } // Opm
187 
188 #endif // LINEAR_LEAST_SQUARES_HPP
Linear least squares calculations and properties.
Definition: linearleastsquares.hpp:44
Scalar residualSumOfSquares() const
Measure of the discrepancy between data and regression model.
Definition: linearleastsquares.hpp:97
Scalar evaluate(const Vector &x) const
Evaluate regression model at input x vector.
Definition: linearleastsquares.hpp:87
Scalar explainedSumOfSquares() const
Value for how well regression model represents the model.
Definition: linearleastsquares.hpp:109
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Scalar RSquared() const
Coefficient of determination.
Definition: linearleastsquares.hpp:153
LinearLeastSquares(const Matrix &A, const Vector &b)
Constructor.
Definition: linearleastsquares.hpp:56
void solve()
Solve linear least squares system.
Definition: linearleastsquares.hpp:66
const Vector & x() const
Read-only vector of calculated coefficient vector.
Definition: linearleastsquares.hpp:76
Scalar totalSumOfSquares() const
Sum of all squared differences.
Definition: linearleastsquares.hpp:131