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