Commit d931a42e authored by niklas.baumgarten's avatar niklas.baumgarten
Browse files

added new way to log information

parent 33b9b8b0
#include "MonteCarloLogger.h"
#ifndef MLMC__MULTILEVELMONTECARLO__HPP
#define MLMC__MULTILEVELMONTECARLO__HPP
#include "m++.h"
class MultilevelMonteCarloLogger {
private:
Date timestamp;
int verbose = 0;
public:
string default_indent = " ";
string indent = "";
string inner_indent = default_indent;
MultilevelMonteCarloLogger() {
ReadConfig(Settings, "MLMCVerbose", verbose);
}
void increase_indent() {
indent += default_indent;
inner_indent += default_indent;
}
void decrease_indent() {
int pos = indent.rfind(default_indent);
if (pos != -1) {
indent.erase(pos, -3);
inner_indent.erase(pos, -3);
}
}
virtual string name() {
return "MLMC";
}
virtual void startMethodMSG() {
Date start;
timestamp = start;
vout (1) << indent << "<Start MLMC method>" << endl;
}
virtual void endMethodMSG() {
vout (1) << indent << "<End after " << Date() - timestamp << ">" << endl;
}
virtual void logMSGV1(string msg) {
vout(1) << inner_indent << msg << endl;
}
virtual void logMSGV2(string msg) {
vout(2) << inner_indent << msg << endl;
}
};
class MonteCarloLogger : public MultilevelMonteCarloLogger {
private:
Date timestamp;
int verbose = 0;
public:
MonteCarloLogger() : MultilevelMonteCarloLogger() {
ReadConfig(Settings, "MCVerbose", verbose);
indent += default_indent;
inner_indent += default_indent;
}
void startMethodMSG() override {
Date start;
timestamp = start;
vout (1) << indent << "<Start MC method>" << endl;
}
void endMethodMSG() override {
vout (1) << indent << "<End after " << Date() - timestamp << ">" << endl;
}
void logMSGV1(string msg) override {
vout(1) << inner_indent << msg << endl;
}
void logMSGV2(string msg) override {
vout(2) << inner_indent << msg << endl;
}
};
#endif //MLMC__MULTILEVELMONTECARLO__HPP
......@@ -38,19 +38,14 @@ void MultilevelMonteCarlo::clearMapMC() {
}
void MultilevelMonteCarlo::method() {
Date Start;
vout (1) << "Start multilevel Monte Carlo method only for initial values" << endl;
logger->startMethodMSG();
for (auto &mc : map_mc)
mc.second->method();
vout (1) << "End after " << Date() - Start << endl;
logger->endMethodMSG();
}
void MultilevelMonteCarlo::method(const double eps) {
Date Start;
vout (1) << "Start multilevel Monte Carlo method for epsilon " << eps << endl;
logger->startMethodMSG();
bool converged = false;
while (!converged) {
for (auto &mc : map_mc)
......@@ -58,26 +53,16 @@ void MultilevelMonteCarlo::method(const double eps) {
mc.second->method();
estimateExponents();
vout (2) << " Estimated exponents: " << "alpha=" << alpha
<< " beta=" << beta << " gamma=" << gamma << endl;
updateNumSamples(eps);
bool check_for_new_level = true;
for (auto &mc : map_mc) {
if (mc.second->dM > 0) {
check_for_new_level = false;
break;
}
}
if (check_for_new_level) {
if (checkForNewLevel()) {
double err = estimateNumericalError();
if (err > eps / sqrt(2.0)) {
int L = map_mc.rbegin()->first + 1;
if (L > Lmax) {
Exit ("Maximum level has been reached.")
} else {
vout(2) << " Append level " << L << endl;
logger->logMSGV2("append level " + to_string(L));
map_mc[L] = getMonteCarlo(L, 0, false);
map_mc[L]->var_Y = map_mc[L - 1]->var_Y / pow(2.0, beta);
map_mc[L]->avg_cost = map_mc[L - 1]->avg_cost * pow(2.0, gamma);
......@@ -91,19 +76,12 @@ void MultilevelMonteCarlo::method(const double eps) {
Vector u((*graphs)[map_mc.rbegin()->first - pLevel]);
u = 0.0;
wrapUpResults(u, value, cost, levels, numsamples);
if (plotting >= 1) {
}
if (plotting >= 2) {
}
vout (1) << "End after " << Date() - Start << endl;
logger->endMethodMSG();
}
void MultilevelMonteCarlo::method(const vector<double> &eps_lst) {
Date Start;
vout (1) << "Start multilevel Monte Carlo method for several epsilon" << endl;
logger->startMethodMSG();
logger->increase_indent();
for (auto &eps : eps_lst) {
initializeMapMC();
initializeValuesMLMC();
......@@ -113,8 +91,8 @@ void MultilevelMonteCarlo::method(const vector<double> &eps_lst) {
value_vs_eps.push_back(value);
cost_vs_eps.push_back(cost);
}
vout (1) << "End after " << Date() - Start << endl;
logger->decrease_indent();
logger->endMethodMSG();
}
void MultilevelMonteCarlo::estimateExponents(bool excludeBaseLevel) {
......@@ -136,6 +114,11 @@ void MultilevelMonteCarlo::estimateExponents(bool excludeBaseLevel) {
beta = v.front();
v = linear_fit(level_lst, costs);
gamma = v.front();
string msg = "alpha: " + to_string(alpha) +
" beta: " + to_string(beta) +
" gamma: " + to_string(gamma);
logger->logMSGV2(msg);
}
void MultilevelMonteCarlo::updateNumSamples(const double &eps) {
......@@ -149,9 +132,21 @@ void MultilevelMonteCarlo::updateNumSamples(const double &eps) {
if (M_optimal == 1) M_optimal++; // Hack
map_mc[mc.first]->dM = M_optimal - map_mc[mc.first]->M;
}
vout(2) << " Missing samples:";
for (auto &mc:map_mc) vout(1) << " " << mc.second->dM;
vout(2) << endl;
string msg = "dM:";
for (auto &mc:map_mc) msg += " " + to_string(mc.second->dM);
logger->logMSGV2(msg);
}
bool MultilevelMonteCarlo::checkForNewLevel() {
bool newLevel = true;
for (auto &mc : map_mc) {
if (mc.second->dM > 0) {
newLevel = false;
break;
}
}
return newLevel;
}
double MultilevelMonteCarlo::estimateNumericalError() {
......@@ -255,19 +250,10 @@ void MultilevelMonteCarlo::showExponentResults() {
void MultilevelMonteCarlo::showResultsMLMCRun(double eps) {
showResultsMLMCRunHead();
string level_str, sample_str;
mout << setw(6) << eps << setw(12) << value << setw(12) << cost;
for (unsigned long i = 0; i < levels.size(); i++) {
if (i != levels.size() - 1) level_str += to_string(levels[i]) + " ";
else level_str += to_string(levels[i]);
}
mout << setw(14) << level_str;
for (unsigned long i = 0; i < numsamples.size(); i++) {
if (i != numsamples.size() - 1) sample_str += to_string(numsamples[i]) + " ";
else sample_str += to_string(numsamples[i]);
}
mout << setw(36) << sample_str << endl;
string level_str = vec2str(levels);
string sample_str = vec2str(numsamples);
mout << setw(6) << eps << setw(12) << value << setw(12) << cost
<< setw(14) << level_str << setw(36) << sample_str << endl;
showTableBottom();
}
......@@ -297,7 +283,3 @@ void MultilevelMonteCarlo::showResultsOverEpsilon(const vector<double> &eps_lst)
}
showTableBottom();
}
#ifndef MULTILEVELMONTECARLO_H
#define MULTILEVELMONTECARLO_H
#include "MonteCarloLogger.h"
#include "mc/MonteCarloElliptic.h"
#include "mc/MonteCarloTransport.h"
class MultilevelMonteCarlo {
public:
int verbose = 0, plotting = 0;
MultilevelMonteCarloLogger *logger;
int Lmax, pLevel;
vector<int> &l_init, &M_init;
......@@ -35,25 +37,30 @@ public:
ReadConfig(Settings, "MLMCVerbose", verbose);
ReadConfig(Settings, "MLMCPlotting", plotting);
logger = new MultilevelMonteCarloLogger();
initializeMapMC();
}
~MultilevelMonteCarlo() {
delete logger;
clearMapMC();
}
MonteCarlo *getMonteCarlo(int l, int dM, bool baseLevel);
void initializeMapMC();
void initializeValuesMLMC();
~MultilevelMonteCarlo() {
clearMapMC();
}
void clearMapMC();
void estimateExponents(bool excludeBaseLevel = true);
void updateNumSamples(const double &eps);
bool checkForNewLevel();
double estimateNumericalError();
void wrapUpResults(Vector &u, double &val, double &mlmc_cost,
......
......@@ -3,10 +3,12 @@
#include "m++.h"
#include "stochfields/StochasticFields.h"
#include "MonteCarloLogger.h"
class MonteCarlo {
public:
int verbose = 0, plotting = 0;
MonteCarloLogger *logger;
int l = 0, plevel = 0;
bool baseLevel = true;
......@@ -41,15 +43,18 @@ public:
u_sum_diff(u_sum), u_avg_diff(u_sum),
plot((*meshes)[l], meshes->dim(), 2) {
ReadConfig(Settings, "MCVerbose", verbose);
ReadConfig(Settings, "MCPlotting", plotting);
ReadConfig(Settings, "functional", functional);
logger = new MonteCarloLogger();
u_sum = 0.0, u_avg = 0.0, u_sum_diff = 0.0, u_avg_diff = 0.0;
}
virtual ~MonteCarlo() = default;;
~MonteCarlo() {
delete logger;
}
void updateSum(const double *sums) {
sum_cost += sums[0];
......
......@@ -3,10 +3,15 @@
using namespace std;
void MonteCarloElliptic::method() {
Date Start;
vout(1) << " Start Monte Carlo method on level " << l;
if (!baseLevel) vout(1) << " and level " << l - 1;
vout(1) << " with " << dM << " samples" << endl;
logger->startMethodMSG();
if (!baseLevel)
logger->logMSGV1("l: " + to_string(l)
+ " dM: " + to_string(dM));
else
logger->logMSGV1("l: " + to_string(l)
+ " dM: " + to_string(dM)
+ " baseLevel: True");
stochFields->setCurrentLevel(l);
for (int m = M; m < M + dM; m++) {
......@@ -31,14 +36,8 @@ void MonteCarloElliptic::method() {
Vector uf(u_sum), uc_up(u_sum), uc((*graphs)[l - plevel - 1]);
uf = 0.0, uc = 0.0, uc_up = 0.0;
Vector fluxf(flux_sum), fluxc_up(flux_sum);
fluxf = 0.0, fluxc_up = 0.0;
Vector permf(flux_sum), permc_up(flux_sum);
permf = 0.0, permc_up = 0.0;
Date Start_solving;
vout(2) << " Solving PDE on level " << l;
logger->logMSGV2("solve PDE on level " + to_string(l));
solveElliptic(Qf, costf, uf);
vout(2) << " took " << Start_solving - Date() << endl;
......@@ -65,11 +64,15 @@ void MonteCarloElliptic::method() {
updateUSum(uc_up, uf);
if (plotting >= 2) {
Vector fluxf(flux_sum), permf(flux_sum);;
fluxf = 0.0, permf = 0.0;
assemble->setFlux(uf, fluxf);
assemble->setPerm(permf);
plotSolution(uf, fluxf, permf, m, "");
}
if (plotting >= 3 && !baseLevel) {
Vector fluxc_up(flux_sum), permc_up(flux_sum);
fluxc_up = 0.0, permc_up = 0.0;
stochFields->setFineField(false);
assemble->setFlux(uc_up, fluxc_up);
assemble->setPerm(permc_up);
......@@ -89,8 +92,9 @@ void MonteCarloElliptic::method() {
-1, "avg");
}
vout (1) << " End after " << Date() - Start << ": |E(Y)|=" << avg_Y
<< " V(Y)=" << var_Y << endl;
logger->logMSGV1("|E[Y]|: " + to_string(avg_Y)
+ " V[Y]: " + to_string(var_Y));
logger->endMethodMSG();
}
void MonteCarloElliptic::solveElliptic(double &Q, double &cost, Vector &u) {
......
......@@ -32,7 +32,7 @@ public:
perm_sum = 0.0, perm_avg = 0.0, perm_sum_diff = 0.0, perm_avg_diff = 0.0;
}
~MonteCarloElliptic() override {
~MonteCarloElliptic() {
transfer->Destruct();
delete transfer;
}
......
......@@ -21,7 +21,7 @@ public:
transfer->Construct((*graphs)[l - plevel], (*graphs)[l - plevel - 1]);
}
~MonteCarloTransport() override {
~MonteCarloTransport() {
transfer->Destruct();
delete transfer;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment