|
from itertools import product |
|
import math |
|
import inspect |
|
import linecache |
|
import gc |
|
|
|
import mpmath |
|
import cmath |
|
|
|
from sympy.testing.pytest import raises, warns_deprecated_sympy |
|
from sympy.concrete.summations import Sum |
|
from sympy.core.function import (Function, Lambda, diff) |
|
from sympy.core.numbers import (E, Float, I, Rational, all_close, oo, pi) |
|
from sympy.core.relational import Eq |
|
from sympy.core.singleton import S |
|
from sympy.core.symbol import (Dummy, symbols) |
|
from sympy.functions.combinatorial.factorials import (RisingFactorial, factorial) |
|
from sympy.functions.combinatorial.numbers import bernoulli, harmonic |
|
from sympy.functions.elementary.complexes import Abs, sign |
|
from sympy.functions.elementary.exponential import exp, log |
|
from sympy.functions.elementary.hyperbolic import asinh,acosh,atanh |
|
from sympy.functions.elementary.integers import floor |
|
from sympy.functions.elementary.miscellaneous import (Max, Min, sqrt) |
|
from sympy.functions.elementary.piecewise import Piecewise |
|
from sympy.functions.elementary.trigonometric import (asin, acos, atan, cos, cot, sin, |
|
sinc, tan) |
|
from sympy.functions import sinh,cosh,tanh |
|
from sympy.functions.special.bessel import (besseli, besselj, besselk, bessely, jn, yn) |
|
from sympy.functions.special.beta_functions import (beta, betainc, betainc_regularized) |
|
from sympy.functions.special.delta_functions import (Heaviside) |
|
from sympy.functions.special.error_functions import (Ei, erf, erfc, fresnelc, fresnels, Si, Ci) |
|
from sympy.functions.special.gamma_functions import (digamma, gamma, loggamma, polygamma) |
|
from sympy.functions.special.zeta_functions import zeta |
|
from sympy.integrals.integrals import Integral |
|
from sympy.logic.boolalg import (And, false, ITE, Not, Or, true) |
|
from sympy.matrices.expressions.dotproduct import DotProduct |
|
from sympy.simplify.cse_main import cse |
|
from sympy.tensor.array import derive_by_array, Array |
|
from sympy.tensor.array.expressions import ArraySymbol |
|
from sympy.tensor.indexed import IndexedBase, Idx |
|
from sympy.utilities.lambdify import lambdify |
|
from sympy.utilities.iterables import numbered_symbols |
|
from sympy.vector import CoordSys3D |
|
from sympy.core.expr import UnevaluatedExpr |
|
from sympy.codegen.cfunctions import expm1, log1p, exp2, log2, log10, hypot, isnan, isinf |
|
from sympy.codegen.numpy_nodes import logaddexp, logaddexp2, amin, amax, minimum, maximum |
|
from sympy.codegen.scipy_nodes import cosm1, powm1 |
|
from sympy.functions.elementary.complexes import re, im, arg |
|
from sympy.functions.special.polynomials import \ |
|
chebyshevt, chebyshevu, legendre, hermite, laguerre, gegenbauer, \ |
|
assoc_legendre, assoc_laguerre, jacobi |
|
from sympy.matrices import Matrix, MatrixSymbol, SparseMatrix |
|
from sympy.printing.codeprinter import PrintMethodNotImplementedError |
|
from sympy.printing.lambdarepr import LambdaPrinter |
|
from sympy.printing.numpy import NumPyPrinter |
|
from sympy.utilities.lambdify import implemented_function, lambdastr |
|
from sympy.testing.pytest import skip |
|
from sympy.utilities.decorator import conserve_mpmath_dps |
|
from sympy.utilities.exceptions import ignore_warnings |
|
from sympy.external import import_module |
|
from sympy.functions.special.gamma_functions import uppergamma, lowergamma |
|
|
|
|
|
import sympy |
|
|
|
|
|
MutableDenseMatrix = Matrix |
|
|
|
numpy = import_module('numpy') |
|
scipy = import_module('scipy', import_kwargs={'fromlist': ['sparse']}) |
|
numexpr = import_module('numexpr') |
|
tensorflow = import_module('tensorflow') |
|
cupy = import_module('cupy') |
|
jax = import_module('jax') |
|
numba = import_module('numba') |
|
|
|
if tensorflow: |
|
|
|
import os |
|
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' |
|
|
|
w, x, y, z = symbols('w,x,y,z') |
|
|
|
|
|
|
|
|
|
def test_no_args(): |
|
f = lambdify([], 1) |
|
raises(TypeError, lambda: f(-1)) |
|
assert f() == 1 |
|
|
|
|
|
def test_single_arg(): |
|
f = lambdify(x, 2*x) |
|
assert f(1) == 2 |
|
|
|
|
|
def test_list_args(): |
|
f = lambdify([x, y], x + y) |
|
assert f(1, 2) == 3 |
|
|
|
|
|
def test_nested_args(): |
|
f1 = lambdify([[w, x]], [w, x]) |
|
assert f1([91, 2]) == [91, 2] |
|
raises(TypeError, lambda: f1(1, 2)) |
|
|
|
f2 = lambdify([(w, x), (y, z)], [w, x, y, z]) |
|
assert f2((18, 12), (73, 4)) == [18, 12, 73, 4] |
|
raises(TypeError, lambda: f2(3, 4)) |
|
|
|
f3 = lambdify([w, [[[x]], y], z], [w, x, y, z]) |
|
assert f3(10, [[[52]], 31], 44) == [10, 52, 31, 44] |
|
|
|
|
|
def test_str_args(): |
|
f = lambdify('x,y,z', 'z,y,x') |
|
assert f(3, 2, 1) == (1, 2, 3) |
|
assert f(1.0, 2.0, 3.0) == (3.0, 2.0, 1.0) |
|
|
|
raises(TypeError, lambda: f(0)) |
|
|
|
|
|
def test_own_namespace_1(): |
|
myfunc = lambda x: 1 |
|
f = lambdify(x, sin(x), {"sin": myfunc}) |
|
assert f(0.1) == 1 |
|
assert f(100) == 1 |
|
|
|
|
|
def test_own_namespace_2(): |
|
def myfunc(x): |
|
return 1 |
|
f = lambdify(x, sin(x), {'sin': myfunc}) |
|
assert f(0.1) == 1 |
|
assert f(100) == 1 |
|
|
|
|
|
def test_own_module(): |
|
f = lambdify(x, sin(x), math) |
|
assert f(0) == 0.0 |
|
|
|
p, q, r = symbols("p q r", real=True) |
|
ae = abs(exp(p+UnevaluatedExpr(q+r))) |
|
f = lambdify([p, q, r], [ae, ae], modules=math) |
|
results = f(1.0, 1e18, -1e18) |
|
refvals = [math.exp(1.0)]*2 |
|
for res, ref in zip(results, refvals): |
|
assert abs((res-ref)/ref) < 1e-15 |
|
|
|
|
|
def test_bad_args(): |
|
|
|
raises(TypeError, lambda: lambdify(1)) |
|
|
|
raises(TypeError, lambda: lambdify([1, 2])) |
|
|
|
|
|
def test_atoms(): |
|
|
|
f = lambdify(x, pi + x, {"pi": 3.14}) |
|
assert f(0) == 3.14 |
|
f = lambdify(x, I + x, {"I": 1j}) |
|
assert f(1) == 1 + 1j |
|
|
|
|
|
|
|
|
|
|
|
|
|
@conserve_mpmath_dps |
|
def test_sympy_lambda(): |
|
mpmath.mp.dps = 50 |
|
sin02 = mpmath.mpf("0.19866933079506121545941262711838975037020672954020") |
|
f = lambdify(x, sin(x), "sympy") |
|
assert f(x) == sin(x) |
|
prec = 1e-15 |
|
assert -prec < f(Rational(1, 5)).evalf() - Float(str(sin02)) < prec |
|
|
|
|
|
|
|
|
|
|
|
@conserve_mpmath_dps |
|
def test_math_lambda(): |
|
mpmath.mp.dps = 50 |
|
sin02 = mpmath.mpf("0.19866933079506121545941262711838975037020672954020") |
|
f = lambdify(x, sin(x), "math") |
|
prec = 1e-15 |
|
assert -prec < f(0.2) - sin02 < prec |
|
raises(TypeError, lambda: f(x)) |
|
|
|
|
|
|
|
@conserve_mpmath_dps |
|
def test_mpmath_lambda(): |
|
mpmath.mp.dps = 50 |
|
sin02 = mpmath.mpf("0.19866933079506121545941262711838975037020672954020") |
|
f = lambdify(x, sin(x), "mpmath") |
|
prec = 1e-49 |
|
assert -prec < f(mpmath.mpf("0.2")) - sin02 < prec |
|
raises(TypeError, lambda: f(x)) |
|
|
|
|
|
ref2 = (mpmath.mpf("1e-30") |
|
- mpmath.mpf("1e-45")/2 |
|
+ 5*mpmath.mpf("1e-60")/6 |
|
- 3*mpmath.mpf("1e-75")/4 |
|
+ 33*mpmath.mpf("1e-90")/40 |
|
) |
|
f2a = lambdify((x, y), x**y - 1, "mpmath") |
|
f2b = lambdify((x, y), powm1(x, y), "mpmath") |
|
f2c = lambdify((x,), expm1(x*log1p(x)), "mpmath") |
|
ans2a = f2a(mpmath.mpf("1")+mpmath.mpf("1e-15"), mpmath.mpf("1e-15")) |
|
ans2b = f2b(mpmath.mpf("1")+mpmath.mpf("1e-15"), mpmath.mpf("1e-15")) |
|
ans2c = f2c(mpmath.mpf("1e-15")) |
|
assert abs(ans2a - ref2) < 1e-51 |
|
assert abs(ans2b - ref2) < 1e-67 |
|
assert abs(ans2c - ref2) < 1e-80 |
|
|
|
|
|
@conserve_mpmath_dps |
|
def test_number_precision(): |
|
mpmath.mp.dps = 50 |
|
sin02 = mpmath.mpf("0.19866933079506121545941262711838975037020672954020") |
|
f = lambdify(x, sin02, "mpmath") |
|
prec = 1e-49 |
|
assert -prec < f(0) - sin02 < prec |
|
|
|
@conserve_mpmath_dps |
|
def test_mpmath_precision(): |
|
mpmath.mp.dps = 100 |
|
assert str(lambdify((), pi.evalf(100), 'mpmath')()) == str(pi.evalf(100)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_math_transl(): |
|
from sympy.utilities.lambdify import MATH_TRANSLATIONS |
|
for sym, mat in MATH_TRANSLATIONS.items(): |
|
assert sym in sympy.__dict__ |
|
assert mat in math.__dict__ |
|
|
|
|
|
def test_mpmath_transl(): |
|
from sympy.utilities.lambdify import MPMATH_TRANSLATIONS |
|
for sym, mat in MPMATH_TRANSLATIONS.items(): |
|
assert sym in sympy.__dict__ or sym == 'Matrix' |
|
assert mat in mpmath.__dict__ |
|
|
|
|
|
def test_numpy_transl(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
|
|
from sympy.utilities.lambdify import NUMPY_TRANSLATIONS |
|
for sym, nump in NUMPY_TRANSLATIONS.items(): |
|
assert sym in sympy.__dict__ |
|
assert nump in numpy.__dict__ |
|
|
|
|
|
def test_scipy_transl(): |
|
if not scipy: |
|
skip("scipy not installed.") |
|
|
|
from sympy.utilities.lambdify import SCIPY_TRANSLATIONS |
|
for sym, scip in SCIPY_TRANSLATIONS.items(): |
|
assert sym in sympy.__dict__ |
|
assert scip in scipy.__dict__ or scip in scipy.special.__dict__ |
|
|
|
|
|
def test_numpy_translation_abs(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
|
|
f = lambdify(x, Abs(x), "numpy") |
|
assert f(-1) == 1 |
|
assert f(1) == 1 |
|
|
|
|
|
def test_numexpr_printer(): |
|
if not numexpr: |
|
skip("numexpr not installed.") |
|
|
|
|
|
|
|
from sympy.printing.lambdarepr import NumExprPrinter |
|
|
|
blacklist = ('where', 'complex', 'contains') |
|
arg_tuple = (x, y, z) |
|
for sym in NumExprPrinter._numexpr_functions.keys(): |
|
if sym in blacklist: |
|
continue |
|
ssym = S(sym) |
|
if hasattr(ssym, '_nargs'): |
|
nargs = ssym._nargs[0] |
|
else: |
|
nargs = 1 |
|
args = arg_tuple[:nargs] |
|
f = lambdify(args, ssym(*args), modules='numexpr') |
|
assert f(*(1, )*nargs) is not None |
|
|
|
|
|
def test_cmath_sqrt(): |
|
f = lambdify(x, sqrt(x), "cmath") |
|
assert f(0) == 0 |
|
assert f(1) == 1 |
|
assert f(4) == 2 |
|
assert abs(f(2) - 1.414) < 0.001 |
|
assert f(-1) == 1j |
|
assert f(-4) == 2j |
|
|
|
|
|
def test_cmath_log(): |
|
f = lambdify(x, log(x), "cmath") |
|
assert abs(f(1) - 0) < 1e-15 |
|
assert abs(f(cmath.e) - 1) < 1e-15 |
|
assert abs(f(-1) - cmath.log(-1)) < 1e-15 |
|
|
|
|
|
def test_cmath_sinh(): |
|
f = lambdify(x, sinh(x), "cmath") |
|
assert abs(f(0) - cmath.sinh(0)) < 1e-15 |
|
assert abs(f(pi) - cmath.sinh(pi)) < 1e-15 |
|
assert abs(f(-pi) - cmath.sinh(-pi)) < 1e-15 |
|
assert abs(f(1j) - cmath.sinh(1j)) < 1e-15 |
|
|
|
|
|
def test_cmath_cosh(): |
|
f = lambdify(x, cosh(x), "cmath") |
|
assert abs(f(0) - cmath.cosh(0)) < 1e-15 |
|
assert abs(f(pi) - cmath.cosh(pi)) < 1e-15 |
|
assert abs(f(-pi) - cmath.cosh(-pi)) < 1e-15 |
|
assert abs(f(1j) - cmath.cosh(1j)) < 1e-15 |
|
|
|
|
|
def test_cmath_tanh(): |
|
f = lambdify(x, tanh(x), "cmath") |
|
assert abs(f(0) - cmath.tanh(0)) < 1e-15 |
|
assert abs(f(pi) - cmath.tanh(pi)) < 1e-15 |
|
assert abs(f(-pi) - cmath.tanh(-pi)) < 1e-15 |
|
assert abs(f(1j) - cmath.tanh(1j)) < 1e-15 |
|
|
|
|
|
def test_cmath_sin(): |
|
f = lambdify(x, sin(x), "cmath") |
|
assert abs(f(0) - cmath.sin(0)) < 1e-15 |
|
assert abs(f(pi) - cmath.sin(pi)) < 1e-15 |
|
assert abs(f(-pi) - cmath.sin(-pi)) < 1e-15 |
|
assert abs(f(1j) - cmath.sin(1j)) < 1e-15 |
|
|
|
|
|
def test_cmath_cos(): |
|
f = lambdify(x, cos(x), "cmath") |
|
assert abs(f(0) - cmath.cos(0)) < 1e-15 |
|
assert abs(f(pi) - cmath.cos(pi)) < 1e-15 |
|
assert abs(f(-pi) - cmath.cos(-pi)) < 1e-15 |
|
assert abs(f(1j) - cmath.cos(1j)) < 1e-15 |
|
|
|
|
|
def test_cmath_tan(): |
|
f = lambdify(x, tan(x), "cmath") |
|
assert abs(f(0) - cmath.tan(0)) < 1e-15 |
|
assert abs(f(1j) - cmath.tan(1j)) < 1e-15 |
|
|
|
|
|
def test_cmath_asin(): |
|
f = lambdify(x, asin(x), "cmath") |
|
assert abs(f(0) - cmath.asin(0)) < 1e-15 |
|
assert abs(f(1) - cmath.asin(1)) < 1e-15 |
|
assert abs(f(-1) - cmath.asin(-1)) < 1e-15 |
|
assert abs(f(2) - cmath.asin(2)) < 1e-15 |
|
assert abs(f(1j) - cmath.asin(1j)) < 1e-15 |
|
|
|
|
|
def test_cmath_acos(): |
|
f = lambdify(x, acos(x), "cmath") |
|
assert abs(f(1) - cmath.acos(1)) < 1e-15 |
|
assert abs(f(-1) - cmath.acos(-1)) < 1e-15 |
|
assert abs(f(2) - cmath.acos(2)) < 1e-15 |
|
assert abs(f(1j) - cmath.acos(1j)) < 1e-15 |
|
|
|
|
|
def test_cmath_atan(): |
|
f = lambdify(x, atan(x), "cmath") |
|
assert abs(f(0) - cmath.atan(0)) < 1e-15 |
|
assert abs(f(1) - cmath.atan(1)) < 1e-15 |
|
assert abs(f(-1) - cmath.atan(-1)) < 1e-15 |
|
assert abs(f(2) - cmath.atan(2)) < 1e-15 |
|
assert abs(f(2j) - cmath.atan(2j)) < 1e-15 |
|
|
|
|
|
def test_cmath_asinh(): |
|
f = lambdify(x, asinh(x), "cmath") |
|
assert abs(f(0) - cmath.asinh(0)) < 1e-15 |
|
assert abs(f(1) - cmath.asinh(1)) < 1e-15 |
|
assert abs(f(-1) - cmath.asinh(-1)) < 1e-15 |
|
assert abs(f(2) - cmath.asinh(2)) < 1e-15 |
|
assert abs(f(2j) - cmath.asinh(2j)) < 1e-15 |
|
|
|
|
|
def test_cmath_acosh(): |
|
f = lambdify(x, acosh(x), "cmath") |
|
assert abs(f(1) - cmath.acosh(1)) < 1e-15 |
|
assert abs(f(2) - cmath.acosh(2)) < 1e-15 |
|
assert abs(f(-1) - cmath.acosh(-1)) < 1e-15 |
|
assert abs(f(2j) - cmath.acosh(2j)) < 1e-15 |
|
|
|
|
|
def test_cmath_atanh(): |
|
f = lambdify(x, atanh(x), "cmath") |
|
assert abs(f(0) - cmath.atanh(0)) < 1e-15 |
|
assert abs(f(0.5) - cmath.atanh(0.5)) < 1e-15 |
|
assert abs(f(-0.5) - cmath.atanh(-0.5)) < 1e-15 |
|
assert abs(f(2) - cmath.atanh(2)) < 1e-15 |
|
assert abs(f(-2) - cmath.atanh(-2)) < 1e-15 |
|
assert abs(f(2j) - cmath.atanh(2j)) < 1e-15 |
|
|
|
|
|
def test_cmath_complex_identities(): |
|
|
|
z = symbols('z') |
|
|
|
|
|
expr = cos(z) - cos(re(z)) * cosh(im(z)) + I * sin(re(z)) * sinh(im(z)) |
|
func = lambdify([z], expr, modules=["cmath", "math"]) |
|
hpi = math.pi / 2 |
|
assert abs(func(hpi + 1j * hpi)) < 4e-16 |
|
|
|
|
|
func = lambdify([z], exp(I * z) - (cos(z) + I * sin(z)), modules=["cmath", "math"]) |
|
assert abs(func(hpi)) < 4e-16 |
|
|
|
|
|
func_exp = lambdify([z], exp(z) - exp(re(z)) * (cos(im(z)) + I * sin(im(z))), |
|
modules=["cmath", "math"]) |
|
assert abs(func_exp(hpi + 1j * hpi)) < 4e-16 |
|
|
|
|
|
func_cos = lambdify([z], cos(z) - (cos(re(z)) * cosh(im(z)) - I * sin(re(z)) * sinh(im(z))), |
|
modules=["cmath", "math"]) |
|
assert abs(func_cos(hpi + 1j * hpi)) < 4e-16 |
|
|
|
|
|
func_sin = lambdify([z], sin(z) - (sin(re(z)) * cosh(im(z)) + I * cos(re(z)) * sinh(im(z))), |
|
modules=["cmath", "math"]) |
|
assert abs(func_sin(hpi + 1j * hpi)) < 4e-16 |
|
|
|
|
|
func_cosh_1 = lambdify([z], cosh(z) - (cosh(re(z)) * cos(im(z)) + I * sinh(re(z)) * sin(im(z))), |
|
modules=["cmath", "math"]) |
|
assert abs(func_cosh_1(hpi + 1j * hpi)) < 4e-16 |
|
|
|
|
|
func_sinh = lambdify([z], sinh(z) - (sinh(re(z)) * cos(im(z)) + I * cosh(re(z)) * sin(im(z))), |
|
modules=["cmath", "math"]) |
|
assert abs(func_sinh(hpi + 1j * hpi)) < 4e-16 |
|
|
|
|
|
func_cosh_2 = lambdify([z], cosh(z) - (exp(z) + exp(-z)) / 2, modules=["cmath", "math"]) |
|
assert abs(func_cosh_2(hpi)) < 4e-16 |
|
|
|
|
|
expr1 = log(re(z)) + log(im(z)) - log(re(z) * im(z)) |
|
expr2 = exp(re(z)) * exp(im(z) * I) - exp(z) |
|
expr3 = log(exp(re(z))) - re(z) |
|
expr4 = exp(log(re(z))) - re(z) |
|
expr5 = log(exp(re(z) + im(z))) - (re(z) + im(z)) |
|
expr6 = exp(log(re(z) + im(z))) - (re(z) + im(z)) |
|
func1 = lambdify([z], expr1, modules=["cmath", "math"]) |
|
func2 = lambdify([z], expr2, modules=["cmath", "math"]) |
|
func3 = lambdify([z], expr3, modules=["cmath", "math"]) |
|
func4 = lambdify([z], expr4, modules=["cmath", "math"]) |
|
func5 = lambdify([z], expr5, modules=["cmath", "math"]) |
|
func6 = lambdify([z], expr6, modules=["cmath", "math"]) |
|
test_value = 3 + 4j |
|
assert abs(func1(test_value)) < 4e-16 |
|
assert abs(func2(test_value)) < 4e-16 |
|
assert abs(func3(test_value)) < 4e-16 |
|
assert abs(func4(test_value)) < 4e-16 |
|
assert abs(func5(test_value)) < 4e-16 |
|
assert abs(func6(test_value)) < 4e-16 |
|
|
|
|
|
def test_issue_9334(): |
|
if not numexpr: |
|
skip("numexpr not installed.") |
|
if not numpy: |
|
skip("numpy not installed.") |
|
expr = S('b*a - sqrt(a**2)') |
|
a, b = sorted(expr.free_symbols, key=lambda s: s.name) |
|
func_numexpr = lambdify((a,b), expr, modules=[numexpr], dummify=False) |
|
foo, bar = numpy.random.random((2, 4)) |
|
func_numexpr(foo, bar) |
|
|
|
|
|
def test_issue_12984(): |
|
if not numexpr: |
|
skip("numexpr not installed.") |
|
func_numexpr = lambdify((x,y,z), Piecewise((y, x >= 0), (z, x > -1)), numexpr) |
|
with ignore_warnings(RuntimeWarning): |
|
assert func_numexpr(1, 24, 42) == 24 |
|
assert str(func_numexpr(-1, 24, 42)) == 'nan' |
|
|
|
|
|
def test_empty_modules(): |
|
x, y = symbols('x y') |
|
expr = -(x % y) |
|
|
|
no_modules = lambdify([x, y], expr) |
|
empty_modules = lambdify([x, y], expr, modules=[]) |
|
assert no_modules(3, 7) == empty_modules(3, 7) |
|
assert no_modules(3, 7) == -3 |
|
|
|
|
|
def test_exponentiation(): |
|
f = lambdify(x, x**2) |
|
assert f(-1) == 1 |
|
assert f(0) == 0 |
|
assert f(1) == 1 |
|
assert f(-2) == 4 |
|
assert f(2) == 4 |
|
assert f(2.5) == 6.25 |
|
|
|
|
|
def test_sqrt(): |
|
f = lambdify(x, sqrt(x)) |
|
assert f(0) == 0.0 |
|
assert f(1) == 1.0 |
|
assert f(4) == 2.0 |
|
assert abs(f(2) - 1.414) < 0.001 |
|
assert f(6.25) == 2.5 |
|
|
|
|
|
def test_trig(): |
|
f = lambdify([x], [cos(x), sin(x)], 'math') |
|
d = f(pi) |
|
prec = 1e-11 |
|
assert -prec < d[0] + 1 < prec |
|
assert -prec < d[1] < prec |
|
d = f(3.14159) |
|
prec = 1e-5 |
|
assert -prec < d[0] + 1 < prec |
|
assert -prec < d[1] < prec |
|
|
|
|
|
def test_integral(): |
|
if numpy and not scipy: |
|
skip("scipy not installed.") |
|
f = Lambda(x, exp(-x**2)) |
|
l = lambdify(y, Integral(f(x), (x, y, oo))) |
|
d = l(-oo) |
|
assert 1.77245385 < d < 1.772453851 |
|
|
|
|
|
def test_double_integral(): |
|
if numpy and not scipy: |
|
skip("scipy not installed.") |
|
|
|
i = Integral(1/(1 - x**2*y**2), (x, 0, 1), (y, 0, z)) |
|
l = lambdify([z], i) |
|
d = l(1) |
|
assert 1.23370055 < d < 1.233700551 |
|
|
|
def test_spherical_bessel(): |
|
if numpy and not scipy: |
|
skip("scipy not installed.") |
|
test_point = 4.2 |
|
x = symbols("x") |
|
jtest = jn(2, x) |
|
assert abs(lambdify(x,jtest)(test_point) - |
|
jtest.subs(x,test_point).evalf()) < 1e-8 |
|
ytest = yn(2, x) |
|
assert abs(lambdify(x,ytest)(test_point) - |
|
ytest.subs(x,test_point).evalf()) < 1e-8 |
|
|
|
|
|
|
|
|
|
|
|
def test_vector_simple(): |
|
f = lambdify((x, y, z), (z, y, x)) |
|
assert f(3, 2, 1) == (1, 2, 3) |
|
assert f(1.0, 2.0, 3.0) == (3.0, 2.0, 1.0) |
|
|
|
raises(TypeError, lambda: f(0)) |
|
|
|
|
|
def test_vector_discontinuous(): |
|
f = lambdify(x, (-1/x, 1/x)) |
|
raises(ZeroDivisionError, lambda: f(0)) |
|
assert f(1) == (-1.0, 1.0) |
|
assert f(2) == (-0.5, 0.5) |
|
assert f(-2) == (0.5, -0.5) |
|
|
|
|
|
def test_trig_symbolic(): |
|
f = lambdify([x], [cos(x), sin(x)], 'math') |
|
d = f(pi) |
|
assert abs(d[0] + 1) < 0.0001 |
|
assert abs(d[1] - 0) < 0.0001 |
|
|
|
|
|
def test_trig_float(): |
|
f = lambdify([x], [cos(x), sin(x)]) |
|
d = f(3.14159) |
|
assert abs(d[0] + 1) < 0.0001 |
|
assert abs(d[1] - 0) < 0.0001 |
|
|
|
|
|
def test_docs(): |
|
f = lambdify(x, x**2) |
|
assert f(2) == 4 |
|
f = lambdify([x, y, z], [z, y, x]) |
|
assert f(1, 2, 3) == [3, 2, 1] |
|
f = lambdify(x, sqrt(x)) |
|
assert f(4) == 2.0 |
|
f = lambdify((x, y), sin(x*y)**2) |
|
assert f(0, 5) == 0 |
|
|
|
|
|
def test_math(): |
|
f = lambdify((x, y), sin(x), modules="math") |
|
assert f(0, 5) == 0 |
|
|
|
|
|
def test_sin(): |
|
f = lambdify(x, sin(x)**2) |
|
assert isinstance(f(2), float) |
|
f = lambdify(x, sin(x)**2, modules="math") |
|
assert isinstance(f(2), float) |
|
|
|
|
|
def test_matrix(): |
|
A = Matrix([[x, x*y], [sin(z) + 4, x**z]]) |
|
sol = Matrix([[1, 2], [sin(3) + 4, 1]]) |
|
f = lambdify((x, y, z), A, modules="sympy") |
|
assert f(1, 2, 3) == sol |
|
f = lambdify((x, y, z), (A, [A]), modules="sympy") |
|
assert f(1, 2, 3) == (sol, [sol]) |
|
J = Matrix((x, x + y)).jacobian((x, y)) |
|
v = Matrix((x, y)) |
|
sol = Matrix([[1, 0], [1, 1]]) |
|
assert lambdify(v, J, modules='sympy')(1, 2) == sol |
|
assert lambdify(v.T, J, modules='sympy')(1, 2) == sol |
|
|
|
|
|
def test_numpy_matrix(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
A = Matrix([[x, x*y], [sin(z) + 4, x**z]]) |
|
sol_arr = numpy.array([[1, 2], [numpy.sin(3) + 4, 1]]) |
|
|
|
f = lambdify((x, y, z), A, ['numpy']) |
|
numpy.testing.assert_allclose(f(1, 2, 3), sol_arr) |
|
|
|
assert isinstance(f(1, 2, 3), numpy.ndarray) |
|
|
|
|
|
class dot(Function): |
|
pass |
|
x_dot_mtx = dot(x, Matrix([[2], [1], [0]])) |
|
f_dot1 = lambdify(x, x_dot_mtx) |
|
inp = numpy.zeros((17, 3)) |
|
assert numpy.all(f_dot1(inp) == 0) |
|
|
|
strict_kw = {"allow_unknown_functions": False, "inline": True, "fully_qualified_modules": False} |
|
p2 = NumPyPrinter(dict(user_functions={'dot': 'dot'}, **strict_kw)) |
|
f_dot2 = lambdify(x, x_dot_mtx, printer=p2) |
|
assert numpy.all(f_dot2(inp) == 0) |
|
|
|
p3 = NumPyPrinter(strict_kw) |
|
|
|
raises(Exception, lambda: lambdify(x, x_dot_mtx, printer=p3)(inp)) |
|
|
|
|
|
def test_numpy_transpose(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
A = Matrix([[1, x], [0, 1]]) |
|
f = lambdify((x), A.T, modules="numpy") |
|
numpy.testing.assert_array_equal(f(2), numpy.array([[1, 0], [2, 1]])) |
|
|
|
|
|
def test_numpy_dotproduct(): |
|
if not numpy: |
|
skip("numpy not installed") |
|
A = Matrix([x, y, z]) |
|
f1 = lambdify([x, y, z], DotProduct(A, A), modules='numpy') |
|
f2 = lambdify([x, y, z], DotProduct(A, A.T), modules='numpy') |
|
f3 = lambdify([x, y, z], DotProduct(A.T, A), modules='numpy') |
|
f4 = lambdify([x, y, z], DotProduct(A, A.T), modules='numpy') |
|
|
|
assert f1(1, 2, 3) == \ |
|
f2(1, 2, 3) == \ |
|
f3(1, 2, 3) == \ |
|
f4(1, 2, 3) == \ |
|
numpy.array([14]) |
|
|
|
|
|
def test_numpy_inverse(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
A = Matrix([[1, x], [0, 1]]) |
|
f = lambdify((x), A**-1, modules="numpy") |
|
numpy.testing.assert_array_equal(f(2), numpy.array([[1, -2], [0, 1]])) |
|
|
|
|
|
def test_numpy_old_matrix(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
A = Matrix([[x, x*y], [sin(z) + 4, x**z]]) |
|
sol_arr = numpy.array([[1, 2], [numpy.sin(3) + 4, 1]]) |
|
f = lambdify((x, y, z), A, [{'ImmutableDenseMatrix': numpy.matrix}, 'numpy']) |
|
with ignore_warnings(PendingDeprecationWarning): |
|
numpy.testing.assert_allclose(f(1, 2, 3), sol_arr) |
|
assert isinstance(f(1, 2, 3), numpy.matrix) |
|
|
|
|
|
def test_scipy_sparse_matrix(): |
|
if not scipy: |
|
skip("scipy not installed.") |
|
A = SparseMatrix([[x, 0], [0, y]]) |
|
f = lambdify((x, y), A, modules="scipy") |
|
B = f(1, 2) |
|
assert isinstance(B, scipy.sparse.coo_matrix) |
|
|
|
|
|
def test_python_div_zero_issue_11306(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
p = Piecewise((1 / x, y < -1), (x, y < 1), (1 / x, True)) |
|
f = lambdify([x, y], p, modules='numpy') |
|
with numpy.errstate(divide='ignore'): |
|
assert float(f(numpy.array(0), numpy.array(0.5))) == 0 |
|
assert float(f(numpy.array(0), numpy.array(1))) == float('inf') |
|
|
|
|
|
def test_issue9474(): |
|
mods = [None, 'math'] |
|
if numpy: |
|
mods.append('numpy') |
|
if mpmath: |
|
mods.append('mpmath') |
|
for mod in mods: |
|
f = lambdify(x, S.One/x, modules=mod) |
|
assert f(2) == 0.5 |
|
f = lambdify(x, floor(S.One/x), modules=mod) |
|
assert f(2) == 0 |
|
|
|
for absfunc, modules in product([Abs, abs], mods): |
|
f = lambdify(x, absfunc(x), modules=modules) |
|
assert f(-1) == 1 |
|
assert f(1) == 1 |
|
assert f(3+4j) == 5 |
|
|
|
|
|
def test_issue_9871(): |
|
if not numexpr: |
|
skip("numexpr not installed.") |
|
if not numpy: |
|
skip("numpy not installed.") |
|
|
|
r = sqrt(x**2 + y**2) |
|
expr = diff(1/r, x) |
|
|
|
xn = yn = numpy.linspace(1, 10, 16) |
|
|
|
fv_exact = -numpy.sqrt(2.)**-3 * xn**-2 |
|
|
|
fv_numpy = lambdify((x, y), expr, modules='numpy')(xn, yn) |
|
fv_numexpr = lambdify((x, y), expr, modules='numexpr')(xn, yn) |
|
numpy.testing.assert_allclose(fv_numpy, fv_exact, rtol=1e-10) |
|
numpy.testing.assert_allclose(fv_numexpr, fv_exact, rtol=1e-10) |
|
|
|
|
|
def test_numpy_piecewise(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
pieces = Piecewise((x, x < 3), (x**2, x > 5), (0, True)) |
|
f = lambdify(x, pieces, modules="numpy") |
|
numpy.testing.assert_array_equal(f(numpy.arange(10)), |
|
numpy.array([0, 1, 2, 0, 0, 0, 36, 49, 64, 81])) |
|
|
|
nodef_func = lambdify(x, Piecewise((x, x > 0), (-x, x < 0))) |
|
numpy.testing.assert_array_equal(nodef_func(numpy.array([-1, 0, 1])), |
|
numpy.array([1, numpy.nan, 1])) |
|
|
|
|
|
def test_numpy_logical_ops(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
and_func = lambdify((x, y), And(x, y), modules="numpy") |
|
and_func_3 = lambdify((x, y, z), And(x, y, z), modules="numpy") |
|
or_func = lambdify((x, y), Or(x, y), modules="numpy") |
|
or_func_3 = lambdify((x, y, z), Or(x, y, z), modules="numpy") |
|
not_func = lambdify((x), Not(x), modules="numpy") |
|
arr1 = numpy.array([True, True]) |
|
arr2 = numpy.array([False, True]) |
|
arr3 = numpy.array([True, False]) |
|
numpy.testing.assert_array_equal(and_func(arr1, arr2), numpy.array([False, True])) |
|
numpy.testing.assert_array_equal(and_func_3(arr1, arr2, arr3), numpy.array([False, False])) |
|
numpy.testing.assert_array_equal(or_func(arr1, arr2), numpy.array([True, True])) |
|
numpy.testing.assert_array_equal(or_func_3(arr1, arr2, arr3), numpy.array([True, True])) |
|
numpy.testing.assert_array_equal(not_func(arr2), numpy.array([True, False])) |
|
|
|
|
|
def test_numpy_matmul(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
xmat = Matrix([[x, y], [z, 1+z]]) |
|
ymat = Matrix([[x**2], [Abs(x)]]) |
|
mat_func = lambdify((x, y, z), xmat*ymat, modules="numpy") |
|
numpy.testing.assert_array_equal(mat_func(0.5, 3, 4), numpy.array([[1.625], [3.5]])) |
|
numpy.testing.assert_array_equal(mat_func(-0.5, 3, 4), numpy.array([[1.375], [3.5]])) |
|
|
|
f = lambdify((x, y, z), xmat*xmat*xmat, modules="numpy") |
|
numpy.testing.assert_array_equal(f(0.5, 3, 4), numpy.array([[72.125, 119.25], |
|
[159, 251]])) |
|
|
|
|
|
def test_numpy_numexpr(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
if not numexpr: |
|
skip("numexpr not installed.") |
|
a, b, c = numpy.random.randn(3, 128, 128) |
|
|
|
expr = sin(x) + cos(y) + tan(z)**2 + Abs(z-y)*acos(sin(y*z)) + \ |
|
Abs(y-z)*acosh(2+exp(y-x))- sqrt(x**2+I*y**2) |
|
npfunc = lambdify((x, y, z), expr, modules='numpy') |
|
nefunc = lambdify((x, y, z), expr, modules='numexpr') |
|
assert numpy.allclose(npfunc(a, b, c), nefunc(a, b, c)) |
|
|
|
|
|
def test_numexpr_userfunctions(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
if not numexpr: |
|
skip("numexpr not installed.") |
|
a, b = numpy.random.randn(2, 10) |
|
uf = type('uf', (Function, ), |
|
{'eval' : classmethod(lambda x, y : y**2+1)}) |
|
func = lambdify(x, 1-uf(x), modules='numexpr') |
|
assert numpy.allclose(func(a), -(a**2)) |
|
|
|
uf = implemented_function(Function('uf'), lambda x, y : 2*x*y+1) |
|
func = lambdify((x, y), uf(x, y), modules='numexpr') |
|
assert numpy.allclose(func(a, b), 2*a*b+1) |
|
|
|
|
|
def test_tensorflow_basic_math(): |
|
if not tensorflow: |
|
skip("tensorflow not installed.") |
|
expr = Max(sin(x), Abs(1/(x+2))) |
|
func = lambdify(x, expr, modules="tensorflow") |
|
|
|
with tensorflow.compat.v1.Session() as s: |
|
a = tensorflow.constant(0, dtype=tensorflow.float32) |
|
assert func(a).eval(session=s) == 0.5 |
|
|
|
|
|
def test_tensorflow_placeholders(): |
|
if not tensorflow: |
|
skip("tensorflow not installed.") |
|
expr = Max(sin(x), Abs(1/(x+2))) |
|
func = lambdify(x, expr, modules="tensorflow") |
|
|
|
with tensorflow.compat.v1.Session() as s: |
|
a = tensorflow.compat.v1.placeholder(dtype=tensorflow.float32) |
|
assert func(a).eval(session=s, feed_dict={a: 0}) == 0.5 |
|
|
|
|
|
def test_tensorflow_variables(): |
|
if not tensorflow: |
|
skip("tensorflow not installed.") |
|
expr = Max(sin(x), Abs(1/(x+2))) |
|
func = lambdify(x, expr, modules="tensorflow") |
|
|
|
with tensorflow.compat.v1.Session() as s: |
|
a = tensorflow.Variable(0, dtype=tensorflow.float32) |
|
s.run(a.initializer) |
|
assert func(a).eval(session=s, feed_dict={a: 0}) == 0.5 |
|
|
|
|
|
def test_tensorflow_logical_operations(): |
|
if not tensorflow: |
|
skip("tensorflow not installed.") |
|
expr = Not(And(Or(x, y), y)) |
|
func = lambdify([x, y], expr, modules="tensorflow") |
|
|
|
with tensorflow.compat.v1.Session() as s: |
|
assert func(False, True).eval(session=s) == False |
|
|
|
|
|
def test_tensorflow_piecewise(): |
|
if not tensorflow: |
|
skip("tensorflow not installed.") |
|
expr = Piecewise((0, Eq(x,0)), (-1, x < 0), (1, x > 0)) |
|
func = lambdify(x, expr, modules="tensorflow") |
|
|
|
with tensorflow.compat.v1.Session() as s: |
|
assert func(-1).eval(session=s) == -1 |
|
assert func(0).eval(session=s) == 0 |
|
assert func(1).eval(session=s) == 1 |
|
|
|
|
|
def test_tensorflow_multi_max(): |
|
if not tensorflow: |
|
skip("tensorflow not installed.") |
|
expr = Max(x, -x, x**2) |
|
func = lambdify(x, expr, modules="tensorflow") |
|
|
|
with tensorflow.compat.v1.Session() as s: |
|
assert func(-2).eval(session=s) == 4 |
|
|
|
|
|
def test_tensorflow_multi_min(): |
|
if not tensorflow: |
|
skip("tensorflow not installed.") |
|
expr = Min(x, -x, x**2) |
|
func = lambdify(x, expr, modules="tensorflow") |
|
|
|
with tensorflow.compat.v1.Session() as s: |
|
assert func(-2).eval(session=s) == -2 |
|
|
|
|
|
def test_tensorflow_relational(): |
|
if not tensorflow: |
|
skip("tensorflow not installed.") |
|
expr = x >= 0 |
|
func = lambdify(x, expr, modules="tensorflow") |
|
|
|
with tensorflow.compat.v1.Session() as s: |
|
assert func(1).eval(session=s) == True |
|
|
|
|
|
def test_tensorflow_complexes(): |
|
if not tensorflow: |
|
skip("tensorflow not installed") |
|
|
|
func1 = lambdify(x, re(x), modules="tensorflow") |
|
func2 = lambdify(x, im(x), modules="tensorflow") |
|
func3 = lambdify(x, Abs(x), modules="tensorflow") |
|
func4 = lambdify(x, arg(x), modules="tensorflow") |
|
|
|
with tensorflow.compat.v1.Session() as s: |
|
|
|
|
|
|
|
a = tensorflow.constant(1+2j) |
|
assert func1(a).eval(session=s) == 1 |
|
assert func2(a).eval(session=s) == 2 |
|
|
|
tensorflow_result = func3(a).eval(session=s) |
|
sympy_result = Abs(1 + 2j).evalf() |
|
assert abs(tensorflow_result-sympy_result) < 10**-6 |
|
|
|
tensorflow_result = func4(a).eval(session=s) |
|
sympy_result = arg(1 + 2j).evalf() |
|
assert abs(tensorflow_result-sympy_result) < 10**-6 |
|
|
|
|
|
def test_tensorflow_array_arg(): |
|
|
|
if not tensorflow: |
|
skip("tensorflow not installed.") |
|
|
|
f = lambdify([[x, y]], x*x + y, 'tensorflow') |
|
|
|
with tensorflow.compat.v1.Session() as s: |
|
fcall = f(tensorflow.constant([2.0, 1.0])) |
|
assert fcall.eval(session=s) == 5.0 |
|
|
|
|
|
|
|
|
|
|
|
def test_sym_single_arg(): |
|
f = lambdify(x, x * y) |
|
assert f(z) == z * y |
|
|
|
|
|
def test_sym_list_args(): |
|
f = lambdify([x, y], x + y + z) |
|
assert f(1, 2) == 3 + z |
|
|
|
|
|
def test_sym_integral(): |
|
f = Lambda(x, exp(-x**2)) |
|
l = lambdify(x, Integral(f(x), (x, -oo, oo)), modules="sympy") |
|
assert l(y) == Integral(exp(-y**2), (y, -oo, oo)) |
|
assert l(y).doit() == sqrt(pi) |
|
|
|
|
|
def test_namespace_order(): |
|
|
|
|
|
|
|
|
|
|
|
|
|
n1 = {'f': lambda x: 'first f'} |
|
n2 = {'f': lambda x: 'second f', |
|
'g': lambda x: 'function g'} |
|
f = sympy.Function('f') |
|
g = sympy.Function('g') |
|
if1 = lambdify(x, f(x), modules=(n1, "sympy")) |
|
assert if1(1) == 'first f' |
|
if2 = lambdify(x, g(x), modules=(n2, "sympy")) |
|
|
|
assert if1(1) == 'first f' |
|
|
|
assert if2(1) == 'function g' |
|
|
|
|
|
def test_imps(): |
|
|
|
|
|
f = implemented_function('f', lambda x: 2*x) |
|
g = implemented_function('f', lambda x: math.sqrt(x)) |
|
l1 = lambdify(x, f(x)) |
|
l2 = lambdify(x, g(x)) |
|
assert str(f(x)) == str(g(x)) |
|
assert l1(3) == 6 |
|
assert l2(3) == math.sqrt(3) |
|
|
|
func = sympy.Function('myfunc') |
|
assert not hasattr(func, '_imp_') |
|
my_f = implemented_function(func, lambda x: 2*x) |
|
assert hasattr(my_f, '_imp_') |
|
|
|
f2 = implemented_function("f", lambda x: x + 101) |
|
raises(ValueError, lambda: lambdify(x, f(f2(x)))) |
|
|
|
|
|
def test_imps_errors(): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for val, error_class in product((0, 0., 2, 2.0), (TypeError, ValueError)): |
|
|
|
def myfunc(a): |
|
if a == 0: |
|
raise error_class |
|
return 1 |
|
|
|
f = implemented_function('f', myfunc) |
|
expr = f(val) |
|
assert expr == f(val) |
|
|
|
|
|
def test_imps_wrong_args(): |
|
raises(ValueError, lambda: implemented_function(sin, lambda x: x)) |
|
|
|
|
|
def test_lambdify_imps(): |
|
|
|
|
|
f = sympy.cos |
|
assert lambdify(x, f(x))(0) == 1 |
|
assert lambdify(x, 1 + f(x))(0) == 2 |
|
assert lambdify((x, y), y + f(x))(0, 1) == 2 |
|
|
|
f = implemented_function("f", lambda x: x + 100) |
|
assert lambdify(x, f(x))(0) == 100 |
|
assert lambdify(x, 1 + f(x))(0) == 101 |
|
assert lambdify((x, y), y + f(x))(0, 1) == 101 |
|
|
|
lam = lambdify(x, (f(x), x)) |
|
assert lam(3) == (103, 3) |
|
lam = lambdify(x, [f(x), x]) |
|
assert lam(3) == [103, 3] |
|
lam = lambdify(x, [f(x), (f(x), x)]) |
|
assert lam(3) == [103, (103, 3)] |
|
lam = lambdify(x, {f(x): x}) |
|
assert lam(3) == {103: 3} |
|
lam = lambdify(x, {f(x): x}) |
|
assert lam(3) == {103: 3} |
|
lam = lambdify(x, {x: f(x)}) |
|
assert lam(3) == {3: 103} |
|
|
|
d = {'f': lambda x: x + 99} |
|
lam = lambdify(x, f(x), d) |
|
assert lam(3) == 103 |
|
|
|
lam = lambdify(x, f(x), d, use_imps=False) |
|
assert lam(3) == 102 |
|
|
|
|
|
def test_dummification(): |
|
t = symbols('t') |
|
F = Function('F') |
|
G = Function('G') |
|
|
|
|
|
|
|
alpha = symbols(r'\alpha') |
|
some_expr = 2 * F(t)**2 / G(t) |
|
lam = lambdify((F(t), G(t)), some_expr) |
|
assert lam(3, 9) == 2 |
|
lam = lambdify(sin(t), 2 * sin(t)**2) |
|
assert lam(F(t)) == 2 * F(t)**2 |
|
|
|
lam = lambdify((alpha, t), 2*alpha + t) |
|
assert lam(2, 1) == 5 |
|
raises(SyntaxError, lambda: lambdify(F(t) * G(t), F(t) * G(t) + 5)) |
|
raises(SyntaxError, lambda: lambdify(2 * F(t), 2 * F(t) + 5)) |
|
raises(SyntaxError, lambda: lambdify(2 * F(t), 4 * F(t) + 5)) |
|
|
|
|
|
def test_lambdify__arguments_with_invalid_python_identifiers(): |
|
|
|
N = CoordSys3D('N') |
|
xn, yn, zn = N.base_scalars() |
|
expr = xn + yn |
|
f = lambdify([xn, yn], expr) |
|
res = f(0.2, 0.3) |
|
ref = 0.2 + 0.3 |
|
assert abs(res-ref) < 1e-15 |
|
|
|
|
|
def test_curly_matrix_symbol(): |
|
|
|
curlyv = sympy.MatrixSymbol("{v}", 2, 1) |
|
lam = lambdify(curlyv, curlyv) |
|
assert lam(1)==1 |
|
lam = lambdify(curlyv, curlyv, dummify=True) |
|
assert lam(1)==1 |
|
|
|
|
|
def test_python_keywords(): |
|
|
|
|
|
|
|
python_if = symbols('if') |
|
expr = python_if / 2 |
|
f = lambdify(python_if, expr) |
|
assert f(4.0) == 2.0 |
|
|
|
|
|
def test_lambdify_docstring(): |
|
func = lambdify((w, x, y, z), w + x + y + z) |
|
ref = ( |
|
"Created with lambdify. Signature:\n\n" |
|
"func(w, x, y, z)\n\n" |
|
"Expression:\n\n" |
|
"w + x + y + z" |
|
).splitlines() |
|
assert func.__doc__.splitlines()[:len(ref)] == ref |
|
syms = symbols('a1:26') |
|
func = lambdify(syms, sum(syms)) |
|
ref = ( |
|
"Created with lambdify. Signature:\n\n" |
|
"func(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,\n" |
|
" a16, a17, a18, a19, a20, a21, a22, a23, a24, a25)\n\n" |
|
"Expression:\n\n" |
|
"a1 + a10 + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a2 + a20 +..." |
|
).splitlines() |
|
assert func.__doc__.splitlines()[:len(ref)] == ref |
|
|
|
|
|
def test_lambdify_linecache(): |
|
func = lambdify(x, x + 1) |
|
source = 'def _lambdifygenerated(x):\n return x + 1\n' |
|
assert inspect.getsource(func) == source |
|
filename = inspect.getsourcefile(func) |
|
assert filename.startswith('<lambdifygenerated-') |
|
assert filename in linecache.cache |
|
assert linecache.cache[filename] == (len(source), None, source.splitlines(True), filename) |
|
del func |
|
gc.collect() |
|
assert filename not in linecache.cache |
|
|
|
|
|
|
|
|
|
def test_special_printers(): |
|
from sympy.printing.lambdarepr import IntervalPrinter |
|
|
|
def intervalrepr(expr): |
|
return IntervalPrinter().doprint(expr) |
|
|
|
expr = sqrt(sqrt(2) + sqrt(3)) + S.Half |
|
|
|
func0 = lambdify((), expr, modules="mpmath", printer=intervalrepr) |
|
func1 = lambdify((), expr, modules="mpmath", printer=IntervalPrinter) |
|
func2 = lambdify((), expr, modules="mpmath", printer=IntervalPrinter()) |
|
|
|
mpi = type(mpmath.mpi(1, 2)) |
|
|
|
assert isinstance(func0(), mpi) |
|
assert isinstance(func1(), mpi) |
|
assert isinstance(func2(), mpi) |
|
|
|
|
|
exp1 = lambdify(x, loggamma(x), 'mpmath')(5) |
|
exp2 = lambdify(x, loggamma(x), 'mpmath')(1.8) |
|
exp3 = lambdify(x, loggamma(x), 'mpmath')(15) |
|
exp_ls = [exp1, exp2, exp3] |
|
|
|
sol1 = mpmath.loggamma(5) |
|
sol2 = mpmath.loggamma(1.8) |
|
sol3 = mpmath.loggamma(15) |
|
sol_ls = [sol1, sol2, sol3] |
|
|
|
assert exp_ls == sol_ls |
|
|
|
|
|
def test_true_false(): |
|
|
|
assert lambdify([], true)() is True |
|
assert lambdify([], false)() is False |
|
|
|
|
|
def test_issue_2790(): |
|
assert lambdify((x, (y, z)), x + y)(1, (2, 4)) == 3 |
|
assert lambdify((x, (y, (w, z))), w + x + y + z)(1, (2, (3, 4))) == 10 |
|
assert lambdify(x, x + 1, dummify=False)(1) == 2 |
|
|
|
|
|
def test_issue_12092(): |
|
f = implemented_function('f', lambda x: x**2) |
|
assert f(f(2)).evalf() == Float(16) |
|
|
|
|
|
def test_issue_14911(): |
|
class Variable(sympy.Symbol): |
|
def _sympystr(self, printer): |
|
return printer.doprint(self.name) |
|
|
|
_lambdacode = _sympystr |
|
_numpycode = _sympystr |
|
|
|
x = Variable('x') |
|
y = 2 * x |
|
code = LambdaPrinter().doprint(y) |
|
assert code.replace(' ', '') == '2*x' |
|
|
|
|
|
def test_ITE(): |
|
assert lambdify((x, y, z), ITE(x, y, z))(True, 5, 3) == 5 |
|
assert lambdify((x, y, z), ITE(x, y, z))(False, 5, 3) == 3 |
|
|
|
|
|
def test_Min_Max(): |
|
|
|
assert lambdify((x, y, z), Min(x, y, z))(1, 2, 3) == 1 |
|
assert lambdify((x, y, z), Max(x, y, z))(1, 2, 3) == 3 |
|
|
|
|
|
def test_amin_amax_minimum_maximum(): |
|
if not numpy: |
|
skip("numpy not installed") |
|
|
|
a234 = numpy.array([2, 3, 4]) |
|
a152 = numpy.array([1, 5, 2]) |
|
|
|
a254 = numpy.array([2, 5, 4]) |
|
a132 = numpy.array([1, 3, 2]) |
|
|
|
assert numpy.all(lambdify((x, y), maximum(x, y))(a234, a152) == a254) |
|
assert numpy.all(lambdify((x, y), minimum(x, y))(a234, a152) == a132) |
|
|
|
|
|
assert numpy.all(lambdify((x, y, z), maximum(x, y, z))(a234, a152, a234) == a254) |
|
assert numpy.all(lambdify((x, y, z), minimum(x, y, z))(a234, a152, a234) == a132) |
|
|
|
|
|
assert numpy.all(lambdify((x,), maximum(x))(a234) == a234) |
|
assert numpy.all(lambdify((x,), minimum(x))(a234) == a234) |
|
|
|
|
|
assert numpy.all(lambdify((x, y, z, w), maximum(x, y, z, w))(a234, a152, a234, 3) == [3, 5, 4]) |
|
assert numpy.all(lambdify((x, y, z, w), minimum(x, y, z, w))(a234, a152, a234, 2) == [1, 2, 2]) |
|
|
|
|
|
assert lambdify((x, y), [amin(x), amax(y)])(a234, a152) == [2, 5] |
|
A = numpy.array([ |
|
[0, 4, 8], |
|
[1, 5, 9], |
|
[2, 6, 10], |
|
]) |
|
min_, max_ = lambdify((x,), [amin(x, axis=0), amax(x, axis=1)])(A) |
|
assert numpy.all(min_ == numpy.amin(A, axis=0)) |
|
assert numpy.all(max_ == numpy.amax(A, axis=1)) |
|
|
|
|
|
assert numpy.all(lambdify((x, y), Max(x, y))([1, 2, 3], [3, 2, 1]) == [3, 2, 3]) |
|
assert numpy.all(lambdify((x), Min(2, x))([1, 2, 3]) == [1, 2, 2]) |
|
|
|
|
|
|
|
def test_Indexed(): |
|
|
|
if not numpy: |
|
skip("numpy not installed") |
|
|
|
a = IndexedBase('a') |
|
i, j = symbols('i j') |
|
b = numpy.array([[1, 2], [3, 4]]) |
|
assert lambdify(a, Sum(a[x, y], (x, 0, 1), (y, 0, 1)))(b) == 10 |
|
|
|
def test_Sum(): |
|
e = Sum(z, (y, 0, x), (x, 0, 10)) |
|
ref = 66*z |
|
assert e.doit() == ref |
|
assert lambdify([z], e)(7) == ref.subs(z, 7) |
|
|
|
def test_Idx(): |
|
|
|
a = IndexedBase('a') |
|
i = Idx('i') |
|
b = [1,2,3] |
|
assert lambdify([a, i], a[i])(b, 2) == 3 |
|
|
|
|
|
def test_issue_12173(): |
|
|
|
expr1 = lambdify((x, y), uppergamma(x, y),"mpmath")(1, 2) |
|
expr2 = lambdify((x, y), lowergamma(x, y),"mpmath")(1, 2) |
|
assert expr1 == uppergamma(1, 2).evalf() |
|
assert expr2 == lowergamma(1, 2).evalf() |
|
|
|
|
|
def test_issue_13642(): |
|
if not numpy: |
|
skip("numpy not installed") |
|
f = lambdify(x, sinc(x)) |
|
assert Abs(f(1) - sinc(1)).n() < 1e-15 |
|
|
|
|
|
def test_sinc_mpmath(): |
|
f = lambdify(x, sinc(x), "mpmath") |
|
assert Abs(f(1) - sinc(1)).n() < 1e-15 |
|
|
|
|
|
def test_lambdify_dummy_arg(): |
|
d1 = Dummy() |
|
f1 = lambdify(d1, d1 + 1, dummify=False) |
|
assert f1(2) == 3 |
|
f1b = lambdify(d1, d1 + 1) |
|
assert f1b(2) == 3 |
|
d2 = Dummy('x') |
|
f2 = lambdify(d2, d2 + 1) |
|
assert f2(2) == 3 |
|
f3 = lambdify([[d2]], d2 + 1) |
|
assert f3([2]) == 3 |
|
|
|
|
|
def test_lambdify_mixed_symbol_dummy_args(): |
|
d = Dummy() |
|
|
|
dsym = symbols(str(d)) |
|
f = lambdify([d, dsym], d - dsym) |
|
assert f(4, 1) == 3 |
|
|
|
|
|
def test_numpy_array_arg(): |
|
|
|
if not numpy: |
|
skip("numpy not installed") |
|
|
|
f = lambdify([[x, y]], x*x + y, 'numpy') |
|
|
|
assert f(numpy.array([2.0, 1.0])) == 5 |
|
|
|
|
|
def test_scipy_fns(): |
|
if not scipy: |
|
skip("scipy not installed") |
|
|
|
single_arg_sympy_fns = [Ei, erf, erfc, factorial, gamma, loggamma, digamma, Si, Ci] |
|
single_arg_scipy_fns = [scipy.special.expi, scipy.special.erf, scipy.special.erfc, |
|
scipy.special.factorial, scipy.special.gamma, scipy.special.gammaln, |
|
scipy.special.psi, scipy.special.sici, scipy.special.sici] |
|
numpy.random.seed(0) |
|
for (sympy_fn, scipy_fn) in zip(single_arg_sympy_fns, single_arg_scipy_fns): |
|
f = lambdify(x, sympy_fn(x), modules="scipy") |
|
for i in range(20): |
|
tv = numpy.random.uniform(-10, 10) + 1j*numpy.random.uniform(-5, 5) |
|
|
|
|
|
|
|
if sympy_fn == factorial: |
|
tv = numpy.abs(tv) |
|
|
|
|
|
if sympy_fn == loggamma: |
|
tv = numpy.abs(tv) |
|
|
|
|
|
if sympy_fn == digamma: |
|
tv = numpy.real(tv) |
|
sympy_result = sympy_fn(tv).evalf() |
|
scipy_result = scipy_fn(tv) |
|
|
|
|
|
if sympy_fn == Si: |
|
scipy_result = scipy_fn(tv)[0] |
|
if sympy_fn == Ci: |
|
scipy_result = scipy_fn(tv)[1] |
|
assert abs(f(tv) - sympy_result) < 1e-13*(1 + abs(sympy_result)) |
|
assert abs(f(tv) - scipy_result) < 1e-13*(1 + abs(sympy_result)) |
|
|
|
double_arg_sympy_fns = [RisingFactorial, besselj, bessely, besseli, |
|
besselk, polygamma] |
|
double_arg_scipy_fns = [scipy.special.poch, scipy.special.jv, |
|
scipy.special.yv, scipy.special.iv, scipy.special.kv, scipy.special.polygamma] |
|
for (sympy_fn, scipy_fn) in zip(double_arg_sympy_fns, double_arg_scipy_fns): |
|
f = lambdify((x, y), sympy_fn(x, y), modules="scipy") |
|
for i in range(20): |
|
|
|
tv1 = numpy.random.uniform(-10, 10) |
|
tv2 = numpy.random.uniform(-10, 10) + 1j*numpy.random.uniform(-5, 5) |
|
|
|
if sympy_fn in (RisingFactorial, polygamma): |
|
tv2 = numpy.real(tv2) |
|
if sympy_fn == polygamma: |
|
tv1 = abs(int(tv1)) |
|
sympy_result = sympy_fn(tv1, tv2).evalf() |
|
assert abs(f(tv1, tv2) - sympy_result) < 1e-13*(1 + abs(sympy_result)) |
|
assert abs(f(tv1, tv2) - scipy_fn(tv1, tv2)) < 1e-13*(1 + abs(sympy_result)) |
|
|
|
|
|
def test_scipy_polys(): |
|
if not scipy: |
|
skip("scipy not installed") |
|
numpy.random.seed(0) |
|
|
|
params = symbols('n k a b') |
|
|
|
polys = [ |
|
(chebyshevt, 1), |
|
(chebyshevu, 1), |
|
(legendre, 1), |
|
(hermite, 1), |
|
(laguerre, 1), |
|
(gegenbauer, 2), |
|
(assoc_legendre, 2), |
|
(assoc_laguerre, 2), |
|
(jacobi, 3) |
|
] |
|
|
|
msg = \ |
|
"The random test of the function {func} with the arguments " \ |
|
"{args} had failed because the SymPy result {sympy_result} " \ |
|
"and SciPy result {scipy_result} had failed to converge " \ |
|
"within the tolerance {tol} " \ |
|
"(Actual absolute difference : {diff})" |
|
|
|
for sympy_fn, num_params in polys: |
|
args = params[:num_params] + (x,) |
|
f = lambdify(args, sympy_fn(*args)) |
|
for _ in range(10): |
|
tn = numpy.random.randint(3, 10) |
|
tparams = tuple(numpy.random.uniform(0, 5, size=num_params-1)) |
|
tv = numpy.random.uniform(-10, 10) + 1j*numpy.random.uniform(-5, 5) |
|
|
|
if sympy_fn == hermite: |
|
tv = numpy.real(tv) |
|
|
|
if sympy_fn == assoc_legendre: |
|
tv = numpy.random.uniform(-1, 1) |
|
tparams = tuple(numpy.random.randint(1, tn, size=1)) |
|
|
|
vals = (tn,) + tparams + (tv,) |
|
scipy_result = f(*vals) |
|
sympy_result = sympy_fn(*vals).evalf() |
|
atol = 1e-9*(1 + abs(sympy_result)) |
|
diff = abs(scipy_result - sympy_result) |
|
try: |
|
assert diff < atol |
|
except TypeError: |
|
raise AssertionError( |
|
msg.format( |
|
func=repr(sympy_fn), |
|
args=repr(vals), |
|
sympy_result=repr(sympy_result), |
|
scipy_result=repr(scipy_result), |
|
diff=diff, |
|
tol=atol) |
|
) |
|
|
|
|
|
def test_lambdify_inspect(): |
|
f = lambdify(x, x**2) |
|
|
|
|
|
assert 'x**2' in inspect.getsource(f) |
|
|
|
|
|
def test_issue_14941(): |
|
x, y = Dummy(), Dummy() |
|
|
|
|
|
f1 = lambdify([x, y], {x: 3, y: 3}, 'sympy') |
|
assert f1(2, 3) == {2: 3, 3: 3} |
|
|
|
|
|
f2 = lambdify([x, y], (y, x), 'sympy') |
|
assert f2(2, 3) == (3, 2) |
|
f2b = lambdify([], (1,)) |
|
assert f2b() == (1,) |
|
|
|
|
|
f3 = lambdify([x, y], [y, x], 'sympy') |
|
assert f3(2, 3) == [3, 2] |
|
|
|
|
|
def test_lambdify_Derivative_arg_issue_16468(): |
|
f = Function('f')(x) |
|
fx = f.diff() |
|
assert lambdify((f, fx), f + fx)(10, 5) == 15 |
|
assert eval(lambdastr((f, fx), f/fx))(10, 5) == 2 |
|
raises(Exception, lambda: |
|
eval(lambdastr((f, fx), f/fx, dummify=False))) |
|
assert eval(lambdastr((f, fx), f/fx, dummify=True))(10, 5) == 2 |
|
assert eval(lambdastr((fx, f), f/fx, dummify=True))(S(10), 5) == S.Half |
|
assert lambdify(fx, 1 + fx)(41) == 42 |
|
assert eval(lambdastr(fx, 1 + fx, dummify=True))(41) == 42 |
|
|
|
|
|
def test_lambdify_Derivative_zeta(): |
|
|
|
expr1 = zeta(x).diff(x, evaluate=False) |
|
f1 = lambdify(x, expr1, modules=['mpmath']) |
|
ans1 = f1(2) |
|
ref1 = (zeta(2+1e-8).evalf()-zeta(2).evalf())/1e-8 |
|
assert abs(ans1 - ref1)/abs(ref1) < 1e-7 |
|
|
|
expr2 = zeta(x**2).diff(x) |
|
f2 = lambdify(x, expr2, modules=['mpmath']) |
|
ans2 = f2(2**0.5) |
|
ref2 = 2*2**0.5*ref1 |
|
assert abs(ans2-ref2)/abs(ref2) < 1e-7 |
|
|
|
|
|
def test_lambdify_Derivative_custom_printer(): |
|
func1 = Function('func1') |
|
func2 = Function('func2') |
|
|
|
class MyPrinter(NumPyPrinter): |
|
|
|
def _print_Derivative_func1(self, args, seq_orders): |
|
arg, = args |
|
order, = seq_orders |
|
return '42' |
|
|
|
expr1 = func1(x).diff(x) |
|
raises(PrintMethodNotImplementedError, lambda: lambdify([x], expr1)) |
|
f1 = lambdify([x], expr1, printer=MyPrinter) |
|
assert f1(7) == 42 |
|
|
|
expr2 = func2(x).diff(x) |
|
raises(PrintMethodNotImplementedError, lambda: lambdify([x], expr2, printer=MyPrinter)) |
|
|
|
|
|
def test_lambdify_derivative_and_functions_as_arguments(): |
|
|
|
t, a, b = symbols('t, a, b') |
|
f = Function('f')(t) |
|
args = f.diff(t, 2), f.diff(t), f, a, b |
|
expr1 = a*f.diff(t, 2) + b*f.diff(t) + a*b*f + a**2 |
|
num_args = 2.0, 3.0, 4.0, 5.0, 6.0 |
|
ref1 = 5*2 + 6*3 + 5*6*4 + 5**2 |
|
|
|
expr2 = a*f.diff(t, 2) + b*f.diff(t) - a*b*f + b**2 - a**2 |
|
ref2 = 5*2 + 6*3 - 5*6*4 + 6**2 - 5**2 |
|
|
|
for dummify, _cse in product([False, None, True], [False, True]): |
|
func1 = lambdify(args, expr1, cse=_cse, dummify=dummify) |
|
res1 = func1(*num_args) |
|
assert abs(res1 - ref1) < 1e-12 |
|
|
|
func12 = lambdify(args, [expr1, expr2], cse=_cse, dummify=dummify) |
|
res12 = func12(*num_args) |
|
assert len(res12) == 2 |
|
assert abs(res12[0] - ref1) < 1e-12 |
|
assert abs(res12[1] - ref2) < 1e-12 |
|
|
|
|
|
def test_imag_real(): |
|
f_re = lambdify([z], sympy.re(z)) |
|
val = 3+2j |
|
assert f_re(val) == val.real |
|
|
|
f_im = lambdify([z], sympy.im(z)) |
|
assert f_im(val) == val.imag |
|
|
|
|
|
def test_MatrixSymbol_issue_15578(): |
|
if not numpy: |
|
skip("numpy not installed") |
|
A = MatrixSymbol('A', 2, 2) |
|
A0 = numpy.array([[1, 2], [3, 4]]) |
|
f = lambdify(A, A**(-1)) |
|
assert numpy.allclose(f(A0), numpy.array([[-2., 1.], [1.5, -0.5]])) |
|
g = lambdify(A, A**3) |
|
assert numpy.allclose(g(A0), numpy.array([[37, 54], [81, 118]])) |
|
|
|
|
|
def test_issue_15654(): |
|
if not scipy: |
|
skip("scipy not installed") |
|
from sympy.abc import n, l, r, Z |
|
from sympy.physics import hydrogen |
|
nv, lv, rv, Zv = 1, 0, 3, 1 |
|
sympy_value = hydrogen.R_nl(nv, lv, rv, Zv).evalf() |
|
f = lambdify((n, l, r, Z), hydrogen.R_nl(n, l, r, Z)) |
|
scipy_value = f(nv, lv, rv, Zv) |
|
assert abs(sympy_value - scipy_value) < 1e-15 |
|
|
|
|
|
def test_issue_15827(): |
|
if not numpy: |
|
skip("numpy not installed") |
|
A = MatrixSymbol("A", 3, 3) |
|
B = MatrixSymbol("B", 2, 3) |
|
C = MatrixSymbol("C", 3, 4) |
|
D = MatrixSymbol("D", 4, 5) |
|
k=symbols("k") |
|
f = lambdify(A, (2*k)*A) |
|
g = lambdify(A, (2+k)*A) |
|
h = lambdify(A, 2*A) |
|
i = lambdify((B, C, D), 2*B*C*D) |
|
assert numpy.array_equal(f(numpy.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])), \ |
|
numpy.array([[2*k, 4*k, 6*k], [2*k, 4*k, 6*k], [2*k, 4*k, 6*k]], dtype=object)) |
|
|
|
assert numpy.array_equal(g(numpy.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])), \ |
|
numpy.array([[k + 2, 2*k + 4, 3*k + 6], [k + 2, 2*k + 4, 3*k + 6], \ |
|
[k + 2, 2*k + 4, 3*k + 6]], dtype=object)) |
|
|
|
assert numpy.array_equal(h(numpy.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])), \ |
|
numpy.array([[2, 4, 6], [2, 4, 6], [2, 4, 6]])) |
|
|
|
assert numpy.array_equal(i(numpy.array([[1, 2, 3], [1, 2, 3]]), numpy.array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]), \ |
|
numpy.array([[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]])), numpy.array([[ 120, 240, 360, 480, 600], \ |
|
[ 120, 240, 360, 480, 600]])) |
|
|
|
|
|
def test_issue_16930(): |
|
if not scipy: |
|
skip("scipy not installed") |
|
|
|
x = symbols("x") |
|
f = lambda x: S.GoldenRatio * x**2 |
|
f_ = lambdify(x, f(x), modules='scipy') |
|
assert f_(1) == scipy.constants.golden_ratio |
|
|
|
def test_issue_17898(): |
|
if not scipy: |
|
skip("scipy not installed") |
|
x = symbols("x") |
|
f_ = lambdify([x], sympy.LambertW(x,-1), modules='scipy') |
|
assert f_(0.1) == mpmath.lambertw(0.1, -1) |
|
|
|
def test_issue_13167_21411(): |
|
if not numpy: |
|
skip("numpy not installed") |
|
f1 = lambdify(x, sympy.Heaviside(x)) |
|
f2 = lambdify(x, sympy.Heaviside(x, 1)) |
|
res1 = f1([-1, 0, 1]) |
|
res2 = f2([-1, 0, 1]) |
|
assert Abs(res1[0]).n() < 1e-15 |
|
assert Abs(res1[1] - 1/2).n() < 1e-15 |
|
assert Abs(res1[2] - 1).n() < 1e-15 |
|
assert Abs(res2[0]).n() < 1e-15 |
|
assert Abs(res2[1] - 1).n() < 1e-15 |
|
assert Abs(res2[2] - 1).n() < 1e-15 |
|
|
|
def test_single_e(): |
|
f = lambdify(x, E) |
|
assert f(23) == exp(1.0) |
|
|
|
def test_issue_16536(): |
|
if not scipy: |
|
skip("scipy not installed") |
|
|
|
a = symbols('a') |
|
f1 = lowergamma(a, x) |
|
F = lambdify((a, x), f1, modules='scipy') |
|
assert abs(lowergamma(1, 3) - F(1, 3)) <= 1e-10 |
|
|
|
f2 = uppergamma(a, x) |
|
F = lambdify((a, x), f2, modules='scipy') |
|
assert abs(uppergamma(1, 3) - F(1, 3)) <= 1e-10 |
|
|
|
|
|
def test_issue_22726(): |
|
if not numpy: |
|
skip("numpy not installed") |
|
|
|
x1, x2 = symbols('x1 x2') |
|
f = Max(S.Zero, Min(x1, x2)) |
|
g = derive_by_array(f, (x1, x2)) |
|
G = lambdify((x1, x2), g, modules='numpy') |
|
point = {x1: 1, x2: 2} |
|
assert (abs(g.subs(point) - G(*point.values())) <= 1e-10).all() |
|
|
|
|
|
def test_issue_22739(): |
|
if not numpy: |
|
skip("numpy not installed") |
|
|
|
x1, x2 = symbols('x1 x2') |
|
f = Heaviside(Min(x1, x2)) |
|
F = lambdify((x1, x2), f, modules='numpy') |
|
point = {x1: 1, x2: 2} |
|
assert abs(f.subs(point) - F(*point.values())) <= 1e-10 |
|
|
|
|
|
def test_issue_22992(): |
|
if not numpy: |
|
skip("numpy not installed") |
|
|
|
a, t = symbols('a t') |
|
expr = a*(log(cot(t/2)) - cos(t)) |
|
F = lambdify([a, t], expr, 'numpy') |
|
|
|
point = {a: 10, t: 2} |
|
|
|
assert abs(expr.subs(point) - F(*point.values())) <= 1e-10 |
|
|
|
|
|
F = lambdify([a, t], expr) |
|
|
|
assert abs(expr.subs(point) - F(*point.values())) <= 1e-10 |
|
|
|
|
|
def test_issue_19764(): |
|
if not numpy: |
|
skip("numpy not installed") |
|
|
|
expr = Array([x, x**2]) |
|
f = lambdify(x, expr, 'numpy') |
|
|
|
assert f(1).__class__ == numpy.ndarray |
|
|
|
def test_issue_20070(): |
|
if not numba: |
|
skip("numba not installed") |
|
|
|
f = lambdify(x, sin(x), 'numpy') |
|
assert numba.jit(f, nopython=True)(1)==0.8414709848078965 |
|
|
|
|
|
def test_fresnel_integrals_scipy(): |
|
if not scipy: |
|
skip("scipy not installed") |
|
|
|
f1 = fresnelc(x) |
|
f2 = fresnels(x) |
|
F1 = lambdify(x, f1, modules='scipy') |
|
F2 = lambdify(x, f2, modules='scipy') |
|
|
|
assert abs(fresnelc(1.3) - F1(1.3)) <= 1e-10 |
|
assert abs(fresnels(1.3) - F2(1.3)) <= 1e-10 |
|
|
|
|
|
def test_beta_scipy(): |
|
if not scipy: |
|
skip("scipy not installed") |
|
|
|
f = beta(x, y) |
|
F = lambdify((x, y), f, modules='scipy') |
|
|
|
assert abs(beta(1.3, 2.3) - F(1.3, 2.3)) <= 1e-10 |
|
|
|
|
|
def test_beta_math(): |
|
f = beta(x, y) |
|
F = lambdify((x, y), f, modules='math') |
|
|
|
assert abs(beta(1.3, 2.3) - F(1.3, 2.3)) <= 1e-10 |
|
|
|
|
|
def test_betainc_scipy(): |
|
if not scipy: |
|
skip("scipy not installed") |
|
|
|
f = betainc(w, x, y, z) |
|
F = lambdify((w, x, y, z), f, modules='scipy') |
|
|
|
assert abs(betainc(1.4, 3.1, 0.1, 0.5) - F(1.4, 3.1, 0.1, 0.5)) <= 1e-10 |
|
|
|
|
|
def test_betainc_regularized_scipy(): |
|
if not scipy: |
|
skip("scipy not installed") |
|
|
|
f = betainc_regularized(w, x, y, z) |
|
F = lambdify((w, x, y, z), f, modules='scipy') |
|
|
|
assert abs(betainc_regularized(0.2, 3.5, 0.1, 1) - F(0.2, 3.5, 0.1, 1)) <= 1e-10 |
|
|
|
|
|
def test_numpy_special_math(): |
|
if not numpy: |
|
skip("numpy not installed") |
|
|
|
funcs = [expm1, log1p, exp2, log2, log10, hypot, logaddexp, logaddexp2] |
|
for func in funcs: |
|
if 2 in func.nargs: |
|
expr = func(x, y) |
|
args = (x, y) |
|
num_args = (0.3, 0.4) |
|
elif 1 in func.nargs: |
|
expr = func(x) |
|
args = (x,) |
|
num_args = (0.3,) |
|
else: |
|
raise NotImplementedError("Need to handle other than unary & binary functions in test") |
|
f = lambdify(args, expr) |
|
result = f(*num_args) |
|
reference = expr.subs(dict(zip(args, num_args))).evalf() |
|
assert numpy.allclose(result, float(reference)) |
|
|
|
lae2 = lambdify((x, y), logaddexp2(log2(x), log2(y))) |
|
assert abs(2.0**lae2(1e-50, 2.5e-50) - 3.5e-50) < 1e-62 |
|
|
|
|
|
def test_scipy_special_math(): |
|
if not scipy: |
|
skip("scipy not installed") |
|
|
|
cm1 = lambdify((x,), cosm1(x), modules='scipy') |
|
assert abs(cm1(1e-20) + 5e-41) < 1e-200 |
|
|
|
have_scipy_1_10plus = tuple(map(int, scipy.version.version.split('.')[:2])) >= (1, 10) |
|
|
|
if have_scipy_1_10plus: |
|
cm2 = lambdify((x, y), powm1(x, y), modules='scipy') |
|
assert abs(cm2(1.2, 1e-9) - 1.82321557e-10) < 1e-17 |
|
|
|
|
|
def test_scipy_bernoulli(): |
|
if not scipy: |
|
skip("scipy not installed") |
|
|
|
bern = lambdify((x,), bernoulli(x), modules='scipy') |
|
assert bern(1) == 0.5 |
|
|
|
|
|
def test_scipy_harmonic(): |
|
if not scipy: |
|
skip("scipy not installed") |
|
|
|
hn = lambdify((x,), harmonic(x), modules='scipy') |
|
assert hn(2) == 1.5 |
|
hnm = lambdify((x, y), harmonic(x, y), modules='scipy') |
|
assert hnm(2, 2) == 1.25 |
|
|
|
|
|
def test_cupy_array_arg(): |
|
if not cupy: |
|
skip("CuPy not installed") |
|
|
|
f = lambdify([[x, y]], x*x + y, 'cupy') |
|
result = f(cupy.array([2.0, 1.0])) |
|
assert result == 5 |
|
assert "cupy" in str(type(result)) |
|
|
|
|
|
def test_cupy_array_arg_using_numpy(): |
|
|
|
|
|
|
|
if not cupy: |
|
skip("CuPy not installed") |
|
|
|
f = lambdify([[x, y]], x*x + y, 'numpy') |
|
result = f(cupy.array([2.0, 1.0])) |
|
assert result == 5 |
|
assert "cupy" in str(type(result)) |
|
|
|
def test_cupy_dotproduct(): |
|
if not cupy: |
|
skip("CuPy not installed") |
|
|
|
A = Matrix([x, y, z]) |
|
f1 = lambdify([x, y, z], DotProduct(A, A), modules='cupy') |
|
f2 = lambdify([x, y, z], DotProduct(A, A.T), modules='cupy') |
|
f3 = lambdify([x, y, z], DotProduct(A.T, A), modules='cupy') |
|
f4 = lambdify([x, y, z], DotProduct(A, A.T), modules='cupy') |
|
|
|
assert f1(1, 2, 3) == \ |
|
f2(1, 2, 3) == \ |
|
f3(1, 2, 3) == \ |
|
f4(1, 2, 3) == \ |
|
cupy.array([14]) |
|
|
|
|
|
def test_jax_array_arg(): |
|
if not jax: |
|
skip("JAX not installed") |
|
|
|
f = lambdify([[x, y]], x*x + y, 'jax') |
|
result = f(jax.numpy.array([2.0, 1.0])) |
|
assert result == 5 |
|
assert "jax" in str(type(result)) |
|
|
|
|
|
def test_jax_array_arg_using_numpy(): |
|
if not jax: |
|
skip("JAX not installed") |
|
|
|
f = lambdify([[x, y]], x*x + y, 'numpy') |
|
result = f(jax.numpy.array([2.0, 1.0])) |
|
assert result == 5 |
|
assert "jax" in str(type(result)) |
|
|
|
|
|
def test_jax_dotproduct(): |
|
if not jax: |
|
skip("JAX not installed") |
|
|
|
A = Matrix([x, y, z]) |
|
f1 = lambdify([x, y, z], DotProduct(A, A), modules='jax') |
|
f2 = lambdify([x, y, z], DotProduct(A, A.T), modules='jax') |
|
f3 = lambdify([x, y, z], DotProduct(A.T, A), modules='jax') |
|
f4 = lambdify([x, y, z], DotProduct(A, A.T), modules='jax') |
|
|
|
assert f1(1, 2, 3) == \ |
|
f2(1, 2, 3) == \ |
|
f3(1, 2, 3) == \ |
|
f4(1, 2, 3) == \ |
|
jax.numpy.array([14]) |
|
|
|
|
|
def test_lambdify_cse(): |
|
def no_op_cse(exprs): |
|
return (), exprs |
|
|
|
def dummy_cse(exprs): |
|
from sympy.simplify.cse_main import cse |
|
return cse(exprs, symbols=numbered_symbols(cls=Dummy)) |
|
|
|
def minmem(exprs): |
|
from sympy.simplify.cse_main import cse_release_variables, cse |
|
return cse(exprs, postprocess=cse_release_variables) |
|
|
|
class Case: |
|
def __init__(self, *, args, exprs, num_args, requires_numpy=False): |
|
self.args = args |
|
self.exprs = exprs |
|
self.num_args = num_args |
|
subs_dict = dict(zip(self.args, self.num_args)) |
|
self.ref = [e.subs(subs_dict).evalf() for e in exprs] |
|
self.requires_numpy = requires_numpy |
|
|
|
def lambdify(self, *, cse): |
|
return lambdify(self.args, self.exprs, cse=cse) |
|
|
|
def assertAllClose(self, result, *, abstol=1e-15, reltol=1e-15): |
|
if self.requires_numpy: |
|
assert all(numpy.allclose(result[i], numpy.asarray(r, dtype=float), |
|
rtol=reltol, atol=abstol) |
|
for i, r in enumerate(self.ref)) |
|
return |
|
|
|
for i, r in enumerate(self.ref): |
|
abs_err = abs(result[i] - r) |
|
if r == 0: |
|
assert abs_err < abstol |
|
else: |
|
assert abs_err/abs(r) < reltol |
|
|
|
cases = [ |
|
Case( |
|
args=(x, y, z), |
|
exprs=[ |
|
x + y + z, |
|
x + y - z, |
|
2*x + 2*y - z, |
|
(x+y)**2 + (y+z)**2, |
|
], |
|
num_args=(2., 3., 4.) |
|
), |
|
Case( |
|
args=(x, y, z), |
|
exprs=[ |
|
x + sympy.Heaviside(x), |
|
y + sympy.Heaviside(x), |
|
z + sympy.Heaviside(x, 1), |
|
z/sympy.Heaviside(x, 1) |
|
], |
|
num_args=(0., 3., 4.) |
|
), |
|
Case( |
|
args=(x, y, z), |
|
exprs=[ |
|
x + sinc(y), |
|
y + sinc(y), |
|
z - sinc(y) |
|
], |
|
num_args=(0.1, 0.2, 0.3) |
|
), |
|
Case( |
|
args=(x, y, z), |
|
exprs=[ |
|
Matrix([[x, x*y], [sin(z) + 4, x**z]]), |
|
x*y+sin(z)-x**z, |
|
Matrix([x*x, sin(z), x**z]) |
|
], |
|
num_args=(1.,2.,3.), |
|
requires_numpy=True |
|
), |
|
Case( |
|
args=(x, y), |
|
exprs=[(x + y - 1)**2, x, x + y, |
|
(x + y)/(2*x + 1) + (x + y - 1)**2, (2*x + 1)**(x + y)], |
|
num_args=(1,2) |
|
) |
|
] |
|
for case in cases: |
|
if not numpy and case.requires_numpy: |
|
continue |
|
for _cse in [False, True, minmem, no_op_cse, dummy_cse]: |
|
f = case.lambdify(cse=_cse) |
|
result = f(*case.num_args) |
|
case.assertAllClose(result) |
|
|
|
def test_issue_25288(): |
|
syms = numbered_symbols(cls=Dummy) |
|
ok = lambdify(x, [x**2, sin(x**2)], cse=lambda e: cse(e, symbols=syms))(2) |
|
assert ok |
|
|
|
|
|
def test_deprecated_set(): |
|
with warns_deprecated_sympy(): |
|
lambdify({x, y}, x + y) |
|
|
|
def test_issue_13881(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
|
|
X = MatrixSymbol('X', 3, 1) |
|
|
|
f = lambdify(X, X.T*X, 'numpy') |
|
assert f(numpy.array([1, 2, 3])) == 14 |
|
assert f(numpy.array([3, 2, 1])) == 14 |
|
|
|
f = lambdify(X, X*X.T, 'numpy') |
|
assert f(numpy.array([1, 2, 3])) == 14 |
|
assert f(numpy.array([3, 2, 1])) == 14 |
|
|
|
f = lambdify(X, (X*X.T)*X, 'numpy') |
|
arr1 = numpy.array([[1], [2], [3]]) |
|
arr2 = numpy.array([[14],[28],[42]]) |
|
|
|
assert numpy.array_equal(f(arr1), arr2) |
|
|
|
|
|
def test_23536_lambdify_cse_dummy(): |
|
|
|
f = Function('x')(y) |
|
g = Function('w')(y) |
|
expr = z + (f**4 + g**5)*(f**3 + (g*f)**3) |
|
expr = expr.expand() |
|
eval_expr = lambdify(((f, g), z), expr, cse=True) |
|
ans = eval_expr((1.0, 2.0), 3.0) |
|
assert ans == 300.0 |
|
|
|
|
|
class LambdifyDocstringTestCase: |
|
SIGNATURE = None |
|
EXPR = None |
|
SRC = None |
|
|
|
def __init__(self, docstring_limit, expected_redacted): |
|
self.docstring_limit = docstring_limit |
|
self.expected_redacted = expected_redacted |
|
|
|
@property |
|
def expected_expr(self): |
|
expr_redacted_msg = "EXPRESSION REDACTED DUE TO LENGTH, (see lambdify's `docstring_limit`)" |
|
return self.EXPR if not self.expected_redacted else expr_redacted_msg |
|
|
|
@property |
|
def expected_src(self): |
|
src_redacted_msg = "SOURCE CODE REDACTED DUE TO LENGTH, (see lambdify's `docstring_limit`)" |
|
return self.SRC if not self.expected_redacted else src_redacted_msg |
|
|
|
@property |
|
def expected_docstring(self): |
|
expected_docstring = ( |
|
f'Created with lambdify. Signature:\n\n' |
|
f'func({self.SIGNATURE})\n\n' |
|
f'Expression:\n\n' |
|
f'{self.expected_expr}\n\n' |
|
f'Source code:\n\n' |
|
f'{self.expected_src}\n\n' |
|
f'Imported modules:\n\n' |
|
) |
|
return expected_docstring |
|
|
|
def __len__(self): |
|
return len(self.expected_docstring) |
|
|
|
def __repr__(self): |
|
return ( |
|
f'{self.__class__.__name__}(' |
|
f'docstring_limit={self.docstring_limit}, ' |
|
f'expected_redacted={self.expected_redacted})' |
|
) |
|
|
|
|
|
def test_lambdify_docstring_size_limit_simple_symbol(): |
|
|
|
class SimpleSymbolTestCase(LambdifyDocstringTestCase): |
|
SIGNATURE = 'x' |
|
EXPR = 'x' |
|
SRC = ( |
|
'def _lambdifygenerated(x):\n' |
|
' return x\n' |
|
) |
|
|
|
x = symbols('x') |
|
|
|
test_cases = ( |
|
SimpleSymbolTestCase(docstring_limit=None, expected_redacted=False), |
|
SimpleSymbolTestCase(docstring_limit=100, expected_redacted=False), |
|
SimpleSymbolTestCase(docstring_limit=1, expected_redacted=False), |
|
SimpleSymbolTestCase(docstring_limit=0, expected_redacted=True), |
|
SimpleSymbolTestCase(docstring_limit=-1, expected_redacted=True), |
|
) |
|
for test_case in test_cases: |
|
lambdified_expr = lambdify( |
|
[x], |
|
x, |
|
'sympy', |
|
docstring_limit=test_case.docstring_limit, |
|
) |
|
assert lambdified_expr.__doc__ == test_case.expected_docstring |
|
|
|
|
|
def test_lambdify_docstring_size_limit_nested_expr(): |
|
|
|
class ExprListTestCase(LambdifyDocstringTestCase): |
|
SIGNATURE = 'x, y, z' |
|
EXPR = ( |
|
'[x, [y], z, x**3 + 3*x**2*y + 3*x**2*z + 3*x*y**2 + 6*x*y*z ' |
|
'+ 3*x*z**2 +...' |
|
) |
|
SRC = ( |
|
'def _lambdifygenerated(x, y, z):\n' |
|
' return [x, [y], z, x**3 + 3*x**2*y + 3*x**2*z + 3*x*y**2 ' |
|
'+ 6*x*y*z + 3*x*z**2 + y**3 + 3*y**2*z + 3*y*z**2 + z**3]\n' |
|
) |
|
|
|
x, y, z = symbols('x, y, z') |
|
expr = [x, [y], z, ((x + y + z)**3).expand()] |
|
|
|
test_cases = ( |
|
ExprListTestCase(docstring_limit=None, expected_redacted=False), |
|
ExprListTestCase(docstring_limit=200, expected_redacted=False), |
|
ExprListTestCase(docstring_limit=50, expected_redacted=True), |
|
ExprListTestCase(docstring_limit=0, expected_redacted=True), |
|
ExprListTestCase(docstring_limit=-1, expected_redacted=True), |
|
) |
|
for test_case in test_cases: |
|
lambdified_expr = lambdify( |
|
[x, y, z], |
|
expr, |
|
'sympy', |
|
docstring_limit=test_case.docstring_limit, |
|
) |
|
assert lambdified_expr.__doc__ == test_case.expected_docstring |
|
|
|
|
|
def test_lambdify_docstring_size_limit_matrix(): |
|
|
|
class MatrixTestCase(LambdifyDocstringTestCase): |
|
SIGNATURE = 'x, y, z' |
|
EXPR = ( |
|
'Matrix([[0, x], [x + y + z, x**3 + 3*x**2*y + 3*x**2*z + 3*x*y**2 ' |
|
'+ 6*x*y*z...' |
|
) |
|
SRC = ( |
|
'def _lambdifygenerated(x, y, z):\n' |
|
' return ImmutableDenseMatrix([[0, x], [x + y + z, x**3 ' |
|
'+ 3*x**2*y + 3*x**2*z + 3*x*y**2 + 6*x*y*z + 3*x*z**2 + y**3 ' |
|
'+ 3*y**2*z + 3*y*z**2 + z**3]])\n' |
|
) |
|
|
|
x, y, z = symbols('x, y, z') |
|
expr = Matrix([[S.Zero, x], [x + y + z, ((x + y + z)**3).expand()]]) |
|
|
|
test_cases = ( |
|
MatrixTestCase(docstring_limit=None, expected_redacted=False), |
|
MatrixTestCase(docstring_limit=200, expected_redacted=False), |
|
MatrixTestCase(docstring_limit=50, expected_redacted=True), |
|
MatrixTestCase(docstring_limit=0, expected_redacted=True), |
|
MatrixTestCase(docstring_limit=-1, expected_redacted=True), |
|
) |
|
for test_case in test_cases: |
|
lambdified_expr = lambdify( |
|
[x, y, z], |
|
expr, |
|
'sympy', |
|
docstring_limit=test_case.docstring_limit, |
|
) |
|
assert lambdified_expr.__doc__ == test_case.expected_docstring |
|
|
|
|
|
def test_lambdify_empty_tuple(): |
|
a = symbols("a") |
|
expr = ((), (a,)) |
|
f = lambdify(a, expr) |
|
result = f(1) |
|
assert result == ((), (1,)), "Lambdify did not handle the empty tuple correctly." |
|
|
|
|
|
def test_assoc_legendre_numerical_evaluation(): |
|
|
|
tol = 1e-10 |
|
|
|
sympy_result_integer = assoc_legendre(1, 1/2, 0.1).evalf() |
|
sympy_result_complex = assoc_legendre(2, 1, 3).evalf() |
|
mpmath_result_integer = -0.474572528387641 |
|
mpmath_result_complex = -25.45584412271571*I |
|
|
|
assert all_close(sympy_result_integer, mpmath_result_integer, tol) |
|
assert all_close(sympy_result_complex, mpmath_result_complex, tol) |
|
|
|
|
|
def test_Piecewise(): |
|
|
|
modules = [math] |
|
if numpy: |
|
modules.append('numpy') |
|
|
|
for mod in modules: |
|
|
|
f = lambdify(x, Piecewise((7.0, isinf(x)), (3.0, True)), mod) |
|
assert f(+float('inf')) == +7.0 |
|
assert f(-float('inf')) == +7.0 |
|
assert f(42.) == 3.0 |
|
|
|
f2 = lambdify(x, Piecewise((7.0*sign(x), isinf(x)), (3.0, True)), mod) |
|
assert f2(+float('inf')) == +7.0 |
|
assert f2(-float('inf')) == -7.0 |
|
assert f2(42.) == 3.0 |
|
|
|
|
|
g = lambdify(x, Piecewise((7.0, isnan(x)), (3.0, True)), mod) |
|
assert g(float('nan')) == 7.0 |
|
assert g(42.) == 3.0 |
|
|
|
|
|
def test_array_symbol(): |
|
if not numpy: |
|
skip("numpy not installed.") |
|
a = ArraySymbol('a', (3,)) |
|
f = lambdify((a), a) |
|
assert numpy.all(f(numpy.array([1,2,3])) == numpy.array([1,2,3])) |
|
|