Line data Source code
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 :
10 : #include "SquaredExponentialCovariance.h"
11 : #include <cmath>
12 :
13 : registerMooseObject("StochasticToolsApp", SquaredExponentialCovariance);
14 :
15 : InputParameters
16 620 : SquaredExponentialCovariance::validParams()
17 : {
18 620 : InputParameters params = CovarianceFunctionBase::validParams();
19 620 : params.addClassDescription("Squared Exponential covariance function.");
20 1240 : params.addRequiredParam<std::vector<Real>>("length_factor",
21 : "Length factors to use for Covariance Kernel");
22 1240 : params.addRequiredParam<Real>("signal_variance",
23 : "Signal Variance ($\\sigma_f^2$) to use for kernel calculation.");
24 1240 : params.addParam<Real>(
25 1240 : "noise_variance", 0.0, "Noise Variance ($\\sigma_n^2$) to use for kernel calculation.");
26 620 : return params;
27 0 : }
28 :
29 310 : SquaredExponentialCovariance::SquaredExponentialCovariance(const InputParameters & parameters)
30 : : CovarianceFunctionBase(parameters),
31 310 : _length_factor(addVectorRealHyperParameter(
32 : "length_factor", getParam<std::vector<Real>>("length_factor"), true)),
33 310 : _sigma_f_squared(
34 930 : addRealHyperParameter("signal_variance", getParam<Real>("signal_variance"), true)),
35 310 : _sigma_n_squared(
36 1240 : addRealHyperParameter("noise_variance", getParam<Real>("noise_variance"), true))
37 : {
38 310 : }
39 :
40 : void
41 1234870 : SquaredExponentialCovariance::computeCovarianceMatrix(RealEigenMatrix & K,
42 : const RealEigenMatrix & x,
43 : const RealEigenMatrix & xp,
44 : const bool is_self_covariance) const
45 : {
46 1234870 : if ((unsigned)x.cols() != _length_factor.size())
47 0 : mooseError("length_factor size does not match dimension of trainer input.");
48 :
49 1234870 : SquaredExponentialFunction(
50 1234870 : K, x, xp, _length_factor, _sigma_f_squared, _sigma_n_squared, is_self_covariance);
51 1234870 : }
52 :
53 : void
54 2184870 : SquaredExponentialCovariance::SquaredExponentialFunction(RealEigenMatrix & K,
55 : const RealEigenMatrix & x,
56 : const RealEigenMatrix & xp,
57 : const std::vector<Real> & length_factor,
58 : const Real sigma_f_squared,
59 : const Real sigma_n_squared,
60 : const bool is_self_covariance)
61 : {
62 2184870 : unsigned int num_samples_x = x.rows();
63 2184870 : unsigned int num_samples_xp = xp.rows();
64 2184870 : unsigned int num_params_x = x.cols();
65 :
66 : mooseAssert(num_params_x == xp.cols(),
67 : "Number of parameters do not match in covariance kernel calculation");
68 :
69 36731410 : for (unsigned int ii = 0; ii < num_samples_x; ++ii)
70 : {
71 741965692 : for (unsigned int jj = 0; jj < num_samples_xp; ++jj)
72 : {
73 : // Compute distance per parameter, scaled by length factor
74 : Real r_squared_scaled = 0;
75 2374959114 : for (unsigned int kk = 0; kk < num_params_x; ++kk)
76 1667539962 : r_squared_scaled += std::pow((x(ii, kk) - xp(jj, kk)) / length_factor[kk], 2);
77 707419152 : K(ii, jj) = sigma_f_squared * std::exp(-r_squared_scaled / 2.0);
78 : }
79 34546540 : if (is_self_covariance)
80 15058522 : K(ii, ii) += sigma_n_squared;
81 : }
82 2184870 : }
83 :
84 : bool
85 3304000 : SquaredExponentialCovariance::computedKdhyper(RealEigenMatrix & dKdhp,
86 : const RealEigenMatrix & x,
87 : const std::string & hyper_param_name,
88 : unsigned int ind) const
89 : {
90 3304000 : if (name().length() + 1 > hyper_param_name.length())
91 : return false;
92 :
93 3304000 : const std::string name_without_prefix = hyper_param_name.substr(name().length() + 1);
94 :
95 3304000 : if (name_without_prefix == "noise_variance")
96 : {
97 0 : SquaredExponentialFunction(dKdhp, x, x, _length_factor, 0, 1, true);
98 : return true;
99 : }
100 :
101 3304000 : if (name_without_prefix == "signal_variance")
102 : {
103 950000 : SquaredExponentialFunction(dKdhp, x, x, _length_factor, 1, 0, false);
104 : return true;
105 : }
106 :
107 2354000 : if (name_without_prefix == "length_factor")
108 : {
109 2354000 : computedKdlf(dKdhp, x, _length_factor, _sigma_f_squared, ind);
110 : return true;
111 : }
112 :
113 : return false;
114 : }
115 :
116 : void
117 2354000 : SquaredExponentialCovariance::computedKdlf(RealEigenMatrix & K,
118 : const RealEigenMatrix & x,
119 : const std::vector<Real> & length_factor,
120 : const Real sigma_f_squared,
121 : const int ind)
122 : {
123 2354000 : unsigned int num_samples_x = x.rows();
124 2354000 : unsigned int num_params_x = x.cols();
125 :
126 : mooseAssert(ind < x.cols(), "Incorrect length factor index");
127 :
128 38508000 : for (unsigned int ii = 0; ii < num_samples_x; ++ii)
129 : {
130 858064000 : for (unsigned int jj = 0; jj < num_samples_x; ++jj)
131 : {
132 : // Compute distance per parameter, scaled by length factor
133 : Real r_squared_scaled = 0;
134 2856216000 : for (unsigned int kk = 0; kk < num_params_x; ++kk)
135 2034306000 : r_squared_scaled += std::pow((x(ii, kk) - x(jj, kk)) / length_factor[kk], 2);
136 821910000 : K(ii, jj) = sigma_f_squared * std::exp(-r_squared_scaled / 2.0);
137 821910000 : K(ii, jj) =
138 821910000 : std::pow(x(ii, ind) - x(jj, ind), 2) / std::pow(length_factor[ind], 3) * K(ii, jj);
139 : }
140 : }
141 2354000 : }
|