Source code for examples.demo_setrule

"""Demo demo_setrule
-----------------

Show usage of :py:func:`.setrule` to override a function's automatic
derivative, in this case. The same procedure must be used to provide
derivatives for function that do not have Python source code. This
concerns :py:mod:`numpy` in particular.

"""

import numpy
import pyadi

from .demo_babylonian import gbabylonian as f

[docs] def run(): """Use :py:func:`.setrule` to override the derivative of :py:func:`~.demo_babylonian.gbabylonian`. Prints as output:: x0 = 12.4 dr = [0.1419904585617669], r = 3.5213633723318023 Rule called dr2 = [0.14199045856176618], r = 3.5213633723318023 """ x0 = 12.4 r0 = f(x0) print(f'x0 = {x0}') assert numpy.linalg.norm(r0 * r0 - x0) < 1e-7 dr1, r1 = pyadi.DiffFor(f, x0, verbose=0) assert numpy.linalg.norm(r1 - r0) < 1e-7 print(f'dr = {dr1}, r = {r1}') def rule(r, dx, x, *args): print('Rule called') return 0.5 * dx / r pyadi.setrule(f, rule) pyadi.clear(f) dr2, r2 = pyadi.DiffFor(f, x0, verbose=0) print(f'dr2 = {dr2}, r = {r2}') assert numpy.linalg.norm(dr2[0] - dr1[0]) < 1e-15
if __name__ == "__main__": run()