.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/calculus/dual_numbers/plot_01_forward_mode_autodiff.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_api_gallery_calculus_dual_numbers_plot_01_forward_mode_autodiff.py: Forward-mode automatic differentiation via dual numbers ============================================================ Dual numbers compute a function's value and its exact derivative together, with no finite-difference step-size tradeoff between truncation error (large ``h``) and floating-point cancellation (small ``h``). .. GENERATED FROM PYTHON SOURCE LINES 12-19 .. code-block:: Python import math import numpy as np from mathematicskit.calculus.systems.dual_numbers import derivative from mathematicskit.calculus.systems.finite_differences import central_difference .. GENERATED FROM PYTHON SOURCE LINES 20-22 Exact derivative, compared against central differences at various h ---------------------------------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 22-35 .. code-block:: Python f_dual = lambda x: (x * x).sin() # d/dx sin(x^2) = 2x cos(x^2) f_plain = lambda x: math.sin(x * x) x0 = 1.3 exact = 2.0 * x0 * math.cos(x0**2) dual_result = derivative(f_dual, x0) print(f"dual-number derivative: {dual_result:.15f} (exact: {exact:.15f}, error {abs(dual_result - exact):.2e})") for h in (1e-1, 1e-3, 1e-5, 1e-7, 1e-9, 1e-11): cd = central_difference(f_plain, x0, h=h) print(f"central diff h={h:.0e}: {cd:.15f}, error {abs(cd - exact):.2e}") .. rst-class:: sphx-glr-script-out .. code-block:: none dual-number derivative: -0.309196080171192 (exact: -0.309196080171192, error 0.00e+00) central diff h=1e-01: -0.331234137017592, error 2.20e-02 central diff h=1e-03: -0.309198313356795, error 2.23e-06 central diff h=1e-05: -0.309196080394702, error 2.24e-10 central diff h=1e-07: -0.309196080405805, error 2.35e-10 central diff h=1e-09: -0.309196113157384, error 3.30e-08 central diff h=1e-11: -0.309197112358106, error 1.03e-06 .. GENERATED FROM PYTHON SOURCE LINES 36-38 Composite functions and the chain rule fall out automatically ---------------------------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 38-44 .. code-block:: Python g = lambda x: (x.exp() / (x + 1.0)).log() x1 = 2.0 grad = derivative(g, x1) print(f"d/dx log(exp(x)/(x+1)) at x={x1}: {grad:.10f}") .. rst-class:: sphx-glr-script-out .. code-block:: none d/dx log(exp(x)/(x+1)) at x=2.0: 0.6666666667 .. GENERATED FROM PYTHON SOURCE LINES 45-47 A NumPy sanity check against a nearby closed-form derivative ---------------------------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 47-50 .. code-block:: Python numpy_gradient_estimate = np.gradient([f_plain(x0 - 1e-6), f_plain(x0), f_plain(x0 + 1e-6)], 1e-6)[1] print("close to numpy finite-difference estimate:", bool(np.isclose(dual_result, numpy_gradient_estimate, atol=1e-3))) .. rst-class:: sphx-glr-script-out .. code-block:: none close to numpy finite-difference estimate: True .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.001 seconds) .. _sphx_glr_download_api_gallery_calculus_dual_numbers_plot_01_forward_mode_autodiff.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_01_forward_mode_autodiff.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_01_forward_mode_autodiff.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_01_forward_mode_autodiff.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_