void Stats::printTabular(int depth, std::ostream &out) const { DEBUG_SINVARIANT(checkInvariants()); std::string spaces; for(int i = 0; i < depth; i++) { spaces += " "; } out << spaces << "count " << countll() << "\n"; if (count() > 0) { out << spaces << "min " << min() << "\n"; out << spaces << "max " << max() << "\n"; out << spaces << "mean " << mean() << "\n"; out << spaces << "stddev " << stddev() << "\n"; out << spaces << "variance " << variance() << "\n"; out << spaces << "conf95 " << conf95() << "\n"; out << spaces << "total " << total() << "\n"; out << spaces << "total_sq " << total_sq() << "\n"; } // This is kind of a hack, but I had problems when the printout of // Stats changed for an empty list. else { out << spaces << "min " << min() << "\n"; out << spaces << "max " << max() << "\n"; out << spaces << "mean " << 0 << "\n"; out << spaces << "stddev " << 0 << "\n"; out << spaces << "variance " << 0 << "\n"; out << spaces << "conf95 " << 0 << "\n"; out << spaces << "total " << total() << "\n"; out << spaces << "total_sq " << total_sq() << "\n"; } }
/** * Apply Principal Component Analysis to the provided data set. * * @param data - Data matrix * @param transformedData - Data with PCA applied * @param eigVal - contains eigen values in a column vector * @param coeff - PCA Loadings/Coeffs/EigenVectors */ void PCA::Apply(const arma::mat& data, arma::mat& transformedData, arma::vec& eigVal, arma::mat& coeffs) const { //Original transpose op goes here. arma::mat covMat = ccov(data); //Centering is built into ccov if (scaleData) { covMat = covMat / (arma::ones<arma::colvec>(covMat.n_rows)) * stddev(covMat, 0, 0); } arma::eig_sym(eigVal, coeffs, covMat); int nEigVal = eigVal.n_elem; for (int i = 0; i < floor(nEigVal / 2.0); i++) eigVal.swap_rows(i, (nEigVal - 1) - i); coeffs = arma::fliplr(coeffs); transformedData = trans(coeffs) * data; arma::colvec transformedDataMean = arma::mean(transformedData, 1); transformedData = transformedData - (transformedDataMean * arma::ones<arma::rowvec>(transformedData.n_cols)); }
// make a report on the data collected so far and print it to a stream void report(FILE *file) const { fprintf(file, "Statistics on: %s Num samples = %u SUM=%f\n", _name, samples(), sum()); if (_samples > 0) fprintf(file, "MAX=%f MIN=%f Mean=%f StdDev=%f\n", maxVal(), minVal(), mean(), stddev()); }
inline void op_cor::direct_cor(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const uword norm_type) { arma_extra_debug_sigprint(); typedef typename std::complex<T> eT; if(A.is_empty()) { out.reset(); return; } if(A.is_vec()) { out.set_size(1,1); out[0] = eT(1); } else { const uword N = A.n_rows; const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); const Row<eT> acc = sum(A); const Row<T> sd = stddev(A); out = trans(A) * A; // out = strans(conj(A)) * A; out -= (trans(acc) * acc)/eT(N); // out -= (strans(conj(acc)) * acc)/eT(N); out /= norm_val; //out = out / (trans(sd) * sd); out /= conv_to< Mat<eT> >::from(trans(sd) * sd); } }
// determine which numbers on the list of all_data are outside one standard of deviation // and which ones fall within bool calc_outliers_inliers() { if(statistics.totalMeasurements == 0 || !statistics.totalMeasurements) { return false; } // initialize statistical values statistics.totalMeasurements_withinOneStandardDeviation = 0; statistics.totalMeasurements_outsideOneStandardDeviation = 0; // save stddev to statistics statistics.stddev = stddev(); double topThreshold = statistics.mean + statistics.stddev; double bottomThreshold = statistics.mean - statistics.stddev; for(std::vector<Measurement>::iterator measurement = all_data.begin(); measurement != all_data.end(); ++measurement) { if(measurement->value > bottomThreshold && measurement->value < topThreshold) { statistics.totalMeasurements_withinOneStandardDeviation++; inlier_data.push_back(*measurement); } else { statistics.totalMeasurements_outsideOneStandardDeviation++; outlier_data.push_back(*measurement); } } return true; }
// make a report on the data collected so far and print it to a string buffer // The buffer must be allocated by the caller (256 bytes should be enough) void report(char *str) const { int l = sprintf(str, "Statistics on: %s Num samples = %u SUM=%f\n", _name, samples(), sum()); if (_samples > 0) sprintf(str+l, "MAX=%f MIN=%f Mean=%f StdDev=%f\n", maxVal(), minVal(), mean(), stddev()); }
inline void op_cor::direct_cor(Mat<eT>& out, const Mat<eT>& A, const uword norm_type) { arma_extra_debug_sigprint(); if(A.is_empty()) { out.reset(); return; } if(A.is_vec()) { out.set_size(1,1); out[0] = eT(1); } else { const uword N = A.n_rows; const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); const Row<eT> acc = sum(A); const Row<eT> sd = stddev(A); out = (trans(A) * A); out -= (trans(acc) * acc)/eT(N); out /= norm_val; out /= trans(sd) * sd; } }
// TODO-future: Add in an optional invariant that checks statistical validity, // i.e., that number>30. Consider also adding a generic conf function that // takes a z-constant as input so that we can easily add more/different conf // intervals. Could also add an interface that checks if a specific value is // within some specified confidence interval. // Potential z constants of interest: // conf90 z= 1.645 // conf95 z= 1.960 // conf99 z= 2.576 double Stats::conf95() const { DEBUG_SINVARIANT(checkInvariants()); if (number == 0) return DBL_MAX; // **** Should really be NaN if count==0 DEBUG_SINVARIANT(number > 0); // **** Could be number > 30 for statistical // **** validity. return 1.96*stddev()/sqrt((double)number); }
double stddev( vd v, double avg) { vd::iterator it; double sumSq = SumSquaredDifferences(v, avg); return( stddev(sumSq,v.size()) ); }
/****************************************************************** * 函数功能:几何校正需要调用的函数 * * */ arma::mat centering(arma::mat &x){ arma::mat tmp = -mean(x.rows(0, 1), 1); arma::mat tmp2(2,2); tmp2.eye(); arma::mat tmp1 = join_horiz(tmp2, tmp); arma::mat v; v << 0 << 0 << 1 << arma::endr; arma::mat T = join_vert(tmp1, v); //T.print("T ="); arma::mat xm = T * x; //xm.print("xm ="); //at least one pixel apart to avoid numerical problems //xm.print("xm ="); double std11 = arma::stddev(xm.row(0)); //cout << "std11:" << std11 << endl; double std22 = stddev(xm.row(1)); //cout << "std22:" << std22 << endl; double std1 = std::max(std11, 1.0); double std2 = std::max(std22, 1.0); arma::mat S; S << 1/std1 << 0 << 0 << arma::endr << 0 << 1/std2 << 0 << arma::endr << 0 << 0 << 1 << arma::endr; arma::mat C = S * T ; //C.print("C ="); return C; }
virtual std::ostream& json(std::ostream& o) const { o << '"' << name << "\": " << value_ << ", "; o << '"' << name << "_count\": " << n << ", "; o << '"' << name << "_mean\": " << mean << ", "; o << '"' << name << "_stddev\": " << stddev() << ", "; o << '"' << name << "_min\": " << min << ", "; o << '"' << name << "_max\": " << max; return o; }
void stddevtime(struct timeval *SumTime, double SumSquareTime, int NumTimes, struct timeval *StdDevTime) { double result; result = stddev(timevaldouble(SumTime), SumSquareTime, NumTimes); doubletimeval(result, StdDevTime); }
inline arma_warn_unused typename get_pod_type<eT>::result stddev(const subview_elem1<eT,T1>& A, const u32 norm_type = 0) { arma_extra_debug_sigprint(); const Col<eT> X(A); return stddev(X, norm_type); }
std::string Stats::debugString() const { DEBUG_SINVARIANT(checkInvariants()); if (count() == 0) { return "count 0"; } else { return str(boost::format("count %d mean %G stddev %G var %G 95%%conf %G rel95%%conf %G" " min %G max %G") % count() % mean() % stddev() % variance() % conf95() % relconf95() % min() % max()); } };
/** * The within-module degree z-score is a within-module version of degree * centrality. * Inputs: W, binary/weighted undirected connection matrix * Ci, community affiliation vector * Output: Z, within-module degree z-score. * Reference: Guimera R, Amaral L. Nature (2005) 433:895-900. */ rowvec Connectome::moduleZscore(const mat &W, const urowvec &Ci) { uint n = W.n_rows; rowvec Z = zeros(1,n); rowvec Koi; for (uint i=0; i<=Ci.max();++i) { Koi = sum(W(find(Ci == i),find(Ci==i)),0); Z(find(Ci==i)) = (Koi - mean(Koi))/stddev(Koi); } Z(find(Z == datum::nan)).fill(0); return Z; }
void FITSImage::calculateStats(bool refresh) { calculateMinMax(refresh); // #1 call average, average is used in std deviation stats.average = average(); // #2 call std deviation stats.stddev = stddev(); if (refresh && markStars) // Let's try to find star positions again after transformation starsSearched = false; }
void normalize_each(Container& values){ for(auto& vec : values){ //zero-mean auto m = mnist::mean(vec); for(auto& v : vec){ v -= m; } //unit variance auto s = stddev(vec, 0.0); for(auto& v : vec){ v /= s; } } }
static void avg_measurement( long int *data, int loops) { int i = 0; long int sum = 0; for (i = 0; i < loops; ++i) { sum += data[i]; } printf("mean %f, stdev %f\n", (double) ((double) sum / (double) loops), stddev(data, loops)); }
/* Hash test: buffer of size byte. Run test n times. */ static void run_test(size_t size, unsigned int n, unsigned int l) { uint64_t t; struct statistics stats; TEEC_Operation op; int n0 = n; alloc_shm(size, algo); if (!random_in) memset((uint8_t *)in_shm.buffer + offset, 0, size); memset(&op, 0, sizeof(op)); op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT, TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_VALUE_INPUT, TEEC_NONE); op.params[0].memref.parent = &in_shm; op.params[0].memref.offset = 0; op.params[0].memref.size = size + offset; op.params[1].memref.parent = &out_shm; op.params[1].memref.offset = 0; op.params[1].memref.size = hash_size(algo); op.params[2].value.a = l; op.params[2].value.b = offset; verbose("Starting test: %s, size=%zu bytes, ", algo_str(algo), size); verbose("random=%s, ", yesno(random_in)); verbose("unaligned=%s, ", yesno(offset)); verbose("inner loops=%u, loops=%u, warm-up=%u s\n", l, n, warmup); if (warmup) do_warmup(); memset(&stats, 0, sizeof(stats)); while (n-- > 0) { t = run_test_once((uint8_t *)in_shm.buffer + offset, size, &op, l); update_stats(&stats, t); if (n % (n0/10) == 0) vverbose("#"); } vverbose("\n"); printf("min=%gμs max=%gμs mean=%gμs stddev=%gμs (%gMiB/s)\n", stats.min/1000, stats.max/1000, stats.m/1000, stddev(&stats)/1000, mb_per_sec(size, stats.m)); free_shm(); }
void FITSViewer::calculateStats() { /*kdDebug() << "Calculating statistics..." << endl;*/ stats.min = min(stats.minAt); stats.max = max(stats.maxAt); stats.average = average(); stats.stddev = stddev(); stats.bitpix = image->bitpix; stats.width = image->width; stats.height = image->height; /*kdDebug() << "Min: " << stats.min << " - Max: " << stats.max << endl; kdDebug() << "Average: " << stats.average << " - stddev: " << stats.stddev << endl; kdDebug() << "Width: " << stats.width << " - Height " << stats.height << " - bitpix " << stats.bitpix << endl;*/ statusBar()->changeItem( QString("%1 x %2").arg( (int) stats.width).arg( (int) stats.height), 2); }
// calculate average round trip time, ignoring outliers outside 1 standard deviation int avg_rtt(int data[], int n) { float average = 0.0f; float result = 0.0f; int j = 0;; for (int i=0; i < n; i++) { average += data[i]; } average = average/n; float sd = stddev(average, data, n); for (int i=0; i < n; i++) { if (abs(data[i] - average) <= sd) { result += data[i]; j++; } } return trunc(result/j); }
void Stats::printRome(int depth, std::ostream &out) const { DEBUG_SINVARIANT(checkInvariants()); std::string spaces; for(int i = 0; i < depth; i++) { spaces += " "; } out << spaces << "{ count " << countll() << " }\n"; if (count() > 0) { out << spaces << "{ min " << min() << " }\n"; out << spaces << "{ max " << max() << " }\n"; out << spaces << "{ mean " << mean() << " }\n"; out << spaces << "{ stddev " << stddev() << " }\n"; out << spaces << "{ variance " << variance() << " }\n"; out << spaces << "{ conf95 " << conf95() << " }\n"; out << spaces << "{ total " << total() << " }\n"; out << spaces << "{ total_sq " << total_sq() << " }\n"; } }
int main(int argc, char* argv[]) { int data[SIZE]; fill_random(data, SIZE); int sorted[SIZE]; for (int i = 0; i < SIZE; i++) { sorted[i] = data[i]; } bubblesort(sorted, SIZE); printf("Der Inhalt des Arrays ist: \n"); print_array(data, SIZE); printf("Der Inhalt des sortierten Arrays ist: \n"); print_array(sorted, SIZE); printf("Der Durchschnitt der im Array enthaltenen Zahlen ist %.2f\n", average(data, SIZE)); printf("Der Median der im Array enthaltenen Zahlen ist %.2f\n", median(data, SIZE)); printf("Die kleinste Zahl in dem Array ist %d\n", minimum(data, SIZE)); printf("Die groesste Zahl in dem Array ist %d\n", maximum(data, SIZE)); printf("Die Summe der im Array enthaltenen Zahlen ist %d\n", sum(data, SIZE)); printf("Die Varianz der im Array enthaltenen Zahlen ist %.2f\n", variance(data, SIZE)); printf("Die Standardabweichung der im Array enthaltenen Zahlen ist %.2f\n\n", stddev(data, SIZE)); return 0; }
static void time_obj_delpid(struct osd_device *osd, int numobj, int numiter) { int ret = 0; int i = 0, j = 0; uint64_t start, end; double *t = 0; double mu, sd; t = Malloc(sizeof(*t) * numiter); if (!t) return; ret = obj_insert(osd->dbc, 1, 2, 128); assert(ret == 0); ret = obj_delete_pid(osd->dbc, 1); assert(ret == 0); for (i = 0; i < numiter; i++) { for (j = 0; j < numobj; j++) { ret = obj_insert(osd->dbc, 1, j, 128); assert(ret == 0); } rdtsc(start); ret = obj_delete_pid(osd->dbc, 1); rdtsc(end); assert(ret == 0); t[i] = (double) (end - start) / mhz; start = end = 0; } mu = mean(t, numiter); sd = stddev(t, mu, numiter); printf("%s numiter %d numobj %d avg %lf +- %lf us\n", __func__, numiter, numobj, mu, sd); free(t); }
void Danceability::compute() { const vector<Real>& signal = _signal.get(); Real& danceability = _danceability.get(); Real sampleRate = parameter("sampleRate").toReal(); //--------------------------------------------------------------------- // preprocessing: // cut up into 10 ms frames and calculate the stddev for each slice // store in s(n), then integrate int numSamples = signal.size(); int frameSize = int(0.01 * sampleRate); // 10ms int numFrames = numSamples / frameSize; vector<Real> s(numFrames, 0.0); for (int i=0; i<numFrames; i++) { int frameBegin = i * frameSize; int frameEnd = min((i+1) * frameSize, numSamples); s[i] = stddev(signal, frameBegin, frameEnd); } // subtract the mean from the array to make it have 0 DC Real mean_s = mean(s,0,s.size()); for (int i=0; i<numFrames; i++) s[i] -= mean_s; // integrate the signal for (int i=1; i<(int)s.size(); i++) s[i] += s[i-1]; //--------------------------------------------------------------------- // processing vector<Real> F(_tau.size(), 0.0); int nFValues = 0; // for each tau (i.e. block size) for (int i=0; i<(int)_tau.size(); i++) { int tau = _tau[i]; // the original algorithm slides/jumps the blocks forward with // one sample, but that's very CPU intensive. // So, ... for large tau values, lets take larger jumps int jump = max(tau/50, 1); // perhaps we're working on a short file, then we don't have all values... if(numFrames >= tau) { // cut up the audio in tau-sized blocks for(int k=0; k<numFrames - tau; k += jump) { int frameBegin = k; int frameEnd = k + tau; // find the average residual error in this block // the residual error is sum( squared( signal - linear_regression ) ) F[i] += residualError(s, frameBegin, frameEnd); } // the square root of the total residual error, for all the // blocks of size tau if (numFrames == tau) { F[i] = 0.0; } else { F[i] = sqrt(F[i] / ((Real)(numFrames - tau)/(Real)jump)); } nFValues++; } else { break; } } danceability = 0.0; // the original article tells us: for small tau's we need to adjust alpha (danceability) for (int i=0; i<nFValues - 1; i++) { if (F[i+1] != 0.0) { danceability += log10(F[i+1] / F[i]) / log10( ((Real)_tau[i+1]+3.0) / ((Real)_tau[i]+3.0)); cout << "DEBUG:" << danceability << "log(F[i+1]/F[i])" << log10(F[i+1] / F[i]) << "Denominator" << log10( ((Real)_tau[i+1]+3.0) / ((Real)_tau[i]+3.0)) << endl; } else { danceability = 0.0; return; } } danceability /= (nFValues-1); if (danceability != 0.0) { danceability = 1.0 / danceability; } else { danceability = 0.0; } }
static void query_speed(struct osd_device *osd, int numiter, int numobj, int numobj_in_coll, int nummatch, int numattr, int numcriteria) { struct osd_command c; int i; uint64_t start, end; double *v; uint64_t pid = PARTITION_PID_LB; uint64_t cid = COLLECTION_OID_LB; uint8_t *results, *query; double mu, sd; struct attribute_list *attr; uint8_t *attr_val_lo, *attr_val_match, *attr_val_nomatch, *attr_val_hi; uint64_t alloc_len, query_len, criterion_len; uint8_t cidn[8], *cp; if (numobj_in_coll > numobj) return; if (nummatch > numobj_in_coll) return; if (numcriteria > numattr) return; v = Malloc(numiter * sizeof(*v)); if (!v) return; alloc_len = 12 + numobj * 8; results = Malloc(alloc_len); if (!results) return; attr = Malloc((1 + numattr) * sizeof(*attr)); if (!attr) return; attr_val_lo = Malloc(4 * ATTR_LEN); if (!attr_val_lo) return; attr_val_match = attr_val_lo + ATTR_LEN; attr_val_hi = attr_val_lo + 2 * ATTR_LEN; attr_val_nomatch = attr_val_lo + 3 * ATTR_LEN; memset(attr_val_lo, 0x4b, ATTR_LEN); memset(attr_val_match, 0x5a, ATTR_LEN); memset(attr_val_hi, 0x69, ATTR_LEN); memset(attr_val_nomatch, 0x78, ATTR_LEN); osd_command_set_create_partition(&c, pid); run(osd, &c); osd_command_set_create_collection(&c, pid, cid); run(osd, &c); for (i=0; i<numattr; i++) { attr[i].type = ATTR_SET; attr[i].page = LUN_PG_LB; attr[i].number = 1 + i; /* skip directory */ attr[i].val = attr_val_nomatch; attr[i].len = ATTR_LEN; } /* one extra attr to stick it in the collection, for some of them */ set_htonll(cidn, cid); attr[numattr].type = ATTR_SET; attr[numattr].page = USER_COLL_PG; attr[numattr].number = 1; attr[numattr].len = 8; attr[numattr].val = cidn; for (i=0; i<numobj; i++) { int j, this_numattr; osd_command_set_create(&c, pid, 0, 1); this_numattr = numattr; if (i < numobj_in_coll) ++this_numattr; /* stick in coll */ /* some of the ones in the collection will match */ for (j=0; j<numattr; j++) attr[j].val = (i < nummatch ? attr_val_match : attr_val_nomatch); osd_command_attr_build(&c, attr, this_numattr); run(osd, &c); osd_command_attr_free(&c); } criterion_len = 12 + 2 + ATTR_LEN + 2 + ATTR_LEN; if (numcriteria == 0) query_len = 8; /* special case, just one empty criterion */ else query_len = 4 + numcriteria * criterion_len; query = Malloc(query_len); if (!query) return; memset(query, 0, query_len); query[0] = 1; /* intersection */ cp = query + 4; for (i=0; i<numcriteria; i++) { set_htons(cp + 2, criterion_len); set_htonl(cp + 4, LUN_PG_LB); set_htonl(cp + 8, 1 + i); set_htons(cp + 12, ATTR_LEN); memcpy(cp + 12 + 2, attr_val_lo, ATTR_LEN); set_htons(cp + 12 + 2 + ATTR_LEN, ATTR_LEN); memcpy(cp + 12 + 2 + ATTR_LEN + 2, attr_val_hi, ATTR_LEN); cp += criterion_len; } osd_command_set_query(&c, pid, cid, query_len, alloc_len); c.outdata = query; c.outlen = query_len; for (i=0; i<5; i++) run(osd, &c); for (i=0; i<numiter; i++) { rdtsc(start); run(osd, &c); rdtsc(end); v[i] = (double)(end - start) / mhz; } mu = mean(v, numiter); sd = stddev(v, mu, numiter); printf("query numiter %d numobj %d numobj_in_coll %d nummatch %d" " numattr %d numcriteria %d avg %lf +/- %lf us\n", numiter, numobj, numobj_in_coll, nummatch, numattr, numcriteria, mu, sd); free(query); free(attr_val_lo); free(attr); free(results); free(v); }
template <> void SummarizingMetric<float>::vt_sample() const { VT_COUNT_DOUBLE_VAL(vt_counter_value, value_); VT_COUNT_UNSIGNED_VAL(vt_counter_count, n); VT_COUNT_DOUBLE_VAL(vt_counter_mean, mean); VT_COUNT_DOUBLE_VAL(vt_counter_stddev, stddev()); }
void CalibratePassbandAction::calibrate(TimeFrequencyData& data) const { const size_t height = data.ImageHeight(); std::vector<num_t> stddev(_steps); for(size_t step=0; step!=_steps; ++step) { const size_t startY = step*height/_steps, endY = (step+1)*height/_steps; std::vector<num_t> dataVector((1+endY-startY) * data.ImageWidth() * data.ImageCount()); std::vector<num_t>::iterator vecIter = dataVector.begin(); const Mask2DCPtr maskPtr = data.GetSingleMask(); const Mask2D &mask = *maskPtr; for(size_t i=0; i!=data.ImageCount(); ++i) { const Image2D &image = *data.GetImage(i); for(size_t y=startY; y!=endY; ++y) { const num_t *inputPtr = image.ValuePtr(0, y); const bool *maskPtr = mask.ValuePtr(0, y); for(size_t x=0; x!=image.Width(); ++x) { if(!*maskPtr && std::isfinite(*inputPtr)) { *vecIter = *inputPtr; ++vecIter; } ++inputPtr; ++maskPtr; } } } dataVector.resize(vecIter - dataVector.begin()); num_t mean; ThresholdTools::WinsorizedMeanAndStdDev<num_t>(dataVector, mean, stddev[step]); } for(size_t i=0; i!=data.ImageCount(); ++i) { const Image2D &image = *data.GetImage(i); Image2D *destImage = Image2D::CreateUnsetImage(image.Width(), image.Height()); for(size_t step=0; step!=_steps; ++step) { const size_t startY = step*height/_steps, endY = (step+1)*height/_steps; float correctionFactor; if(stddev[step] == 0.0) correctionFactor = 0.0; else correctionFactor = 1.0 / stddev[step]; const __m128 corrFact4 = _mm_set_ps(correctionFactor, correctionFactor, correctionFactor, correctionFactor); for(size_t y=startY; y!=endY; ++y) { const float *inputPtr = image.ValuePtr(0, y); float *destPtr = destImage->ValuePtr(0, y); for(size_t x=0;x<image.Width();x+=4) { _mm_store_ps(destPtr, _mm_mul_ps(corrFact4, _mm_load_ps(inputPtr))); inputPtr += 4; destPtr += 4; } } } data.SetImage(i, Image2DPtr(destImage)); } }
int main() { std::cout << stddev(4, 25.0, 27.3, 26.9, 25.7) << '\n'; }
std::string BootstrappedQuantity::format() { std::ostringstream oss; oss << mean() << " ± " << stddev(); return oss.str(); }