https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Standardizer.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#ifdef MOOSE_LIBTORCH_ENABLED
10
11#include "Standardizer.h"
12#include "DataIO.h"
13
14namespace StochasticTools
15{
16
17namespace
18{
19
20void
21checkInputCompatibility(const torch::Tensor & input, const torch::Tensor & reference)
22{
23 if (input.dim() != 2)
24 mooseError("Standardizer input must be a rank-2 tensor.");
25 if (reference.dim() != 1)
26 mooseError("Standardizer moments must be stored as feature vectors.");
27 if (input.size(1) != reference.size(0))
28 mooseError("Standardizer input dimension mismatch.");
29}
30
31torch::Tensor
32toStandardizerOptions(const torch::Tensor & tensor, const torch::TensorOptions & options)
33{
34 auto result = tensor.to(options.device());
35 if (result.scalar_type() != at::kDouble)
36 result = result.to(at::kDouble);
37 return result;
38}
39
40torch::Tensor
41asFeatureVector(const torch::Tensor & feature_vector, const torch::Tensor & input)
42{
43 return toStandardizerOptions(feature_vector, input.options().dtype(at::kDouble));
44}
45
46} // namespace
47
48void
49Standardizer::set(const Real & n)
50{
51 _mean = torch::zeros({long(n)}, at::kDouble);
52 _stdev = torch::ones({long(n)}, at::kDouble);
53}
54
55void
56Standardizer::set(const Real & mean, const Real & stdev)
57{
58 _mean = torch::full({1}, mean, at::kDouble);
59 _stdev = torch::full({1}, stdev, at::kDouble);
60}
61
62void
63Standardizer::set(const Real & mean, const Real & stdev, const Real & n)
64{
65 auto options = torch::TensorOptions().dtype(at::kDouble);
66 _mean = torch::full({long(n)}, mean, options);
67 _stdev = torch::full({long(n)}, stdev, options);
68}
69
70void
71Standardizer::set(const std::vector<Real> & mean, const std::vector<Real> & stdev)
72{
73 mooseAssert(mean.size() == stdev.size(),
74 "Provided mean and standard deviation vectors are of differing size.");
75 _mean = LibtorchUtils::vectorToTensorCopy(mean, {long(mean.size())});
76 _stdev = LibtorchUtils::vectorToTensorCopy(stdev, {long(stdev.size())});
77}
78
79void
80Standardizer::computeSet(const torch::Tensor & input)
81{
82 if (input.dim() != 2)
83 mooseError("Standardizer input must be a rank-2 tensor.");
84 // Compute mean and standard deviation
85 _mean = torch::mean(input, 0, false);
86 _stdev = torch::std(input, 0, 0, false);
87}
88
89void
90Standardizer::getStandardized(torch::Tensor & input) const
91{
92 checkInputCompatibility(input, _mean);
93 input.sub_(asFeatureVector(_mean, input)).div_(asFeatureVector(_stdev, input));
94}
95
96void
97Standardizer::getDestandardized(torch::Tensor & input) const
98{
99 checkInputCompatibility(input, _mean);
100 input.mul_(asFeatureVector(_stdev, input)).add_(asFeatureVector(_mean, input));
101}
102
103void
104Standardizer::getDescaled(torch::Tensor & input) const
105{
106 checkInputCompatibility(input, _stdev);
107 input.mul_(asFeatureVector(_stdev, input));
108}
109
110void
111Standardizer::getScaled(torch::Tensor & input) const
112{
113 checkInputCompatibility(input, _stdev);
114 input.div_(asFeatureVector(_stdev, input));
115}
116
118void
119Standardizer::dataStore(std::ostream & stream, void * context) const
120{
121 const auto mean = LibtorchUtils::toCPUContiguous(_mean);
122 const auto stdev = LibtorchUtils::toCPUContiguous(_stdev);
123 auto mean_accessor = mean.accessor<Real, 1>();
124 auto stdev_accessor = stdev.accessor<Real, 1>();
125 unsigned int n = mean.size(0);
126 ::dataStore(stream, n, context);
127 for (unsigned int ii = 0; ii < n; ++ii)
128 ::dataStore(stream, mean_accessor[ii], context);
129 for (unsigned int ii = 0; ii < n; ++ii)
130 ::dataStore(stream, stdev_accessor[ii], context);
131}
132
133} // StochasticTools namespace
134
135template <>
136void
137dataStore(std::ostream & stream, StochasticTools::Standardizer & standardizer, void * context)
138{
139 standardizer.dataStore(stream, context);
140}
141
142template <>
143void
144dataLoad(std::istream & stream, StochasticTools::Standardizer & standardizer, void * context)
145{
146 unsigned int n;
147 dataLoad(stream, n, context);
148 std::vector<Real> mean(n);
149 std::vector<Real> stdev(n);
150 for (unsigned int ii = 0; ii < n; ++ii)
151 dataLoad(stream, mean[ii], context);
152 for (unsigned int ii = 0; ii < n; ++ii)
153 dataLoad(stream, stdev[ii], context);
154 standardizer.set(mean, stdev);
155}
156
157#endif
void mooseError(Args &&... args)
void dataLoad(std::istream &stream, StochasticTools::Standardizer &standardizer, void *context)
void dataStore(std::ostream &stream, StochasticTools::Standardizer &standardizer, void *context)
Class for standardizing data (centering and scaling)
void set(const Real &n)
Methods for setting mean and standard deviation directly Sets mean=0, std=1 for n variables.
void getDescaled(torch::Tensor &input) const
De-scales the assumed scaled input.
void getDestandardized(torch::Tensor &input) const
De-standardizes (de-centered and de-scaled) the assumed standardized input.
void getStandardized(torch::Tensor &input) const
Returns the standardized (centered and scaled) of the provided input.
void getScaled(torch::Tensor &input) const
Scales the assumed de-scaled input.
void computeSet(const torch::Tensor &input)
Methods for computing and setting mean and standard deviation.
void dataStore(std::ostream &stream, void *context) const
Helper for dataStore.
torch::Tensor toCPUContiguous(const torch::Tensor &tensor)
torch::Tensor vectorToTensorCopy(const std::vector< DataType > &vector, c10::IntArrayRef sizes)
Enum for batch type in stochastic tools MultiApp.