From 60750bff8a7529982a695af2b077a2ce4c76a453 Mon Sep 17 00:00:00 2001 From: Pascal Resch Date: Sun, 22 Nov 2020 17:26:33 +0100 Subject: [PATCH 1/6] Add class that handles plots from csv files --- .../Final/FinalExtrapolationErrorPlots.ipynb | 254 ++++++------------ src/PerformTestCase.py | 167 +++++++++++- 2 files changed, 234 insertions(+), 187 deletions(-) diff --git a/ipynb/Extrapolation/Results/Final/FinalExtrapolationErrorPlots.ipynb b/ipynb/Extrapolation/Results/Final/FinalExtrapolationErrorPlots.ipynb index 25d8645..01f5fb7 100644 --- a/ipynb/Extrapolation/Results/Final/FinalExtrapolationErrorPlots.ipynb +++ b/ipynb/Extrapolation/Results/Final/FinalExtrapolationErrorPlots.ipynb @@ -5,9 +5,7 @@ "execution_count": null, "outputs": [], "source": [ - "import csv\n", - "import matplotlib.pyplot as plt\n", - "\n", + "from PerformTestCase import PlotTestCase\n", "colormap = {\n", " \"Gauss-Legendre Grid (Standard Combi) lmin=1\": \"tab:gray\",\n", " \"Gauss-Legendre Grid (Standard Combi) lmin=2\": \"silver\",\n", @@ -56,77 +54,6 @@ " \"Extrapolation Grid (Grouped Optimized, Romberg, Simpson Romberg, Balanced)\": \"-\"\n", "}\n", "\n", - "def plot_csv_data(import_filename, algorithm_subset=None, plot_filename=None, \n", - " import_filepath=\"../\", export_filepath=\"./\", legend_title=None):\n", - " # Read\n", - " import_data = []\n", - " \n", - " # if not os.path.isfile(import_filepath):\n", - " # raise RuntimeError(\"Import-File {}{}.csv does not exist.\".format(import_filepath, import_filename))\n", - " \n", - " with open(\"{}{}.csv\".format(import_filepath, import_filename), newline='') as csvfile:\n", - " csv_reader = csv.reader(csvfile, delimiter='|', quoting=csv.QUOTE_NONNUMERIC)\n", - " \n", - " buffer = []\n", - " \n", - " for row in csv_reader:\n", - " if len(row) > 0:\n", - " row_type = row[0]\n", - " row_data = row[1:]\n", - " \n", - " if row_type == \"name\":\n", - " buffer.extend(row_data)\n", - " else:\n", - " buffer.append(row_data)\n", - " else:\n", - " import_data.append(buffer)\n", - " buffer = []\n", - " \n", - " # Append last algorithm, if buffer is not empty.\n", - " # This is for example the case if there is no blank line at the bottom of the csv file \n", - " if len(buffer) > 0:\n", - " import_data.append(buffer)\n", - "\n", - " # Plot \n", - " fig = plt.figure(num=None, figsize=(8, 6), dpi=100, facecolor='w', edgecolor='w')\n", - " ax = fig.add_subplot(111)\n", - " \n", - " for name, num_points, error in import_data:\n", - " if algorithm_subset is not None and name not in algorithm_subset:\n", - " continue\n", - " \n", - " color = colormap[name]\n", - " line_style = line_style_map[name]\n", - "\n", - " ax.loglog(num_points, error, line_style, color=color, label=name)\n", - " \n", - " if legend_title is not None:\n", - " ax.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc='lower left',\n", - " ncol=1, mode=\"expand\", borderaxespad=0., title=legend_title)\n", - " \n", - " ax.set_xlabel('Number of points')\n", - " ax.set_ylabel('Approximation error')\n", - " \n", - " if plot_filename is not None:\n", - " ax.figure.savefig(\"{}{}.pdf\".format(export_filepath, plot_filename), bbox_inches='tight', dpi=300)\n", - "\n", - "# Make legend https://stackoverflow.com/questions/4534480/get-legend-as-a-separate-picture-in-matplotlib\n", - "import pylab\n", - "import numpy as np\n", - "\n", - "def export_legend(algorithms, filename=\"legend\", export_filepath=\".\"):\n", - " figData = pylab.figure()\n", - " ax = pylab.gca()\n", - " x = np.arange(10)\n", - " \n", - " for i, algo in enumerate(algorithms):\n", - " pylab.plot(x, x * (i+1), line_style_map[algo], color=colormap[algo], label=algo)\n", - " \n", - " figlegend = pylab.figure()\n", - " figlegend.legend(*ax.get_legend_handles_labels(), loc=\"center\", mode=\"expand\", prop={'size': 9})\n", - " figlegend.show()\n", - " figlegend.savefig(\"{}/{}.pdf\".format(export_filepath, filename))\n", - "\n", "function_names = [\n", " \"FunctionExpVar\",\n", " \"GenzC0\",\n", @@ -138,13 +65,16 @@ "]\n", "\n", "dim = 5\n", - "directory = \"{}d/medium_hard\".format(dim)\n" + "directory = \"{}d/medium_hard\".format(dim)\n", + "\n", + "plot_test_case = PlotTestCase(colormap=colormap, line_style_map=line_style_map,\n", + " import_filepath=\"../{}/\".format(directory),\n", + " export_filepath=\"./{}/\".format(directory))\n" ], "metadata": { "collapsed": false, "pycharm": { - "name": "#%%\n", - "is_executing": false + "name": "#%%\n" } } }, @@ -212,22 +142,17 @@ " title = \"{} {}D\".format(function_name, dim) \n", " plot_filename = \"error_comparison_{}_{}d\".format(function_name, dim)\n", "\n", - " print(\"Processing {}.csv ...\".format(import_filename))\n", - "\n", - " plot_csv_data(import_filename,\n", - " import_filepath=\"../{}/\".format(directory),\n", - " export_filepath=\"./{}/\".format(directory),\n", - " algorithm_subset=compare_algorithms,\n", - " legend_title=None,\n", - " plot_filename=plot_filename)\n", + " plot_test_case.plot_error_approximation(import_filename,\n", + " algorithm_subset=compare_algorithms,\n", + " legend_title=None,\n", + " plot_filename=plot_filename)\n", "\n", - "export_legend(compare_algorithms, export_filepath=directory)\n" + "plot_test_case.export_legend(compare_algorithms)\n" ], "metadata": { "collapsed": false, "pycharm": { - "name": "#%%\n", - "is_executing": false + "name": "#%%\n" } } }, @@ -262,22 +187,20 @@ " \"Extrapolation Grid (Grouped Optimized, Romberg, Default Romberg, Balanced)\",\n", "]\n", "export_path = \"./{}/balancing/\".format(directory)\n", + "plot_test_case.set_export_filepath(export_path)\n", "\n", "for function_name in function_names:\n", - " plot_csv_data(\"error_comparison_{}_{}d\".format(function_name, dim),\n", - " import_filepath=\"../{}/\".format(directory),\n", - " export_filepath=export_path,\n", - " algorithm_subset=algorithms,\n", - " legend_title=None,\n", - " plot_filename=\"balancing_{}_{}d\".format(function_name, dim))\n", + " plot_test_case.plot_error_approximation(\"error_comparison_{}_{}d\".format(function_name, dim),\n", + " algorithm_subset=algorithms,\n", + " legend_title=None,\n", + " plot_filename=\"balancing_{}_{}d\".format(function_name, dim))\n", "\n", - "export_legend(algorithms, export_filepath=export_path, filename=\"balancing_legend\")" + "plot_test_case.export_legend(algorithms, filename=\"balancing_legend\")" ], "metadata": { "collapsed": false, "pycharm": { - "name": "#%%\n", - "is_executing": false + "name": "#%%\n" } } }, @@ -311,22 +234,20 @@ " \"Extrapolation Grid (Grouped Optimized, Romberg, Default Romberg, Balanced)\",\n", "]\n", "export_path = \"./{}/grouping/\".format(directory)\n", + "plot_test_case.set_export_filepath(export_path)\n", "\n", "for function_name in function_names:\n", - " plot_csv_data(\"error_comparison_{}_5d\".format(function_name),\n", - " import_filepath=\"../{}/\".format(directory),\n", - " export_filepath=export_path,\n", - " algorithm_subset=algorithms,\n", - " legend_title=None,\n", - " plot_filename=\"balanced_grouping_{}_5d\".format(function_name))\n", + " plot_test_case.plot_error_approximation(\"error_comparison_{}_5d\".format(function_name),\n", + " algorithm_subset=algorithms,\n", + " legend_title=None,\n", + " plot_filename=\"balanced_grouping_{}_5d\".format(function_name))\n", "\n", - "export_legend(algorithms, export_filepath=export_path, filename=\"balanced_grouping_legend\")" + "plot_test_case.export_legend(algorithms, filename=\"balanced_grouping_legend\")" ], "metadata": { "collapsed": false, "pycharm": { - "name": "#%%\n", - "is_executing": false + "name": "#%%\n" } } }, @@ -344,31 +265,31 @@ "execution_count": null, "outputs": [], "source": [ + "export_path = \"./{}/grouping/\".format(directory)\n", + "plot_test_case.set_export_filepath(export_path)\n", + "\n", "for function_name in function_names:\n", - " plot_csv_data(\"error_comparison_{}_5d\".format(function_name),\n", - " import_filepath=\"../{}/\".format(directory),\n", - " export_filepath=\"./{}/grouping/\".format(directory),\n", - " algorithm_subset=[\n", - " \"Gauss-Legendre Grid (Standard Combi) lmin=1\",\n", - " \"Gauss-Legendre Grid (Standard Combi) lmin=2\",\n", - " \n", - " \"Trapezoidal Grid\",\n", - " \"Trapezoidal Grid (Rebalancing)\",\n", - " \n", - " \"Extrapolation Grid (Unit, Romberg, Default Romberg)\",\n", - " \n", - " \"Extrapolation Grid (Grouped, Romberg, Default Romberg)\",\n", - " \n", - " \"Extrapolation Grid (Grouped Optimized, Romberg, Default Romberg)\",\n", - " ],\n", - " legend_title=\"{} 5D\".format(function_name),\n", - " plot_filename=\"unbalanced_grouping_{}_5d\".format(function_name))" + " plot_test_case.plot_error_approximation(\"error_comparison_{}_5d\".format(function_name),\n", + " algorithm_subset=[\n", + " \"Gauss-Legendre Grid (Standard Combi) lmin=1\",\n", + " \"Gauss-Legendre Grid (Standard Combi) lmin=2\",\n", + "\n", + " \"Trapezoidal Grid\",\n", + " \"Trapezoidal Grid (Rebalancing)\",\n", + "\n", + " \"Extrapolation Grid (Unit, Romberg, Default Romberg)\",\n", + "\n", + " \"Extrapolation Grid (Grouped, Romberg, Default Romberg)\",\n", + "\n", + " \"Extrapolation Grid (Grouped Optimized, Romberg, Default Romberg)\",\n", + " ],\n", + " legend_title=\"{} 5D\".format(function_name),\n", + " plot_filename=\"unbalanced_grouping_{}_5d\".format(function_name))" ], "metadata": { "collapsed": false, "pycharm": { - "name": "#%%\n", - "is_executing": false + "name": "#%%\n" } } }, @@ -396,22 +317,20 @@ " \"Extrapolation Grid (Grouped Optimized, Romberg, Lagrange Full Romberg)\",\n", "]\n", "export_path = \"./{}/interpolation/\".format(directory)\n", + "plot_test_case.set_export_filepath(export_path)\n", "\n", "for function_name in function_names:\n", - " plot_csv_data(\"error_comparison_{}_5d\".format(function_name),\n", - " import_filepath=\"../{}/\".format(directory),\n", - " export_filepath=export_path,\n", - " algorithm_subset=algorithms,\n", - " legend_title=None,\n", - " plot_filename=\"lagrange_{}_5d\".format(function_name))\n", + " plot_test_case.plot_error_approximation(\"error_comparison_{}_5d\".format(function_name),\n", + " algorithm_subset=algorithms,\n", + " legend_title=None,\n", + " plot_filename=\"lagrange_{}_5d\".format(function_name))\n", " \n", - "export_legend(algorithms, export_filepath=export_path, filename=\"lagrange_legend\")" + "plot_test_case.export_legend(algorithms, filename=\"lagrange_legend\")" ], "metadata": { "collapsed": false, "pycharm": { - "name": "#%%\n", - "is_executing": false + "name": "#%%\n" } } }, @@ -443,22 +362,20 @@ " \"Extrapolation Grid (Grouped Optimized, Romberg, Lagrange Full Romberg)\"]\n", "\n", "export_path = \"./{}/interpolation/\".format(directory)\n", + "plot_test_case.set_export_filepath(export_path)\n", "\n", "for function_name in function_names:\n", - " plot_csv_data(\"error_comparison_{}_5d\".format(function_name),\n", - " import_filepath=\"../{}/\".format(directory),\n", - " export_filepath=export_path,\n", + " plot_test_case.plot_error_approximation(\"error_comparison_{}_5d\".format(function_name),\n", " algorithm_subset=algorithms,\n", " legend_title=None,\n", " plot_filename=\"comparison_{}_5d\".format(function_name))\n", " \n", - "export_legend(algorithms, export_filepath=export_path, filename=\"comparison_legend\")" + "plot_test_case.export_legend(algorithms, filename=\"comparison_legend\")" ], "metadata": { "collapsed": false, "pycharm": { - "name": "#%%\n", - "is_executing": false + "name": "#%%\n" } } }, @@ -486,22 +403,20 @@ " \"Extrapolation Grid (Grouped Optimized, Trapezoid, Romberg, Balanced)\"\n", "]\n", "export_path = \"./{}/slices/\".format(directory)\n", + "plot_test_case.set_export_filepath(export_path)\n", "\n", "for function_name in function_names:\n", - " plot_csv_data(\"error_comparison_{}_5d\".format(function_name),\n", - " import_filepath=\"../{}/\".format(directory),\n", - " export_filepath=export_path,\n", - " algorithm_subset=algorithms,\n", - " legend_title=None,\n", - " plot_filename=\"slice_version_{}_5d\".format(function_name))\n", + " plot_test_case.plot_error_approximation(\"error_comparison_{}_5d\".format(function_name),\n", + " algorithm_subset=algorithms,\n", + " legend_title=None,\n", + " plot_filename=\"slice_version_{}_5d\".format(function_name))\n", "\n", - "export_legend(algorithms, export_filepath=export_path, filename=\"slice_version_legend\")" + "plot_test_case.export_legend(algorithms, filename=\"slice_version_legend\")" ], "metadata": { "collapsed": false, "pycharm": { - "name": "#%%\n", - "is_executing": false + "name": "#%%\n" } } }, @@ -530,22 +445,20 @@ " \"Extrapolation Grid (Grouped Optimized, Romberg, Default Romberg, Balanced)\",\n", "]\n", "export_path = \"./{}/high_order/\".format(directory)\n", + "plot_test_case.set_export_filepath(export_path)\n", "\n", "for function_name in function_names:\n", - " plot_csv_data(\"error_comparison_{}_5d\".format(function_name),\n", - " import_filepath=\"../{}/\".format(directory),\n", - " export_filepath=export_path,\n", - " algorithm_subset=algorithms,\n", - " legend_title=None,\n", - " plot_filename=\"high_order_{}_5d\".format(function_name))\n", + " plot_test_case.plot_error_approximation(\"error_comparison_{}_5d\".format(function_name),\n", + " algorithm_subset=algorithms,\n", + " legend_title=None,\n", + " plot_filename=\"high_order_{}_5d\".format(function_name))\n", "\n", - "export_legend(algorithms, export_filepath=export_path, filename=\"high_order_legend\")\n" + "plot_test_case.export_legend(algorithms, filename=\"high_order_legend\")\n" ], "metadata": { "collapsed": false, "pycharm": { - "name": "#%%\n", - "is_executing": false + "name": "#%%\n" } } }, @@ -590,22 +503,24 @@ " \"Extrapolation Grid (Grouped Optimized, Romberg, Lagrange Full Romberg)\"\n", "]\n", "export_path = \"./2d/medium_hard/\"\n", + "plot_test_case.set_import_filepath(\"../2d/medium_hard/\")\n", + "plot_test_case.set_export_filepath(export_path)\n", "\n", "for function_name in function_names:\n", - " plot_csv_data(\"error_comparison_{}_2d\".format(function_name),\n", - " import_filepath=\"../2d/medium_hard/\",\n", - " export_filepath=export_path,\n", + " plot_test_case.plot_error_approximation(\"error_comparison_{}_2d\".format(function_name),\n", " algorithm_subset=algorithms,\n", " legend_title=None,\n", " plot_filename=\"dimensionality_{}_2d\".format(function_name))\n", "\n", - "export_legend(algorithms, export_filepath=export_path, filename=\"dimensionality_legend\")" + "plot_test_case.export_legend(algorithms, filename=\"dimensionality_legend\")\n", + "\n", + "\n", + "plot_test_case.set_import_filepath(\"../\")" ], "metadata": { "collapsed": false, "pycharm": { - "name": "#%%\n", - "is_executing": false + "name": "#%%\n" } } } @@ -627,15 +542,6 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" - }, - "pycharm": { - "stem_cell": { - "cell_type": "raw", - "source": [], - "metadata": { - "collapsed": false - } - } } }, "nbformat": 4, diff --git a/src/PerformTestCase.py b/src/PerformTestCase.py index 75d3d3a..4143310 100644 --- a/src/PerformTestCase.py +++ b/src/PerformTestCase.py @@ -2,6 +2,27 @@ import matplotlib.cm as mplcm import matplotlib, numpy as np, matplotlib.pyplot as plt +import csv +import matplotlib.pyplot as plt +import pylab +import numpy as np + +def clear_csv(filepath, filename): + file = "{}{}.csv".format(filepath, filename) + print("Clearing {}".format(file)) + + f = open(file, "w+") + f.close() + +def export_to_csv(filepath, filename, export_data): + with open("{}{}.csv".format(filepath, filename), 'a') as out: + csv_out = csv.writer(out, delimiter="|", quoting=csv.QUOTE_NONNUMERIC) + + for name, num_points, error in export_data: + csv_out.writerow(["name", name]) + csv_out.writerow(["num_points"] + num_points) + csv_out.writerow(["error"] + error) + csv_out.writerow([]) def performTestStandard(f, a, b, grid, lmin, maxLmax, dim, reference_solution, evaluation_points): # calculate standard combination scheme results @@ -240,20 +261,140 @@ def performTestcaseArbitraryDim(f, a, b, adaptiveAlgorithmVector, maxtol, dim, m # ax.figure.show() -def clear_csv(filepath, filename): - file = "{}{}.csv".format(filepath, filename) - print("Clearing {}".format(file)) - f = open(file, "w+") - f.close() +class PlotTestCase: + def __init__(self, colormap: dict, line_style_map: dict, import_filepath="../", export_filepath="./"): + """ + Initializes the plots + + Parameters + ---------- + colormap: dict that maps algorithm name strings to color strings, e.g.: + colormap = { + "Gauss-Legendre Grid (Standard Combi) lmin=1": "tab:gray", + "Trapezoidal Grid (Standard Combi) lmin=1": "violet", + "Trapezoidal Grid": "red", + "Trapezoidal Grid (Rebalancing)": "royalblue", + } + line_style_map: dict that maps algorithm name strings to color strings, e.g.: + line_style_map = { + "Gauss-Legendre Grid (Standard Combi) lmin=1": "--", + "Trapezoidal Grid (Standard Combi) lmin=1": "--", + "Trapezoidal Grid": "-.", + "Trapezoidal Grid (Rebalancing)": "-.", + } + import_filepath: From where the CSV files are imported + export_filepath: Where the plots are written + """ + self.colormap = colormap + self.line_style_map = line_style_map + self.import_filepath = import_filepath + self.export_filepath = export_filepath + + def set_import_filepath(self, filepath="../"): + self.import_filepath = filepath + + def set_export_filepath(self, filepath="./"): + self.export_filepath = filepath + + def load_csv_data(self, import_filename): + # Read + import_data = [] + + # if not os.path.isfile(import_filepath): + # raise RuntimeError("Import-File {}{}.csv does not exist.".format(import_filepath, import_filename)) + + with open("{}{}.csv".format(self.import_filepath, import_filename), newline='') as csvfile: + csv_reader = csv.reader(csvfile, delimiter='|', quoting=csv.QUOTE_NONNUMERIC) + + buffer = [] + + for row in csv_reader: + if len(row) > 0: + row_type = row[0] + row_data = row[1:] + + if row_type == "name": + buffer.extend(row_data) + else: + buffer.append(row_data) + else: + import_data.append(buffer) + buffer = [] + + # Append last algorithm, if buffer is not empty. + # This is for example the case if there is no blank line at the bottom of the csv file + if len(buffer) > 0: + import_data.append(buffer) + + return import_data + + def plot_error_approximation(self, import_filename, algorithm_subset=None, plot_filename=None, legend_title=None): + """ + This methods imports a csv file, generated by the PerformTestCase class, + and plots a subset of the provided algorithms. The line colors and styles are according to the configuration. + + Parameters + ---------- + import_filename + algorithm_subset: a list of algorithm names that should vbe plotted + plot_filename + legend_title: if this argument is None, no legend will be plotted + + Returns + ------- + + """ + print("Processing {}.csv ...".format(import_filename)) + + import_data = self.load_csv_data(import_filename) + + # Plot + fig = plt.figure(num=None, figsize=(8, 6), dpi=100, facecolor='w', edgecolor='w') + ax = fig.add_subplot(111) + + for name, num_points, error in import_data: + if algorithm_subset is not None and name not in algorithm_subset: + continue + + color = self.colormap[name] + line_style = self.line_style_map[name] + + ax.loglog(num_points, error, line_style, color=color, label=name) + + if legend_title is not None: + ax.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc='lower left', + ncol=1, mode="expand", borderaxespad=0., title=legend_title) + + ax.set_xlabel('Number of points') + ax.set_ylabel('Approximation error') + + if plot_filename is not None: + ax.figure.savefig("{}{}.pdf".format(self.export_filepath, plot_filename), bbox_inches='tight', dpi=300) + + def export_legend(self, algorithms, filename="legend"): + """ + Export legend separately from plots. + https://stackoverflow.com/questions/4534480/get-legend-as-a-separate-picture-in-matplotlib + + Parameters + ---------- + algorithms: a list of algorithms names, that should appear in the legend + filename + export_filepath + + Returns + ------- + """ + figData = pylab.figure() + ax = pylab.gca() + x = np.arange(10) -def export_to_csv(filepath, filename, export_data): - with open("{}{}.csv".format(filepath, filename), 'a') as out: - csv_out = csv.writer(out, delimiter="|", quoting=csv.QUOTE_NONNUMERIC) + for i, algo in enumerate(algorithms): + pylab.plot(x, x * (i + 1), self.line_style_map[algo], color=self.colormap[algo], label=algo) - for name, num_points, error in export_data: - csv_out.writerow(["name", name]) - csv_out.writerow(["num_points"] + num_points) - csv_out.writerow(["error"] + error) - csv_out.writerow([]) + figlegend = pylab.figure() + figlegend.legend(*ax.get_legend_handles_labels(), loc="center", mode="expand", prop={'size': 9}) + figlegend.show() + figlegend.savefig("{}/{}.pdf".format(self.export_filepath, filename)) \ No newline at end of file From 118e83756ddf4ecb1b51b334b8ceaad927ccab13 Mon Sep 17 00:00:00 2001 From: Pascal Date: Sun, 27 Dec 2020 15:55:19 +0100 Subject: [PATCH 2/6] Refactor PerformTestCase.py --- ipynb/Extrapolation/Extrapolation_Test.ipynb | 50 +-- sparseSpACE/PerformTestCase.py | 422 ++++++++++--------- 2 files changed, 256 insertions(+), 216 deletions(-) diff --git a/ipynb/Extrapolation/Extrapolation_Test.ipynb b/ipynb/Extrapolation/Extrapolation_Test.ipynb index 788a92c..e6c9b2e 100644 --- a/ipynb/Extrapolation/Extrapolation_Test.ipynb +++ b/ipynb/Extrapolation/Extrapolation_Test.ipynb @@ -5,7 +5,6 @@ "execution_count": null, "metadata": { "pycharm": { - "is_executing": false, "name": "#%%\n" } }, @@ -43,11 +42,11 @@ " force_balanced_refinement_tree=force_balanced_refinement_tree)\n", "\n", "# Settings\n", - "dim = 5\n", + "dim = 2\n", "a = np.zeros(dim)\n", "b = np.ones(dim)\n", "max_tol = 20 # set to max, for better comparison\n", - "max_evaluations = 10 ** 5\n", + "max_evaluations = 10 ** 3\n", "evaluation_points = evaluation_points(a, b, dim)\n", "functions = []\n", "sasd_version = 6\n", @@ -271,26 +270,32 @@ " function_name = f.__class__.__name__\n", " filename = \"error_comparison_{}_{}d\".format(function_name, dim)\n", "\n", - " performTestcaseArbitraryDim(f, a, b, algorithmArray,\n", - " max_tol, dim, 6, grids=standard_combi_grids, evaluation_points=evaluation_points,\n", - " max_evaluations=max_evaluations,\n", - " calc_standard_schemes=True, # enable for standard schemes\n", - " minLmin=1,\n", - " maxLmin=3,\n", - " grid_names=standard_combi_grid_names,\n", - " legend_title=\"{} function\".format(function_name),\n", - " filename=filename,\n", - " save_csv=True,\n", - " save_plot=True\n", - " )" + " testcase = TestCase(f, a, b)\n", + "\n", + " testcase.test_algorithm_vectors(\n", + " adaptive_algorithm_vectors=algorithmArray,\n", + " max_tol=max_tol, dim=dim, max_lmax=6,\n", + " grids=standard_combi_grids,\n", + " grid_names=standard_combi_grid_names,\n", + " calc_dim_adaptive_schemes=False, # enable for dimensional adaptive schemes\n", + " calc_standard_schemes=True, # enable for standard schemes\n", + " evaluation_points=evaluation_points,\n", + " max_evaluations=max_evaluations,\n", + " min_lmin=1,\n", + " max_lmin=3,\n", + " legend_title=\"{} function\".format(function_name),\n", + " filename=filename,\n", + " save_csv=True,\n", + " save_plot=True\n", + " )" ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "name": "pycharm-4d8d33d1", "language": "python", - "name": "python3" + "display_name": "PyCharm (sparseSpACE)" }, "language_info": { "codemirror_mode": { @@ -303,17 +308,8 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.9" - }, - "pycharm": { - "stem_cell": { - "cell_type": "raw", - "metadata": { - "collapsed": false - }, - "source": [] - } } }, "nbformat": 4, "nbformat_minor": 1 -} +} \ No newline at end of file diff --git a/sparseSpACE/PerformTestCase.py b/sparseSpACE/PerformTestCase.py index 302eafb..005cf15 100644 --- a/sparseSpACE/PerformTestCase.py +++ b/sparseSpACE/PerformTestCase.py @@ -10,97 +10,133 @@ import pylab import numpy as np -def clear_csv(filepath, filename): - file = "{}{}.csv".format(filepath, filename) - print("Clearing {}".format(file)) - - f = open(file, "w+") - f.close() - -def export_to_csv(filepath, filename, export_data): - with open("{}{}.csv".format(filepath, filename), 'a') as out: - csv_out = csv.writer(out, delimiter="|", quoting=csv.QUOTE_NONNUMERIC) - - for name, num_points, error in export_data: - csv_out.writerow(["name", name]) - csv_out.writerow(["num_points"] + num_points) - csv_out.writerow(["error"] + error) - csv_out.writerow([]) - -def performTestStandard(f, a, b, grid, lmin, maxLmax, dim, reference_solution, evaluation_points): - # calculate standard combination scheme results - errorArrayStandard = [] - pointArray = [] - distinctFEvalArray = [] - operation = Integration(f, grid, dim, reference_solution) - standardCombi = StandardCombi(a, b, operation=operation) - interpolation_errorL2 = [] - interpolation_errorMax = [] - for i in range(lmin + 1, lmin + maxLmax): - scheme, error, result = standardCombi.perform_operation(lmin, i) - errorArrayStandard.append(error / abs(reference_solution)) - pointArray.append(standardCombi.get_total_num_points()) - distinctFEvalArray.append(standardCombi.get_total_num_points(distinct_function_evals=True)) - if evaluation_points is not None: - interpolated_values = np.asarray(standardCombi(evaluation_points)) - real_values = np.asarray([f.eval(point) for point in evaluation_points]) - diff = [real_values[i] - interpolated_values[i] for i in range(len(evaluation_points))] - # print(interpolated_values, diff) - interpolation_errorL2.append(scipy.linalg.norm(diff, 2)) - interpolation_errorMax.append(scipy.linalg.norm(diff, np.inf)) - return pointArray, distinctFEvalArray, errorArrayStandard, interpolation_errorL2, interpolation_errorMax - - -def performTestcaseArbitraryDim(f, a, b, adaptiveAlgorithmVector, maxtol, dim, maxLmax, grids=None, - minLmin=1, maxLmin=3, - minTol=-1, doDimAdaptive=False, max_evaluations=10 ** 7, evaluation_points=None, - calc_standard_schemes=True, grid_names=None, - legend_title="", - filepath="./Results/", filename=None, save_plot:bool=False, save_csv:bool=False, clear_csv:bool=False): - # realIntegral = scipy.integrate.dblquad(f, a, b, lambda x:a, lambda x:b, epsabs=1e-15, epsrel=1e-15)[0] - reference_solution = f.getAnalyticSolutionIntegral(a, b) - print("Exact integral", reference_solution) - errorArray = [] - surplusErrorArray = [] - - numEvaluationsArray = [] - numNaive = [] - numIdeal = [] - numFEvalIdeal = [] - # interpolation_error_arrayL2 = [] - # interpolation_error_arrayMax = [] - - # https://stackoverflow.com/questions/8389636/creating-over-20-unique-legend-colors-using-matplotlib - NUM_COLORS = len(adaptiveAlgorithmVector) + (maxLmin - minLmin) - - # cm = plt.get_cmap('tab20') # alternative: gist_rainbow, hsv, tab20 - # cNorm = colors.Normalize(vmin=0, vmax=NUM_COLORS - 1) - # scalarMap = mplcm.ScalarMappable(norm=cNorm, cmap=cm) - fig = plt.figure(num=None, figsize=(8, 6), dpi=100, facecolor='w', edgecolor='w') - ax = fig.add_subplot(111) - # ax.set_prop_cycle('color', [scalarMap.to_rgba((4 * i + 2) % NUM_COLORS) for i in range(NUM_COLORS)]) - from_list = matplotlib.colors.LinearSegmentedColormap.from_list - cm = from_list('Set1', plt.cm.Set1(range(0, NUM_COLORS)), NUM_COLORS) - # plt.set_cmap(cm) - - # Clear CSV - if save_csv and clear_csv: - clear_csv(filepath, filename) - - print("\n\n\n\n\n\n -------------------------- Start {} -------------------------- \n\n\n\n\n\n".format(legend_title)) - - # calculate refinements for different tolerance values - for algorithm in adaptiveAlgorithmVector: - errorArrayAlgorithm = [] - surplusErrorArrayAlgorithm = [] - numEvaluationsArrayAlgorithm = [] - numNaiveAlgorithm = [] - numIdealAlgorithm = [] - numFEvalIdealAlgorithm = [] + +class TestCase: + def __init__(self, f: Function, a: Sequence[float], b: Sequence[float]): + self.f = f + self.a = a + self.b = b + + self.__init_test_case("./Results/", False, False) + + def __init_test_case(self, filepath, save_csv: bool, clear_csv: bool): + # realIntegral = scipy.integrate.dblquad(f, a, b, lambda x:a, lambda x:b, epsabs=1e-15, epsrel=1e-15)[0] + self.reference_solution = self.f.getAnalyticSolutionIntegral(self.a, self.b) + print("Exact integral", self.reference_solution) + self.errorArray = [] + self.surplusErrorArray = [] + + self.numEvaluationsArray = [] + self.numNaive = [] + self.numIdeal = [] + self.numFEvalIdeal = [] + self.interpolation_error_arrayL2 = [] + self.interpolation_error_arrayMax = [] + + self.errorArrayDimAdaptiveArray = [] + self.numFEvalIdealDimAdaptiveArray = [] + + self.filepath = filepath + self.save_csv = save_csv + self.clear_csv = clear_csv + + self.ax = None + + def test_algorithm_vectors(self, adaptive_algorithm_vectors, max_tol, dim, max_lmax, grids=None, grid_names=None, + min_lmin=1, max_lmin=3, min_tol=-1, max_evaluations=10 ** 7, + evaluation_points=None, + calc_standard_schemes=True, calc_dim_adaptive_schemes=False, + legend_title="", filepath="./Results/", filename=None, + save_plot: bool = False, save_csv: bool = False, clear_csv: bool = False): + # Init test case + self.__init_test_case(filepath, save_csv, clear_csv) + + # Plot color cycle + # https://stackoverflow.com/questions/8389636/creating-over-20-unique-legend-colors-using-matplotlib + NUM_COLORS = len(adaptive_algorithm_vectors) + (max_lmin - min_lmin) + + # cm = plt.get_cmap('tab20') # alternative: gist_rainbow, hsv, tab20 + # cNorm = colors.Normalize(vmin=0, vmax=NUM_COLORS - 1) + # scalarMap = mplcm.ScalarMappable(norm=cNorm, cmap=cm) + # self.ax.set_prop_cycle('color', [scalarMap.to_rgba((4 * i + 2) % NUM_COLORS) for i in range(NUM_COLORS)]) + + fig = plt.figure(num=None, figsize=(8, 6), dpi=100, facecolor='w', edgecolor='w') + self.ax = fig.add_subplot(111) + + from_list = matplotlib.colors.LinearSegmentedColormap.from_list + cm = from_list('Set1', plt.cm.Set1(range(0, NUM_COLORS)), NUM_COLORS) + # plt.set_cmap(cm) + + # Clear CSV + if save_csv and clear_csv: + self.__clear_csv(filepath, filename) + + print("\n\n\n\n\n\n ----------------------- Start {} ----------------------- \n\n\n\n\n\n".format(legend_title)) + + # calculate refinements for different tolerance values + for algorithm_vector in adaptive_algorithm_vectors: + self.__perform_algorithm_vector_spatially_adaptive(algorithm_vector, max_tol, max_evaluations, + evaluation_points, filename) + + if calc_dim_adaptive_schemes: + self.__perform_dim_adaptive_combi(grids, grid_names, dim, max_tol, max_evaluations, filename) + + # calculate different standard combination scheme results + if calc_standard_schemes: + self.__perform_standard_combi(grids, grid_names, min_lmin, max_lmin, max_lmax, dim, evaluation_points, + filename) + + if calc_dim_adaptive_schemes: + for i in range(len(self.numFEvalIdealDimAdaptiveArray)): + name = "{}: Number of Points DimAdaptive lmin= 1".format(grid_names[i]) + print("numPoints =", self.numFEvalIdealDimAdaptiveArray[i]) + print("error=", self.errorArrayDimAdaptiveArray[i], name) + self.ax.loglog(self.numFEvalIdealDimAdaptiveArray[i], self.errorArrayDimAdaptiveArray[i], label=name) + + line = '-' + + for i in range(len(adaptive_algorithm_vectors)): + # if line == '-': + # line = '--' + # elif line == '--': + # line = '-' + + # print(self.numNaive[i], self.errorArray[i], adaptive_algorithm_vectors[i][4] + ' Naive evaluation') + # print(self.numIdeal[i], self.errorArray[i], adaptive_algorithm_vectors[i][4] + ' total points') + print(self.numFEvalIdeal[i], self.errorArray[i], adaptive_algorithm_vectors[i][4] + ' error (distinct f evals)') + # print(self.numFEvalIdeal[i], self.surplusErrorArray[i], adaptive_algorithm_vectors[i][4] + ' surplus error distinct f evals') + + # print(self.numFEvalIdeal[i],self.interpolation_error_arrayL2[i], adaptive_algorithm_vectors[i][4] + ' L2 interpolation error') + # print(self.numFEvalIdeal[i], self.interpolation_error_arrayMax[i], adaptive_algorithm_vectors[i][4] + ' Linf interpolation error') + + # self.ax.loglog(self.numNaive[i],self.errorArray[i],label= adaptive_algorithm_vectors[i][3] +' Naive evaluation') + # self.ax.loglog(self.numIdeal[i],self.errorArray[i],label=adaptive_algorithm_vectors[i][3] +' total points') + name = adaptive_algorithm_vectors[i][4] + self.ax.loglog(self.numFEvalIdeal[i], self.errorArray[i], line, label=name + ' error (distinct f evals)') + + # TODO if do_plot_surplus + + # self.ax.loglog(self.numFEvalIdeal[i], self.interpolation_error_arrayL2[i], label=adaptive_algorithm_vectors[i][4] + ' L2') + # self.ax.loglog(self.numFEvalIdeal[i], self.interpolation_error_arrayMax[i], label=adaptive_algorithm_vectors[i][4] + ' Linf') + + # self.ax.loglog(self.numFEvalIdeal[i], self.surplusErrorArray[i], '--', label=adaptive_algorithm_vectors[i][4] + ' surplus error') + + self.ax.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc='lower left', + ncol=1, mode="expand", borderaxespad=0., title=legend_title) + self.ax.set_xlabel('Number of points') + self.ax.set_ylabel('Approximation error') + + if save_plot: + self.ax.figure.savefig("{}{}.pdf".format(filepath, filename), bbox_inches='tight', dpi=300) + + # self.ax.figure.show() + + def __perform_algorithm_vector_spatially_adaptive(self, algorithm_vector, max_tol, max_evaluations, + evaluation_points, filename=None): ''' - for i in range(minTol, maxtol+1): + for i in range(min_tol, max_tol+1): start = time.time() - if i == minTol: + if i == min_tol: coarsening, combischeme, lmax, integral, numberOfEvaluations, error_array_new, num_point_array_new = algorithm[0].performSpatiallyAdaptiv( algorithm[1], algorithm[2], f, algorithm[3], 10 ** -i, reference_solution=reference_solution) # errorArrayAlgorithm.append(abs(integral - realIntegral) / abs(realIntegral)) @@ -122,11 +158,18 @@ def performTestcaseArbitraryDim(f, a, b, adaptiveAlgorithmVector, maxtol, dim, m end = time.time() print("time spent in case", i, end - start) ''' - coarsening, combischeme, lmax, integral, numberOfEvaluations, error_array_new, num_point_array_new, surplus_error_array_new, interpolation_errorL2, interpolation_errorMax = \ - algorithm[ - 0].performSpatiallyAdaptiv( - algorithm[1], algorithm[2], algorithm[3], 10 ** -maxtol, max_evaluations=max_evaluations, - evaluation_points=evaluation_points) + errorArrayAlgorithm = [] + surplusErrorArrayAlgorithm = [] + numEvaluationsArrayAlgorithm = [] + numNaiveAlgorithm = [] + numIdealAlgorithm = [] + numFEvalIdealAlgorithm = [] + + coarsening, combischeme, lmax, integral, numberOfEvaluations, error_array_new, num_point_array_new, \ + surplus_error_array_new, interpolation_errorL2, interpolation_errorMax = \ + algorithm_vector[0].performSpatiallyAdaptiv( + algorithm_vector[1], algorithm_vector[2], algorithm_vector[3], 10 ** -max_tol, + max_evaluations=max_evaluations, evaluation_points=evaluation_points) # errorArrayAlgorithm.append(abs(integral - reference_solution) / abs(reference_solution)) errorArrayAlgorithm.extend(error_array_new) surplusErrorArrayAlgorithm.extend(surplus_error_array_new) @@ -136,62 +179,59 @@ def performTestcaseArbitraryDim(f, a, b, adaptiveAlgorithmVector, maxtol, dim, m # numNaiveAlgorithm.append(algorithm[0].get_total_num_points_arbitrary_dim(True)) numFEvalIdealAlgorithm.extend(num_point_array_new) - errorArray.append(errorArrayAlgorithm) - surplusErrorArray.append(surplusErrorArrayAlgorithm) + self.errorArray.append(errorArrayAlgorithm) + self.surplusErrorArray.append(surplusErrorArrayAlgorithm) - numEvaluationsArray.append(numEvaluationsArrayAlgorithm) - numNaive.append(numNaiveAlgorithm) - numIdeal.append(numIdealAlgorithm) - numFEvalIdeal.append(numFEvalIdealAlgorithm) - # interpolation_error_arrayL2.append(interpolation_errorL2) - # interpolation_error_arrayMax.append(interpolation_errorMax) + self.numEvaluationsArray.append(numEvaluationsArrayAlgorithm) + self.numNaive.append(numNaiveAlgorithm) + self.numIdeal.append(numIdealAlgorithm) + self.numFEvalIdeal.append(numFEvalIdealAlgorithm) + # self.interpolation_error_arrayL2.append(interpolation_errorL2) + # self.interpolation_error_arrayMax.append(interpolation_errorMax) # Export Data to csv - if save_csv: - export_to_csv(filepath, filename, [(algorithm[4], numFEvalIdealAlgorithm, errorArrayAlgorithm)]) + if self.save_csv: + self.__export_to_csv(self.filepath, filename, + [(algorithm_vector[4], numFEvalIdealAlgorithm, errorArrayAlgorithm)]) # Spacing in console print("\n\n\n\n\n\n-----------------------------------------------------------------------------------------------\n\n\n\n\n\n") - errorArrayDimAdaptiveArray = [] - numFEvalIdealDimAdaptiveArray = [] - - if doDimAdaptive: + def __perform_dim_adaptive_combi(self, grids, grid_names, dim, max_tol, max_evaluations, filename=None): for i, grid in enumerate(grids): - dimAdaptiveCombi = DimAdaptiveCombi(a, b, grid) - operation = Integration(f, grid, dim, reference_solution) - dimAdaptiveCombi = DimAdaptiveCombi(a, b, operation=operation) - scheme, error, result, errorArrayDimAdaptive, numFEvalIdealDimAdaptive = dimAdaptiveCombi.perform_combi(1, - 1, - 10 ** -maxtol, - max_number_of_points=max_evaluations) - errorArrayDimAdaptiveArray.append(errorArrayDimAdaptive) - numFEvalIdealDimAdaptiveArray.append(numFEvalIdealDimAdaptive) + # dimAdaptiveCombi = DimAdaptiveCombi(self.a, self.b, grid) + operation = Integration(self.f, grid, dim, self.reference_solution) + dimAdaptiveCombi = DimAdaptiveCombi(self.a, self.b, operation=operation) + scheme, error, result, errorArrayDimAdaptive, numFEvalIdealDimAdaptive \ + = dimAdaptiveCombi.perform_combi(1, 1, 10 ** -max_tol, max_number_of_points=max_evaluations) + self.errorArrayDimAdaptiveArray.append(errorArrayDimAdaptive) + self.numFEvalIdealDimAdaptiveArray.append(numFEvalIdealDimAdaptive) # Export Data to csv - if save_csv: + if self.save_csv: name = "{}: Number of Points DimAdaptive lmin= 1".format(grid_names[i]) - export_to_csv(filepath, filename, [(name, numFEvalIdealDimAdaptive, errorArrayDimAdaptive)]) + self.__export_to_csv(self.filepath, filename, [(name, numFEvalIdealDimAdaptive, errorArrayDimAdaptive)]) - # calculate different standard combination scheme results - if calc_standard_schemes: + def __perform_standard_combi(self, grids, grid_names, min_lmin, max_lmin, max_lmax, dim, evaluation_points, + filename=None): for k, grid in enumerate(grids): xArrayStandard = [] xFEvalArrayStandard = [] errorArrayStandard = [] - # interpolation_error_standardL2 = [] - # interpolation_error_standardMax = [] + interpolation_error_standardL2 = [] + interpolation_error_standardMax = [] - for i in range(minLmin, maxLmin): + for i in range(min_lmin, max_lmin): xArrayStandardTest, \ xFEvalArrayStandardTest, \ errorArrayStandardTest, \ interpolation_errorL2, \ - interpolation_errorMax = performTestStandard(f, a, b, grid, i, - maxLmax - (i - 1) * ( - dim - 1) + i - 1, - dim, - reference_solution, evaluation_points=evaluation_points) + interpolation_errorMax = self.execute_standard_combi(grid, i, + max_lmax - (i - 1) * ( + dim - 1) + i - 1, + dim, + self.reference_solution, + evaluation_points=evaluation_points) xArrayStandard.append(xArrayStandardTest) xFEvalArrayStandard.append(xFEvalArrayStandardTest) @@ -200,69 +240,73 @@ def performTestcaseArbitraryDim(f, a, b, adaptiveAlgorithmVector, maxtol, dim, m # interpolation_error_standardMax.append(interpolation_errorMax) # plot - print(maxLmin) - print(minLmin) - for i in range(maxLmin - minLmin): - print(xArrayStandard[i], errorArrayStandard[i], "Number of Points Standard lmin= " + str(i + minLmin)) - print(xFEvalArrayStandard[i], errorArrayStandard[i], "Distinct f evals Standard lmin= " + str(i + minLmin)) - # print(xFEvalArrayStandard[i], interpolation_error_standardL2[i], "L2 interpolation error lmin= " + str(i + minLmin)) - # print(xFEvalArrayStandard[i], interpolation_error_standardMax[i], "Linf interpolation error lmin= " + str(i + minLmin)) - - # ax.loglog(xArrayStandard[i], errorArrayStandard[i], label='standardCombination lmin=' + str(i + minLmin)) - name = "{} (Standard Combi) lmin={}".format(grid_names[k], str(i + minLmin)) - ax.loglog(xFEvalArrayStandard[i], errorArrayStandard[i], "--", label=name + " distinct f evals") + print(max_lmin) + print(min_lmin) - # Export Data to csv - if save_csv: - export_to_csv(filepath, filename, [(name, xFEvalArrayStandard[i], errorArrayStandard[i])]) - - # ax.loglog(xFEvalArrayStandard[i], interpolation_error_standardL2[i], - # label='standardCombination L2 lmin=' + str(i + minLmin)) - # ax.loglog(xFEvalArrayStandard[i], interpolation_error_standardMax[i], - # label='standardCombination Linf lmin=' + str(i + minLmin)) - - if doDimAdaptive: - for i in range(len(numFEvalIdealDimAdaptiveArray)): - name = "{}: Number of Points DimAdaptive lmin= 1".format(grid_names[i]) - print("numPoints =", numFEvalIdealDimAdaptiveArray[i]) - print("error=", errorArrayDimAdaptiveArray[i], name) - ax.loglog(numFEvalIdealDimAdaptiveArray[i], errorArrayDimAdaptiveArray[i], label=name) - - line = '-' - - for i in range(len(adaptiveAlgorithmVector)): - # if line == '-': - # line = '--' - # elif line == '--': - # line = '-' - - # print(numNaive[i], errorArray[i], adaptiveAlgorithmVector[i][4] + ' Naive evaluation') - # print(numIdeal[i], errorArray[i], adaptiveAlgorithmVector[i][4] + ' total points') - print(numFEvalIdeal[i], errorArray[i], adaptiveAlgorithmVector[i][4] + ' error (distinct f evals)') - # print(numFEvalIdeal[i], surplusErrorArray[i], adaptiveAlgorithmVector[i][4] + ' surplus error distinct f evals') + for i in range(max_lmin - min_lmin): + print(xArrayStandard[i], errorArrayStandard[i], "Number of Points Standard lmin= " + str(i + min_lmin)) + print(xFEvalArrayStandard[i], errorArrayStandard[i], + "Distinct f evals Standard lmin= " + str(i + min_lmin)) + # print(xFEvalArrayStandard[i], interpolation_error_standardL2[i], "L2 interpolation error lmin= " + str(i + min_lmin)) + # print(xFEvalArrayStandard[i], interpolation_error_standardMax[i], "Linf interpolation error lmin= " + str(i + min_lmin)) - # print(numFEvalIdeal[i],interpolation_error_arrayL2[i], adaptiveAlgorithmVector[i][4] + ' L2 interpolation error') - # print(numFEvalIdeal[i], interpolation_error_arrayMax[i], adaptiveAlgorithmVector[i][4] + ' Linf interpolation error') + # self.ax.loglog(xArrayStandard[i], errorArrayStandard[i], label='standardCombination lmin=' + str(i + min_lmin)) + name = "{} (Standard Combi) lmin={}".format(grid_names[k], str(i + min_lmin)) + self.ax.loglog(xFEvalArrayStandard[i], errorArrayStandard[i], "--", label=name + " distinct f evals") - # ax.loglog(numNaive[i],errorArray[i],label= adaptiveAlgorithmVector[i][3] +' Naive evaluation') - # ax.loglog(numIdeal[i],errorArray[i],label=adaptiveAlgorithmVector[i][3] +' total points') - name = adaptiveAlgorithmVector[i][4] - ax.loglog(numFEvalIdeal[i], errorArray[i], line, label=name + ' error (distinct f evals)') - - # ax.loglog(numFEvalIdeal[i], interpolation_error_arrayL2[i], label=adaptiveAlgorithmVector[i][4] + ' L2') - # ax.loglog(numFEvalIdeal[i], interpolation_error_arrayMax[i], label=adaptiveAlgorithmVector[i][4] + ' Linf') - - # ax.loglog(numFEvalIdeal[i], surplusErrorArray[i], '--', label=adaptiveAlgorithmVector[i][4] + ' surplus error') - - ax.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc='lower left', - ncol=1, mode="expand", borderaxespad=0., title=legend_title) - ax.set_xlabel('Number of points') - ax.set_ylabel('Approximation error') - - if save_plot: - ax.figure.savefig("{}{}.pdf".format(filepath, filename), bbox_inches='tight', dpi=300) - - # ax.figure.show() + # Export Data to csv + if self.save_csv: + self.__export_to_csv(self.filepath, filename, + [(name, xFEvalArrayStandard[i], errorArrayStandard[i])]) + + # self.ax.loglog(xFEvalArrayStandard[i], interpolation_error_standardL2[i], + # label='standardCombination L2 lmin=' + str(i + min_lmin)) + # self.ax.loglog(xFEvalArrayStandard[i], interpolation_error_standardMax[i], + # label='standardCombination Linf lmin=' + str(i + min_lmin)) + + def __clear_csv(self, filepath, filename): + file = "{}{}.csv".format(filepath, filename) + print("Clearing {}".format(file)) + + f = open(file, "w+") + f.close() + + def __export_to_csv(self, filepath, filename, export_data): + with open("{}{}.csv".format(filepath, filename), 'a') as out: + csv_out = csv.writer(out, delimiter="|", quoting=csv.QUOTE_NONNUMERIC) + + for name, num_points, error in export_data: + csv_out.writerow(["name", name]) + csv_out.writerow(["num_points"] + num_points) + csv_out.writerow(["error"] + error) + csv_out.writerow([]) + + def execute_standard_combi(self, grid: Grid, lmin: int, max_lmax: int, dim: int, reference_solution: Sequence[float], + evaluation_points: Sequence[Tuple[float, ...]]): + # calculate standard combination scheme results + errorArrayStandard = [] + pointArray = [] + distinctFEvalArray = [] + operation = Integration(self.f, grid, dim, reference_solution) + standardCombi = StandardCombi(self.a, self.b, operation=operation) + interpolation_errorL2 = [] + interpolation_errorMax = [] + + for i in range(lmin + 1, lmin + max_lmax): + scheme, error, result = standardCombi.perform_operation(lmin, i) + errorArrayStandard.append(error / abs(reference_solution)) + pointArray.append(standardCombi.get_total_num_points()) + distinctFEvalArray.append(standardCombi.get_total_num_points(distinct_function_evals=True)) + + if evaluation_points is not None: + interpolated_values = np.asarray(standardCombi(evaluation_points)) + real_values = np.asarray([self.f.eval(point) for point in evaluation_points]) + diff = [real_values[i] - interpolated_values[i] for i in range(len(evaluation_points))] + # print(interpolated_values, diff) + interpolation_errorL2.append(scipy.linalg.norm(diff, 2)) + interpolation_errorMax.append(scipy.linalg.norm(diff, np.inf)) + + return pointArray, distinctFEvalArray, errorArrayStandard, interpolation_errorL2, interpolation_errorMax class PlotTestCase: From 786786e346b477d9cc7f1d38f529d62845e21a22 Mon Sep 17 00:00:00 2001 From: Pascal Date: Sun, 3 Jan 2021 15:47:25 +0100 Subject: [PATCH 3/6] Add switch for interpolation error plotting --- ipynb/Extrapolation/Extrapolation_Test.ipynb | 3 +- sparseSpACE/PerformTestCase.py | 53 +++++++++++--------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/ipynb/Extrapolation/Extrapolation_Test.ipynb b/ipynb/Extrapolation/Extrapolation_Test.ipynb index e6c9b2e..b786556 100644 --- a/ipynb/Extrapolation/Extrapolation_Test.ipynb +++ b/ipynb/Extrapolation/Extrapolation_Test.ipynb @@ -286,7 +286,8 @@ " legend_title=\"{} function\".format(function_name),\n", " filename=filename,\n", " save_csv=True,\n", - " save_plot=True\n", + " save_plot=True,\n", + " plot_interpolation_error=True\n", " )" ] } diff --git a/sparseSpACE/PerformTestCase.py b/sparseSpACE/PerformTestCase.py index 005cf15..dd5d331 100644 --- a/sparseSpACE/PerformTestCase.py +++ b/sparseSpACE/PerformTestCase.py @@ -46,6 +46,7 @@ def test_algorithm_vectors(self, adaptive_algorithm_vectors, max_tol, dim, max_l min_lmin=1, max_lmin=3, min_tol=-1, max_evaluations=10 ** 7, evaluation_points=None, calc_standard_schemes=True, calc_dim_adaptive_schemes=False, + plot_interpolation_error=False, legend_title="", filepath="./Results/", filename=None, save_plot: bool = False, save_csv: bool = False, clear_csv: bool = False): # Init test case @@ -84,7 +85,7 @@ def test_algorithm_vectors(self, adaptive_algorithm_vectors, max_tol, dim, max_l # calculate different standard combination scheme results if calc_standard_schemes: self.__perform_standard_combi(grids, grid_names, min_lmin, max_lmin, max_lmax, dim, evaluation_points, - filename) + filename, plot_interpolation_error=plot_interpolation_error) if calc_dim_adaptive_schemes: for i in range(len(self.numFEvalIdealDimAdaptiveArray)): @@ -96,29 +97,28 @@ def test_algorithm_vectors(self, adaptive_algorithm_vectors, max_tol, dim, max_l line = '-' for i in range(len(adaptive_algorithm_vectors)): - # if line == '-': - # line = '--' - # elif line == '--': - # line = '-' - # print(self.numNaive[i], self.errorArray[i], adaptive_algorithm_vectors[i][4] + ' Naive evaluation') # print(self.numIdeal[i], self.errorArray[i], adaptive_algorithm_vectors[i][4] + ' total points') print(self.numFEvalIdeal[i], self.errorArray[i], adaptive_algorithm_vectors[i][4] + ' error (distinct f evals)') # print(self.numFEvalIdeal[i], self.surplusErrorArray[i], adaptive_algorithm_vectors[i][4] + ' surplus error distinct f evals') - # print(self.numFEvalIdeal[i],self.interpolation_error_arrayL2[i], adaptive_algorithm_vectors[i][4] + ' L2 interpolation error') - # print(self.numFEvalIdeal[i], self.interpolation_error_arrayMax[i], adaptive_algorithm_vectors[i][4] + ' Linf interpolation error') + if plot_interpolation_error: + print(self.numFEvalIdeal[i],self.interpolation_error_arrayL2[i], + adaptive_algorithm_vectors[i][4] + ' L2 interpolation error') + print(self.numFEvalIdeal[i], self.interpolation_error_arrayMax[i], + adaptive_algorithm_vectors[i][4] + ' Linf interpolation error') + + self.ax.loglog(self.numFEvalIdeal[i], self.interpolation_error_arrayL2[i], + label=adaptive_algorithm_vectors[i][4] + ' L2') + self.ax.loglog(self.numFEvalIdeal[i], self.interpolation_error_arrayMax[i], + label=adaptive_algorithm_vectors[i][4] + ' Linf') # self.ax.loglog(self.numNaive[i],self.errorArray[i],label= adaptive_algorithm_vectors[i][3] +' Naive evaluation') # self.ax.loglog(self.numIdeal[i],self.errorArray[i],label=adaptive_algorithm_vectors[i][3] +' total points') + name = adaptive_algorithm_vectors[i][4] self.ax.loglog(self.numFEvalIdeal[i], self.errorArray[i], line, label=name + ' error (distinct f evals)') - # TODO if do_plot_surplus - - # self.ax.loglog(self.numFEvalIdeal[i], self.interpolation_error_arrayL2[i], label=adaptive_algorithm_vectors[i][4] + ' L2') - # self.ax.loglog(self.numFEvalIdeal[i], self.interpolation_error_arrayMax[i], label=adaptive_algorithm_vectors[i][4] + ' Linf') - # self.ax.loglog(self.numFEvalIdeal[i], self.surplusErrorArray[i], '--', label=adaptive_algorithm_vectors[i][4] + ' surplus error') self.ax.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc='lower left', @@ -186,8 +186,8 @@ def __perform_algorithm_vector_spatially_adaptive(self, algorithm_vector, max_to self.numNaive.append(numNaiveAlgorithm) self.numIdeal.append(numIdealAlgorithm) self.numFEvalIdeal.append(numFEvalIdealAlgorithm) - # self.interpolation_error_arrayL2.append(interpolation_errorL2) - # self.interpolation_error_arrayMax.append(interpolation_errorMax) + self.interpolation_error_arrayL2.append(interpolation_errorL2) + self.interpolation_error_arrayMax.append(interpolation_errorMax) # Export Data to csv if self.save_csv: @@ -213,7 +213,7 @@ def __perform_dim_adaptive_combi(self, grids, grid_names, dim, max_tol, max_eval self.__export_to_csv(self.filepath, filename, [(name, numFEvalIdealDimAdaptive, errorArrayDimAdaptive)]) def __perform_standard_combi(self, grids, grid_names, min_lmin, max_lmin, max_lmax, dim, evaluation_points, - filename=None): + filename=None, plot_interpolation_error=False): for k, grid in enumerate(grids): xArrayStandard = [] xFEvalArrayStandard = [] @@ -236,8 +236,8 @@ def __perform_standard_combi(self, grids, grid_names, min_lmin, max_lmin, max_lm xArrayStandard.append(xArrayStandardTest) xFEvalArrayStandard.append(xFEvalArrayStandardTest) errorArrayStandard.append(errorArrayStandardTest) - # interpolation_error_standardL2.append(interpolation_errorL2) - # interpolation_error_standardMax.append(interpolation_errorMax) + interpolation_error_standardL2.append(interpolation_errorL2) + interpolation_error_standardMax.append(interpolation_errorMax) # plot print(max_lmin) @@ -247,23 +247,26 @@ def __perform_standard_combi(self, grids, grid_names, min_lmin, max_lmin, max_lm print(xArrayStandard[i], errorArrayStandard[i], "Number of Points Standard lmin= " + str(i + min_lmin)) print(xFEvalArrayStandard[i], errorArrayStandard[i], "Distinct f evals Standard lmin= " + str(i + min_lmin)) - # print(xFEvalArrayStandard[i], interpolation_error_standardL2[i], "L2 interpolation error lmin= " + str(i + min_lmin)) - # print(xFEvalArrayStandard[i], interpolation_error_standardMax[i], "Linf interpolation error lmin= " + str(i + min_lmin)) # self.ax.loglog(xArrayStandard[i], errorArrayStandard[i], label='standardCombination lmin=' + str(i + min_lmin)) name = "{} (Standard Combi) lmin={}".format(grid_names[k], str(i + min_lmin)) self.ax.loglog(xFEvalArrayStandard[i], errorArrayStandard[i], "--", label=name + " distinct f evals") + if plot_interpolation_error: + print(xFEvalArrayStandard[i], interpolation_error_standardL2[i], + "L2 interpolation error lmin= " + str(i + min_lmin)) + print(xFEvalArrayStandard[i], interpolation_error_standardMax[i], + "Linf interpolation error lmin= " + str(i + min_lmin)) + self.ax.loglog(xFEvalArrayStandard[i], interpolation_error_standardL2[i], + label='standardCombination L2 lmin=' + str(i + min_lmin)) + self.ax.loglog(xFEvalArrayStandard[i], interpolation_error_standardMax[i], + label='standardCombination Linf lmin=' + str(i + min_lmin)) + # Export Data to csv if self.save_csv: self.__export_to_csv(self.filepath, filename, [(name, xFEvalArrayStandard[i], errorArrayStandard[i])]) - # self.ax.loglog(xFEvalArrayStandard[i], interpolation_error_standardL2[i], - # label='standardCombination L2 lmin=' + str(i + min_lmin)) - # self.ax.loglog(xFEvalArrayStandard[i], interpolation_error_standardMax[i], - # label='standardCombination Linf lmin=' + str(i + min_lmin)) - def __clear_csv(self, filepath, filename): file = "{}{}.csv".format(filepath, filename) print("Clearing {}".format(file)) From 4aa1ea018b7b5f905c6dde75a7642839c72a9e66 Mon Sep 17 00:00:00 2001 From: Pascal Resch Date: Fri, 12 Mar 2021 18:05:14 +0100 Subject: [PATCH 4/6] Fix imports --- .../Final/FinalExtrapolationErrorPlots.ipynb | 3 ++- .../Results/Final/FinalGrids.ipynb | 24 +++++++------------ 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/ipynb/Extrapolation/Results/Final/FinalExtrapolationErrorPlots.ipynb b/ipynb/Extrapolation/Results/Final/FinalExtrapolationErrorPlots.ipynb index 01f5fb7..a1076c0 100644 --- a/ipynb/Extrapolation/Results/Final/FinalExtrapolationErrorPlots.ipynb +++ b/ipynb/Extrapolation/Results/Final/FinalExtrapolationErrorPlots.ipynb @@ -5,7 +5,8 @@ "execution_count": null, "outputs": [], "source": [ - "from PerformTestCase import PlotTestCase\n", + "import sparseSpACE\n", + "from sparseSpACE.PerformTestCase import PlotTestCase\n", "colormap = {\n", " \"Gauss-Legendre Grid (Standard Combi) lmin=1\": \"tab:gray\",\n", " \"Gauss-Legendre Grid (Standard Combi) lmin=2\": \"silver\",\n", diff --git a/ipynb/Extrapolation/Results/Final/FinalGrids.ipynb b/ipynb/Extrapolation/Results/Final/FinalGrids.ipynb index c320dbf..c504a58 100644 --- a/ipynb/Extrapolation/Results/Final/FinalGrids.ipynb +++ b/ipynb/Extrapolation/Results/Final/FinalGrids.ipynb @@ -10,14 +10,15 @@ }, "outputs": [], "source": [ - "from Extrapolation import SliceGrouping, SliceVersion, SliceContainerVersion\n", - "from Grid import GlobalTrapezoidalGrid, GlobalRombergGrid\n", - "from GridOperation import Integration\n", - "from spatiallyAdaptiveSingleDimension2 import SpatiallyAdaptiveSingleDimensions2\n", + "import sparseSpACE\n", + "from sparseSpACE.Extrapolation import SliceGrouping, SliceVersion, SliceContainerVersion\n", + "from sparseSpACE.Grid import GlobalTrapezoidalGrid, GlobalRombergGrid\n", + "from sparseSpACE.GridOperation import Integration\n", + "from sparseSpACE.spatiallyAdaptiveSingleDimension2 import SpatiallyAdaptiveSingleDimensions2\n", "%matplotlib inline\n", "\n", - "from Function import *\n", - "from ErrorCalculator import *\n", + "from sparseSpACE.Function import *\n", + "from sparseSpACE.ErrorCalculator import *\n", "\n", "dim = 2\n", "a = np.zeros(dim)\n", @@ -514,17 +515,8 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.9" - }, - "pycharm": { - "stem_cell": { - "cell_type": "raw", - "metadata": { - "collapsed": false - }, - "source": [] - } } }, "nbformat": 4, "nbformat_minor": 1 -} +} \ No newline at end of file From 9d83e4e3bdeae99528b2747124994503b4d56509 Mon Sep 17 00:00:00 2001 From: Pascal Resch Date: Sun, 14 Mar 2021 12:27:12 +0100 Subject: [PATCH 5/6] Add default colors and line_styles --- sparseSpACE/PerformTestCase.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/sparseSpACE/PerformTestCase.py b/sparseSpACE/PerformTestCase.py index dd5d331..bec98bf 100644 --- a/sparseSpACE/PerformTestCase.py +++ b/sparseSpACE/PerformTestCase.py @@ -1,3 +1,5 @@ +import random + import sparseSpACE from sparseSpACE.DimAdaptiveCombi import * from sparseSpACE.StandardCombi import * @@ -313,7 +315,7 @@ def execute_standard_combi(self, grid: Grid, lmin: int, max_lmax: int, dim: int, class PlotTestCase: - def __init__(self, colormap: dict, line_style_map: dict, import_filepath="../", export_filepath="./"): + def __init__(self, colormap: dict = None, line_style_map: dict = None, import_filepath="../", export_filepath="./"): """ Initializes the plots @@ -336,8 +338,9 @@ def __init__(self, colormap: dict, line_style_map: dict, import_filepath="../", import_filepath: From where the CSV files are imported export_filepath: Where the plots are written """ - self.colormap = colormap - self.line_style_map = line_style_map + self.colormap = colormap if colormap is not None else {} + self.line_style_map = line_style_map if line_style_map is not None else {} + self.import_filepath = import_filepath self.export_filepath = export_filepath @@ -407,10 +410,22 @@ def plot_error_approximation(self, import_filename, algorithm_subset=None, plot_ if algorithm_subset is not None and name not in algorithm_subset: continue - color = self.colormap[name] - line_style = self.line_style_map[name] - - ax.loglog(num_points, error, line_style, color=color, label=name) + # Add entries to style maps for plots + if name not in self.colormap: + backup_colors = [ + 'black', 'gray', 'silver', 'indianred', 'red', 'tomato', 'chocolate', 'saddlebrown', 'darkorange', 'goldenrod', 'darkkhaki', 'darkolivegreen', 'lightgreen', + 'forestgreen', 'lime', 'turquoise', 'teal', 'cyan', 'steelblue', 'darkslategray', 'slategray', 'royalblue', 'navy', 'indigo', 'darkviolet', 'violet', 'deeppink', 'crimson', 'lightpink' + ] + self.colormap[name] = random.choice(backup_colors) + + if name not in self.line_style_map: + backup_line_styles = [ + '-', '.', '--', '-.' + ] + self.line_style_map[name] = random.choice(backup_line_styles) + + # Plot + ax.loglog(num_points, error, self.line_style_map[name], color=self.colormap[name], label=name) if legend_title is not None: ax.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc='lower left', From 70313542763e2c2e4b001227db7652c98865c945 Mon Sep 17 00:00:00 2001 From: Pascal Resch Date: Sun, 25 Apr 2021 17:01:33 +0200 Subject: [PATCH 6/6] Fix error when results folder does not exist --- sparseSpACE/PerformTestCase.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sparseSpACE/PerformTestCase.py b/sparseSpACE/PerformTestCase.py index bec98bf..d680063 100644 --- a/sparseSpACE/PerformTestCase.py +++ b/sparseSpACE/PerformTestCase.py @@ -6,6 +6,7 @@ from sparseSpACE.GridOperation import * import matplotlib.cm as mplcm import matplotlib, numpy as np, matplotlib.pyplot as plt +from pathlib import Path import csv import matplotlib.pyplot as plt @@ -38,6 +39,11 @@ def __init_test_case(self, filepath, save_csv: bool, clear_csv: bool): self.errorArrayDimAdaptiveArray = [] self.numFEvalIdealDimAdaptiveArray = [] + # Create folder if it does not exist + if not Path(filepath).is_dir(): + p = Path(filepath) + p.mkdir(parents=True, exist_ok=True) + self.filepath = filepath self.save_csv = save_csv self.clear_csv = clear_csv