Commit 6b0dcd93 authored by niklas.baumgarten's avatar niklas.baumgarten
Browse files

Updated WelfordAggregate

parent e224c1dc
...@@ -51,7 +51,7 @@ public: ...@@ -51,7 +51,7 @@ public:
std::vector<double> GetCostVector() const { std::vector<double> GetCostVector() const {
std::vector<double> costVector; std::vector<double> costVector;
for (auto &&[level, entry]: _levelMap) for (auto &&[level, entry]: _levelMap)
costVector.push_back(entry.Cost); costVector.push_back(entry.C);
return costVector; return costVector;
} }
......
#ifndef MLMC_MC_HPP #ifndef MLMC_MC_HPP
#define MLMC_MC_HPP #define MLMC_MC_HPP
#include "montecarlo/datastructure/EmpiricMeasures.hpp"
#include "montecarlo/datastructure/WelfordAggregate.hpp" #include "montecarlo/datastructure/WelfordAggregate.hpp"
#include "pdesolver/PDESolverCreator.hpp" #include "pdesolver/PDESolverCreator.hpp"
......
...@@ -3,64 +3,67 @@ ...@@ -3,64 +3,67 @@
void MonteCarloMap::UpdateSampleCounter(double epsilon) { void MonteCarloMap::UpdateSampleCounter(double epsilon) {
int optimalM; int optimalM;
double factor = 0.0; double factor = 0.0;
for (auto &[level, mc] : _levelMap) for (auto &[level, mc] : _levelMap)
factor += sqrt(mc.vars.Y * mc.avgs.Cost); factor += sqrt(mc.aggregate.sVar.Y * mc.aggregate.mean.C);
for (auto &[level, mc] : _levelMap) { for (auto &[level, mc] : _levelMap) {
optimalM = (int) (ceil(2 * pow(epsilon, -2) * factor * optimalM = (int) (ceil(2 * pow(epsilon, -2) * factor *
sqrt(mc.vars.Y / mc.avgs.Cost))); sqrt(mc.aggregate.sVar.Y / mc.aggregate.mean.C)));
if (optimalM == 1) optimalM++; // Hack if (optimalM == 1) optimalM++; // Hack
mc.aggregate.UpdateSampleCounter(optimalM - mc.aggregate.ctr.M); mc.aggregate.UpdateSampleCounter(optimalM - mc.aggregate.ctr.M);
} }
} }
void MonteCarloMap::AppendLevel(double epsilon, Exponents exponents, int newLevel) { void MonteCarloMap::AppendLevel(double epsilon, Exponents exponents, int newLevel) {
if (newLevel <= maxLevel) { if (newLevel <= maxLevel) {
auto oldLevel = this->rbegin(); auto oldLevel = this->rbegin();
double varsY = oldLevel->second.vars.Y / pow(2.0, exponents.beta); double sVarY = oldLevel->second.aggregate.sVar.Y / pow(2.0, exponents.beta);
double avgsCost = oldLevel->second.avgs.Cost * pow(2.0, exponents.gamma); double avgsCost = oldLevel->second.aggregate.mean.C * pow(2.0, exponents.gamma);
_levelMap.insert(
LevelMonteCarloPair(newLevel, MonteCarlo(newLevel, 0, false, true))); _levelMap.insert(
_levelMap.find(newLevel)->second.vars.Y = varsY; {newLevel, MonteCarlo(newLevel, 0, false, true)}
_levelMap.find(newLevel)->second.avgs.Cost = avgsCost; );
this->UpdateSampleCounter(epsilon);
} else { _levelMap.find(newLevel)->second.aggregate.sVar.Y = sVarY;
Exit ("Maximum level has been reached.") _levelMap.find(newLevel)->second.aggregate.mean.C = avgsCost;
} this->UpdateSampleCounter(epsilon);
} else {
Exit ("Maximum level has been reached.")
}
} }
void SampleCounterMap::Update(const MonteCarloMap &mcMap) { void SampleCounterMap::Update(const MonteCarloMap &mcMap) {
for (auto &[level, mc]: mcMap) for (auto &[level, mc]: mcMap)
_levelMap[level] = SampleCounter(mc.aggregate.ctr); _levelMap[level] = SampleCounter(mc.aggregate.ctr);
} }
bool SampleCounterMap::NoSamplesLeft() { bool SampleCounterMap::NoSamplesLeft() {
bool noSamplesLeft = true; bool noSamplesLeft = true;
for (auto &&[level, entry]: _levelMap) for (auto &&[level, entry]: _levelMap)
if (entry.dM > 0) { if (entry.dM > 0) {
noSamplesLeft = false; noSamplesLeft = false;
break; break;
} }
return noSamplesLeft; return noSamplesLeft;
} }
void AveragesMap::Update(const MonteCarloMap &mcMap) { void MeanMap::Update(const MonteCarloMap &mcMap) {
for (auto &&[level, mc]: mcMap) { for (auto &&[level, mc]: mcMap) {
_levelMap[level] = mc.avgs; _levelMap[level] = mc.aggregate.mean;
Q += mc.avgs.Y; Q += mc.aggregate.mean.Y;
Cost += mc.avgs.Cost; // Todo at the right place? Cost += mc.aggregate.mean.C; // Todo at the right place?
} }
} }
void VariancesMap::Update(const MonteCarloMap &mcMap) { void SVarMap::Update(const MonteCarloMap &mcMap) {
for (auto &[level, mc]: mcMap) for (auto &[level, mc]: mcMap)
_levelMap[level] = mc.vars; _levelMap[level] = mc.aggregate.sVar;
} }
void KurtosisMap::Update(const MonteCarloMap &mcMap) { void KurtosisMap::Update(const MonteCarloMap &mcMap) {
for (auto &[level, mc]: mcMap) for (auto &[level, mc]: mcMap)
_levelMap[level] = mc.kurtosis; _levelMap[level] = mc.aggregate.kurtosis;
} }
#ifndef EMPIRICMEASURELEVELMAPS_HPP #ifndef EMPIRICMEASURELEVELMAPS_HPP
#define EMPIRICMEASURELEVELMAPS_HPP #define EMPIRICMEASURELEVELMAPS_HPP
#include "EmpiricMeasures.hpp"
#include "WelfordAggregate.hpp" #include "WelfordAggregate.hpp"
#include "basics/Level.hpp" #include "basics/Level.hpp"
#include "montecarlo/MonteCarlo.hpp" #include "montecarlo/MonteCarlo.hpp"
...@@ -10,8 +9,6 @@ ...@@ -10,8 +9,6 @@
struct Exponents; struct Exponents;
typedef std::pair<int, MonteCarlo> LevelMonteCarloPair;
struct MonteCarloMap : public LevelMap<MonteCarlo> { struct MonteCarloMap : public LevelMap<MonteCarlo> {
int maxLevel = 10; int maxLevel = 10;
...@@ -20,7 +17,7 @@ struct MonteCarloMap : public LevelMap<MonteCarlo> { ...@@ -20,7 +17,7 @@ struct MonteCarloMap : public LevelMap<MonteCarlo> {
config.get("maxLevel", maxLevel); config.get("maxLevel", maxLevel);
}; };
MonteCarloMap(std::initializer_list<LevelMonteCarloPair> mcMap) : MonteCarloMap(std::initializer_list<std::pair<int, MonteCarlo>> mcMap) :
LevelMap<MonteCarlo>(mcMap) { LevelMap<MonteCarlo>(mcMap) {
config.get("maxLevel", maxLevel); config.get("maxLevel", maxLevel);
}; };
...@@ -42,30 +39,30 @@ struct SampleCounterMap : public LevelMap<SampleCounter> { ...@@ -42,30 +39,30 @@ struct SampleCounterMap : public LevelMap<SampleCounter> {
bool NoSamplesLeft(); bool NoSamplesLeft();
}; };
struct AveragesMap : public LevelMap<Averages> { struct MeanMap : public LevelMap<Mean> {
double Q = 0.0; double Q = 0.0;
double Cost = 0.0; double Cost = 0.0;
AveragesMap() {}; MeanMap() {};
AveragesMap(std::initializer_list<std::pair<int, Averages>> avgs) : MeanMap(std::initializer_list<std::pair<int, Mean>> avgs) :
LevelMap<Averages>(avgs) {}; LevelMap<Mean>(avgs) {};
AveragesMap(const MonteCarloMap &mcMap) { MeanMap(const MonteCarloMap &mcMap) {
Update(mcMap); Update(mcMap);
}; };
void Update(const MonteCarloMap &mcMap); void Update(const MonteCarloMap &mcMap);
}; };
struct VariancesMap : public LevelMap<Variances> { struct SVarMap : public LevelMap<SVar> {
VariancesMap() {}; SVarMap() {};
VariancesMap(std::initializer_list<std::pair<int, Variances>> vars) : SVarMap(std::initializer_list<std::pair<int, SVar>> vars) :
LevelMap<Variances>(vars) {}; LevelMap<SVar>(vars) {};
VariancesMap(const MonteCarloMap &mcMap) { SVarMap(const MonteCarloMap &mcMap) {
Update(mcMap); Update(mcMap);
}; };
...@@ -88,8 +85,8 @@ struct KurtosisMap : LevelMap<Kurtosis> { ...@@ -88,8 +85,8 @@ struct KurtosisMap : LevelMap<Kurtosis> {
struct MultiLevelMonteCarloData { struct MultiLevelMonteCarloData {
SampleCounterMap ctrs; SampleCounterMap ctrs;
AveragesMap avgs; MeanMap avgs;
VariancesMap vars; SVarMap vars;
KurtosisMap kurtosis; KurtosisMap kurtosis;
MultiLevelMonteCarloData() {}; MultiLevelMonteCarloData() {};
...@@ -98,8 +95,8 @@ struct MultiLevelMonteCarloData { ...@@ -98,8 +95,8 @@ struct MultiLevelMonteCarloData {
ExtractDataFrom(mcMap); ExtractDataFrom(mcMap);
} }
MultiLevelMonteCarloData(const SampleCounterMap &ctrs, const AveragesMap &avgs, MultiLevelMonteCarloData(const SampleCounterMap &ctrs, const MeanMap &avgs,
const VariancesMap &vars, const KurtosisMap &kurtosis) : const SVarMap &vars, const KurtosisMap &kurtosis) :
ctrs(ctrs), avgs(avgs), vars(vars), kurtosis(kurtosis) {}; ctrs(ctrs), avgs(avgs), vars(vars), kurtosis(kurtosis) {};
void ExtractDataFrom(const MonteCarloMap &mcMap); void ExtractDataFrom(const MonteCarloMap &mcMap);
......
...@@ -17,7 +17,7 @@ double Errors::EstimateNumeric(const MultiLevelMonteCarloData &data) { ...@@ -17,7 +17,7 @@ double Errors::EstimateNumeric(const MultiLevelMonteCarloData &data) {
return EstimateNumeric(data.avgs); return EstimateNumeric(data.avgs);
} }
double Errors::EstimateNumeric(const AveragesMap& avgs) { double Errors::EstimateNumeric(const MeanMap& avgs) {
auto _levels = avgs.GetLevelVector(); auto _levels = avgs.GetLevelVector();
auto _avgs = avgs.GetYVector(); auto _avgs = avgs.GetYVector();
double alpha = exponents.alpha; double alpha = exponents.alpha;
...@@ -39,7 +39,7 @@ double Errors::EstimateStochastic(const MultiLevelMonteCarloData &data) { ...@@ -39,7 +39,7 @@ double Errors::EstimateStochastic(const MultiLevelMonteCarloData &data) {
return EstimateStochastic(data.ctrs, data.vars); return EstimateStochastic(data.ctrs, data.vars);
} }
double Errors::EstimateStochastic(const SampleCounterMap &ctrs, const VariancesMap &vars) { double Errors::EstimateStochastic(const SampleCounterMap &ctrs, const SVarMap &vars) {
auto _ctrs = ctrs.GetMVector(); auto _ctrs = ctrs.GetMVector();
auto _vars = vars.GetYVector(); auto _vars = vars.GetYVector();
......
...@@ -17,11 +17,11 @@ struct Errors { ...@@ -17,11 +17,11 @@ struct Errors {
double EstimateNumeric(const MultiLevelMonteCarloData &data); double EstimateNumeric(const MultiLevelMonteCarloData &data);
double EstimateNumeric(const AveragesMap& avgs); double EstimateNumeric(const MeanMap& avgs);
double EstimateStochastic(const MultiLevelMonteCarloData &data); double EstimateStochastic(const MultiLevelMonteCarloData &data);
double EstimateStochastic(const SampleCounterMap &ctrs, const VariancesMap &vars); double EstimateStochastic(const SampleCounterMap &ctrs, const SVarMap &vars);
}; };
#endif //ERRORS_HPP #endif //ERRORS_HPP
...@@ -8,13 +8,13 @@ void Exponents::ComputeExponents(const MultiLevelMonteCarloData &data) { ...@@ -8,13 +8,13 @@ void Exponents::ComputeExponents(const MultiLevelMonteCarloData &data) {
ComputeExponents(data.avgs, data.vars); ComputeExponents(data.avgs, data.vars);
} }
void Exponents::ComputeExponents(const AveragesMap &avgs, const VariancesMap &vars) { void Exponents::ComputeExponents(const MeanMap &mean, const SVarMap &sVar) {
alpha = ComputeAlpha(avgs); alpha = ComputeAlpha(mean);
beta = ComputeBeta(vars); beta = ComputeBeta(sVar);
gamma = ComputeGamma(avgs); gamma = ComputeGamma(mean);
} }
double Exponents::ComputeAlpha(const AveragesMap &avgs) { double Exponents::ComputeAlpha(const MeanMap &avgs) {
auto _levels = avgs.GetLevelVector(); auto _levels = avgs.GetLevelVector();
auto _avgsY = avgs.GetYVector(); auto _avgsY = avgs.GetYVector();
...@@ -27,7 +27,7 @@ double Exponents::ComputeAlpha(const AveragesMap &avgs) { ...@@ -27,7 +27,7 @@ double Exponents::ComputeAlpha(const AveragesMap &avgs) {
return linearFit(levels, avgsY).first; return linearFit(levels, avgsY).first;
} }
double Exponents::ComputeBeta(const VariancesMap &vars) { double Exponents::ComputeBeta(const SVarMap &vars) {
auto _levels = vars.GetLevelVector(); auto _levels = vars.GetLevelVector();
auto _varsY = vars.GetYVector(); auto _varsY = vars.GetYVector();
...@@ -40,7 +40,7 @@ double Exponents::ComputeBeta(const VariancesMap &vars) { ...@@ -40,7 +40,7 @@ double Exponents::ComputeBeta(const VariancesMap &vars) {
return linearFit(levels, varsY).first; return linearFit(levels, varsY).first;
} }
double Exponents::ComputeGamma(const AveragesMap &avgs) { double Exponents::ComputeGamma(const MeanMap &avgs) {
auto _levels = avgs.GetLevelVector(); auto _levels = avgs.GetLevelVector();
auto _avgsCost = avgs.GetCostVector(); auto _avgsCost = avgs.GetCostVector();
......
...@@ -23,13 +23,13 @@ struct Exponents { ...@@ -23,13 +23,13 @@ struct Exponents {
void ComputeExponents(const MonteCarloMap &mcMap); void ComputeExponents(const MonteCarloMap &mcMap);
void ComputeExponents(const AveragesMap &avgs, const VariancesMap &vars); void ComputeExponents(const MeanMap &mean, const SVarMap &sVar);
double ComputeAlpha(const AveragesMap &avgs); double ComputeAlpha(const MeanMap &avgs);
double ComputeBeta(const VariancesMap &vars); double ComputeBeta(const SVarMap &vars);
double ComputeGamma(const AveragesMap &avgs); double ComputeGamma(const MeanMap &avgs);
std::pair<double, double> linearFit(std::vector<double> &x, std::vector<double> &y); std::pair<double, double> linearFit(std::vector<double> &x, std::vector<double> &y);
......
...@@ -20,40 +20,176 @@ struct SampleCounter { ...@@ -20,40 +20,176 @@ struct SampleCounter {
} }
void UpdateParallel(int commSplit) { void UpdateParallel(int commSplit) {
pout << "test" << endl;
M = PPM->SumOnCommSplit(Mcomm, 0) / PPM->Size(commSplit); M = PPM->SumOnCommSplit(Mcomm, 0) / PPM->Size(commSplit);
dM = PPM->SumOnCommSplit(dMcomm, 0) / PPM->Size(commSplit); dM = PPM->SumOnCommSplit(dMcomm, 0) / PPM->Size(commSplit);
} }
friend Logging &operator<<(Logging &s, const SampleCounter &ctr) { friend Logging &operator<<(Logging &s, const SampleCounter &ctr) {
return s << "M=" << ctr.M << " dM=" << ctr.dM return s << "M=" << ctr.M
<< " MComm=" << ctr.Mcomm << " dMComm=" << ctr.dMcomm << endl; << " dM=" << ctr.dM
<< " MComm=" << ctr.Mcomm
<< " dMComm=" << ctr.dMcomm << endl;
}
};
struct Mean {
double C = 0.0;
double Q = 0.0;
double Y = 0.0;
double Qcomm = 0.0;
double Ycomm = 0.0;
double Ccomm = 0.0;
void Update(double dC, double dQ, double dY, SampleCounter ctr) {
Ccomm += dC / ctr.Mcomm;
Qcomm += dQ / ctr.Mcomm;
Ycomm += dY / ctr.Mcomm;
}
void UpdateParallel(SampleCounter ctr, int commSplit) {
C = abs(PPM->SumAcrossComm(ctr.Mcomm * Ccomm, commSplit) / ctr.M);
Q = abs(PPM->SumAcrossComm(ctr.Mcomm * Qcomm, commSplit) / ctr.M);
Y = abs(PPM->SumAcrossComm(ctr.Mcomm * Ycomm, commSplit) / ctr.M);
}
friend Logging &operator<<(Logging &s, const Mean &mean) {
return s << "MeanQ=" << mean.Q
<< " MeanY=" << mean.Y
<< " MeanC=" << mean.C
<< " MeanQcomm=" << mean.Qcomm
<< " MeanYcomm=" << mean.Ycomm
<< " MeanCcomm=" << mean.Ccomm << endl;
}
};
struct SVar {
double C = 0.0;
double Q = 0.0;
double Y = 0.0;
double Ccomm = 0.0;
double Qcomm = 0.0;
double Ycomm = 0.0;
void Update(double C2comm, double Q2comm, double Y2comm, SampleCounter ctr) {
Ccomm = C2comm / (ctr.Mcomm - 1);
Qcomm = Q2comm / (ctr.Mcomm - 1);
Ycomm = Y2comm / (ctr.Mcomm - 1);
}
void UpdateParallel(int commSplit) {
}
friend Logging &operator<<(Logging &s, const SVar &sVar) {
return s << "SVarQ=" << sVar.Q
<< " SVarY=" << sVar.Y
<< " SVarC=" << sVar.C
<< " SVarQcomm=" << sVar.Qcomm
<< " SVarYcomm=" << sVar.Ycomm
<< " SVarCcomm=" << sVar.Ccomm << endl;
}
};
struct Skewness {
double C = 0.0;
double Q = 0.0;
double Y = 0.0;
double Ccomm = 0.0;
double Qcomm = 0.0;
double Ycomm = 0.0;
void Update() {
}
void UpdateParallel(int commSplit) {
}
friend Logging &operator<<(Logging &s, const Skewness &skewness) {
return s << "S[Q]=" << skewness.Q << " S[Y]=" << skewness.Y << endl;
}
};
struct Kurtosis {
double C = 0.0;
double Q = 0.0;
double Y = 0.0;
double Ccomm = 0.0;
double Qcomm = 0.0;
double Ycomm = 0.0;
void Update() {//Averages avgs, Variances vars) {
// Q = (avgs.Q4 - 4.0 * avgs.Q3 * avgs.Q + 6.0 * avgs.Q2 * avgs.Q * avgs.Q -
// 3.0 * avgs.Q * avgs.Q * avgs.Q * avgs.Q) / vars.Q / vars.Q;
// Y = (avgs.Y4 - 4.0 * avgs.Y3 * avgs.Y + 6.0 * avgs.Y2 * avgs.Y * avgs.Y -
// 3.0 * avgs.Y * avgs.Y * avgs.Y * avgs.Y) / vars.Y / vars.Y;
// if (Y > 100.0) Warning("Kurtosis of Y above 100!")
}
void UpdateParallel(int commSplit) {
}
friend Logging &operator<<(Logging &s, const Kurtosis &kurtosis) {
return s << "K[Q]=" << kurtosis.Q << " K[Y]=" << kurtosis.Y << endl;
} }
}; };
class WelfordAggregate { class WelfordAggregate {
private:
double C2comm = 0.0;
double Q2comm = 0.0;
double Y2comm = 0.0;
double C3comm = 0.0;
double Q3comm = 0.0;
double Y3comm = 0.0;
double C4comm = 0.0;
double Q4comm = 0.0;
double Y4comm = 0.0;
public: public:
SampleCounter ctr; SampleCounter ctr;
Mean mean;
double MeanQcomm = 0.0; SVar sVar;
double Q2comm = 0.0;
double SVarQcomm = 0.0;
double MeanYcomm = 0.0; Skewness skewness;
double Y2comm = 0.0;