lambdified sympy expression returns incorrect result

Marek

I encountered following problem, first I will explain briefly what is going on:

f(x)
g(x, y) = f(x) - y

From there we expect

g(x, f(x)) = f(x) - f(x) = 0

lambdified g(x,y) returns something very close to zero instead of zero. Here's a code that reproduces the problem. It arrives only when I put sufficient amount of log evaluations in f(x)

gist: https://gist.github.com/marekyggdrasil/39a24213ebaba6293464d116821cc334

source:

from sympy import Symbol, pprint, log, lambdify

# setting symbols
g1 = Symbol("gamma1")
g2 = Symbol("gamma2")
g3 = Symbol("gamma3")
g4 = Symbol("gamma4")
rt = Symbol("rt")

# setting expressions
criteria  = (g1 * log(g1, 2.0))/2.0
criteria += (g2 * log(g2, 2.0))/2.0
criteria += (g3 * log(g3, 2.0))/2.0
criteria += (g4 * log(g4, 2.0))/2.0
rooteq = criteria - rt

print "\ncriteria function: "
pprint(criteria)

print "\ncriteria function - rt: "
pprint(rooteq)

# lambdifying expressions to callable functions
tsymbols = [g1, g2, g3, g4, rt]
lambfun_criteria = lambdify(tsymbols, criteria)
lambfun_rooteq = lambdify(tsymbols, rooteq)

# example point x
x = [0.25006462253641376, 2.2501938662000542, 2.2501938662000542, 2.2501938662000542, 0.0]

# evaluating of criteria on x
rootval = lambfun_criteria(*x)

# setting rt to this evaluation
x[4] = rootval

print "\nactual evaluation of rooteq: " + str(lambfun_rooteq(*x))
print "\nexpected evaluation of rooteq: " + str(- x[4] + lambfun_criteria(*x))

output

$ python lambdifytest.py 

criteria function: 
0.721347520444482⋅γ₁⋅log(γ₁) + 0.721347520444482⋅γ₂⋅log(γ₂) + 0.721347520444482⋅γ₃⋅log(γ₃) + 0.721347520444482⋅γ₄⋅log(γ₄)

criteria function - rt: 
0.721347520444482⋅γ₁⋅log(γ₁) + 0.721347520444482⋅γ₂⋅log(γ₂) + 0.721347520444482⋅γ₃⋅log(γ₃) + 0.721347520444482⋅γ₄⋅log(γ₄) - rt

actual evaluation of rooteq: 4.4408920985e-16

expected evaluation of rooteq: 0.0
Marek

I found that a custom math module can be specified when SymPy expression is lambdified. In my case mpmath helped.

Import mpmath and set the precision to something you find sufficient

from mpmath import mp
mp.dps = 15

Tell SymPy you want your lambda function to use mpmath for handling floating point arithmetic

lambfun_criteria = lambdify(tsymbols, criteria, "mpmath")
lambfun_rooteq = lambdify(tsymbols, rooteq, "mpmath")

Then finally I get the output

actual evaluation of rooteq: 0.0
expected evaluation of rooteq: 0.0

The cause of the issue was the following, the default floating point arithmetic used in created lambda function was not same as one used in the script that compares the results.

I updated the gist with full solution file if someone needs copy-paste

https://gist.github.com/marekyggdrasil/39a24213ebaba6293464d116821cc334#file-lambdify_test_solution-py

Edit: forgot to give docs reference

http://docs.sympy.org/dev/modules/utilities/lambdify.html

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to serialize sympy lambdified function?

sympy dsolve returns incorrect answer

MySQL MAX returns incorrect result

File.isFile() returns incorrect result?

Gremlin using select in hasId returns incorrect result

getting an array from webservice returns an incorrect result

removing rows without returns incorrect result

Kadane algorithm implementation returns incorrect result

PL/pgSQL function returns incorrect bitwise result

Azure pipeline powershell script returns incorrect result

TimeZoneInfo.ConvertTimeFromUtc returns incorrect result

MarkLogic Query By Example returns incorrect result

Array formula with SUM Function returns incorrect result

Google Maps Autocomplete Place returns incorrect result

in MySQL, MAX() command returns an incorrect result

In-line R expression returns incorrect value

evalf in sympy returns expression instead of value in single variable expression

SymPy outputs a numerical result when a symbolic expression is expected

wcslen() returns incorrect result when pragma pack used

Count of multiple items in one MySQL query returns an incorrect result

Fetch DPI from JPEG without library returns incorrect result

numpy.square returns incorrect result for sparse matrices

GROUP BY on column alias with NULLs returns incorrect result in MySQL

Eloquent ORM 5.1 query returns incorrect result (compared to plain SQL)

IoT Hub device twin query returns incorrect result on lastActivityTime property

JavaScript requesting JSON info. returns incorrect result

Checking is array contains some elements of another returns incorrect result

SUM operation on SET data type returns incorrect result

C++ Template Parameter sizeof Returns Incorrect Result