Sagemath not evaluating complicated expression
I'm working with Sagemath for an in-depth project for the first time. I'm experiencing what I perceive to be some very strange behavior and I'm totally stumped on resolving it. I have a class that is encoding some geometric objects.
It works perfectly fine for relatively simple inputs. The strange thing is that when self.center and/or C get sufficiently complicated, I get an error:
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-11-4e5b3134f826> in <module>()
1 c1 = circle(I+Integer(1),Integer(4))
2 m1 = c1.mobToRealLine()
----> 3 c2 = m1.imageCircle(c1)
4 print(c2)
<ipython-input-8-5610dc2742b9> in imageCircle(self, circle)
70 print("new A, B, C = {}, {}, {}".format(newA, newB, newC))
71
---> 72 return Circle(newA, newB, newC)
73
74 def circle(center, radius):
<ipython-input-8-5610dc2742b9> in __init__(self, A, B, C)
9 if A != Integer(0):
10 self.center = -conjugate(B)
---> 11 self.radius = abs(sqrt(abs(self.center)**Integer(2) - C))
12 elif A == Integer(0):
13 self.center = None
/Applications/SageMath/local/lib/python2.7/site-packages/sage/functions/other.pyc in sqrt(x, *args, **kwds)
869 return sqrt(x)
870 try:
--> 871 return x.sqrt(*args, **kwds)
872 # The following includes TypeError to catch cases where sqrt
873 # is called with a "prec" keyword, for example, but the sqrt
/Applications/SageMath/local/lib/python2.7/site-packages/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.sqrt (build/cythonized/sage/symbolic/expression.cpp:44675)()
8075 """
8076 return new_Expression_from_GEx(self._parent,
-> 8077 g_hold2_wrapper(g_power_construct, self._gobj, g_ex1_2, hold))
8078
8079 def sin(self, hold=False):
RuntimeError: unsupported type in numeric::lcm
The error occurs when it's trying to initialize a the class with
A, B, C, = 1/2*abs(sqrt(16) - I - 1)^2/sqrt(16) + (1/2*I + 1/2)*(sqrt(16) + I - 1)/sqrt(16) - (1/2*I - 1/2)*(sqrt(16) - I - 1)/sqrt(16) - 7/sqrt(16),1/2*I*(sqrt(16) - I + 1)*(sqrt(16) - I - 1)/sqrt(16) + (1/2*I - 1/2)*(sqrt(16) - I + 1)/sqrt(16) - (1/2*I + 1/2)*(sqrt(16) - I - 1)/sqrt(16) + 7*I/sqrt(16),1/2*abs(sqrt(16) + I + 1)^2/sqrt(16) + (1/2*I - 1/2)*(sqrt(16) + I + 1)/sqrt(16) - (1/2*I + 1/2)*(sqrt(16) - I + 1)/sqrt(16) - 7/sqrt(16)
If I (by hand) initialize the class with these values of A, B, and C, it works just fine. If, on the other hand, I use the "imagecircle" method that I've written (which is implemented as follows. prints are there for debugging), it fails, despite the fact that the A, B, and C given by the imagecircle method are exactly as above. Here is code that if run, gives the error:
class Circle:
"""Unified line and circle class. If A=0,
then this represents a line."""
def __init__(self, A, B, C):
self.A = A
self.B = B
self.C = C
if A != 0:
self.center = -conjugate(B)
self.radius = abs(sqrt(abs(self.center)^2 - C))
elif A == 0:
self.center = None
self.radius = None
def isCircle(self):
"""Am I a geometric circle in the complex plane?"""
return self.A != 0
def isLine(self):
"""Am I a geometric line in the complex plane?"""
return self.A == 0
def mobToRealLine(self):
if self.isCircle():
"""return the Mobius that takes self to the real line. It takes z0+r to 0, and z0 +- Ir to +-1"""
z0 = self.center
r = self.radius
a = 1/sqrt(r) * (1/2 - I/2)
b = -1/sqrt(r) * (1/2 - I/2) * (r+z0)
c = 1/sqrt(r) * (1/2 + I/2)
d = 1/sqrt(r) * (1/2 + I/2) * (r-z0)
return Mobius(a,b,c,d)
if self.isLine() and imag(self.B) != 0: #This takes iC/2Im(B), 1/2 +- I(ReB + ImC)/(2ImB) to 0, +-1
B, C = self.B, self.C
a = (1-I) / sqrt( conjugate(B)/imag(B) )
b = -( (1/2+I/2)*C*sqrt( conjugate(B)/imag(B) ) ) / ( conjugate(B) )
c = 0
d = (1/2+I/2)*sqrt( conjugate(B)/imag(B) )
return Mobius(a,b,c,d)
else:#Vertical line case x=x0
B, C = self.B, self.C
x0 = -C/(2*B)
a = -sqrt(2)/2 + I*sqrt(2)/2
b = (sqrt(2)/2 - I*sqrt(2)/2)*x0
c = 0
d = -sqrt(2)/2 - I*sqrt(2)/2
return Mobius(a,b,c,d)
class Mobius:
"""Mobius transformation class"""
def __init__(self, a, b, c, d):
self.a = a
self.b = b
self.c = c
self.d = d
self.matrix = Matrix([[a,b],[c,d]])
def imageCircle(self, circle):#This seems broken for a vertical line...
"""Return the image of circle under self."""
A, B, C = circle.A, circle.B, circle.C
cA, cB, cC = conjugate(A), conjugate(B), conjugate(C)
a, b, c, d = self.a, self.b, self.c, self.d
ca, cb, cc, cd = conjugate(a), conjugate(b), conjugate(c), conjugate(d)
newA = A*abs(d)^2 - cc*d*B - c*cd*cB + C*abs(c)^2
newB = -A*cb*d + ca*d*B + cb*c*cB - ca*c*C
newC = A*abs(b)^2 - ca*b*B - a*cb*cB + abs(a)^2*C
print("new A, B, C = {}, {}, {}".format(newA, newB, newC))
return Circle(newA, newB, newC)
def circle(center, radius):
"""returns Circle(A,B,C) with appropriate A, B, C (for simplicity of use)"""
A = 1
B = -conjugate(center)
C = abs(center)^2 - radius^2
return Circle(A,B,C)
c1 = circle(I+1,4)
m1 = c1.mobToRealLine()
c2 = m1.imageCircle(c1)
print(c2)
Please provide the exact code one can use to reproduce the error.
Try using algebraic numbers instead of the symbolic ring.
Ok, I updated my post with code to reproduce the error. If using algebraic numbers is the key, can you lead me to how to get that working here? Thanks in advance for your help.
There seems to be some weird "holding" going on, e.g.
sqrt(abs(1+I)^2 + 14)
evaluates tosqrt(16)
instead of4
.Yes, exactly! I don't understand why this is happening.
I reported this (sub)issue as trac ticket #27897.