diff --git a/exercises/week5/series/sources-solution/compute_algebraic.py b/exercises/week5/series/sources-solution/compute_algebraic.py new file mode 100644 index 0000000..6dbab63 --- /dev/null +++ b/exercises/week5/series/sources-solution/compute_algebraic.py @@ -0,0 +1,18 @@ +from __future__ import print_function +from series import Series +################################################################ + + +class ComputeAlgebraic(Series): + + def __init__(self): + Series.__init__(self) + + def __del__(self): + pass + + def getAnalyticPrediction(self): + return 1.*self.current_term*(self.current_term+1)/2. + + def computeTerm(self, k): + return 1.*k diff --git a/exercises/week5/series/sources-solution/compute_pi.py b/exercises/week5/series/sources-solution/compute_pi.py new file mode 100644 index 0000000..393b9ed --- /dev/null +++ b/exercises/week5/series/sources-solution/compute_pi.py @@ -0,0 +1,24 @@ +from __future__ import print_function +import math +from series import Series +################################################################ + + +class ComputePi(Series): + + def __init__(self,): + Series.__init__(self) + self.current_value = 0 + + def __del__(self): + pass + + def compute(self, N): + Series.compute(self, N) + return math.sqrt(6.*self.current_value) + + def computeTerm(self, k): + return 1./(1.*k*k) + + def getAnalyticPrediction(self): + return math.pi diff --git a/exercises/week5/series/sources-solution/dumper_series.py b/exercises/week5/series/sources-solution/dumper_series.py new file mode 100644 index 0000000..516a10f --- /dev/null +++ b/exercises/week5/series/sources-solution/dumper_series.py @@ -0,0 +1,21 @@ +from abc import ABC, abstractmethod + + +class DumperSeries(ABC): + + def __init__(self, series): + self.series = series + self.precision = 4 + + def __del__(self): + pass + + @abstractmethod + def dump(self): + pass + + def setPrecision(self, precision): + self.precision = precision + + def __str__(self): + return self.dump() diff --git a/exercises/week5/series/sources-solution/main.py b/exercises/week5/series/sources-solution/main.py new file mode 100644 index 0000000..138659b --- /dev/null +++ b/exercises/week5/series/sources-solution/main.py @@ -0,0 +1,55 @@ +################################################################ +from __future__ import print_function +import sys +from compute_pi import ComputePi +from compute_algebraic import ComputeAlgebraic +from print_series import PrintSeries +from plot_series import PlotSeries +################################################################ + + +def main(): + + argc = len(sys.argv) + if argc < 5: + print('Usage: python3 main.py series_type dumper_type maxiter freq\n\n' + '\tseries_type: pi/algebraic\n' + '\tdumper_type: print/plot\n' + '\tmaxiter: number of loop iteration to compute the series\n' + '\tfreq: frequency at which dumps/plots are made\n\n') + sys.exit(-1) + + series_type = sys.argv[1] + dumper_type = sys.argv[2] + maxiter = int(sys.argv[3]) + freq = int(sys.argv[4]) + + outfile = "" + if argc == 6: + outfile = sys.argv[5] + + if series_type == "pi": + serie_object = ComputePi() + elif series_type == "algebraic": + serie_object = ComputeAlgebraic() + else: + raise RuntimeError("unknown series type: " + series_type) + + if dumper_type == "print": + dumper_object = PrintSeries(serie_object, maxiter, freq) + elif dumper_type == "plot": + dumper_object = PlotSeries(serie_object, maxiter, freq) + else: + print("unknown dumper type: " + dumper_type) + sys.exit(-1) + + dumper_object.setPrecision(20) + + if outfile != "": + _file = open(outfile, 'w') + _file.write(str(dumper_object)) + else: + print(dumper_object) + + +main() diff --git a/exercises/week5/series/sources-solution/plot_series.py b/exercises/week5/series/sources-solution/plot_series.py new file mode 100644 index 0000000..f716d1b --- /dev/null +++ b/exercises/week5/series/sources-solution/plot_series.py @@ -0,0 +1,40 @@ +from __future__ import print_function +from dumper_series import DumperSeries +import matplotlib.pyplot as plt +################################################################ + + +class PlotSeries(DumperSeries): + + def __init__(self, series, maxiter, freq): + + DumperSeries.__init__(self, series) + + self.maxiter = maxiter + self.freq = freq + + def __del__(self): + pass + + def dump(self): + + fig = plt.figure() + axe = fig.add_subplot(1, 1, 1) + x = [] + numerical = [] + analytic = [] + + for i in range(1, int(self.maxiter/self.freq)): + res = self.series.compute(i*self.freq-1) + x.append(i*self.freq) + numerical.append(res) + analytic.append(self.series.getAnalyticPrediction()) + + axe.plot(x, numerical, marker='o', label='Numerical') + axe.plot(x, analytic, label='Analytical') + axe.set_xlabel(r'$k$') + axe.set_ylabel(r'Series') + axe.legend() + plt.show() + + return "Plotted" diff --git a/exercises/week5/series/sources-solution/print_series.py b/exercises/week5/series/sources-solution/print_series.py new file mode 100644 index 0000000..f41fdd6 --- /dev/null +++ b/exercises/week5/series/sources-solution/print_series.py @@ -0,0 +1,38 @@ +from __future__ import print_function +import math +from dumper_series import DumperSeries +################################################################ + + +class PrintSeries(DumperSeries): + + def __init__(self, series, maxiter, freq): + + DumperSeries.__init__(self, series) + + self.maxiter = maxiter + self.freq = freq + + def __del__(self): + pass + + def dump(self): + out = "" + for i in range(1, int(self.maxiter/self.freq)): + res = self.series.compute(i*self.freq-1) + res2 = self.series.compute(i*self.freq) + + my_format = '{:.' + str(self.precision) + 'e}' + out += str(i*self.freq) + " " + out += my_format.format(res) + " " + out += my_format.format(res2 - res) + + try: + out += " " + my_format.format( + math.fabs(res2 - self.series.getAnalyticPrediction())) + + except Exception as e: + pass + + out += "\n" + return out diff --git a/exercises/week5/series/sources-solution/series.py b/exercises/week5/series/sources-solution/series.py new file mode 100644 index 0000000..d28db43 --- /dev/null +++ b/exercises/week5/series/sources-solution/series.py @@ -0,0 +1,34 @@ +from abc import ABC, abstractmethod + + +class Series(ABC): + + def __init__(self): + self.current_term = 0 + self.current_value = 0 + + def __del__(self): + pass + + def compute(self, N): + if self.current_term <= N: + N -= self.current_term + else: + self.current_value = 0. + self.current_term = 0 + + for k in range(0, N): + self.addTerm() + + return self.current_value + + @abstractmethod + def getAnalyticPrediction(self): + pass + + def addTerm(self): + self.current_term += 1 + self.current_value += self.computeTerm(self.current_term) + + def computeTerm(self, k): + pass diff --git a/exercises/week5/series/sujet.pdf b/exercises/week5/series/sujet.pdf new file mode 100644 index 0000000..8f1f8bd Binary files /dev/null and b/exercises/week5/series/sujet.pdf differ