5#ifndef LINE_API_TRACE_MTRACE_BOOTSTRAP_H
6#define LINE_API_TRACE_MTRACE_BOOTSTRAP_H
79std::vector<T> stat_vector(
const std::vector<T>& Tv,
const std::vector<int>& A) {
80 const std::vector<unsigned> ord(1, 1u);
87 for (std::size_t i = 0; i < pc.size(); ++i) out.push_back(pc[i]);
88 for (std::size_t i = 0; i < B.
rows(); ++i) out.push_back(B(i, 0));
89 for (std::size_t i = 0; i < F.
rows(); ++i) out.push_back(F(i, 0));
91 for (std::size_t j = 0; j < S.
cols(); ++j)
92 for (std::size_t i = 0; i < S.
rows(); ++i) out.push_back(S(i, j));
98void assemble(
const std::vector<T>& Tv,
const std::vector<int>& A,
99 const std::vector<std::size_t>& first,
const std::vector<std::size_t>& len,
100 const std::vector<std::size_t>& pick, std::vector<T>* t, std::vector<int>* a) {
103 for (std::size_t i = 0; i < pick.size(); ++i) {
104 const std::size_t b = pick[i];
105 for (std::size_t k = 0; k < len[b]; ++k) {
106 t->push_back(Tv[first[b] + k]);
107 a->push_back(A[first[b] + k]);
113inline double quantile(
const std::vector<double>& sorted,
double p) {
114 if (sorted.empty())
return 0.0;
115 if (p <= 0.0)
return sorted.front();
116 if (p >= 1.0)
return sorted.back();
117 const double h = p *
static_cast<double>(sorted.size() - 1);
118 const std::size_t lo =
static_cast<std::size_t
>(std::floor(h));
119 const std::size_t hi = std::min(lo + 1, sorted.size() - 1);
120 return sorted[lo] + (h -
static_cast<double>(lo)) * (sorted[hi] - sorted[lo]);
139 double alpha = 0.05, std::size_t blockLen = 50) {
141 "mtrace_bootstrap inverts the normal distribution");
142 if (Tv.empty() || Tv.size() != A.size())
143 throw InputError(
"mtrace_bootstrap: the trace and its labels must agree in length");
144 if (resamples < 2)
throw InputError(
"mtrace_bootstrap: at least two replicates are required");
145 if (!(alpha > 0.0) || !(alpha < 1.0))
146 throw InputError(
"mtrace_bootstrap: the level must lie strictly inside (0,1)");
147 if (blockLen == 0)
throw InputError(
"mtrace_bootstrap: the block length must be positive");
149 const std::size_t N = Tv.size();
150 const std::size_t BN = N / blockLen;
153 "mtrace_bootstrap: the trace is too short to cut into at least two blocks at this "
154 "block length; the block bootstrap has nothing to resample");
158 const std::size_t base = N / BN, extra = N % BN;
159 std::vector<std::size_t> len(BN, base), first(BN, 0);
160 for (std::size_t b = 0; b < extra; ++b) len[b] += 1;
161 for (std::size_t b = 1; b < BN; ++b) first[b] = first[b - 1] + len[b - 1];
165 out.
estimate = bootdetail::stat_vector(Tv, A);
166 const std::size_t P = out.
estimate.size();
169 std::vector<std::vector<double>> rep(P);
170 for (std::size_t i = 0; i < P; ++i) rep[i].reserve(resamples);
171 std::vector<std::size_t> pick(BN, 0);
174 for (std::size_t r = 0; r < resamples; ++r) {
175 for (std::size_t b = 0; b < BN; ++b)
177 for (std::size_t b = 0; b < BN; ++b)
178 if (pick[b] >= BN) pick[b] = BN - 1;
179 bootdetail::assemble(Tv, A, first, len, pick, &bt, &
ba);
182 s = bootdetail::stat_vector(bt,
ba);
183 }
catch (
const Error&) {
186 if (s.size() != P)
continue;
191 std::vector<std::vector<double>> jack(P);
192 std::vector<std::size_t> all;
193 for (std::size_t b = 0; b < BN; ++b) all.push_back(b);
194 for (std::size_t drop = 0; drop < BN; ++drop) {
195 std::vector<std::size_t> keep;
196 for (std::size_t b = 0; b < BN; ++b)
197 if (b != drop) keep.push_back(b);
198 bootdetail::assemble(Tv, A, first, len, keep, &bt, &
ba);
201 s = bootdetail::stat_vector(bt,
ba);
202 }
catch (
const Error&) {
205 if (s.size() != P)
continue;
212 for (std::size_t i = 0; i < P; ++i) {
213 std::vector<double> v = rep[i];
219 std::sort(v.begin(), v.end());
223 std::size_t below = 0;
224 for (std::size_t k = 0; k < v.size(); ++k)
225 if (v[k] < theta) ++below;
226 double frac =
static_cast<double>(below) /
static_cast<double>(v.size());
228 const double eps = 0.5 /
static_cast<double>(v.size());
229 if (frac < eps) frac = eps;
230 if (frac > 1.0 - eps) frac = 1.0 - eps;
235 if (jack[i].size() >= 2) {
237 for (std::size_t k = 0; k < jack[i].size(); ++k) mean += jack[i][k];
238 mean /=
static_cast<double>(jack[i].size());
239 double s2 = 0.0, s3 = 0.0;
240 for (std::size_t k = 0; k < jack[i].size(); ++k) {
241 const double d = mean - jack[i][k];
245 if (s2 > 0.0) acc = s3 / (6.0 * std::pow(s2, 1.5));
248 auto endpoint = [&](
double z) {
249 const double num = z0 + z;
250 const double den = 1.0 - acc * num;
251 if (!(std::fabs(den) > 0.0))
return 0.5;
254 double a1 = endpoint(za), a2 = endpoint(-za);
255 if (a1 > a2) std::swap(a1, a2);
Base error for the multiprecision C++ port.
The exception types the port throws.
Dense matrix and non-owning view.
Empirical class-dependent moments of a marked trace.
Class probabilities of a marked trace, p_c = count_c / N.
One-step class transition frequencies of a marked trace,.
std::mt19937_64 McRng
The generator type every Monte Carlo entry point in this tree accepts.
double mc_uniform01(McRng &g)
Uniform deviate on [0,1) with 53 significant bits, as a double.
double sim_norminv(double p)
Standard normal quantile function.
double sim_normcdf(double z)
Standard normal cumulative distribution function.
MtraceBootstrapResult< T > mtrace_bootstrap(const std::vector< T > &Tv, const std::vector< int > &A, pfqn::McRng &rng, std::size_t resamples=1000, double alpha=0.05, std::size_t blockLen=50)
Block-bootstrap confidence intervals for the descriptors of a marked trace.
std::vector< T > mtrace_pc(const std::vector< int > &A)
Class probabilities of a marked trace, p_c = count_c / N.
Matrix< T > mtrace_moment(const std::vector< T > &Tv, const std::vector< int > &A, const std::vector< unsigned > &orders, bool after=false, bool norm=false)
Empirical class-dependent moments of a marked trace.
Matrix< T > mtrace_sigma(const std::vector< int > &L)
One-step class transition frequencies of a marked trace, sigma(i,j) = #{t : A_t = i,...
Number-type abstraction for the templated API port.
Randomness scaffolding shared by the Monte Carlo normalizing-constant estimators (pfqn_mci,...
Normal and Student t quantiles used by the output-analysis routines.
Lower and upper BCa endpoints of each descriptor, and the point estimate.
std::vector< T > lower
lower confidence limit, same layout
std::vector< T > estimate
the statistic on the whole trace
std::size_t blocks
BN, the number of blocks resampled.
std::vector< T > upper
upper confidence limit, same layout