https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PolynomialRegressionTrainer.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
11#include "Sampler.h"
12
14
17{
19
20 params.addClassDescription("Computes coefficients for polynomial regession model.");
21
22 MooseEnum rtype("ols=0 ridge=1");
24 "regression_type", rtype, "The type of regression to perform.");
25 params.addRequiredParam<unsigned int>("max_degree",
26 "Maximum polynomial degree to use for the regression.");
27 params.addParam<Real>("penalty", 0.0, "Penalty for Ridge regularization.");
28
29 return params;
30}
31
33 : SurrogateTrainer(parameters), // SurrogateTrainer(parameters),
34 _predictor_row(getPredictorData()),
35 _regression_type(getParam<MooseEnum>("regression_type")),
36 _penalty(getParam<Real>("penalty")),
37 _coeff(declareModelData<std::vector<std::vector<Real>>>("_coeff")),
38 _max_degree(
39 declareModelData<unsigned int>("_max_degree", getParam<unsigned int>("max_degree"))),
40 _power_matrix(declareModelData<std::vector<std::vector<unsigned int>>>(
41 "_power_matrix",
42 StochasticTools::MultiDimPolynomialGenerator::generateTuple(_n_dims, _max_degree + 1))),
43 _n_poly_terms(_power_matrix.size()),
44 _matrix(_n_poly_terms, _n_poly_terms),
45 _rhs(1, DenseVector<Real>(_n_poly_terms, 0.0)),
46 _r_sum(1, 0.0)
47{
48 _coeff.resize(_n_poly_terms);
49
50 // Throwing a warning if the penalty parameter is set with OLS regression
51 if (_regression_type == "ols" && _penalty != 0)
52 mooseWarning("Penalty parameter is not used for OLS regression, found penalty=", _penalty);
53
54 // Check if we have enough data points to solve the problem
56 mooseError("Number of data points must be greater than the number of terms in the polynomial.");
57
58 // Creating calculators needed for feature standardization.
59 _calculators.resize(_n_poly_terms * 3);
60 for (const auto & term : make_range(_n_poly_terms))
61 {
63 _calculators[3 * term + 1] = StochasticTools::makeCalculator(MooseEnumItem("stddev"), *this);
64 _calculators[3 * term + 2] = StochasticTools::makeCalculator(MooseEnumItem("sum"), *this);
65 }
66}
67
68void
70{
71 _matrix.zero();
72 for (unsigned int r = 0; r < _rhs.size(); ++r)
73 _rhs[r].zero();
74
76 for (auto & calc : _calculators)
77 calc->initializeCalculator();
78
79 _r_sum.assign(_rhs.size(), 0.0);
80}
81
82void
84{
85 // Caching the different powers of data to accelerate the assembly of the
86 // system
87 DenseMatrix<Real> data_pow(_n_dims, _max_degree + 1);
88 for (unsigned int d = 0; d < _n_dims; ++d)
89 for (unsigned int i = 0; i <= _max_degree; ++i)
90 data_pow(d, i) = pow(_predictor_row[d], i);
91
92 // Emplace new values if necessary
93 if (_rvecval)
94 for (unsigned int r = _rhs.size(); r < _rvecval->size(); ++r)
95 {
96 _rhs.emplace_back(_n_poly_terms, 0.0);
97 _r_sum.emplace_back(0.0);
98 }
99
100 for (unsigned int i = 0; i < _n_poly_terms; ++i)
101 {
102 Real i_value(1.0);
103 for (unsigned int ii = 0; ii < _n_dims; ++ii)
104 i_value *= data_pow(ii, _power_matrix[i][ii]);
105
106 for (unsigned int j = 0; j < _n_poly_terms; ++j)
107 {
108 Real j_value(1.0);
109 for (unsigned int jj = 0; jj < _n_dims; ++jj)
110 j_value *= data_pow(jj, _power_matrix[j][jj]);
111
112 _matrix(i, j) += i_value * j_value;
113 }
114
115 // Update calculators.
116 for (unsigned int c = i * 3; c < (i + 1) * 3; ++c)
117 _calculators[c]->updateCalculator(i_value);
118
119 if (_rval)
120 _rhs[0](i) += i_value * (*_rval);
121 else if (_rvecval)
122 for (unsigned int r = 0; r < _rvecval->size(); ++r)
123 _rhs[r](i) += i_value * (*_rvecval)[r];
124 }
125
126 if (_rval)
127 _r_sum[0] += (*_rval);
128 else if (_rvecval)
129 for (unsigned int r = 0; r < _rvecval->size(); ++r)
130 _r_sum[r] += (*_rvecval)[r];
131
132 // Adding penalty term for Ridge regularization
133 if (_regression_type == "ridge")
134 for (unsigned int i = 0; i < _n_poly_terms; ++i)
135 _matrix(i, i) += _penalty;
136}
137
138void
140{
141 // Make sure _rhs are all the same size
142 unsigned int nrval = _rhs.size();
143 gatherMax(nrval);
144 for (unsigned int r = _rhs.size(); r < nrval; ++r)
145 {
146 _rhs.emplace_back(_n_poly_terms, 0.0);
147 _r_sum.emplace_back(0.0);
148 }
149
150 // Gather regression data
152 for (auto & it : _rhs)
153 gatherSum(it.get_values());
154
155 // Gather response sums.
157
158 // Finalize calculators.
159 for (auto & calc : _calculators)
160 calc->finalizeCalculator(true);
161
162 std::vector<Real> mu(_n_poly_terms);
163 std::vector<Real> sig(_n_poly_terms);
164 std::vector<Real> sum_pf(_n_poly_terms);
165
166 for (unsigned int i = 0; i < _n_poly_terms; ++i)
167 {
168 // To handle intercept, use mu = 0, sig = 1.
169 mu[i] = i > 0 ? _calculators[3 * i]->getValue() : 0.0;
170 sig[i] = i > 0 ? _calculators[3 * i + 1]->getValue() : 1.0;
171 sum_pf[i] = _calculators[3 * i + 2]->getValue();
172 }
173
174 // Transform _matrix and _rhs to match standardized features.
175 const Real n = sum_pf[0]; // Sum of intercept term = n.
176 for (unsigned int i = 0; i < _n_poly_terms; ++i)
177 {
178 for (unsigned int j = 0; j < _n_poly_terms; ++j)
179 {
180 _matrix(i, j) -= (mu[j] * sum_pf[i] + mu[i] * sum_pf[j]);
181 _matrix(i, j) += n * mu[i] * mu[j];
182 _matrix(i, j) /= (sig[i] * sig[j]);
183 }
184 for (unsigned int r = 0; r < _rhs.size(); ++r)
185 _rhs[r](i) = (_rhs[r](i) - mu[i] * _r_sum[r]) / sig[i];
186 }
187
188 DenseVector<Real> sol;
189
190 _coeff.resize(_rhs.size());
191 for (unsigned int r = 0; r < _rhs.size(); ++r)
192 {
193 _matrix.lu_solve(_rhs[r], sol);
194 _coeff[r] = sol.get_values();
195
196 // Transform coefficients to match unstandardized features.
197 for (unsigned int i = 1; i < _n_poly_terms; ++i)
198 {
199 _coeff[r][i] /= sig[i];
200 _coeff[r][0] -= _coeff[r][i] * mu[i];
201 }
202 }
203}
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
const double mu
registerMooseObject("StochasticToolsApp", PolynomialRegressionTrainer)
void ErrorVector unsigned int
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void mooseError(Args &&... args) const
void mooseWarning(Args &&... args) const
const unsigned int & _max_degree
Maximum polynomial degree, limiting the sum of constituent polynomial degrees.
std::vector< Real > _r_sum
Calculator used to sum response values.
const Real & _penalty
The penalty parameter for Ridge regularization.
std::vector< std::unique_ptr< RealCalculator > > _calculators
Calculators used in standardizing polynomial features.
const MooseEnum & _regression_type
Types for the polynomial regression.
const std::vector< std::vector< unsigned int > > & _power_matrix
Matirx co containing the touples of the powers for each term.
const unsigned int _n_poly_terms
Number of terms in the polynomial expression.
std::vector< std::vector< Real > > & _coeff
Coefficients of regression model.
std::vector< DenseVector< Real > > _rhs
PolynomialRegressionTrainer(const InputParameters &parameters)
const std::vector< Real > & _predictor_row
Data from the current predictor row.
dof_id_type getNumberOfRows() const
This is the main trainer base class.
const std::vector< Real > * _rvecval
Vector response value.
const Real * _rval
Response value.
static InputParameters validParams()
unsigned int _n_dims
Dimension of predictor data - either _sampler.getNumberOfCols() or _pvals.size() + _pcols....
void gatherSum(T &value)
void gatherMax(T &value)
std::vector< T > & get_values()
void resize(const unsigned int new_m, const unsigned int new_n)
void lu_solve(const DenseVector< T > &b, DenseVector< T > &x)
virtual void zero() override final
Enum for batch type in stochastic tools MultiApp.
std::unique_ptr< Calculator< InType, OutType > > makeCalculator(const MooseEnumItem &item, const libMesh::ParallelObject &other)