Reputation: 43
I am baffled at why the answer to the following code is 10 and not 1. Can someone help me understand what is going on with lambdify
or what is creating the wrong answer?
import sympy
from sympy.utilities.lambdify import lambdify
from sympy import Function
from sympy.abc import x, y
def kFct(xIndex,loc,k1,k2):
... if xIndex <= loc:
... return k1
... else:
... return k2
...
loc = 0.5
k1 = 1
k2 = 10
kfun = lambdify( (x,y), kFct(x,loc,k1,k2) )
print kfun(0,0)
>>> 10
Why isn't the answer k1
or 1, since x = 0
, which is less than loc = 0.5
?
However, it return the correct answer if I do
print kfct(0,loc,k1,k2)
>>> 1
I need to have kfun
as a function of x and y, because later on, I use it as part of an argument for an integral. It will also eventually depend on y.
I'm using python 2.6.8 on a Mac 10.6.x.
Upvotes: 2
Views: 636
Reputation: 91620
You want to use Piecewise
, which represents if branches in a symbolic way that SymPy can work with.
Here's your example with the values of loc
, k1
, and k2
put in explicitly. You can of course use them symbolically and replace them later with subs
if your code dictates that.
>>> kFct = Piecewise((1, x < 0.5), (10, True))
>>> kfun = lambdify(x, kFct)
>>> kfun(0)
1
>>> kfun(1)
10
Upvotes: 2
Reputation: 353419
The arguments to lambdify
are evaluated before they're passed, and so you're not actually passing your function to lambdify
, you're passing the number 10:
>>> kFct(x, loc, k1, k2)
10
You get 10 here because
>>> x <= loc
x <= 0.5
>>> bool(x <= loc)
False
and so the second branch is taken. Because of the way Python works, I don't think you'll be able to get this to work -- you can't suppress only one branch being taken. (In principle, a program could do some crazy bytecode introspection, but I'm pretty sure sympy
doesn't.)
You could use implemented_function
, though:
>>> f = implemented_function(Function('kFct'), lambda x,y: kFct(x, loc, k1, k2))
>>> kfun = lambdify((x,y), f(x,y))
>>> kfun(0,0)
1
>>> kfun(0.5,0)
1
>>> kfun(0.51,0)
10
>>> kfun(1, 0.0)
10
I'm not sure how much this really benefits you, though, given the extra indirection: I'd probably just work with the function itself (assuming you're ultimately looking for a numerical evaluation of the integral.)
Upvotes: 3