From bdc12117a791f51ffb45be2b2280b76b0e9f2828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gi=C3=B9=20Marcer?= Date: Tue, 19 May 2020 16:01:52 +0200 Subject: [PATCH] ex-5: revised and typo-fixed Some images and an article have also been added to the folder. The todo has been updated too as well as the readme. --- README.md | 45 ++- ex-5/main.c | 29 +- ex-5/plot.py | 4 +- notes/docs/bibliography.bib | 32 +++ notes/images/{MC_some.pdf => MC_MC.pdf} | Bin 17005 -> 14782 bytes notes/images/{MC_all.pdf => MC_MC_MI.pdf} | Bin 17593 -> 16296 bytes notes/images/{MC_few.pdf => MC_MI_VE.pdf} | Bin notes/sections/4.md | 3 +- notes/sections/5.md | 319 +++++++++++++--------- notes/todo | 2 - 10 files changed, 276 insertions(+), 158 deletions(-) mode change 100644 => 100755 ex-5/plot.py rename notes/images/{MC_some.pdf => MC_MC.pdf} (60%) rename notes/images/{MC_all.pdf => MC_MC_MI.pdf} (69%) rename notes/images/{MC_few.pdf => MC_MI_VE.pdf} (100%) diff --git a/README.md b/README.md index 070dcaa..3c33f27 100644 --- a/README.md +++ b/README.md @@ -42,15 +42,15 @@ See this [guide](https://nixos.org/nix/manual/#chap-quick-start) if you have never used Nix before. Running `nix-shell` in the top-level will drop you into the development shell. -Once ready, invoke `make` with the program you wish to build. For example +Once ready, invoke `make` with the program you wish to build. For example: $ make ex-1/bin/main -or, to build every program of an exercise +or, to build every program of an exercise: $ make ex-1 -To clean up the build results run +To clean up the build results run: $ make clean @@ -82,9 +82,9 @@ The output can be redirected to `ex-1/pdf-plot.py` to generate a plot. Every program in `ex-2` computes the best available approximation (with a given method) to the Euler-Mascheroni γ constant and prints[1]: -1. the leading decimal digits of the approximate value found +1. the leading decimal digits of the approximate value found; -2. the exact decimal digits of γ +2. the exact decimal digits of γ; 3. the absolute difference between the 1. and 2. @@ -104,7 +104,7 @@ cases the best fit and the parameter covariance matrix are printed. The program then performs a t-test to assert the compatibility of the data with two hypothesis and print the results in a table. -To plot a 2D histogram of the generated sample do +To plot a 2D histogram of the generated sample do: $ ex-3/bin/main -i | ex-3/plot.py @@ -123,7 +123,7 @@ horizontal component. It is possible to set the maximum momentum with the option `-p`. A χ² fit and a t-test compatibility are performed with respect to the expected distribution and results are printed. -To plot a histogram of the generated sample do +To plot a histogram of the generated sample do: $ ex-4/bin/main -o | ex-4/plot.py @@ -133,11 +133,30 @@ and `-b`. ### Exercise 5 -`ex-5/main` compute the integral of exp(1) between 0 and 1 with the methods -plain MC, MISER and VEGAS. Being reiterative routines, it takes the number of -iterations as its only argument. -It prints out the obatined value and its estimated error for each method. +`ex-5/main` compute estimations of the integral of exp(1) between 0 and 1 +with the methods plain MC, MISER and VEGAS with different number of points. +It takes no arguments in input. +It prints out eight columns: +1. the number of sorted points; + +2. the integral estimation with plain MC; + +3. its uncertainty; + +4. the integral estimation with MISER; + +5. its uncertainty; + +6. the integral estimation with VEGAS; + +7. its uncertainty; + +8. its χ². + +To plot the results do: + + $ ex-5/main | ex-5/plot.py ### Exercise 6 @@ -167,8 +186,8 @@ classified data in this order: signal then noise. To plot the result of the linear classification pipe the output to `ex-7/plot.py`. The program generates two figures: - - a scatter plot showing the Fisher projection line and the cut line - - two histograms of the projected data and the cut line + - a scatter plot showing the Fisher projection line and the cut line; + - two histograms of the projected data and the cut line. `ex-7/bin/test` takes a model trained in `ex-7/bin/main` and test it against newly generated datasets (`-i` to set the number of test iterations). The diff --git a/ex-5/main.c b/ex-5/main.c index bfb6014..39931b5 100644 --- a/ex-5/main.c +++ b/ex-5/main.c @@ -15,14 +15,18 @@ double function (double * x, size_t dim, void * params) // Function which prints out the results when called. // -void results (size_t calls, double result, double error) +void results (size_t calls, double result, double error, double chi) { if (calls != 0) { - printf ("%ld\t", calls); + printf ("%.0e\t", (double)calls); } printf ("%.10f\t", result); printf ("%.10f\t", error); + if (chi != 0) + { + printf ("%.3f\t", chi); + } } @@ -33,7 +37,7 @@ int main(int argc, char** argv) size_t dims = 1; // Integral dimension double lower[1] = {0}; // Integration lower limit double upper[1] = {1}; // Integration upper limit - size_t calls = 5000; // Initial number of function calls + size_t calls = 50; // Initial number of function calls double integral, error; // Initialize an RNG. @@ -65,26 +69,37 @@ int main(int argc, char** argv) gsl_monte_plain_integrate (&expo, lower, upper, dims, calls, r, sMC, &integral, &error); gsl_monte_plain_free(sMC); - results(calls, integral, error); + results(calls, integral, error, 0); // MISER gsl_monte_miser_state *sMI = gsl_monte_miser_alloc (dims); gsl_monte_miser_integrate (&expo, lower, upper, dims, calls, r, sMI, &integral, &error); gsl_monte_miser_free(sMI); - results(0, integral, error); + results(0, integral, error, 0); // VEGAS gsl_monte_vegas_state *sVE = gsl_monte_vegas_alloc (dims); gsl_monte_vegas_integrate (&expo, lower, upper, dims, calls, r, sVE, &integral, &error); + + // In order to see the parameters of the VEGAS integration, decomment this + // paragraph: + // + // gsl_monte_vegas_params params; + // gsl_monte_vegas_params_get(sVE, ¶ms); + // params.verbose = 1; + // params.ostream = stderr; + // gsl_monte_vegas_params_set(sVE, ¶ms); do { gsl_monte_vegas_integrate (&expo, lower, upper, dims, - calls/5, r, sVE, &integral, &error); + calls, r, sVE, &integral, &error); } while (fabs (gsl_monte_vegas_chisq (sVE) - 1.0) > 0.5); gsl_monte_vegas_free(sVE); - results(0, integral, error); + double chi = sVE->chisq; + results(0, integral, error, chi); + // Update function calls printf ("\n"); diff --git a/ex-5/plot.py b/ex-5/plot.py old mode 100644 new mode 100755 index 4c74c51..d297e70 --- a/ex-5/plot.py +++ b/ex-5/plot.py @@ -1,8 +1,10 @@ +#!/usr/bin/env python + import matplotlib.pyplot as plt import numpy as np import sys -calls, I_MC, σ_MC, I_MI, σ_MI, I_VE, σ_VE = np.loadtxt(sys.stdin, unpack=True) +calls, I_MC, σ_MC, I_MI, σ_MI, I_VE, σ_VE, chi = np.loadtxt(sys.stdin, unpack=True) exact = 1.7182818285 plt.rcParams['font.size'] = 17 diff --git a/notes/docs/bibliography.bib b/notes/docs/bibliography.bib index f73e77b..af6bf5e 100644 --- a/notes/docs/bibliography.bib +++ b/notes/docs/bibliography.bib @@ -106,3 +106,35 @@ year={2005}, journal={Matrix} } + +@article{sayah19, + title={Adaptive stratified Monte Carlo algorithm for numerical computation + of integrals}, + author={Sayah, Toni}, + journal={Mathematics and Computers in Simulation}, + volume={157}, + pages={143--158}, + year={2019}, + publisher={Elsevier} +} + + +@article{ridder17, + title={Variance reduction}, + author={Ridder, AAN and Botev, ZI}, + journal={Wiley StatsRef: Statistics Reference Online}, + pages={1--6}, + year={2017}, + publisher={Wiley} +} + +@article{lepage78, + title={A new algorithm for adaptive multidimensional integration}, + author={Lepage, G Peter}, + journal={Journal of Computational Physics}, + volume={27}, + number={2}, + pages={192--203}, + year={1978}, + publisher={Elsevier} +} diff --git a/notes/images/MC_some.pdf b/notes/images/MC_MC.pdf similarity index 60% rename from notes/images/MC_some.pdf rename to notes/images/MC_MC.pdf index f995a9a9fc28f4e38a1127ebe580fa1736decc6c..2f0e06130febf694e6a6c5f1d9022dc81a2bf24e 100644 GIT binary patch delta 4619 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
(}hPc6yPNn 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