Lambdify
This module provides convenient functions to transform diofant expressions to lambda functions which can be used to calculate numerical values very fast.
- diofant.utilities.lambdify.implemented_function(symfunc, implementation)[source]
Add numerical
implementationto functionsymfunc.symfunccan be anUndefinedFunctioninstance, or a name string. In the latter case we create anUndefinedFunctioninstance with that name.Be aware that this is a quick workaround, not a general method to create special symbolic functions. If you want to create a symbolic function to be used by all the machinery of Diofant you should subclass the
Functionclass.- Parameters:
symfunc (
strorUndefinedFunctioninstance) – Ifstr, then create newUndefinedFunctionwith this as name. If \(symfunc\) is a diofant function, attach implementation to it.implementation (callable) – numerical implementation to be called by
evalf()orlambdify
- Returns:
afunc (diofant.FunctionClass instance) – function with attached implementation
Examples
>>> f = implemented_function(Function('f'), lambda x: x+1) >>> lam_f = lambdify(x, f(x)) >>> lam_f(4) 5
- diofant.utilities.lambdify.lambdastr(args, expr, printer=None, dummify=False)[source]
Returns a string that can be evaluated to a lambda function.
Examples
>>> lambdastr(x, x**2) 'lambda x: (x**2)' >>> lambdastr((x, y, z), [z, y, x]) 'lambda x,y,z: ([z, y, x])'
Although tuples may not appear as arguments to lambda in Python 3, lambdastr will create a lambda function that will unpack the original arguments so that nested arguments can be handled:
>>> lambdastr((x, (y, z)), x + y) 'lambda _0,_1: (lambda x,y,z: (x + y))(*list(__flatten_args__([_0,_1])))'
- diofant.utilities.lambdify.lambdify(args, expr, modules=None, printer=None, use_imps=True, dummify=True)[source]
Returns a lambda function for fast calculation of numerical values.
If not specified differently by the user,
modulesdefaults to["numpy"]if NumPy is installed, and["math", "mpmath", "sympy"]if it isn’t, that is, Diofant functions are replaced as far as possible by eithernumpyfunctions if available, and Python’s standard librarymath, ormpmathfunctions otherwise. To change this behavior, the “modules” argument can be used. It accepts:the strings “math”, “mpmath”, “numpy”, “diofant”
any modules (e.g. math)
dictionaries that map names of diofant functions to arbitrary functions
lists that contain a mix of the arguments above, with higher priority given to entries appearing first.
The default behavior is to substitute all arguments in the provided expression with dummy symbols. This allows for applied functions (e.g. f(t)) to be supplied as arguments. Call the function with dummify=False if dummy substitution is unwanted (and \(args\) is not a string). If you want to view the lambdified function or provide “diofant” as the module, you should probably set dummify=False.
In previous releases
lambdifyreplacedMatrixwithnumpy.matrixby default. As of release 0.7.7numpy.arrayis the default. To get the old default behavior you must pass in[{'ImmutableMatrix': numpy.matrix}, 'numpy']to themoduleskwarg.Use one of the provided modules:
>>> f = lambdify(x, sin(x), 'math')
- Attention: Functions that are not in the math module will throw a name
error when the lambda function is evaluated! So this would be better:
>>> f = lambdify(x, sin(x)*gamma(x), ('math', 'mpmath', 'diofant'))
Use some other module:
>>> import numpy >>> f = lambdify((x, y), tan(x*y), numpy)
- Attention: There are naming differences between numpy and diofant. So if
you simply take the numpy module, e.g. diofant.atan will not be translated to numpy.arctan. Use the modified module instead by passing the string “numpy”:
>>> f = lambdify((x, y), tan(x*y), 'numpy') >>> f(1, 2) -2.18503986326 >>> from numpy import array >>> f(array([1, 2, 3]), array([2, 3, 5])) [-2.18503986 -0.29100619 -0.8559934 ]
Use a dictionary defining custom functions:
>>> def my_cool_function(x): ... return f'sin({x}) is cool' >>> myfuncs = {'sin': my_cool_function} >>> f = lambdify(x, sin(x), myfuncs) >>> f(1) 'sin(1) is cool'
Examples
>>> from diofant.abc import w
>>> f = lambdify(x, x**2) >>> f(2) 4 >>> f = lambdify((x, y, z), [z, y, x]) >>> f(1, 2, 3) [3, 2, 1] >>> f = lambdify(x, sqrt(x)) >>> f(4) 2.0 >>> f = lambdify((x, y), sin(x*y)**2) >>> f(0, 5) 0.0 >>> row = lambdify((x, y), Matrix((x, x + y)).T, modules='diofant') >>> row(1, 2) Matrix([[1, 3]])
Tuple arguments are handled and the lambdified function should be called with the same type of arguments as were used to create the function.:
>>> f = lambdify((x, (y, z)), x + y) >>> f(1, (2, 4)) 3
A more robust way of handling this is to always work with flattened arguments:
>>> args = w, (x, (y, z)) >>> vals = 1, (2, (3, 4)) >>> f = lambdify(flatten(args), w + x + y + z) >>> f(*flatten(vals)) 10
Functions present in \(expr\) can also carry their own numerical implementations, in a callable attached to the
_imp_attribute. Usually you attach this using theimplemented_functionfactory:>>> f = implemented_function(Function('f'), lambda x: x+1) >>> func = lambdify(x, f(x)) >>> func(4) 5
lambdifyalways prefers_imp_implementations to implementations in other namespaces, unless theuse_impsinput parameter is False.