Protected Division Using Sympy - python

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

Related

Is there a function in python for the fourth, fifth e.t.c. root? [duplicate]

In maths, if I wish to calculate 3 to the power of 2 then no symbol is required, but I write the 2 small: 3². In Python this operation seems to be represented by the ** syntax.
>>> 3**2
9
If I want to go the other direction and calculate the 2nd root of 9 then in maths I need to use a symbol: 2√9 = 3
Is there a short-hand symbol in Python, similar to ** that achieves this i.e. 2<symbol>9? Or do I need to use the math module?
nth root of x is x^(1/n), so you can do 9**(1/2) to find the 2nd root of 9, for example. In general, you can compute the nth root of x as:
x**(1/n)
Note: In Python 2, you had to do 1/float(n) or 1.0/n so that the result would be a float rather than an int. For more details, see Why does Python give the "wrong" answer for square root?
You may also use some logarithms:
Nth root of x:
exp(log(x)/n)
For example:
>>> from math import exp, log
>>> x = 8
>>> n = 3
>>> exp(log(x)/n)
2.0
Also: x**(n**-1), which is the same but shorter than x**(1/float(n))
If you prefer to apply this operation functionally rather than with an infix operator (the ** symbol), you can pass the base and exponent as arguments to the pow function:
In [23]: (9**(0.5)) == pow(9, 0.5)
Out[23]: True
I am also fond of finding new uses for this Infix hack in Python although it's more of a fun aside than a heavy-duty solution. But you could effectively make your own personal symbol for this by doing the following:
class Infix:
def __init__(self, function):
self.function = function
def __ror__(self, other):
return Infix(lambda x, self=self, other=other: self.function(other, x))
def __or__(self, other):
return self.function(other)
def __rlshift__(self, other):
return Infix(lambda x, self=self, other=other: self.function(other, x))
def __rshift__(self, other):
return self.function(other)
def __call__(self, value1, value2):
return self.function(value1, value2)
root_of = Infix(lambda x,y: y**(1.0/x))
print 2 |root_of| 9
3.0
There is. It's just ** =)
Any nth root is an exponentiation by 1/n, so to get the square root of 9, you use 9**(1/2) (or 9**0.5) to get the cube root, you use 9 ** (1/3) (which we can't write with a simpler fraction), and to get the nth root, 9 ** (1/n).
Also note that as of Python 3, adding periods to integers to make them a float is no longer necessary. Saying 1/3 works the way you would actually expect it to, giving 0.333... as result, rather than zero. For legacy versions of Python, you'll have to remember to use that period (but also critically wonder why you're using a legacy version of a programming language)
Basically sqrt(9) is equivalent to 9^.5
>>>9**.5
3.0
You should do
16**(0.5) #If you print it, you get 4, So you can use this formula.
def nthrootofm(a,n):
return pow(a,(1/n))
a=81
n=4
q=nthrootofm(a,n)
print(q)
pow() function takes two parameters .
You can take the nth root of a number in Python by using nroot included in the libnum library:
from libnum import nroot
nth_root = nroot(a, n)
This would be equivalent to
Although note, that it will return the truncated nth root of a.

Overload python ternary operator

Is it possible to overload the ternary operator in python? Basically what I want is something like:
class A(object):
def __ternary__(self, a, c):
return a + c
a = A()
print "asdf" if a else "fdsa" # prints "asdffdsa"
I'm trying to implement a symbolic package and basically want something that can do things like:
sym = Symbol("s")
result = 1 if sym < 3 else 10
print result.evaluate(sym=2) # prints 1
print result.evaluate(sym=4) # prints 10
Edit: Let me put out a bit more complex example to show how this could be layered upon.
sym = Symbol("s")
result = 1 if sym < 3 else 10
...
something_else = (result+1)*3.5
...
my_other_thing = sqrt(something_else)
print my_other_thing.evaluate(sym=2) # prints sqrt(7) or rather the decimal equivalent
The point is, I don't need to just be able to late evaluate the one ternary operator, I need to take the result and do other symbolic stuff with that before finally evaluating. Furthermore, my code can do partial evaluations where I give it a few bindings and it returns another symbolic expression if it can't evaluate the full expression.
My backup plan is just to directly use the ternary class taking 3 expressions objects that I would need to make anyway. I was just trying to hide the generation of this class with an operator overload. Basically:
a = TernaryOperator(a,b,c)
# vs
b = a if b else c
look at the sympy module; it already does this
for simple comparison, write A.__eq__ and A.__lt__ methods and use the total_ordering class decorator; this should be sufficient for comparing two As or an A and a constant
write it as a lambda,
result = lambda sym: 1 if sym < 3 else 10
print(result(2)) # => 1
print(result(4)) # => 10
Overload the comparison operators instead (something you probably needed to do anyway):
class A(object):
def __lt__(self, other):
return self.value() < other.value() # Replace with your own implementation of <
Then, use lambda functions to achieve the delayed evaluation you desire:
sym = Symbol("s")
result = lambda s: 1 if s < 3 else 10
sym.set(2)
print result(sym) # prints 1
sym.set(4)
print result(sym) # prints 10
(I don't think you can overload the assignment operator, as it doesn't actually perform an operation on any object, but rather on a variable.)

