myList = ['100', 'sin(x)', '0', '1']
I read these strings from a text file. I now want to execute the function call sin(x) from that string -- I want this to be a general interpretation of the string for any function expression.
I have tried the following with no success.
myList[1].replace("'", "")
I guess what I am asking is how to pull a string from a list and use it's 'raw text' so to speak.
The end goal is to get this function, where myList[1] should turn to sin(x)
from math import sin
def f(x):
return myList[1]
Thus f(x) will give the computed value of sin(x) from this list.
use dict and you archive it
from math import sin
myList = ['100', 'sin(x)', '0', '1']
options = { 'sin(x)':sin }
options[myList[1]](1)
0.8414709848078965
You're confusing a string value with executable code. Two basic points:
You can do this with the eval function, which evaluates a string as Python code.
Don't. Really; eval is a loaded gun pointed at your foot, and usually indicates a poor system design.
What is it that you're trying to do overall? If you want to trigger the trig functions with text input, you're better heeled to do it with enumerated checks, such as:
choice = myList[1]
if choice == "sin":
return sin(x)
elif choice == "cos":
return cos(x)
...
The safest way I can see to do this is to store the expected functions in a dictionary like this:
math_dict = {'sin(x)':sin, 'cos(x)':cos}
then you can call sin from the list like this:
def f(x):
return math_dict[myList[1]](x)
I just added cos(x) to show you can do this with any arbitrary function. You could then do something like this to generalize it:
def f(x):
return math_dict[x] if x in math_dict else None
Sin function is part of math library, you can get it like:
import math
getattr(math, 'sin')
That is same for all non-builtin libraries. Just split the string to get function name:
function_name = myList[1].split('(')[0]
function = getattr(math, function_name)
function(value for x)
For builtin functions like round:
getattr(globals()['__builtins__'], 'round')
With sympy.sympify and highlighting the warning
Warning : sympify uses eval. Don’t use it on unsanitized input.
you can solve this as
myList = ['100', 'sin(x)', '0', '1']
from sympy.abc import x
from sympy import sympify
N, expr, a,b = myList
# convert strings to objects
N=int(N); a=float(a); b=float(b);
expr = sympify(expr)
# define user function
def f(xval): return expr.subs(x,xval)
or for multi-point evaluation replace the last line with
from sympy import lambdify
f = lambdify(x, expr, "numpy")
# integrate as left Riemann sum (order 1)
from numpy import linspace
xlist = linspace(a,b,N)
integral = sum(f(xlist))*(b-a)/N
Related
A protected division is a normal division but when you divide by 0 it returns a fixed constant (usually 1).
def protected_div(x, y):
if y == 0:
return 1
return x/y
Is there a way to use this as an operator on sympy (For example replacing the standard division)?
Here is an example of what I want:
>>> import sympy as sym
>>> x = sym.Symbol('x')
>>> expr = 1/x #(protected division goes here?)
>>> expr.subs(x, 0)
1
The division has to be protected at evaluation time.
EDIT 1:
What I've tried:
1.
Using sym.lambidify with the modules parameter set:
>>> x = sym.Symbol('x')
>>> expr = 1/x
>>> lamb = sym.lambdify(x, expr, modules={'/':protected_div})
>>> print(lamb(0))
ZeroDivisionError: 0.0 cannot be raised to a negative power
This does not work because sympy converts 1/x to x**(-1) when lambidifying. I tried overriding the power operator but I don't know the function name. I've tried 'Pow', 'pow', '**' and none worked.
However if i declare the expression as expr = 1.0/x it actually does not convert to a negative power, however it does not use my custom division function. I think these types of functions are not overridable using the module parameter.
2.
#Zaz suggestion:
class floatsafe(float):
def __truediv__(self, __x):
if __x == 0:
return floatsafe(1)
return super().__truediv__(__x)
x = sym.Symbol('x')
expr = floatsafe(1)/x
print(expr.subs(x, floatsafe(0)))
Returns
zoo
Which is complex infinity.
I tried combining this approach with sym.lambdify, but the dividend is converted to a float after I lambdify the function.
In the case that the dividend is variable it also does not work:
x = sym.Symbol('x')
expr = x/0.0
a = sym.lambdify(x, expr, modules={'/':floatsafe.__truediv__})
print(inspect.getsource(a))
print(a(floatsafe(0)))
Outputs
def _lambdifygenerated(x):
return nan*x
nan
EDIT: There seems to some confusion around why I'd want that. It's for a genetic programming algorithm using sympy. A protected division is a common operator in GP so that the created solutions are valid.
The regular mathematics we use on the day-to-day is a ring on the set of real numbers, ℝ: The properties of a ring are that you have two operations (such as multiplication and addition) and one of them (such as addition) will always produce another number within the set.
You can create a more specific notion of a field (such that both operations will always produce another member in the set) by removing 0 or expanding the set to the hyperreals.
My point being, without knowing what problem exactly you're trying to solve, I would guess that instead of redefining division, it makes more sense to redefine the number system that you're using: For whatever reason, you have some system of numbers that should return 1 when divided by zero, so why not create a subclass of float, for example?
class floatD01(float):
def __truediv__(self, divisor):
if divisor == 0:
return 1
return self/divisor
You may also want to scan help(float) for any other methods related to division that you may want to change such as __divmod__, __floordiv__ (7//3 == 2), etc, and have a hard think about how you want this new mathematical group that you're creating to work and why.
Other options that may potentially be more robust would be to go nuclear and try catching all ZeroDivisionErrors and replace them with one (either by modifying the class) or within whatever code you're running or, if appropriate, implementing something like what the language R extensively uses: NA values. I'm sure there's some way (I believe in numpy) to do something along the lines of: C = [1/3, 2/2, 3/1, 4/0] # == [1/3, 2/2, 3/1, NA] sum(C) = 4.333
The solution was pretty simple actually, although I was not able to actualy overload the division operator all I had to do was create a sympy function for the protected division and use that instead.
class protected_division(sym.Function):
#classmethod
def eval(cls, x, y):
if y.is_Number:
if y.is_zero:
return sym.S.One
else:
return x/y
Then just use that in an expression:
>>> expr = protected_division(1, sym.Symbol('x'))
protected_division(1, x)
>>> expr.subs(sym.Symbol('x'), 0)
1
>>> expr.subs(sym.Symbol('x'), 3)
1/3
I did not find out how to make the class tell sym.lambdify what to do in case of a "lambdification", but you can use the modules parameters for that:
>>> def pd(x, y):
... if y == 0:
... return 1
... return x/y
...
>>> l = sym.lambdify(sym.Symbol('x'), expr, modules={'protected_division': pd})
>>> l(3)
1.6666666666666667
>>> l(0)
1
Given an expression, we can convert it into a function using sympy.lambdify. Similarly, given a function, we can convert it into an expression by evaluating it at symbol x. We would naturally expect that these two operations are inverses of each other. And, this expected behaviour is displayed when I use polynomial expressions. For example,
import sympy as sym
x = sym.symbols('x')
expr = 5*x**2 + 2*x + 3
f = sym.lambdify([x],expr)
f_expr = f(x)
print(expr == f_expr)
gives True as its output.
On the other hand, the following code does not run
import sympy as sym
x = sym.symbols('x')
expr = sym.sin(x)
f = sym.lambdify([x],expr)
f_expr = f(x)
print(expr == f_expr)
and throws the error "TypeError: loop of ufunc does not support argument 0 of type Symbol which has no callable sin method". Could you please explain why this is happening? My guess would be that sym.sin(x) does not return an "expression" analogous to 5x**2 + 2x + 3. But, I would like to understand it a bit better. Thanks in advance.
For a non-numeric object the lambdify code tries to do x.sin()
with making sure the sin function is from library sympy not numpy to avoid confusions.
you can try :
import sympy as sym
from sympy import sin
x = sym.symbols('x')
expr = sin(x)
# f = sym.lambdify(x,expr)
f = lambda x:sin(x)
f_expr = f(x)
print(expr == f_expr)
I am having a problem.
def f(x):
function = input("Enter yoru Function: ")
return function
a = -1
b = 2
a_Applied = f(a)
b_Applied = f(b)
if a_Applied < 0 and b_Applied > 0:
print "IVT Applies."
elif a_Applied > 0 and b_Applied < 0:
print "IVT Applies"
else:
print "IVT Does Not Apply"
This is my current code. I am trying to let the user make a function in line 2. However this breaks the program because it is a string. How do I get it to not be a string, and instead for it to be able to take a function.
Ex.
User inputs "2*x + 1"
In a perfect world the program then runs 2(a) +1 and 2(b) + 1 and then compares them using the if statement. Because the input is a string ti doesn't work.
Any help?
Use lambda expression and eval function. Like this.
def read_user_function():
function_str = input("Enter your Function: ")
return lambda x: eval(function_str, { 'x' : x })
Call user function by
f = read_user_function()
print(f(2))
Here is a demo https://repl.it/ITuU/2.
Explanation
The function above, read_user_function returns a lambda expression, basically a function, that will evaluate the user's input with the variable, sort of like a parameter, x set to the x value that is passed to the lambda expression. This can get confusing if your new to this sort of thing but just think of read_user_function as returning an anonymous function that accepts a single argument and its body equals eval(function_str, { 'x' : x })
Warning
This is a quick and dirty solution to evaluating mathematical expression. The function would execute any valid python code and not only mathematical expression. This may be dangerous if your application is sensitive - you wouldn't want the user executing custom code.
What you're asking to do is very hard (in general). You'd need to define rigorous semantics for all your supported operations (for example, is power ^ or is it ** like you'd do in python?).
The sympy library has a start on this for you. If you assume your input is a polynomial, for example:
import sympy
y = sympy.Poly("x^2 + 2*x + 1")
print(y(3))
# outputs 16
sympy also has the advantage that it will accept "python-like" input as well:
import sympy
y = sympy.Poly("x**2 + 2*x + 1")
print(y(3))
Note that sympy is not limited to polynomials, just included them here as an example because polynomials are relatively simple.
I'm just wondering if there is an existing method of expanding algebraic powers such as x**2 out to their multiplicative forms (i.e. x**2 -> x*x) in python's Sympy module?
Thanks!
There's no direct support for this. SymPy automatically combines common terms in a multiplication to exponentiation. The only way to make this not happen is to use the evaluate=False mechanism. For example
>>> Mul(x, x, evaluate=False)
x*x
There was a discussion on the SymPy mailing list a while back about this exact question (https://groups.google.com/d/topic/sympy/qaJGesRbX_0/discussion). I posted some code there that will do this. I'll repeat it here:
def pow_to_mul(expr):
"""
Convert integer powers in an expression to Muls, like a**2 => a*a.
"""
pows = list(expr.atoms(Pow))
if any(not e.is_Integer for b, e in (i.as_base_exp() for i in pows)):
raise ValueError("A power contains a non-integer exponent")
repl = zip(pows, (Mul(*[b]*e,evaluate=False) for b,e in (i.as_base_exp() for i in pows)))
return expr.subs(repl)
Here's how it works
>>> a = Symbol('a')
>>> exp = a**2
>>> print(exp)
a**2
>>> print(pow_to_mul(exp))
a*a
I'll put the same caveat here as on the mailing list: "evaluate=False is somewhat of a hack, so be aware that it is fragile. Some functions will reevaluate the expression, converting it back to Pow. Other functions will break because some expected invariant will be broken by the evaluate=False expression (e.g., I doubt factor() would work correctly)."
There seems to be no such thing, it does the reverse only.
sympy always shows the output in the most simple way, so it will always say:
(x**2).expand() -> x**2
simplify(x**2) -> x**2
The replace method is well suited in this task for simple expressions:
>>> expr = (x**2 + 1)/(x**3 - 2*x)
>>> expr.replace(
... lambda x: x.is_Pow and x.exp > 0,
... lambda x: Mul(*[x.base]*x.exp, evaluate=False))
(x*x + 1)/(-2*x + x*x*x)
Tweaking will be necessary to handle things like 1/x**3 or x**2*(1 + x**2). But if you expand the numerator and denominator of the expressions and handle them separately, this may do what you need. And if the bases are always Symbols then this symbol-hackery may do the trick even better:
>>> def sack(expr):
... return expr.replace(
... lambda x: x.is_Pow and x.exp > 0,
... lambda x: Symbol('*'.join([x.base.name]*x.exp)))
...
>>> sack(-x**2)
-x*x
>>> sack(x**2*(1 + x**3)
x*x*(x*x*x + 1)
Following up from Aaron's accepted answer and my comment on it, this is the version of xreplace I am using instead of the final subs line to avoid sub-expressions being evaluated (and thus losing the expansion of the power to a chain of multiplications).
def non_eval_xreplace(expr, rule):
"""
Duplicate of sympy's xreplace but with non-evaluate statement included
"""
if expr in rule:
return rule[expr]
elif rule:
args = []
altered = False
for a in expr.args:
try:
new_a = non_eval_xreplace(a, rule)
except AttributeError:
new_a = a
if new_a != a:
altered = True
args.append(new_a)
args = tuple(args)
if altered:
return expr.func(*args, evaluate=False)
return expr
I was thinking this functionality could be added to the existing xreplace in the SymPy library by letting it take **kwargs that are passed to the expr.func call. Is this something you are interested in doing, or would this be unnecessarily complex for the majority of users? (or did I misunderstand your comment above and is there a simpler way to do this?)
Other answers do not handle -x**2 so I used regex instead to solve only for powers of 2. I understand this is a little hacky but it worked for me.
from sympy.printing import ccode
import re
CPOW = re.compile(r'pow\((?P<var>[A-Za-z_]\w*)\s*,\s*2\s*\)')
def to_c_code(expr):
code = ccode(expr)
# sympy has a hard time unsimplifying x**2 to x*x
# replace all pow(var,2) with var*var
code = re.sub(CPOW, r'\g<var>*\g<var>', code)
return code
I want to have some sort of reference to a function but I do not know if I need to use a def f(x) or a lambda of some kind.
For instance I'd like to print f(3) and have it output 9a, or is this not how python works?
Second question: Assuming I have a working function, how do I return the degree of it?
To create a function, you define it. Functions can do anything, but their primary use pattern is taking parameters and returning values. You have to decide how exactly it transforms parameters into the return value.
For instance, if you want f(x) to return a number, then a should also be a numeric variable defined globally or inside the function:
In [1]: def f(x):
...: a = 2.5
...: return a * x**2
...:
In [2]: f(3)
Out[2]: 22.5
Or maybe you want it to return a string like this:
In [3]: def f(x):
...: return str(x**2) + 'a'
...:
In [4]: f(3)
Out[4]: '9a'
You have to specify your needs if you need more help.
EDIT: As it turns out, you want to work with polynomials or algebraic functions as objects and do some algebraic stuff with them. Python will allow doing that, but not using standard data types. You can define a class for a polynomial and then define any methods or functions to get the highest power or anything else. But Polynomial is not a built-in data type. There may be some good libraries defining such classes, though.
Python (and most other computer languages) don't do algebra, which is what you'll need if you want symbolic output like this. But you could have a function f(a,x) which returns the result for particular (numerical) values of a:
def f(a, x):
return a*x*x
But if you want a program or language which actually does algebra for you, check out sympy or commercial programs like Mathematica.
If you are just working with polynomials, and you just need a data structure which deals well with them, check out numpy and its polynomial class.
I normally use lambda for short and simple functions:
f = lambda a, x: a * x**2
here a and x are parameters of my function. You need to enter a and x
f(2,4)
If you want a as a constant parameter eg. a=2:
f = lambda x: 2 * x**2
f(5)
if you have a list of input values of x, you can combine map with lambda.
it is straighforward and easily readable.
(*map(lambda x: 3 * x**2, [1,2,3,4]),)
or
list(map(lambda x: 3 * x**2, [1,2,3,4])
cheers!
def func():
print "F(x) = 2x + 3"
x = int(raw_input('Enter an integer value for x: '))
Fx = 2 * x + 3
return Fx
print func()
have fun :)
Cheese,
you can use the def function in Python to create a math function, you could type this:
def f(x):
return(2x + (3 + 3) * 11 + 88) # <- you could make your own function.
print(f(3))
Log:
220
Like THAT
or in this:
def f(a, x):
return((a + x) ** (a * x))
then...
print(f(1, 2))
Log...
6