1 | initial version |
To find out, you can look in the __cmp__ special method of the object you're interested in. This function returns negative if x<y
, zero if x==y
, and positive if x>y
. Looking in __cmp__ interactively is probably a better idea than browsing the source, because if you do that you may guess wrong about which __cmp__ is being used (like I did!).
For example:
sage: P.<x> = PolynomialRing(QQ)
sage: I = Ideal([x^2-2*x+1, x^2-1])
sage: J = Ideal([4 + 3*x + x^2, 1 + x^2])
sage: I.__cmp__??
Type: instancemethod
Base Class: <type 'instancemethod'>
String Form: <bound method Ideal_1poly_field.__cmp__ of Principal ideal (x - 1) of Univariate Polynomial Ring in x over Rational Field>
Namespace: Interactive
File: /Applications/sage/local/lib/python2.6/site-packages/sage/rings/ideal.py
Definition: I.__cmp__(self, other)
Source:
def __cmp__(self, other):
if not isinstance(other, Ideal_generic):
other = self.ring().ideal(other)
if not other.is_principal():
return -1
if self.is_zero():
if not other.is_zero():
return -1
return 0
# is other.gen() / self.gen() a unit in the base ring?
g0 = other.gen()
g1 = self.gen()
if g0.divides(g1) and g1.divides(g0):
return 0
return 1
sage: I.gen(), J.gen()
(x - 1, 1)
sage: I == J, I <= J, I >= J
(False, False, True)
sage: # or exactly the same case but now (potentially) multivariate
sage: P.<x,y> = PolynomialRing(QQ,2)
sage: I = Ideal([x^2-2*x+1, x^2-1])
sage: J = Ideal([4 + 3*x + x^2, 1 + x^2])
sage: I.__cmp__??
[docstring removed]
# first check the type
if not isinstance(other, MPolynomialIdeal):
return 1
# the ideals may be defined w.r.t. to different term orders
# but are still the same.
R = self.ring()
S = other.ring()
if R is not S: # rings are unique
if type(R) == type(S) and (R.base_ring() == S.base_ring()) and (R.ngens() == S.ngens()):
other = other.change_ring(R)
else:
return cmp((type(R), R.base_ring(), R.ngens()), (type(S), S.base_ring(), S.ngens()))
# now, check whether the GBs are cached already
if self.groebner_basis.is_in_cache() and other.groebner_basis.is_in_cache():
l = self.groebner_basis()
r = other.groebner_basis()
else: # use easy GB otherwise
try:
l = self.change_ring(R.change_ring(order="degrevlex")).groebner_basis()
r = other.change_ring(R.change_ring(order="degrevlex")).groebner_basis()
except AttributeError: # e.g. quotient rings
l = self.groebner_basis()
r = other.groebner_basis()
return cmp(l,r)
sage: I.groebner_basis(), J.groebner_basis()
([x - 1], [1])
sage: I == J, I <= J, I >= J (False, False, True)
So it seems (modulo some details) it's basically comparing the Sequences of the groebner bases, and that appears to fall through to simply sorting the underlying lists of polynomials. I don't know how useful that is, but that looks like what it's doing.