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 "ExponentialCovariance.h"
11 : #include <cmath>
12 :
13 : registerMooseObject("StochasticToolsApp", ExponentialCovariance);
14 :
15 : InputParameters
16 64 : ExponentialCovariance::validParams()
17 : {
18 64 : InputParameters params = CovarianceFunctionBase::validParams();
19 64 : params.addClassDescription("Exponential covariance function.");
20 128 : params.addRequiredParam<std::vector<Real>>("length_factor",
21 : "Length factors to use for Covariance Kernel");
22 128 : params.addRequiredParam<Real>("signal_variance",
23 : "Signal Variance ($\\sigma_f^2$) to use for kernel calculation.");
24 128 : params.addParam<Real>(
25 128 : "noise_variance", 0.0, "Noise Variance ($\\sigma_n^2$) to use for kernel calculation.");
26 128 : params.addRequiredParam<Real>("gamma", "Gamma to use for Exponential Covariance Kernel");
27 64 : return params;
28 0 : }
29 :
30 32 : ExponentialCovariance::ExponentialCovariance(const InputParameters & parameters)
31 : : CovarianceFunctionBase(parameters),
32 32 : _length_factor(addVectorRealHyperParameter(
33 : "length_factor", getParam<std::vector<Real>>("length_factor"), true)),
34 32 : _sigma_f_squared(
35 96 : addRealHyperParameter("signal_variance", getParam<Real>("signal_variance"), true)),
36 32 : _sigma_n_squared(
37 96 : addRealHyperParameter("noise_variance", getParam<Real>("noise_variance"), true)),
38 96 : _gamma(addRealHyperParameter("gamma", getParam<Real>("gamma"), false))
39 : {
40 32 : }
41 :
42 : void
43 20632 : ExponentialCovariance::computeCovarianceMatrix(RealEigenMatrix & K,
44 : const RealEigenMatrix & x,
45 : const RealEigenMatrix & xp,
46 : const bool is_self_covariance) const
47 : {
48 20632 : if ((unsigned)x.cols() != _length_factor.size())
49 0 : mooseError("length_factor size does not match dimension of trainer input.");
50 :
51 20632 : ExponentialFunction(
52 20632 : K, x, xp, _length_factor, _sigma_f_squared, _sigma_n_squared, _gamma, is_self_covariance);
53 20632 : }
54 :
55 : void
56 36632 : ExponentialCovariance::ExponentialFunction(RealEigenMatrix & K,
57 : const RealEigenMatrix & x,
58 : const RealEigenMatrix & xp,
59 : const std::vector<Real> & length_factor,
60 : const Real sigma_f_squared,
61 : const Real sigma_n_squared,
62 : const Real gamma,
63 : const bool is_self_covariance)
64 : {
65 36632 : unsigned int num_samples_x = x.rows();
66 36632 : unsigned int num_samples_xp = xp.rows();
67 36632 : unsigned int num_params_x = x.cols();
68 :
69 : mooseAssert(num_params_x == xp.cols(),
70 : "Number of parameters do not match in covariance kernel calculation");
71 :
72 714412 : for (unsigned int ii = 0; ii < num_samples_x; ++ii)
73 : {
74 13523080 : for (unsigned int jj = 0; jj < num_samples_xp; ++jj)
75 : {
76 : // Compute distance per parameter, scaled by length factor
77 : Real r_scaled = 0;
78 38535900 : for (unsigned int kk = 0; kk < num_params_x; ++kk)
79 25690600 : r_scaled += pow((x(ii, kk) - xp(jj, kk)) / length_factor[kk], 2);
80 12845300 : r_scaled = sqrt(r_scaled);
81 12845300 : K(ii, jj) = sigma_f_squared * std::exp(-pow(r_scaled, gamma));
82 : }
83 677780 : if (is_self_covariance)
84 322780 : K(ii, ii) += sigma_n_squared;
85 : }
86 36632 : }
87 :
88 : bool
89 48000 : ExponentialCovariance::computedKdhyper(RealEigenMatrix & dKdhp,
90 : const RealEigenMatrix & x,
91 : const std::string & hyper_param_name,
92 : unsigned int ind) const
93 : {
94 48000 : if (name().length() + 1 > hyper_param_name.length())
95 : return false;
96 :
97 48000 : const std::string name_without_prefix = hyper_param_name.substr(name().length() + 1);
98 :
99 48000 : if (name_without_prefix == "noise_variance")
100 : {
101 0 : ExponentialFunction(dKdhp, x, x, _length_factor, 0, 1, _gamma, true);
102 : return true;
103 : }
104 :
105 48000 : if (name_without_prefix == "signal_variance")
106 : {
107 16000 : ExponentialFunction(dKdhp, x, x, _length_factor, 1, 0, _gamma, false);
108 : return true;
109 : }
110 :
111 32000 : if (name_without_prefix == "length_factor")
112 : {
113 32000 : computedKdlf(dKdhp, x, _length_factor, _sigma_f_squared, _gamma, ind);
114 : return true;
115 : }
116 :
117 : return false;
118 : }
119 :
120 : void
121 32000 : ExponentialCovariance::computedKdlf(RealEigenMatrix & K,
122 : const RealEigenMatrix & x,
123 : const std::vector<Real> & length_factor,
124 : const Real sigma_f_squared,
125 : const Real gamma,
126 : const int ind)
127 : {
128 32000 : unsigned int num_samples_x = x.rows();
129 32000 : unsigned int num_params_x = x.cols();
130 :
131 : mooseAssert(ind < x.cols(), "Incorrect length factor index");
132 :
133 672000 : for (unsigned int ii = 0; ii < num_samples_x; ++ii)
134 : {
135 13440000 : for (unsigned int jj = 0; jj < num_samples_x; ++jj)
136 : {
137 : // Compute distance per parameter, scaled by length factor
138 : Real r_scaled = 0;
139 38400000 : for (unsigned int kk = 0; kk < num_params_x; ++kk)
140 25600000 : r_scaled += pow((x(ii, kk) - x(jj, kk)) / length_factor[kk], 2);
141 12800000 : r_scaled = sqrt(r_scaled);
142 12800000 : if (r_scaled != 0)
143 : {
144 12160000 : K(ii, jj) = gamma * std::pow(r_scaled, gamma - 2) * sigma_f_squared *
145 12160000 : std::exp(-pow(r_scaled, gamma));
146 12160000 : K(ii, jj) =
147 12160000 : std::pow(x(ii, ind) - x(jj, ind), 2) / std::pow(length_factor[ind], 3) * K(ii, jj);
148 : }
149 : else // avoid div by 0. 0/0=0 scenario.
150 640000 : K(ii, jj) = 0;
151 : }
152 : }
153 32000 : }
|