#ifndef STATISTICS_H #define STATISTICS_H 1 #include // has max() #include #include #include #include "types.h" // has Dollars #include // Oldham, Jeffrey D. // 2000Apr25 // CS3352 // STATISTICS // Compute statistics on final investment amounts. // Ending investment values less than zero, i.e., bankruptcy, are // treated as zero. class statistics { public: statistics(void) { average = variance = 0; numberOfTimeFramesSoFar = numberOfSuccessesSoFar = 0; return; } // Prints the probability of success, the average, and the standard // deviation. friend ostream& operator<<(ostream& out, const statistics & s) { out << 0 << '\t' << statistics::rounder(100.0*s.numberOfSuccessesSoFar/s.numberOfTimeFramesSoFar,1) << '\t'; out.setf(ios::fixed, ios::floatfield); out << setprecision(0) << statistics::rounder(s.average,0) << '\t'; out.setf(ios::fixed, ios::floatfield); out << statistics::rounder(sqrt(s.variance), 0); return out; } // Invoked at the end of each time frame, giving the ending // investment amount. We use Welford's one-pass algorithm to avoid // overflow problems with standard deviation. void nextValue(const Dollars investmentAmount, const Dollars financialTarget) { #ifdef DEBUG_STATS cout << "Final investment: " << investmentAmount << "\tFinancial Goal: " << financialTarget << endl; #endif // DEBUG_STATS ++numberOfTimeFramesSoFar; double t = max(investmentAmount,static_cast(0)) - average; average += static_cast(t / static_cast(numberOfTimeFramesSoFar)); variance += static_cast((numberOfTimeFramesSoFar-1)/static_cast(numberOfTimeFramesSoFar) * t * t); assert(variance >= 0); if (investmentAmount >= financialTarget) ++numberOfSuccessesSoFar; return; } private: double average; // average so far double variance; // variance so far ul numberOfTimeFramesSoFar; ul numberOfSuccessesSoFar; // number of ending amounts >= desired // ending // Round the value to the specified number of digits. static double rounder(const double & d, const unsigned int nuDigits) { const double p = pow(10.0,nuDigits); return static_cast(d * p + 0.5) / p; } }; #endif