linearleastsquares.hpp
Go to the documentation of this file.
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
32
33#include <stdexcept>
34
35namespace Opm
36{
37
43template <class Scalar>
45{
46 using Matrix = Dune::DynamicMatrix<Scalar>;
47 using Vector = Dune::DynamicVector<Scalar>;
48
49public:
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
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
163private:
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:45
Scalar RSquared() const
Coefficient of determination.
Definition: linearleastsquares.hpp:153
Scalar evaluate(const Vector &x) const
Evaluate regression model at input x vector.
Definition: linearleastsquares.hpp:87
Scalar residualSumOfSquares() const
Measure of the discrepancy between data and regression model.
Definition: linearleastsquares.hpp:97
const Vector & x() const
Read-only vector of calculated coefficient vector.
Definition: linearleastsquares.hpp:76
Scalar explainedSumOfSquares() const
Value for how well regression model represents the model.
Definition: linearleastsquares.hpp:109
Scalar totalSumOfSquares() const
Sum of all squared differences.
Definition: linearleastsquares.hpp:131
void solve()
Solve linear least squares system.
Definition: linearleastsquares.hpp:66
LinearLeastSquares(const Matrix &A, const Vector &b)
Constructor.
Definition: linearleastsquares.hpp:56
static void multMatrixTransposed(const DenseMatrixA &A, const DenseMatrixB &B, DenseMatrixC &ret)
calculates ret = A^T * B
Definition: SmallDenseMatrixUtils.hpp:96
Definition: blackoilbioeffectsmodules.hh:45