https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Calculators.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
10#include "Calculators.h"
11
12namespace StochasticTools
13{
14
17{
18 return MultiMooseEnum(
19 "min=0 max=1 sum=2 mean=3 stddev=4 norm2=5 ratio=6 stderr=7 median=8 meanabs=9");
20}
21
22// MEAN ////////////////////////////////////////////////////////////////////////////////////////////
23template <typename InType, typename OutType>
24void
26{
27 _count = 0;
28 _sum = OutType();
29}
30
31template <typename InType, typename OutType>
32void
33Mean<InType, OutType>::update(const typename InType::value_type & val)
34{
35 _count++;
36 _sum += static_cast<OutType>(val);
37}
38
39template <typename InType, typename OutType>
40void
42{
43 if (is_distributed)
44 {
45 this->_communicator.sum(_count);
46 this->_communicator.sum(_sum);
47 }
48 if (_count > 0)
49 _sum /= static_cast<OutType>(_count);
50}
51
52// MEAN ABS ////////////////////////////////////////////////////////////////////////////////////////
53template <typename InType, typename OutType>
54void
55MeanAbsoluteValue<InType, OutType>::update(const typename InType::value_type & val)
56{
57 Mean<InType, OutType>::update(std::abs(val));
58}
59
60// SUM /////////////////////////////////////////////////////////////////////////////////////////////
61template <typename InType, typename OutType>
62void
64{
65 if (is_distributed)
66 this->_communicator.sum(this->_sum);
67}
68
69// STDDEV //////////////////////////////////////////////////////////////////////////////////////////
70template <typename InType, typename OutType>
71void
73{
74 _count = 0;
75 _sum = OutType();
76 _sum_of_square = OutType();
77}
78
79template <typename InType, typename OutType>
80void
81StdDev<InType, OutType>::update(const typename InType::value_type & val)
82{
83 _count++;
84 _sum += static_cast<OutType>(val);
85 _sum_of_square += MathUtils::pow(static_cast<OutType>(val), 2);
86}
87
88template <typename InType, typename OutType>
89void
91{
92 if (is_distributed)
93 {
94 this->_communicator.sum(_count);
95 this->_communicator.sum(_sum);
96 this->_communicator.sum(_sum_of_square);
97 }
98
99 if (_count <= 1)
100 _sum_of_square = 0;
101 else
102 _sum_of_square = std::sqrt(std::abs(_sum_of_square - _sum * _sum / _count) / (_count - 1));
103}
104
105// STDERR //////////////////////////////////////////////////////////////////////////////////////////
106template <typename InType, typename OutType>
107void
109{
110 StdDev<InType, OutType>::finalize(is_distributed);
111 this->_sum_of_square /= std::sqrt(this->_count);
112}
113
114// RATIO ///////////////////////////////////////////////////////////////////////////////////////////
115template <typename InType, typename OutType>
116void
118{
119 _min = std::numeric_limits<OutType>::max();
120 _max = std::numeric_limits<OutType>::min();
121}
122
123template <typename InType, typename OutType>
124void
125Ratio<InType, OutType>::update(const typename InType::value_type & val)
126{
127 if (_min > val)
128 _min = static_cast<OutType>(val);
129 if (_max < val)
130 _max = static_cast<OutType>(val);
131}
132
133template <typename InType, typename OutType>
134void
136{
137 if (is_distributed)
138 {
139 this->_communicator.min(_min);
140 this->_communicator.max(_max);
141 }
142}
143
144// L2NORM //////////////////////////////////////////////////////////////////////////////////////////
145template <typename InType, typename OutType>
146void
148{
149 _l2_norm = OutType();
150}
151
152template <typename InType, typename OutType>
153void
154L2Norm<InType, OutType>::update(const typename InType::value_type & val)
155{
156 _l2_norm += MathUtils::pow(static_cast<OutType>(val), 2);
157}
158
159template <typename InType, typename OutType>
160void
162{
163 if (is_distributed)
164 this->_communicator.sum(_l2_norm);
165 _l2_norm = std::sqrt(_l2_norm);
166}
167
168// MEDIAN //////////////////////////////////////////////////////////////////////////////////////////
169template <typename InType, typename OutType>
170void
172{
173 _storage.clear();
174}
175
176template <typename InType, typename OutType>
177void
178Median<InType, OutType>::update(const typename InType::value_type & val)
179{
180 _storage.push_back(static_cast<OutType>(val));
181}
182
183template <typename InType, typename OutType>
184void
186{
187 // Make sure we aren't doing anything silly like taking the median of an empty vector
188 _median = OutType();
189 auto count = _storage.size();
190 if (is_distributed)
191 this->_communicator.sum(count);
192 if (count == 0)
193 return;
194
195 if (!is_distributed || this->n_processors() == 1)
196 {
197 std::sort(_storage.begin(), _storage.end());
198 if (count % 2)
199 _median = _storage[count / 2];
200 else
201 _median += (_storage[count / 2] + _storage[count / 2 - 1]) / 2;
202 return;
203 }
204
205 dof_id_type kgt = count % 2 ? (count / 2) : (count / 2 - 1);
206 dof_id_type klt = kgt;
207 while (true)
208 {
209 // Gather all sizes and figure out current number of values
210 std::vector<std::size_t> sz = {_storage.size()};
211 this->_communicator.allgather(sz);
212 dof_id_type n = std::accumulate(sz.begin(), sz.end(), 0);
213
214 // Choose the first value for the first processor with values
215 for (const auto & i : index_range(sz))
216 if (sz[i])
217 {
218 if (this->processor_id() == i)
219 _median = _storage[0];
220 this->_communicator.broadcast(_median, i);
221 break;
222 }
223
224 // Count number of values greater than, less than, and equal to _median
225 std::vector<dof_id_type> m(3, 0);
226 for (const auto & val : _storage)
227 {
228 if (_median < val)
229 m[0]++;
230 else if (val < _median)
231 m[1]++;
232 }
233 this->_communicator.sum(m);
234 m[2] = n - m[0] - m[1];
235
236 // Remove greater than equal to
237 if ((m[0] + m[2]) <= kgt)
238 {
239 _storage.erase(std::remove_if(_storage.begin(),
240 _storage.end(),
241 [this](const OutType & val) { return val >= _median; }),
242 _storage.end());
243 kgt -= m[0] + m[2];
244 }
245 // Remove less than equal to
246 else if ((m[1] + m[2]) <= klt)
247 {
248 _storage.erase(std::remove_if(_storage.begin(),
249 _storage.end(),
250 [this](const OutType & val) { return val <= _median; }),
251 _storage.end());
252 klt -= m[1] + m[2];
253 }
254 // If the number of points is odd, then we've found it
255 else if (count % 2)
256 break;
257 // Get average of the two middle numbers
258 else
259 {
260 OutType num2;
261 // Find the next greater than
262 if (m[0] > kgt)
263 {
264 num2 = std::numeric_limits<OutType>::max();
265 for (const auto & val : _storage)
266 if (_median < val && val < num2)
267 num2 = val;
268 this->_communicator.min(num2);
269 }
270 // Find the next less than
271 else if (m[1] > klt)
272 {
273 num2 = std::numeric_limits<OutType>::min();
274 for (const auto & val : _storage)
275 if (val < _median && num2 < val)
276 num2 += val;
277 this->_communicator.max(num2);
278 }
279 // Otherwise we know the other number is equal
280 else
281 num2 = _median;
282
283 _median = (_median + num2) / 2;
284 break;
285 }
286 }
287}
288
289// CalculatorBuilder
290// //////////////////////////////////////////////////////////////////////////////////
291template <typename InType, typename OutType>
292std::unique_ptr<Calculator<InType, OutType>>
294 const libMesh::ParallelObject & other)
295{
296 if (item == "min")
297 return std::make_unique<Min<InType, OutType>>(other, item);
298
299 else if (item == "max")
300 return std::make_unique<Max<InType, OutType>>(other, item);
301
302 else if (item == "sum")
303 return std::make_unique<Sum<InType, OutType>>(other, item);
304
305 else if (item == "mean" || item == "average") // average is deprecated
306 return std::make_unique<Mean<InType, OutType>>(other, item);
307
308 else if (item == "stddev")
309 return std::make_unique<StdDev<InType, OutType>>(other, item);
310
311 else if (item == "stderr")
312 return std::make_unique<StdErr<InType, OutType>>(other, item);
313
314 else if (item == "norm2")
315 return std::make_unique<L2Norm<InType, OutType>>(other, item);
316
317 else if (item == "ratio")
318 return std::make_unique<Ratio<InType, OutType>>(other, item);
319
320 else if (item == "median")
321 return std::make_unique<Median<InType, OutType>>(other, item);
322
323 else if (item == "meanabs")
324 return std::make_unique<MeanAbsoluteValue<InType, OutType>>(other, item);
325
326 ::mooseError("Failed to create Statistics::Calculator object for ", item);
327 return nullptr;
328}
329
330#define createCalculators(InType, OutType) \
331 template class Mean<InType, OutType>; \
332 template class Max<InType, OutType>; \
333 template class Min<InType, OutType>; \
334 template class Sum<InType, OutType>; \
335 template class StdDev<InType, OutType>; \
336 template class StdErr<InType, OutType>; \
337 template class Ratio<InType, OutType>; \
338 template class L2Norm<InType, OutType>; \
339 template class Median<InType, OutType>; \
340 template struct CalculatorBuilder<InType, OutType>
341
342createCalculators(std::vector<Real>, Real);
343createCalculators(std::vector<int>, Real);
344
345} // StocasticTools namespace
unsigned int count
virtual void update(const typename InType::value_type &val) override
Updating the calculator with a piece of data.
virtual void finalize(bool is_distributed) override
This is used to compute the resulting calculator value by performing necessary arithmetic and paralle...
virtual void initialize() override
This function is used to reset the calculator to its initial state and prepare it for another evaluat...
virtual void update(const typename InType::value_type &val) override
Updating the calculator with a piece of data.
Definition Calculators.C:55
virtual void initialize() override
This function is used to reset the calculator to its initial state and prepare it for another evaluat...
Definition Calculators.C:25
virtual void update(const typename InType::value_type &val) override
Updating the calculator with a piece of data.
Definition Calculators.C:33
virtual void finalize(bool is_distributed) override
This is used to compute the resulting calculator value by performing necessary arithmetic and paralle...
Definition Calculators.C:41
virtual void finalize(bool is_distributed) override
This is used to compute the resulting calculator value by performing necessary arithmetic and paralle...
virtual void update(const typename InType::value_type &val) override
Updating the calculator with a piece of data.
virtual void initialize() override
This function is used to reset the calculator to its initial state and prepare it for another evaluat...
virtual void update(const typename InType::value_type &val) override
Updating the calculator with a piece of data.
virtual void initialize() override
This function is used to reset the calculator to its initial state and prepare it for another evaluat...
virtual void finalize(bool is_distributed) override
This is used to compute the resulting calculator value by performing necessary arithmetic and paralle...
virtual void update(const typename InType::value_type &val) override
Updating the calculator with a piece of data.
Definition Calculators.C:81
virtual void initialize() override
This function is used to reset the calculator to its initial state and prepare it for another evaluat...
Definition Calculators.C:72
virtual void finalize(bool is_distributed) override
This is used to compute the resulting calculator value by performing necessary arithmetic and paralle...
Definition Calculators.C:90
virtual void finalize(bool is_distributed) override
This is used to compute the resulting calculator value by performing necessary arithmetic and paralle...
virtual void finalize(bool is_distributed) override
This is used to compute the resulting calculator value by performing necessary arithmetic and paralle...
Definition Calculators.C:63
T pow(T x, int e)
Enum for batch type in stochastic tools MultiApp.
createCalculators(std::vector< Real >, Real)
MultiMooseEnum makeCalculatorEnum()
Definition Calculators.C:16
static std::unique_ptr< Calculator< InType, OutType > > build(const MooseEnumItem &item, const libMesh::ParallelObject &other)