2 base classes for rings. 5 from __future__
import division
10 Ring is an abstract class which expresses that 11 the derived classes are (in mathematical meaning) rings. 13 Definition of ring is as follows: 14 Ring is a structure with addition and multiplication. It is an 15 abelian group with addition, and a monoid with multiplication. 16 The multiplication obeys the distributive law. 21 Initialize _one and _zero for later use for properties 'one' 25 if type(self)
is Ring:
26 raise NotImplementedError(
"class Ring is abstract")
32 createElement returns an element of the ring with seed. 34 raise NotImplementedError(
"derived class should override")
38 Return the characteristic of the ring. 40 The Characteristic of a ring is the smallest positive integer 41 n s.t. n * a = 0 for any element a of the ring, or 0 if there 42 is no such natural number. 44 raise NotImplementedError(
"derived class should override")
48 Report whether another ring contains the ring as a subring. 50 raise NotImplementedError(
"derived class should override")
54 Report whether the ring is a superring of another ring. 56 raise NotImplementedError(
"derived class should override")
60 Return common super ring of self and another ring. 67 return other.getCommonSuperring(self)
70 raise NotImplementedError(
"no common super ring")
76 raise NotImplementedError(
"derived class should override")
79 raise NotImplementedError(
"derived class should override")
85 return not self.
__eq__(other)
90 CommutativeRing is an abstract subclass of Ring 91 whose multiplication is commutative. 96 Initialize 'properties' attribute by an object of 97 CommutativeRingProperties. 100 if type(self)
is CommutativeRing:
101 raise NotImplementedError(
"class CommutativeRing is abstract")
109 getQuotientField returns the quotient field of the ring 110 if available, otherwise raises exception. 112 raise NotImplementedError
116 isdomain returns True if the ring is actually a domain, 117 False if not, or None if uncertain. 123 isnoetherian returns True if the ring is actually a Noetherian 124 domain, False if not, or None if uncertain. 130 isufd returns True if the ring is actually a unique 131 factorization domain, False if not, or None if uncertain. 137 ispid returns True if the ring is actually a principal 138 ideal domain, False if not, or None if uncertain. 144 iseuclidean returns True if the ring is actually a Euclidean 145 domain, False if not, or None if uncertain. 151 isfield returns True if the ring is actually a field, 152 False if not, or None if uncertain. 158 Register a ring 'action_ring', which act on the ring through 159 'action' so the ring be an 'action_ring' module. 171 Return True if 'action_ring' is registered to provide action. 176 if action_ring.issubring(action_superring):
182 Return the registered action for 'action_ring'. 185 if action_ring.issubring(action_superring):
186 return self.
_actions[action_superring]
187 raise KeyError(
"no action is defined")
192 Field is an abstract class which expresses that 193 the derived classes are (in mathematical meaning) fields. 198 Set field flag True of 'properties' attribute. 201 if type(self)
is Field:
202 raise NotImplementedError
203 CommutativeRing.__init__(self)
208 createElement returns an element of the field. 210 raise NotImplementedError
214 Field overrides isfield of CommutativeRing. 220 A field is trivially a ufd and shuold provide gcd. 228 getQuotientField returns the quotient field of the field. 229 It is, of course, itself. 236 QuotientField is a class of quotient field. 241 Create quotient field from given domain. 242 Initialize 'basedomain' attribute by the given 'domain'. 245 if type(self)
is QuotientField:
246 raise NotImplementedError(
"QuotientField is an abstract class")
250 def baseaction(baseelement, quotient):
251 return quotient.__class__(baseelement * quotient.numerator, quotient.denominator)
258 RingElement is an abstract class for elements of rings. 263 This class is abstract and cannot be instantiated. 265 if type(self)
is RingElement:
266 raise NotImplementedError(
"RingElement is an abstract class.")
270 getRing returns an object of a subclass of Ring, 271 to which the element belongs. 273 raise NotImplementedError
279 raise NotImplementedError
282 raise NotImplementedError
288 return not (self == other)
293 CommutativeRingElement is an abstract class for elements of 299 This class is abstract and cannot be instantiated. 301 if type(self)
is CommutativeRingElement:
302 raise NotImplementedError(
"CommutativeRingElement is an abstract class.")
303 RingElement.__init__(self)
307 Return the result of a module action. 308 other must be in one of the action rings of self's ring. 313 if self_ring.hasaction(other_ring):
314 return self_ring.getaction(other_ring)(other, self)
315 except RuntimeError, e:
318 raise TypeError(
"no module action with %s" % str(other_ring))
322 In UFD, if other divides self, return the quotient as a UFD 323 element. The main difference with / is that / may return the 324 quotient as an element of quotient field. 327 - in a euclidean domain, if remainder of euclidean division 328 is zero, the division // is exact. 329 - in a field, there's no difference with /. 331 If other doesn't divide self, raise ValueError. 333 if self.
getRing().iseuclidean():
334 quotient, remainder = divmod(self, other)
337 raise ValueError(
"division is not exact")
340 raise NotImplementedError(
"exact division is not defined")
345 FieldElement is an abstract class for elements of fields. 349 This class is abstract and cannot be instantiated. 351 if type(self)
is FieldElement:
352 raise NotImplementedError(
"FieldElement is an abstract class.")
353 CommutativeRingElement.__init__(self)
357 in a field, all divisions are exact (without remainder). 363 QuotientFieldElement class is an abstract class to be used as a 364 super class of concrete quotient field element classes. 368 FieldElement.__init__(self)
371 raise ZeroDivisionError
375 if hasattr(other,
"numerator")
and hasattr(other,
"denominator"):
378 return self.__class__(numerator, denominator)
380 return self + self.
getRing().one.mul_module_action(other)
382 return NotImplemented
387 if hasattr(other,
"numerator")
and hasattr(other,
"denominator"):
390 return self.__class__(numerator, denominator)
392 return self - self.
getRing().one.mul_module_action(other)
394 return NotImplemented
397 if hasattr(other,
"numerator")
and hasattr(other,
"denominator"):
400 return self.__class__(numerator, denominator)
402 return self.
getRing().one.mul_module_action(other) - self
404 return NotImplemented
410 if hasattr(other,
"numerator")
and hasattr(other,
"denominator"):
411 numerator = self.
numerator * other.numerator
413 return self.__class__(numerator, denominator)
417 return NotImplemented
425 if hasattr(other,
"numerator")
and hasattr(other,
"denominator"):
426 numerator = self.
numerator * other.denominator
428 return self.__class__(numerator, denominator)
430 return self * self.
getRing().one.mul_module_action(other).
inverse()
432 return NotImplemented
435 if hasattr(other,
"numerator")
and hasattr(other,
"denominator"):
437 denominator = other.denominator * self.
numerator 438 return self.__class__(numerator, denominator)
440 return self.
getRing().one.mul_module_action(other) * self.
inverse()
442 return NotImplemented
444 __div__ = __truediv__
450 if hasattr(other,
"numerator")
and hasattr(other,
"denominator"):
453 return self == self.
getRing().one.mul_module_action(other)
455 return NotImplemented
462 Ideal class is an abstract class to represent the finitely 463 generated ideals. Because the finitely-generatedness is not a 464 restriction for Noetherian rings and in the most cases only 465 Noetherian rings are used, it is general enough. 470 Ideal(generators, ring) creates an ideal of the ring genarated 471 by the generators. generators must be an element of the ring 472 or a list of elements of the ring. 474 if type(self)
is Ideal:
475 raise NotImplementedError(
"class Ideal is abstract")
479 elif generators
in self.
ring:
486 I + J <=> I.__add__(J) 488 where I+J = {i+j | i in I and j in J} 490 assert self.
ring is other.ring
493 return self.__class__(self.
generators + other.generators, self.
ring)
497 I * J <=> I.__mul__(J) 499 where I*J = {sum of i*j | i in I and j in J} 501 assert self.
ring is other.ring
504 for j
in other.generators:
505 generators.append(i * j)
506 return self.__class__(generators, self.
ring)
510 I == J <=> I.__eq__(J) 512 assert type(self)
is type(other)
515 if self.
ring is not other.ring:
520 raise NotImplementedError
524 I != J <=> I.__ne__(J) 526 return not self.
__eq__(other)
530 e in I <=> I.__contains__(e) 532 for e in the ring, to which the ideal I belongs. 534 raise NotImplementedError(
"should be overridden")
538 Report whether another ideal contains this ideal. 542 raise NotImplementedError(
"should be overridden")
546 Report whether this ideal contains another ideal. 550 raise NotImplementedError(
"should be overridden")
554 Reduce an element with the ideal to simpler representative. 556 raise NotImplementedError(
"should be overridden")
561 A residue class ring R/I, 562 where R is a commutative ring and I is its ideal. 567 ResidueClassRing(ring, ideal) creates a resudue class ring. 568 The ring should be an instance of CommutativeRing, and ideal 569 must be an instance of Ideal, whose ring attribute points the 570 same ring with the given ring. 572 CommutativeRing.__init__(self)
579 if isinstance(element, ResidueClass)
and element.ideal == self.
ideal:
584 if isinstance(other, ResidueClassRing):
585 return self.
ideal == other.ideal
589 return hash(self.
ideal)
594 if self.
_one is None:
600 one = property(_getOne,
None,
None,
"multiplicative unit.")
604 if self.
_zero is None:
605 seed = self.
ring.zero
610 zero = property(_getZero,
None,
None,
"additive unit.")
615 Element of residue class ring x+I, where I is the modulus ideal 616 and x is a representative element. 620 CommutativeRingElement.__init__(self)
625 return self.__class__(self.
ideal.reduce(self.
x ), self.
ideal)
628 assert self.
ideal == other.ideal
629 return self.__class__(self.
ideal.reduce(self.
x + other.x), self.
ideal)
632 assert self.
ideal == other.ideal
633 return self.__class__(self.
ideal.reduce(self.
x - other.x), self.
ideal)
636 assert self.
ideal == other.ideal
637 return self.__class__(self.
ideal.reduce(self.
x * other.x), self.
ideal)
640 if isinstance(other, ResidueClass):
641 if self.
ideal == other.ideal:
642 return (self.
x - other.x)
in self.
ideal 646 raise NotImplementedError
650 Return a ResidueClassRing object. 651 This overrides the method inherited from CommutativeRingElement. 658 boolean properties of ring. 660 Each property can have one of three values; True, False, or None. 661 Of cource True is true and False is false, and None means that the 662 property is not set neither directly nor indirectly. 675 Return True/False according to the field flag value being set, 676 otherwise return None. 682 Set True/False value to the field flag. 692 Return True/False according to the euclidean flag value being 693 set, otherwise return None. 699 Set True/False value to the euclidean flag. 712 Return True/False according to the pid flag value being set, 713 otherwise return None. 719 Set True/False value to the pid flag. 721 True -> ufd, noetherian 733 Return True/False according to the ufd flag value being set, 734 otherwise return None. 740 Set True/False value to the ufd flag. 753 Return True/False according to the noetherian flag value being 754 set, otherwise return None. 760 Set True/False value to the noetherian flag. 773 Return True/False according to the domain flag value being 774 set, otherwise return None. 780 Set True/False value to the domain flag. 782 False -> ufd, noetherian 792 Return a RingElement instance which eqauls 'obj'. 794 Mainly for python built-in objects such as int or float. 796 if isinstance(obj, RingElement):
798 elif isinstance(obj, (int, long)):
801 elif isinstance(obj, float):
804 elif isinstance(obj, complex):
811 Return a ring to which 'obj' belongs. 813 Mainly for python built-in objects such as int or float. 818 except AttributeError:
819 if isinstance(obj, (int, long)):
821 return rational.theIntegerRing
822 if isinstance(obj, float):
824 return real.theRealField
825 if isinstance(obj, complex):
827 return imaginary.theComplexField
832 Return the inverse of 'obj'. The inverse can be in the quotient 833 field, if the 'obj' is an element of non-field domain. 835 Mainly for python built-in objects such as int or float. 837 if hasattr(obj,
"inverse"):
840 if isinstance(obj, (int, long)):
843 elif isinstance(obj, (float, complex)):
850 raise NotImplementedError(
"no inversion method found")
854 Return the division of 'self' by 'obj' if the division is exact. 856 Mainly for python built-in objects such as int or float.