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