Reputation: 6144
I have seen and attempted to implement the following answer to a similar question to no avail: https://stackoverflow.com/a/23687379/3696204
I have also reviewed the documentation for SymPy evalf, about halfway down on this article: http://docs.sympy.org/latest/tutorial/basic_operations.html
My code:
from sympy import sympify
def test_function(a, b, c, d, funct):
f = sympify(funct)
dx = 0.2
J = int(2/dx)
for i in range(J-1):
x = -1 + (i * dx)
print("f(", x, ") = ", f.evalf(x))
print("Just for fun: ", a, b, c, d)
return c + d
if __name__ == '__main__':
print(test_function(1, 2, 3, 4, funct="pow(x, 4) - 2 * pow(x, 2) + 2"))
print(test_function(1, 2, 3, 4, funct="x**4 - 2 * x**2 + 2"))
Results in:
f( -1.0 ) = -0.e+0*pow(x, 2) + pow(x, 4) + 0.e+0 f( -0.8 ) = -0.e+0*pow(x, 2) + pow(x, 4) + 0.e+0 f( -0.6 ) = -0.e+0*pow(x, 2) + pow(x, 4) + 0.e+0 f( -0.3999999999999999 ) = -0.e+0*pow(x, 2) + pow(x, 4) + 0.e+0 f( -0.19999999999999996 ) = -0.e+0*pow(x, 2) + pow(x, 4) + 0.e+0 f( 0.0 ) = -0.e+0*pow(x, 2) + pow(x, 4) + 0.e+0 f( 0.20000000000000018 ) = -0.e+0*pow(x, 2) + pow(x, 4) + 0.e+0 f( 0.40000000000000013 ) = -0.e+0*pow(x, 2) + pow(x, 4) + 0.e+0 f( 0.6000000000000001 ) = -0.e+0*pow(x, 2) + pow(x, 4) + 0.e+0 Just for fun: 1 2 3 4 7
f( -1.0 ) = x**4 - 0.e+0*x**2 + 0.e+0 f( -0.8 ) = x**4 - 0.e+0*x**2 + 0.e+0 f( -0.6 ) = x**4 - 0.e+0*x**2 + 0.e+0 f( -0.3999999999999999 ) = x**4 - 0.e+0*x**2 + 0.e+0 f( -0.19999999999999996 ) = x**4 - 0.e+0*x**2 + 0.e+0 f( 0.0 ) = x**4 - 0.e+0*x**2 + 0.e+0 f( 0.20000000000000018 ) = x**4 - 0.e+0*x**2 + 0.e+0 f( 0.40000000000000013 ) = x**4 - 0.e+0*x**2 + 0.e+0 f( 0.6000000000000001 ) = x**4 - 0.e+0*x**2 + 0.e+0 Just for fun: 1 2 3 4 7
Based on reading the documentation, have also tried f.evalf(subs=x)
, f.evalf(subs={x: x_i})
where I redefined my loop in terms of x_i. In the first case I get a complaint about "floats not being subscriptable", and in the second case I get a complaint saying that "x is not defined".
Ok, that's all of my efforts so far. If anybody is curious, I have programmed the Thomas Algorithm for solving tri-diagonal matrices and am now create a method that applies Thomas to solve a PDE with the initial conditions given by some some equation. I want to pass that equation to my algorithm so that initial conditions can be provided on the fly.
Upvotes: 0
Views: 1073
Reputation: 1352
After sympify
ing, f
is an expression. We can turn f
into a sympy function using lambdify
:
>>> x = Symbol('x')
>>> f = lambdify(x, sympify("pow(x, 4) - 2 * pow(x, 2) + 2"))
>>> [f(0.2 * i) for i in range(5)]
[2.0, 1.9216, 1.7056, 1.4096, 1.1296]
Upvotes: 1
Reputation:
When sympify
is executed on an string, the substring "x" gets interpreted as a symbol, namely Symbol("x")
. This object has nothing to do with any Python variables you may call x. Symbol names and variable names are different things.
To replace Symbol("x") by the Python variable called x
, you need
f.subs(Symbol('x'), x)
This subs
is enough, floating-point evaluation happens automatically since you supplied a floating-point argument. Otherwise, evalf
could be forced with
f.evalf(subs={Symbol('x'): x})
By the way, f.evalf(x)
means: evaluate f returning x decimal digits; nothing to do with substitution.
Function names: x**4
and Pow(x, 4)
both work, but pow(x, 4)
has no meaning for SymPy.
To see the difference between variable names and symbol names, try
b = Symbol("a")
print(b) # prints "a"
print(a) # undefined
Upvotes: 1