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 : #pragma once
11 :
12 : #include "Calculators.h"
13 : #include "NormalDistribution.h"
14 : #include "StochasticToolsUtils.h"
15 :
16 : #include "Shuffle.h"
17 : #include "MooseTypes.h"
18 : #include "MooseObject.h"
19 : #include "MooseEnum.h"
20 : #include "MooseError.h"
21 : #include "MooseRandom.h"
22 :
23 : #include "libmesh/parallel.h"
24 : #include "libmesh/parallel_sync.h"
25 :
26 : #include <memory>
27 : #include <vector>
28 :
29 : class MooseEnum;
30 : class MooseEnumItem;
31 : class MooseRandom;
32 :
33 : namespace StochasticTools
34 : {
35 : template <typename InType, typename OutType>
36 : class Calculator;
37 :
38 : /*
39 : * Return available bootstrap statistics calculators.
40 : */
41 : MooseEnum makeBootstrapCalculatorEnum();
42 :
43 : /**
44 : * Base class for computing bootstrap confidence level intervals. These classes follow the same
45 : * design pattern as those Statistics.h.
46 : * @param other ParallelObject that is providing the Communicator
47 : * @param levels The bootstrap confidence level intervals to compute in range (0, 1)
48 : * @param replicates Number of bootstrap replicates to perform
49 : * @param seed Seed for random number generator
50 : */
51 : template <typename InType, typename OutType>
52 : class BootstrapCalculator : public libMesh::ParallelObject
53 : {
54 : public:
55 : BootstrapCalculator(const libMesh::ParallelObject & other,
56 : const std::string & name,
57 : const std::vector<Real> & levels,
58 : unsigned int replicates,
59 : unsigned int seed,
60 : StochasticTools::Calculator<InType, OutType> & calc);
61 : virtual std::vector<OutType> compute(const InType &, const bool) = 0;
62 : const std::string & name() const { return _name; }
63 :
64 : protected:
65 : // Compute Bootstrap estimates of a statistic
66 : std::vector<OutType> computeBootstrapEstimates(const InType &, const bool);
67 :
68 : // Confidence levels to compute in range (0, 1)
69 : const std::vector<Real> _levels;
70 :
71 : // Number of bootstrap replicates
72 : const unsigned int _replicates;
73 :
74 : // Random seed for creating bootstrap replicates
75 : const unsigned int _seed;
76 :
77 : // The Calculator that computes the statistic of interest
78 : StochasticTools::Calculator<InType, OutType> & _calc;
79 :
80 : private:
81 : const std::string _name;
82 : };
83 :
84 : /*
85 : * Implement percentile method of Efron and Tibshirani (2003), Chapter 13.
86 : */
87 : template <typename InType, typename OutType>
88 : class Percentile : public BootstrapCalculator<InType, OutType>
89 : {
90 : public:
91 1028 : using BootstrapCalculator<InType, OutType>::BootstrapCalculator;
92 : virtual std::vector<OutType> compute(const InType &, const bool) override;
93 : };
94 :
95 : /*
96 : * Implement BCa method of Efron and Tibshirani (2003), Chapter 14.
97 : */
98 : template <typename InType, typename OutType>
99 : class BiasCorrectedAccelerated : public BootstrapCalculator<InType, OutType>
100 : {
101 : public:
102 61 : using BootstrapCalculator<InType, OutType>::BootstrapCalculator;
103 : virtual std::vector<OutType> compute(const InType &, const bool) override;
104 :
105 : private:
106 : // Compute the acceleration, see Efron and Tibshirani (2003), Ch. 14, Eq. 14.15, p 186.
107 : OutType acceleration(const InType &, const bool);
108 : };
109 :
110 : /*
111 : * Simple struct that makeBootstrapCalculator wraps around, this is so building calculators
112 : * can be partially specialized.
113 : */
114 : template <typename InType, typename OutType>
115 : struct BootstrapCalculatorBuilder
116 : {
117 : static std::unique_ptr<BootstrapCalculator<InType, OutType>>
118 : build(const MooseEnum &,
119 : const libMesh::ParallelObject &,
120 : const std::vector<Real> &,
121 : unsigned int,
122 : unsigned int,
123 : StochasticTools::Calculator<InType, OutType> &);
124 : };
125 :
126 : template <typename InType, typename OutType>
127 : std::unique_ptr<BootstrapCalculator<InType, OutType>>
128 : makeBootstrapCalculator(const MooseEnum &,
129 : const libMesh::ParallelObject &,
130 : const std::vector<Real> &,
131 : unsigned int,
132 : unsigned int,
133 : StochasticTools::Calculator<InType, OutType> &);
134 :
135 : template <typename InType, typename OutType>
136 1262 : BootstrapCalculator<InType, OutType>::BootstrapCalculator(
137 : const libMesh::ParallelObject & other,
138 : const std::string & name,
139 : const std::vector<Real> & levels,
140 : unsigned int replicates,
141 : unsigned int seed,
142 : StochasticTools::Calculator<InType, OutType> & calc)
143 : : libMesh::ParallelObject(other),
144 1262 : _levels(levels),
145 1262 : _replicates(replicates),
146 1262 : _seed(seed),
147 1262 : _calc(calc),
148 1262 : _name(name)
149 : {
150 : mooseAssert(*std::min_element(levels.begin(), levels.end()) > 0,
151 : "The supplied levels must be greater than zero.");
152 : mooseAssert(*std::max_element(levels.begin(), levels.end()) < 1,
153 : "The supplied levels must be less than one");
154 1262 : }
155 :
156 : template <typename InType, typename OutType>
157 : std::vector<OutType>
158 1912 : BootstrapCalculator<InType, OutType>::computeBootstrapEstimates(const InType & data,
159 : const bool is_distributed)
160 : {
161 : MooseRandom generator;
162 1912 : generator.seed(0, _seed);
163 :
164 : // Compute replicate statistics
165 1912 : std::vector<OutType> values(_replicates);
166 1912 : auto calc_update = [this](const typename InType::value_type & val)
167 355209000 : { _calc.updateCalculator(val); };
168 5667632 : for (std::size_t i = 0; i < _replicates; ++i)
169 : {
170 5665720 : _calc.initializeCalculator();
171 5665720 : MooseUtils::resampleWithFunctor(
172 : data, calc_update, generator, 0, is_distributed ? &this->_communicator : nullptr);
173 5665720 : _calc.finalizeCalculator(is_distributed);
174 7022790 : values[i] = _calc.getValue();
175 : }
176 1912 : inplaceSort(values);
177 1912 : return values;
178 0 : }
179 :
180 : // makeBootstrapCalculator /////////////////////////////////////////////////////////////////////////
181 : template <typename InType, typename OutType>
182 : std::unique_ptr<BootstrapCalculator<InType, OutType>>
183 : makeBootstrapCalculator(const MooseEnum & item,
184 : const libMesh::ParallelObject & other,
185 : const std::vector<Real> & levels,
186 : unsigned int replicates,
187 : unsigned int seed,
188 : StochasticTools::Calculator<InType, OutType> & calc)
189 : {
190 : return BootstrapCalculatorBuilder<InType, OutType>::build(
191 1258 : item, other, levels, replicates, seed, calc);
192 : }
193 :
194 : } // namespace
|