Is there a short-hand for nth root of x in Python?

In maths, if I wish to calculate 3 to the power of 2 then no symbol is required, but I write the 2 small: 3². In Python this operation seems to be represented by the ** syntax.
>>> 3**2
9
If I want to go the other direction and calculate the 2nd root of 9 then in maths I need to use a symbol: 2√9 = 3
Is there a short-hand symbol in Python, similar to ** that achieves this i.e. 2<symbol>9? Or do I need to use the math module?
nth root of x is x^(1/n), so you can do 9**(1/2) to find the 2nd root of 9, for example. In general, you can compute the nth root of x as:
x**(1/n)
Note: In Python 2, you had to do 1/float(n) or 1.0/n so that the result would be a float rather than an int. For more details, see Why does Python give the "wrong" answer for square root?
You may also use some logarithms:
Nth root of x:
exp(log(x)/n)
For example:
>>> from math import exp, log
>>> x = 8
>>> n = 3
>>> exp(log(x)/n)
2.0
Also: x**(n**-1), which is the same but shorter than x**(1/float(n))
If you prefer to apply this operation functionally rather than with an infix operator (the ** symbol), you can pass the base and exponent as arguments to the pow function:
In [23]: (9**(0.5)) == pow(9, 0.5)
Out[23]: True
I am also fond of finding new uses for this Infix hack in Python although it's more of a fun aside than a heavy-duty solution. But you could effectively make your own personal symbol for this by doing the following:
class Infix:
def __init__(self, function):
self.function = function
def __ror__(self, other):
return Infix(lambda x, self=self, other=other: self.function(other, x))
def __or__(self, other):
return self.function(other)
def __rlshift__(self, other):
return Infix(lambda x, self=self, other=other: self.function(other, x))
def __rshift__(self, other):
return self.function(other)
def __call__(self, value1, value2):
return self.function(value1, value2)
root_of = Infix(lambda x,y: y**(1.0/x))
print 2 |root_of| 9
3.0
There is. It's just ** =)
Any nth root is an exponentiation by 1/n, so to get the square root of 9, you use 9**(1/2) (or 9**0.5) to get the cube root, you use 9 ** (1/3) (which we can't write with a simpler fraction), and to get the nth root, 9 ** (1/n).
Also note that as of Python 3, adding periods to integers to make them a float is no longer necessary. Saying 1/3 works the way you would actually expect it to, giving 0.333... as result, rather than zero. For legacy versions of Python, you'll have to remember to use that period (but also critically wonder why you're using a legacy version of a programming language)
Basically sqrt(9) is equivalent to 9^.5
>>>9**.5
3.0
You should do
16**(0.5) #If you print it, you get 4, So you can use this formula.
def nthrootofm(a,n):
return pow(a,(1/n))
a=81
n=4
q=nthrootofm(a,n)
print(q)
pow() function takes two parameters .
You can take the nth root of a number in Python by using nroot included in the libnum library:
from libnum import nroot
nth_root = nroot(a, n)
This would be equivalent to
Although note, that it will return the truncated nth root of a.

How can I pass functions or operators as arguments to a function in Python?

...while still leaving it executable within the function.
The idea behind this is I want to create a summation function. Here's what I have so far:
def summation(n, bound, operation):
if operation is None and upper != 'inf':
g = 0
for num in range(n, limit + 1):
g += num
return g
else:
pass
But summations are most often about infinite convergent series (for which I use 'inf'), with operations applied to each term. Ideally, I'd like to be able to write print summation(0, 'inf', 1 / factorial(n)) and get the mathematical constant e, or def W(x): return summation(1, 'inf', ((-n) ** (n - 1)) / factorial(n)) to get the Lambert W function.
All that comes to my mind is passing the appropriate arithmetic as a string and then using the exec statement to execute it. But I don't think that would accomplish the whole thing, and it's obviously dangerous to use exec with possibly user-entered code.
In Python, functions are first-class, which is to say they can be used and passed around like any other values, so you can take a function:
def example(f):
return f(1) + f(2)
To run it, you could define a function like this:
def square(n):
return n * n
And then pass it to your other function:
example(square) # = square(1) + square(2) = 1 + 4 = 5
You can also use lambda to avoid having to define a new function if it's a simple expression:
example(lambda n: n * n)

Expanding algebraic powers in python (sympy)

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

Categories