5#ifndef LINE_API_SIM_SIM_FIRQUEST_H
6#define LINE_API_SIM_SIM_FIRQUEST_H
88 if (R == 2)
return std::vector<long>{14, 11, 8, 5};
89 if (R == 3)
return std::vector<long>{10, 8, 6, 4};
90 if (R == 4)
return std::vector<long>{6, 5, 4, 3};
91 if (R < 10)
return std::vector<long>{5, 4, 3, 2};
92 if (R < 17)
return std::vector<long>{4, 3, 2, 1};
93 if (R < 23)
return std::vector<long>{3, 2, 1};
94 if (R < 33)
return std::vector<long>{2, 1};
95 return std::vector<long>{1};
120StsQuantileStats<T> firquest_pool(
const std::vector<std::vector<T>>& Yt,
long b,
long m,
double p,
122 const std::size_t R = Yt.size();
123 const std::size_t bm =
static_cast<std::size_t
>(b) *
static_cast<std::size_t
>(m);
125 StsQuantileStats<T> pooled;
126 pooled.b =
static_cast<std::size_t
>(b);
127 pooled.m =
static_cast<std::size_t
>(m);
129 pooled.areas.reserve(R *
static_cast<std::size_t
>(b));
130 pooled.bqe.reserve(R *
static_cast<std::size_t
>(b));
133 all.reserve(pooled.n);
134 for (std::size_t r = 0; r < R; ++r) {
135 const std::vector<T> kept(Yt[r].end() -
static_cast<std::ptrdiff_t
>(bm), Yt[r].end());
137 kept,
static_cast<std::size_t
>(b),
static_cast<std::size_t
>(m), p, weight);
138 pooled.areas.insert(pooled.areas.end(), st.areas.begin(), st.areas.end());
139 pooled.bqe.insert(pooled.bqe.end(), st.bqe.begin(), st.bqe.end());
140 all.insert(all.end(), kept.begin(), kept.end());
143 std::sort(all.begin(), all.end());
145 all[
static_cast<std::size_t
>(std::ceil(
static_cast<double>(pooled.n) * p)) - 1];
147 const std::size_t K = R *
static_cast<std::size_t
>(b);
148 T sumSq = num_traits<T>::from_int(0);
149 for (std::size_t i = 0; i < K; ++i) sumSq += T(pooled.areas[i] * pooled.areas[i]);
150 pooled.Ap = T(sumSq / num_traits<T>::from_int(
static_cast<long>(K)));
152 T sd = num_traits<T>::from_int(0);
153 for (std::size_t i = 0; i < K; ++i) {
154 const T d = T(pooled.bqe[i] - pooled.quantile);
157 pooled.Np = T(num_traits<T>::from_int(m) * sd /
158 num_traits<T>::from_int(
static_cast<long>(K - 1)));
159 pooled.Vp = T((num_traits<T>::from_int(
static_cast<long>(K)) * pooled.Ap +
160 num_traits<T>::from_int(
static_cast<long>(K - 1)) * pooled.Np) /
161 num_traits<T>::from_int(
static_cast<long>(2 * K - 1)));
179 "sim_firquest: the interval is a t quantile times a square root, so exact "
180 "arithmetic is refused");
181 const std::size_t R = Y.size();
183 throw InputError(
"sim_firquest: at least 2 replications are required, use sim_fquest for a "
185 const std::size_t nRep = Y[0].size();
187 throw InputError(
"sim_firquest: the replicate paths must be nonempty and of equal length");
188 for (std::size_t r = 0; r < R; ++r) {
189 if (Y[r].size() != nRep)
190 throw InputError(
"sim_firquest: the replicate paths must be nonempty and of equal "
192 for (std::size_t i = 0; i < nRep; ++i)
193 if (!detail::num_isfinite(Y[r][i]))
194 throw InputError(
"sim_firquest: the sample paths must be finite");
200 if (!(p > 0.0) || !(p < 1.0))
201 throw InputError(
"sim_firquest: p must be a real scalar in (0,1)");
202 if (!(alpha > 0.0) || !(alpha < 1.0))
203 throw InputError(
"sim_firquest: alpha must be a real scalar in (0,1)");
204 if (
static_cast<long>(R) *
opt.s.back() < 3)
205 throw InputError(
"sim_firquest: R*min(s) pooled batches is below the 3 the stage tests "
212 const long n =
static_cast<long>(nRep);
213 const long b0 =
opt.b0;
214 long mStart =
opt.m0;
215 if (n < b0 * mStart) mStart = n / b0;
217 throw InputError(
"sim_firquest: each replication is too short for the initial batch count "
222 for (std::size_t r = 0; r < R; ++r) {
225 bool atMax =
false, passed =
false;
227 const std::vector<T> head(Y[r].begin(),
228 Y[r].begin() +
static_cast<std::ptrdiff_t
>(b0 * m));
230 head,
static_cast<std::size_t
>(b0),
static_cast<std::size_t
>(m), p,
opt.weight);
232 opt.beta * std::exp(-
opt.eta * std::pow(
static_cast<double>(ell - 1),
opt.theta));
239 m = detail::warmup_next_m(n, b0, m, atMax);
242 failed = failed || !passed;
243 mMax = std::max(mMax, m);
246 res.
warnings.push_back(
"the warmup randomness test could not be passed in every "
247 "replication, the replicate paths are too short");
250 const long truncated = mMax > 0 ? mMax : 0;
252 throw InputError(
"sim_firquest: the warmup batch size exhausts the replication length");
253 std::vector<std::vector<T>> Yt(R);
254 for (std::size_t r = 0; r < R; ++r)
255 Yt[r].assign(Y[r].begin() +
static_cast<std::ptrdiff_t
>(truncated), Y[r].end());
256 const long nstarRep =
static_cast<long>(Yt[0].size());
261 long m = nstarRep / b;
262 bool ok =
true, havePooled =
false;
264 for (
int stage = 1; stage <= 4; ++stage) {
270 pooled = detail::firquest_pool<T>(Yt, b, m, p,
opt.weight);
272 const std::vector<T>& sample = stage <= 2 ? pooled.
areas : pooled.
bqe;
277 if (v >=
opt.s.size()) {
287 if (!havePooled || m < 1)
288 throw InputError(
"sim_firquest: the replicate paths are too short to form min(s) batches "
291 res.
b =
static_cast<std::size_t
>(b);
292 res.
m =
static_cast<std::size_t
>(m);
294 res.
truncated =
static_cast<std::size_t
>(truncated);
303 sim_tinv(1.0 - alpha / 2.0,
static_cast<double>(2 *
static_cast<long>(R) * b - 1)));
304 const T half = T(t * detail::num_sqrt(T(pooled.
Vp / nst)));
310 res.
warnings.push_back(
"a randomness or normality test failed at b = " +
311 std::to_string(
opt.s.back()) +
312 " per replication, the delivered interval is heuristic");
321 res.
lower = detail::num_nan<T>();
322 res.
upper = detail::num_nan<T>();
The exception types the port throws.
QuestResult< T > sim_firquest(const std::vector< std::vector< T > > &Y, double p, double alpha=0.05, const QuestOptions *options=nullptr)
Fixed-sample-size quantile interval from independent replications.
std::vector< long > sim_firquest_batchcounts(std::size_t R)
The article's batch counts as a function of the replication count, chosen so that R*b pooled statisti...
StsQuantileStats< T > sim_sts_quantile_areas(const std::vector< T > &Y, std::size_t b, std::size_t m, double p, double weight=std::sqrt(12.0))
Standardized time series areas of the batched quantile process.
VonNeumannResult< T > sim_vonneumann(const std::vector< T > &x, double alpha=0.05)
Von Neumann ratio test for randomness of a sequence.
double sim_tinv(double p, double nu)
Quantile function of Student's t distribution.
QuestOptions sim_firquest_options(std::size_t R)
The FIRQUEST defaults at R replications: b0 = 25 and the R-dependent ladder, every other constant as ...
QuestOptions sim_quest_options(const QuestOptions &options=QuestOptions())
Validates an option set and returns it.
ShapiroWilkResult< T > sim_shapirowilk(const std::vector< T > &x, double alpha=0.05)
Shapiro-Wilk test for univariate normality.
QuestInterval< T > sim_quest_heuristic_ci(const std::vector< T > &bqe, const T ¢re, const T &Ap, const T &Np, std::size_t nstar, double alpha, bool useAutocorr)
Fallback interval used when a QUEST stage test fails.
Number-type abstraction for the templated API port.
Normal and Student t quantiles used by the output-analysis routines.
Fixed-sample-size confidence interval for a steady-state quantile.
Fallback interval used when a QUEST stage test fails.
Options of the QUEST procedures, with the published FQUEST defaults.
Shapiro-Wilk test for univariate normality.
Standardized time series areas of the batched quantile process.
Shared arithmetic helpers for the templated simulation output-analysis port.
Von Neumann ratio test for randomness of a sequence.
A confidence interval, asymmetric about the point estimate in general.
Procedure constants shared by sim_fquest and sim_firquest.
Point estimate and interval delivered by the QUEST procedures.
T halfwidth
(upper-lower)/2, attained only on average when asymmetric
T estimate
Full-sample empirical p-quantile of the truncated path.
std::size_t truncated
Observations deleted from the front of each path.
T upper
Upper confidence limit, NaN if refused.
T Vp
Combined variance-parameter estimator.
T Ap
STS area variance-parameter estimator.
std::size_t b
Final batch count, per replication in sim_firquest.
std::size_t R
Replications, 1 for sim_fquest.
std::size_t n
Observations the interval rests on.
bool heuristic
True when a stage test failed.
T lower
Lower confidence limit, NaN if refused.
std::size_t m
Final batch size.
std::vector< std::string > warnings
Diagnostics, empty on a clean run.
T Np
NBQ variance-parameter estimator.
Batched-quantile statistics of one sample path.
std::size_t n
Number of observations used, b*m.
T Ap
Batched STS area estimator A_p(w;b,m).
std::vector< T > areas
b signed STS areas A_p(w;j,m)
T Np
NBQ variance-parameter estimator N_p(b,m), NaN at b = 1.
std::vector< T > bqe
b batched quantile estimators yhat_p(j,m)
T Vp
Combined variance-parameter estimator, NaN at b = 1.
T quantile
Full-sample empirical p-quantile ytilde_p(n).