.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "_build/auto_examples/tutorial/05-Plotting_scalars.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr__build_auto_examples_tutorial_05-Plotting_scalars.py: Plotting scalar values ====================== .. GENERATED FROM PYTHON SOURCE LINES 7-8 :mod:`pyquickbench` is not only designed to measure and plot the execution time of your Python routines, but also their output. Suppose you want to understand the convergence behavior of the following ODE integrators provided by :mod:`scipy:scipy.integrate`: .. GENERATED FROM PYTHON SOURCE LINES 8-17 .. code-block:: Python method_names = [ "RK45" , "RK23" , "DOP853", "Radau" , ] .. GENERATED FROM PYTHON SOURCE LINES 55-56 Letting :func:`pyquickbench.run_benchmark` know that the benchmark target is the return value of the error function is as simple as passing ``mode = "scalar_output"``. .. GENERATED FROM PYTHON SOURCE LINES 56-129 .. code-block:: Python def scipy_ODE_cpte_error_on_test( method , n , ): # y'' = - w**2 * y # y(x) = A cos(w*x) + B sin(w*x) test_ndim = 2 w = 10 def ex_sol(t) : return np.array( [ np.cos(w*t) , np.sin(w*t),-np.sin(w*t), np.cos(w*t) ] ) def fgun(t, xy): fxy = np.empty(2*test_ndim) fxy[0] = w*xy[2] fxy[1] = w*xy[3] fxy[2] = -w*xy[0] fxy[3] = -w*xy[1] return fxy t_span = (0.,np.pi) max_step = (t_span[1] - t_span[0]) / n ex_init = ex_sol(t_span[0]) ex_final = ex_sol(t_span[1]) bunch = scipy.integrate.solve_ivp( fun = fgun , t_span = t_span , y0 = ex_init , method = method , t_eval = np.array([t_span[1]]) , first_step = max_step , max_step = max_step , atol = 1. , rtol = 1. , ) error = np.linalg.norm(bunch.y[:,0]-ex_final)/np.linalg.norm(ex_final) return error all_nint = np.array([2**i for i in range(16)]) bench = { method: functools.partial( scipy_ODE_cpte_error_on_test , method , ) for method in method_names } plot_ylim = [1e-17, 1e1] bench_filename = os.path.join(bench_folder,basename_bench_filename+'_error.npz') pyquickbench.run_benchmark( all_nint , bench , mode = "scalar_output" , filename = bench_filename , plot_ylim = plot_ylim , title = 'Relative error on integrand' , ylabel = "Relative error" , show = True , ) .. image-sg:: /_build/auto_examples/tutorial/images/sphx_glr_05-Plotting_scalars_001.png :alt: Relative error on integrand :srcset: /_build/auto_examples/tutorial/images/sphx_glr_05-Plotting_scalars_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 130-131 As seen in :ref:`sphx_glr__build_auto_examples_tutorial_01-First_benchmark.py`, the different integrations methods can be timed using :mod:`pyquickbench` with the following code, where we explicitely pass the default ``mode = "timings"``. .. GENERATED FROM PYTHON SOURCE LINES 131-144 .. code-block:: Python timings_filename = os.path.join(bench_folder,basename_bench_filename+'_timings.npz') pyquickbench.run_benchmark( all_nint , bench , mode = "timings" , filename = timings_filename , logx_plot = True , title = 'Computational cost' , show = True , ) .. image-sg:: /_build/auto_examples/tutorial/images/sphx_glr_05-Plotting_scalars_002.png :alt: Computational cost :srcset: /_build/auto_examples/tutorial/images/sphx_glr_05-Plotting_scalars_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 145-146 The best method for a given use case is a compromise between speed and accuracy. These two can be plotted against each other with the following code. Note that the benchmarks are not re-run thanks to the caching mechanism explained in :ref:`sphx_glr__build_auto_examples_tutorial_02-Caching_benchmarks.py`. .. GENERATED FROM PYTHON SOURCE LINES 146-178 .. code-block:: Python bench_filename = os.path.join(bench_folder,basename_bench_filename+'_error.npz') all_errors = pyquickbench.run_benchmark( all_nint , bench , mode = "scalar_output" , filename = bench_filename , ) timings_filename = os.path.join(bench_folder,basename_bench_filename+'_timings.npz') all_times = pyquickbench.run_benchmark( all_nint , bench , mode = "timings" , filename = timings_filename , ) pyquickbench.plot_benchmark( all_errors , all_nint , bench , mode = "scalar_output" , all_xvalues = all_times , logx_plot = True , plot_ylim = plot_ylim , title = 'Relative error as a function of computational cost' , ylabel = "Relative error" , xlabel = "Time (s)" , show = True , ) .. image-sg:: /_build/auto_examples/tutorial/images/sphx_glr_05-Plotting_scalars_003.png :alt: Relative error as a function of computational cost :srcset: /_build/auto_examples/tutorial/images/sphx_glr_05-Plotting_scalars_003.png :class: sphx-glr-single-img .. _sphx_glr_download__build_auto_examples_tutorial_05-Plotting_scalars.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: 05-Plotting_scalars.ipynb <05-Plotting_scalars.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: 05-Plotting_scalars.py <05-Plotting_scalars.py>` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: 05-Plotting_scalars.zip <05-Plotting_scalars.zip>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_