I'm using Sympy to evaluate symbolic expressions provided by users, but the division operator isn't behaving like any other mathematical operator. When evaluating an expression on objects with overridden operators, I get the expected result for addition, subtraction, and multiplication, but not division. The code below illustrates my problem:
import sympy
import numpy
class NewMath(int):
def __add__(self, other):
print "Adding!"
return
def __sub__(self, other):
print "Subtracting!"
return
def __mul__(self, other):
print "Multiplying!"
return
def __div__(self, other):
print "Dividing!"
return
three = NewMath(3)
four = NewMath(4)
three + four
three - four
three * four
three / four
# Override sympys default math
func_map = {'+':NewMath.__add__,
'/':NewMath.__div__}
lambda_args = [sympy.Symbol(arg) for arg in ['three', 'four']]
print "Now sympy math:"
lambda_addition = sympy.lambdify(lambda_args, sympy.Symbol('three') + sympy.Symbol('four'), modules=func_map)
lambda_addition(three, four)
lambda_subtraction = sympy.lambdify(lambda_args, sympy.Symbol('three') - sympy.Symbol('four'), modules=func_map)
lambda_subtraction(three, four)
lambda_multiplucation = sympy.lambdify(lambda_args, sympy.Symbol('three') * sympy.Symbol('four'), modules=func_map)
lambda_multiplucation(three, four)
lambda_division = sympy.lambdify(lambda_args, sympy.Symbol('three') / sympy.Symbol('four'), modules=func_map)
lambda_division(three, four)
The output:
Adding!
Subtracting!
Multiplying!
Dividing!
Now sympy math:
Adding!
Subtracting!
Multiplying!
0.75
I've read the Sympy Docs and seen that the /
operator is a common gotcha, but the docs just seem to indicate that division will default to integer division, I can't see anything that indicates /
can't be overridden. You can see in my example I even attempted to use the modules
argument to manually replace division with my custom operator, to no avail.
I've also seen that division in sympy is really just a power of -1 and multiplication , does this mean my cause is hopeless?
I'm using python 2.7 and sympy 1.0
Your cause is certainly not completely hopeless. Here are a few options to get you started.
First off, it seems as if you understand the difference between \\__div__ \\__truediv__
and \\__floordiv__
but if you didn't already, here is some python 2.7 documentation for them.
In python 2.7, overriding \\__div__
seems like it should do what you want, except for that sympy
documentation you found about a/b
being evaluated as a * b^(-1)
. To get around that, you could also override the exponentiation operator.
I tried running your code in my python3 environment, changing all instances of print so they have parentheses and replacing all instances of div
with truediv
.
This isn't really a complete answer, but I can't post comments, so this is what you get!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.