Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/structure/element.pyx
8814 views
1
r"""
2
Elements
3
4
AUTHORS:
5
6
- David Harvey (2006-10-16): changed CommutativeAlgebraElement to
7
derive from CommutativeRingElement instead of AlgebraElement
8
9
- David Harvey (2006-10-29): implementation and documentation of new
10
arithmetic architecture
11
12
- William Stein (2006-11): arithmetic architecture -- pushing it
13
through to completion.
14
15
- Gonzalo Tornaria (2007-06): recursive base extend for coercion --
16
lots of tests
17
18
- Robert Bradshaw (2007-2010): arithmetic operators and coercion
19
20
- Maarten Derickx (2010-07): added architecture for is_square and sqrt
21
22
The Abstract Element Class Hierarchy
23
------------------------------------
24
25
This is the abstract class hierarchy, i.e., these are all
26
abstract base classes.
27
28
::
29
30
SageObject
31
Element
32
ModuleElement
33
RingElement
34
CommutativeRingElement
35
IntegralDomainElement
36
DedekindDomainElement
37
PrincipalIdealDomainElement
38
EuclideanDomainElement
39
FieldElement
40
FiniteFieldElement
41
CommutativeAlgebraElement
42
AlgebraElement (note -- can't derive from module, since no multiple inheritance)
43
CommutativeAlgebra ??? (should be removed from element.pxd)
44
Matrix
45
InfinityElement
46
PlusInfinityElement
47
MinusInfinityElement
48
AdditiveGroupElement
49
Vector
50
51
MonoidElement
52
MultiplicativeGroupElement
53
ElementWithCachedMethod
54
55
56
How to Define a New Element Class
57
---------------------------------
58
59
Elements typically define a method ``_new_c``, e.g.,
60
61
::
62
63
cdef _new_c(self, defining data):
64
cdef FreeModuleElement_generic_dense x
65
x = PY_NEW(FreeModuleElement_generic_dense)
66
x._parent = self._parent
67
x._entries = v
68
69
that creates a new sibling very quickly from defining data
70
with assumed properties.
71
72
Sage has a special system in place for handling arithmetic operations
73
for all Element subclasses. There are various rules that must be
74
followed by both arithmetic implementers and callers.
75
76
A quick summary for the impatient:
77
78
- To implement addition for any Element class, override def _add_().
79
- If you want to add x and y, whose parents you know are IDENTICAL,
80
you may call _add_(x, y). This will be the fastest way to guarantee
81
that the correct implementation gets called. Of course you can still
82
always use "x + y".
83
84
Now in more detail. The aims of this system are to provide (1) an efficient
85
calling protocol from both Python and Cython, (2) uniform coercion semantics
86
across Sage, (3) ease of use, (4) readability of code.
87
88
We will take addition of RingElements as an example; all other operators
89
and classes are similar. There are four relevant functions.
90
91
- **def RingElement.__add__**
92
93
This function is called by Python or Pyrex when the binary "+" operator
94
is encountered. It ASSUMES that at least one of its arguments is a
95
RingElement; only a really twisted programmer would violate this
96
condition. It has a fast pathway to deal with the most common case
97
where the arguments have the same parent. Otherwise, it uses the coercion
98
module to work out how to make them have the same parent. After any
99
necessary coercions have been performed, it calls _add_ to dispatch to
100
the correct underlying addition implementation.
101
102
Note that although this function is declared as def, it doesn't have the
103
usual overheads associated with python functions (either for the caller
104
or for __add__ itself). This is because python has optimised calling
105
protocols for such special functions.
106
107
- **def RingElement._add_**
108
109
This is the function you should override to implement addition in a
110
python subclass of RingElement.
111
112
.. warning::
113
114
if you override this in a *Cython* class, it won't get called.
115
You should override _add_ instead. It is especially important to
116
keep this in mind whenever you move a class down from Python to
117
Cython.
118
119
The two arguments to this function are guaranteed to have the
120
SAME PARENT. Its return value MUST have the SAME PARENT as its
121
arguments.
122
123
If you want to add two objects from python, and you know that their
124
parents are the same object, you are encouraged to call this function
125
directly, instead of using "x + y".
126
127
The default implementation of this function is to call _add_,
128
so if no-one has defined a python implementation, the correct Pyrex
129
implementation will get called.
130
131
- **cpdef RingElement._add_**
132
133
This is the function you should override to implement addition in a
134
Pyrex subclass of RingElement.
135
136
The two arguments to this function are guaranteed to have the
137
SAME PARENT. Its return value MUST have the SAME PARENT as its
138
arguments.
139
140
The default implementation of this function is to raise a
141
NotImplementedError, which will happen if no-one has supplied
142
implementations of either _add_.
143
144
145
For speed, there are also **inplace** version of the arithmetic commands.
146
DD NOT call them directly, they may mutate the object and will be called
147
when and only when it has been determined that the old object will no longer
148
be accessible from the calling function after this operation.
149
150
- **def RingElement._iadd_**
151
152
This is the function you should override to inplace implement addition
153
in a Python subclass of RingElement.
154
155
The two arguments to this function are guaranteed to have the
156
SAME PARENT. Its return value MUST have the SAME PARENT as its
157
arguments.
158
159
The default implementation of this function is to call _add_,
160
so if no-one has defined a Python implementation, the correct Cython
161
implementation will get called.
162
"""
163
164
165
cdef extern from *:
166
ctypedef struct RefPyObject "PyObject":
167
int ob_refcnt
168
169
170
171
172
##################################################################
173
# Generic element, so all this functionality must be defined
174
# by any element. Derived class must call __init__
175
##################################################################
176
177
include "sage/ext/cdefs.pxi"
178
include "sage/ext/stdsage.pxi"
179
include "sage/ext/python.pxi"
180
181
import operator, types
182
import sys
183
import traceback
184
185
import sage.misc.sageinspect as sageinspect
186
187
cdef MethodType
188
from types import MethodType
189
190
from sage.categories.category import Category
191
from sage.structure.parent cimport Parent
192
from sage.structure.misc import is_extension_type, getattr_from_other_class
193
from sage.misc.lazy_format import LazyFormat
194
195
# Create a dummy attribute error, using some kind of lazy error message,
196
# so that neither the error itself not the message need to be created
197
# repeatedly, which would cost time.
198
199
from sage.structure.misc cimport AttributeErrorMessage
200
cdef AttributeErrorMessage dummy_error_message = AttributeErrorMessage(None, '')
201
dummy_attribute_error = AttributeError(dummy_error_message)
202
203
# This classes uses element.pxd. To add data members, you
204
# must change that file.
205
206
def make_element(_class, _dict, parent):
207
"""
208
This function is only here to support old pickles.
209
210
Pickling functionality is moved to Element.{__getstate__,__setstate__}
211
functions.
212
"""
213
from sage.misc.pickle_old import make_element_old
214
return make_element_old(_class, _dict, parent)
215
216
def py_scalar_to_element(py):
217
from sage.rings.integer_ring import ZZ
218
from sage.rings.real_double import RDF
219
from sage.rings.complex_double import CDF
220
if PyInt_Check(py) or PyLong_Check(py):
221
return ZZ(py)
222
elif PyFloat_Check(py):
223
return RDF(py)
224
elif PyComplex_Check(py):
225
return CDF(py)
226
else:
227
raise TypeError, "Not a scalar"
228
229
def is_Element(x):
230
"""
231
Return True if x is of type Element.
232
233
EXAMPLES::
234
235
sage: from sage.structure.element import is_Element
236
sage: is_Element(2/3)
237
True
238
sage: is_Element(QQ^3)
239
False
240
"""
241
return IS_INSTANCE(x, Element)
242
243
cdef class Element(sage_object.SageObject):
244
"""
245
Generic element of a structure. All other types of elements
246
(RingElement, ModuleElement, etc) derive from this type.
247
248
Subtypes must either call __init__() to set _parent, or may
249
set _parent themselves if that would be more efficient.
250
"""
251
252
def __init__(self, parent):
253
r"""
254
INPUT:
255
256
- ``parent`` - a SageObject
257
"""
258
#if parent is None:
259
# raise RuntimeError, "bug -- can't set parent to None"
260
self._parent = parent
261
262
def _set_parent(self, parent):
263
r"""
264
INPUT:
265
266
- ``parent`` - a SageObject
267
"""
268
self._parent = parent
269
270
cdef _set_parent_c(self, Parent parent):
271
self._parent = parent
272
273
def _make_new_with_parent_c(self, Parent parent):
274
self._parent = parent
275
return self
276
277
278
def __getattr__(self, str name):
279
"""
280
Let cat be the category of the parent of ``self``. This
281
method emulates ``self`` being an instance of both ``Element``
282
and ``cat.element_class``, in that order, for attribute
283
lookup.
284
285
NOTE:
286
287
Attributes beginning with two underscores but not ending with
288
an unnderscore are considered private and are thus exempted
289
from the lookup in ``cat.element_class``.
290
291
EXAMPLES:
292
293
We test that ``1`` (an instance of the extension type
294
``Integer``) inherits the methods from the categories of
295
``ZZ``, that is from ``CommutativeRings().element_class``::
296
297
sage: 1.is_idempotent(), 2.is_idempotent()
298
(True, False)
299
300
This method is actually provided by the ``Magmas()`` super
301
category of ``CommutativeRings()``::
302
303
sage: 1.is_idempotent
304
<bound method EuclideanDomains.element_class.is_idempotent of 1>
305
sage: 1.is_idempotent.__module__
306
'sage.categories.magmas'
307
308
TESTS::
309
310
sage: 1.blah_blah
311
Traceback (most recent call last):
312
...
313
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'blah_blah'
314
sage: Semigroups().example().an_element().is_idempotent
315
<bound method LeftZeroSemigroup_with_category.element_class.is_idempotent of 42>
316
sage: Semigroups().example().an_element().blah_blah
317
Traceback (most recent call last):
318
...
319
AttributeError: 'LeftZeroSemigroup_with_category.element_class' object has no attribute 'blah_blah'
320
321
We test that "private" attributes are not requested from the element class
322
of the category (trac ticket #10467)::
323
324
sage: C = EuclideanDomains()
325
sage: P.<x> = QQ[]
326
sage: C.element_class.__foo = 'bar'
327
sage: x.parent() in C
328
True
329
sage: x.__foo
330
Traceback (most recent call last):
331
...
332
AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute '__foo'
333
334
"""
335
if (name.startswith('__') and not name.endswith('_')):
336
dummy_error_message.cls = type(self)
337
dummy_error_message.name = name
338
raise dummy_attribute_error
339
cdef Parent P = self._parent or self.parent()
340
if P is None or P._category is None:
341
dummy_error_message.cls = type(self)
342
dummy_error_message.name = name
343
raise dummy_attribute_error
344
return getattr_from_other_class(self, P._category.element_class, name)
345
346
def __dir__(self):
347
"""
348
Let cat be the category of the parent of ``self``. This method
349
emulates ``self`` being an instance of both ``Element`` and
350
``cat.element_class``, in that order, for attribute directory.
351
352
EXAMPLES::
353
354
sage: dir(1/2)
355
['N', ..., 'is_idempotent', 'is_integral', ...]
356
357
Caveat: dir on Integer's and some other extension types seem to ignore __dir__::
358
359
sage: 1.__dir__()
360
['N', ..., 'is_idempotent', 'is_integral', ...]
361
sage: dir(1) # todo: not implemented
362
['N', ..., 'is_idempotent', 'is_integral', ...]
363
"""
364
from sage.structure.parent import dir_with_other_class
365
return dir_with_other_class(self, self.parent().category().element_class)
366
367
def _repr_(self):
368
return "Generic element of a structure"
369
370
def __getstate__(self):
371
"""
372
Returns a tuple describing the state of your object.
373
374
This should return all information that will be required to unpickle
375
the object. The functionality for unpickling is implemented in
376
__setstate__().
377
378
TESTS::
379
380
sage: R.<x,y> = QQ[]
381
sage: i = ideal(x^2 - y^2 + 1)
382
sage: i.__getstate__()
383
(Monoid of ideals of Multivariate Polynomial Ring in x, y over Rational Field, {'_Ideal_generic__ring': Multivariate Polynomial Ring in x, y over Rational Field, '_Ideal_generic__gens': (x^2 - y^2 + 1,), '_gb_by_ordering': {}})
384
"""
385
return (self._parent, self.__dict__)
386
387
def __setstate__(self, state):
388
"""
389
Initializes the state of the object from data saved in a pickle.
390
391
During unpickling __init__ methods of classes are not called, the saved
392
data is passed to the class via this function instead.
393
394
TESTS::
395
396
sage: R.<x,y> = QQ[]
397
sage: i = ideal(x); i
398
Ideal (x) of Multivariate Polynomial Ring in x, y over Rational Field
399
sage: S.<x,y,z> = ZZ[]
400
sage: i.__setstate__((R,{'_Ideal_generic__ring':S,'_Ideal_generic__gens': (S(x^2 - y^2 + 1),)}))
401
sage: i
402
Ideal (x^2 - y^2 + 1) of Multivariate Polynomial Ring in x, y, z over Integer Ring
403
"""
404
self._set_parent(state[0])
405
self.__dict__ = state[1]
406
407
def __copy__(self):
408
"""
409
Returns a copy of ``self``.
410
411
OUTPUT:
412
413
- a new object which is a copy of ``self``.
414
415
This implementation ensures that ``self.__dict__`` is properly copied
416
when it exists (typically for instances of classes deriving from
417
:class:`Element`).
418
419
TESTS::
420
421
sage: from sage.structure.element import Element
422
sage: el = Element(parent = ZZ)
423
sage: el1 = copy(el)
424
sage: el1 is el
425
False
426
427
sage: class Demo(Element): pass
428
sage: el = Demo(parent = ZZ)
429
sage: el.x = [1,2,3]
430
sage: el1 = copy(el)
431
sage: el1 is el
432
False
433
sage: el1.__dict__ is el.__dict__
434
False
435
"""
436
cls = self.__class__
437
res = cls.__new__(cls)
438
res._set_parent(self._parent)
439
try:
440
res.__dict__ = self.__dict__.copy()
441
except AttributeError:
442
pass
443
return res
444
445
def __hash__(self):
446
return hash(str(self))
447
448
def _im_gens_(self, codomain, im_gens):
449
"""
450
Return the image of self in codomain under the map that sends
451
the images of the generators of the parent of self to the
452
tuple of elements of im_gens.
453
"""
454
raise NotImplementedError
455
456
cdef base_extend_c(self, Parent R):
457
if HAS_DICTIONARY(self):
458
return self.base_extend(R)
459
else:
460
return self.base_extend_c_impl(R)
461
462
cdef base_extend_c_impl(self, Parent R):
463
cdef Parent V
464
V = self._parent.base_extend(R)
465
return (<Parent>V)._coerce_c(self)
466
467
def base_extend(self, R):
468
return self.base_extend_c_impl(R)
469
470
def base_ring(self):
471
"""
472
Returns the base ring of this element's parent (if that makes sense).
473
"""
474
return self._parent.base_ring()
475
476
def category(self):
477
from sage.categories.all import Elements
478
return Elements(self._parent)
479
480
481
def _test_category(self, **options):
482
"""
483
Run generic tests on the method :meth:`.category`.
484
485
See also: :class:`TestSuite`.
486
487
EXAMPLES::
488
489
sage: 3._test_category()
490
491
Let us now write a broken :meth:`.category` method::
492
493
sage: from sage.categories.examples.sets_cat import PrimeNumbers
494
sage: class CCls(PrimeNumbers):
495
... def an_element(self):
496
... return 18
497
sage: CC = CCls()
498
sage: CC._test_an_element()
499
Traceback (most recent call last):
500
...
501
AssertionError: self.an_element() is not in self
502
"""
503
from sage.categories.objects import Objects
504
tester = self._tester(**options)
505
sage_object.SageObject._test_category(self, tester = tester)
506
category = self.category()
507
# Tests that self inherits methods from the categories
508
if not is_extension_type(self.__class__):
509
# For usual Python classes, that should be done with
510
# standard inheritance
511
tester.assert_(isinstance(self, self.parent().category().element_class))
512
else:
513
# For extension types we just check that inheritance
514
# occurs on a dummy attribute of Sets().ElementMethods
515
tester.assert_(hasattr(self, "_dummy_attribute"))
516
517
def _test_eq(self, **options):
518
"""
519
Test that ``self`` is equal to ``self`` and different to ``None``.
520
521
See also: :class:`TestSuite`.
522
523
TESTS::
524
525
sage: from sage.structure.element import Element
526
sage: O = Element(Parent())
527
sage: O._test_eq()
528
529
Let us now write a broken class method::
530
531
sage: class CCls(Element):
532
... def __eq__(self, other):
533
... return True
534
sage: CCls(Parent())._test_eq()
535
Traceback (most recent call last):
536
...
537
AssertionError: broken equality: Generic element of a structure == None
538
539
Let us now break inequality::
540
541
sage: class CCls(Element):
542
... def __ne__(self, other):
543
... return True
544
sage: CCls(Parent())._test_eq()
545
Traceback (most recent call last):
546
...
547
AssertionError: broken non-equality: Generic element of a structure != itself
548
"""
549
tester = self._tester(**options)
550
# We don't use assertEqual / assertNonEqual in order to be
551
# 100% sure we indeed call the operators == and !=, whatever
552
# the version of Python is (see #11236)
553
tester.assertTrue(self == self,
554
LazyFormat("broken equality: %s == itself is False")%self)
555
tester.assertFalse(self == None,
556
LazyFormat("broken equality: %s == None")%self)
557
tester.assertFalse(self != self,
558
LazyFormat("broken non-equality: %s != itself")%self)
559
tester.assertTrue(self != None,
560
LazyFormat("broken non-equality: %s is not != None")%self)
561
562
def parent(self, x=None):
563
"""
564
Returns parent of this element; or, if the optional argument x is
565
supplied, the result of coercing x into the parent of this element.
566
"""
567
if x is None:
568
return self._parent
569
else:
570
return self._parent(x)
571
572
573
def subs(self, in_dict=None, **kwds):
574
"""
575
Substitutes given generators with given values while not touching
576
other generators. This is a generic wrapper around __call__.
577
The syntax is meant to be compatible with the corresponding method
578
for symbolic expressions.
579
580
INPUT:
581
582
- ``in_dict`` - (optional) dictionary of inputs
583
584
- ``**kwds`` - named parameters
585
586
OUTPUT:
587
588
- new object if substitution is possible, otherwise self.
589
590
EXAMPLES::
591
592
sage: x, y = PolynomialRing(ZZ,2,'xy').gens()
593
sage: f = x^2 + y + x^2*y^2 + 5
594
sage: f((5,y))
595
25*y^2 + y + 30
596
sage: f.subs({x:5})
597
25*y^2 + y + 30
598
sage: f.subs(x=5)
599
25*y^2 + y + 30
600
sage: (1/f).subs(x=5)
601
1/(25*y^2 + y + 30)
602
sage: Integer(5).subs(x=4)
603
5
604
"""
605
if not hasattr(self,'__call__'):
606
return self
607
parent=self._parent
608
# We should better not test for ParentWIthGens,
609
# as this is essentially deprecated.
610
#from sage.structure.parent_gens import is_ParentWithGens
611
#if not is_ParentWithGens(parent):
612
# return self
613
# Better: Duck typing!
614
try:
615
ngens = parent.ngens()
616
except (AttributeError, NotImplementedError, TypeError):
617
return self
618
variables=[]
619
# use "gen" instead of "gens" as a ParentWithGens is not
620
# required to have the latter
621
for i in xrange(0,ngens):
622
gen=parent.gen(i)
623
if kwds.has_key(str(gen)):
624
variables.append(kwds[str(gen)])
625
elif in_dict and in_dict.has_key(gen):
626
variables.append(in_dict[gen])
627
else:
628
variables.append(gen)
629
return self(*variables)
630
631
def numerical_approx (self, prec=None, digits=None):
632
"""
633
Return a numerical approximation of x with at least prec bits of
634
precision.
635
636
EXAMPLES::
637
638
sage: (2/3).n()
639
0.666666666666667
640
sage: pi.n(digits=10)
641
3.141592654
642
sage: pi.n(prec=20) # 20 bits
643
3.1416
644
"""
645
import sage.misc.functional
646
return sage.misc.functional.numerical_approx(self, prec=prec, digits=digits)
647
n=numerical_approx
648
N=n
649
650
def _mpmath_(self, prec=53, rounding=None):
651
"""
652
Evaluates numerically and returns an mpmath number.
653
Used as fallback for conversion by mpmath.mpmathify().
654
655
.. note::
656
657
Currently, the rounding mode is ignored.
658
659
EXAMPLES::
660
661
sage: from sage.libs.mpmath.all import mp, mpmathify
662
sage: mp.dps = 30
663
sage: 25._mpmath_(53)
664
mpf('25.0')
665
sage: mpmathify(3+4*I)
666
mpc(real='3.0', imag='4.0')
667
sage: mpmathify(1+pi)
668
mpf('4.14159265358979323846264338327933')
669
sage: (1+pi)._mpmath_(10)
670
mpf('4.140625')
671
sage: (1+pi)._mpmath_(mp.prec)
672
mpf('4.14159265358979323846264338327933')
673
"""
674
return self.n(prec)._mpmath_(prec=prec)
675
676
def substitute(self,in_dict=None,**kwds):
677
"""
678
This is an alias for self.subs().
679
680
INPUT:
681
682
- ``in_dict`` - (optional) dictionary of inputs
683
684
- ``**kwds`` - named parameters
685
686
OUTPUT:
687
688
- new object if substitution is possible, otherwise self.
689
690
EXAMPLES::
691
692
sage: x, y = PolynomialRing(ZZ,2,'xy').gens()
693
sage: f = x^2 + y + x^2*y^2 + 5
694
sage: f((5,y))
695
25*y^2 + y + 30
696
sage: f.substitute({x:5})
697
25*y^2 + y + 30
698
sage: f.substitute(x=5)
699
25*y^2 + y + 30
700
sage: (1/f).substitute(x=5)
701
1/(25*y^2 + y + 30)
702
sage: Integer(5).substitute(x=4)
703
5
704
"""
705
return self.subs(in_dict,**kwds)
706
707
cpdef _act_on_(self, x, bint self_on_left):
708
"""
709
Use this method to implement self acting on x.
710
711
Return None or raise a CoercionException if no
712
such action is defined here.
713
"""
714
return None
715
716
cpdef _acted_upon_(self, x, bint self_on_left):
717
"""
718
Use this method to implement self acted on by x.
719
720
Return None or raise a CoercionException if no
721
such action is defined here.
722
"""
723
return None
724
725
726
def __xor__(self, right):
727
raise RuntimeError, "Use ** for exponentiation, not '^', which means xor\n"+\
728
"in Python, and has the wrong precedence."
729
730
def __pos__(self):
731
return self
732
733
def _coeff_repr(self, no_space=True):
734
if self._is_atomic():
735
s = repr(self)
736
else:
737
s = "(%s)"%repr(self)
738
if no_space:
739
return s.replace(' ','')
740
return s
741
742
def _latex_coeff_repr(self):
743
try:
744
s = self._latex_()
745
except AttributeError:
746
s = str(self)
747
if self._is_atomic():
748
return s
749
else:
750
return "\\left(%s\\right)"%s
751
752
def _is_atomic(self):
753
"""
754
Return True if and only if parenthesis are not required when
755
*printing* out any of `x - s`, `x + s`, `x^s` and `x/s`.
756
757
EXAMPLES::
758
759
sage: n = 5; n._is_atomic()
760
True
761
sage: n = x+1; n._is_atomic()
762
False
763
"""
764
if self._parent._repr_option('element_is_atomic'):
765
return True
766
s = str(self)
767
return s.find("+") == -1 and s.find("-") == -1 and s.find(" ") == -1
768
769
def __nonzero__(self):
770
r"""
771
Return True if self does not equal self.parent()(0).
772
773
Note that this is automatically called when converting to
774
boolean, as in the conditional of an if or while statement.
775
776
TESTS:
777
Verify that #5185 is fixed.
778
779
::
780
781
sage: v = vector({1: 1, 3: -1})
782
sage: w = vector({1: -1, 3: 1})
783
sage: v + w
784
(0, 0, 0, 0)
785
sage: (v+w).is_zero()
786
True
787
sage: bool(v+w)
788
False
789
sage: (v+w).__nonzero__()
790
False
791
"""
792
return self != self._parent.zero_element()
793
794
def is_zero(self):
795
"""
796
Return True if self equals self.parent()(0). The default
797
implementation is to fall back to 'not self.__nonzero__'.
798
799
.. warning::
800
801
Do not re-implement this method in your subclass but
802
implement __nonzero__ instead.
803
"""
804
return not self
805
806
def _cmp_(left, right):
807
return left._cmp_c_impl(right)
808
809
cdef _cmp(left, right):
810
"""
811
Compare left and right.
812
"""
813
global coercion_model
814
cdef int r
815
if not have_same_parent(left, right):
816
if left is None or left is Ellipsis:
817
return -1
818
elif right is None or right is Ellipsis:
819
return 1
820
try:
821
_left, _right = coercion_model.canonical_coercion(left, right)
822
if PY_IS_NUMERIC(_left):
823
return cmp(_left, _right)
824
else:
825
return _left._cmp_(_right)
826
except TypeError:
827
r = cmp(type(left), type(right))
828
if r == 0:
829
r = -1
830
return r
831
else:
832
if HAS_DICTIONARY(left):
833
left_cmp = left._cmp_
834
if PY_TYPE_CHECK(left_cmp, MethodType):
835
# it must have been overridden
836
return left_cmp(right)
837
838
return left._cmp_c_impl(right)
839
840
def _richcmp_(left, right, op):
841
return left._richcmp(right, op)
842
843
cdef _richcmp(left, right, int op):
844
"""
845
Compare left and right, according to the comparison operator op.
846
"""
847
global coercion_model
848
cdef int r
849
if not have_same_parent(left, right):
850
if left is None or left is Ellipsis:
851
return _rich_to_bool(op, -1)
852
elif right is None or right is Ellipsis:
853
return _rich_to_bool(op, 1)
854
try:
855
_left, _right = coercion_model.canonical_coercion(left, right)
856
if PY_IS_NUMERIC(_left):
857
return _rich_to_bool(op, cmp(_left, _right))
858
else:
859
return _left._richcmp_(_right, op)
860
except (TypeError, NotImplementedError):
861
r = cmp(type(left), type(right))
862
if r == 0:
863
r = -1
864
# Often things are compared against 0 (or 1), even when there
865
# is not a canonical coercion ZZ -> other
866
# Things should implement and/or use __nonzero__ and is_one()
867
# but we can't do that here as that calls this.
868
# The old coercion model would declare a coercion if 0 went in.
869
# (Though would fail with a TypeError for other values, thus
870
# contaminating the _has_coerce_map_from cache.)
871
from sage.rings.integer import Integer
872
try:
873
if PY_TYPE_CHECK(left, Element) and isinstance(right, (int, float, Integer)) and not right:
874
right = (<Element>left)._parent(right)
875
elif PY_TYPE_CHECK(right, Element) and isinstance(left, (int, float, Integer)) and not left:
876
left = (<Element>right)._parent(left)
877
else:
878
return _rich_to_bool(op, r)
879
except TypeError:
880
return _rich_to_bool(op, r)
881
882
if HAS_DICTIONARY(left): # fast check
883
left_cmp = left.__cmp__
884
if PY_TYPE_CHECK(left_cmp, MethodType):
885
# it must have been overridden
886
return _rich_to_bool(op, left_cmp(right))
887
888
return left._richcmp_c_impl(right, op)
889
890
cdef _rich_to_bool(self, int op, int r):
891
return _rich_to_bool(op, r)
892
893
####################################################################
894
# For a derived Cython class, you **must** put the following in
895
# your subclasses, in order for it to take advantage of the
896
# above generic comparison code. You must also define
897
# either _cmp_c_impl (if your subclass is totally ordered),
898
# _richcmp_c_impl (if your subclass is partially ordered), or both
899
# (if your class has both a total order and a partial order;
900
# then the total order will be available with cmp(), and the partial
901
# order will be available with the relation operators; in this case
902
# you must also define __cmp__ in your subclass).
903
# This is simply how Python works.
904
#
905
# For a *Python* class just define __cmp__ as always.
906
# But note that when this gets called you can assume that
907
# both inputs have identical parents.
908
#
909
# If your __cmp__ methods are not getting called, verify that the
910
# canonical_coercion(x,y) is not throwing errors.
911
#
912
####################################################################
913
def __richcmp__(left, right, int op):
914
return (<Element>left)._richcmp(right, op)
915
916
####################################################################
917
# If your subclass has both a partial order (available with the
918
# relation operators) and a total order (available with cmp()),
919
# you **must** put the following in your subclass.
920
#
921
# Note that in this case the total order defined by cmp() will
922
# not properly respect coercions.
923
####################################################################
924
def __cmp__(left, right):
925
return (<Element>left)._cmp(right)
926
927
cdef _richcmp_c_impl(left, Element right, int op):
928
if (<Element>left)._richcmp_c_impl == Element._richcmp_c_impl and \
929
(<Element>left)._cmp_c_impl == Element._cmp_c_impl:
930
# Not implemented, try some basic defaults
931
if op == Py_EQ:
932
return left is right
933
elif op == Py_NE:
934
return left is not right
935
return left._rich_to_bool(op, left._cmp_c_impl(right))
936
937
cdef int _cmp_c_impl(left, Element right) except -2:
938
### For derived Cython code, you *MUST* ALSO COPY the __richcmp__ above
939
### into your class!!! For Python code just use __cmp__.
940
raise NotImplementedError, "BUG: sort algorithm for elements of '%s' not implemented"%right.parent()
941
942
cdef inline bint _rich_to_bool(int op, int r):
943
if op == Py_LT: #<
944
return (r < 0)
945
elif op == Py_EQ: #==
946
return (r == 0)
947
elif op == Py_GT: #>
948
return (r > 0)
949
elif op == Py_LE: #<=
950
return (r <= 0)
951
elif op == Py_NE: #!=
952
return (r != 0)
953
elif op == Py_GE: #>=
954
return (r >= 0)
955
956
957
def is_ModuleElement(x):
958
"""
959
Return True if x is of type ModuleElement.
960
961
This is even faster than using isinstance inline.
962
963
EXAMPLES::
964
965
sage: from sage.structure.element import is_ModuleElement
966
sage: is_ModuleElement(2/3)
967
True
968
sage: is_ModuleElement((QQ^3).0)
969
True
970
sage: is_ModuleElement('a')
971
False
972
"""
973
return IS_INSTANCE(x, ModuleElement)
974
975
cdef class ElementWithCachedMethod(Element):
976
r"""
977
An element class that fully supports cached methods.
978
979
NOTE:
980
981
The :class:`~sage.misc.cachefunc.cached_method` decorator provides
982
a convenient way to automatically cache the result of a computation.
983
Since trac ticket #11115, the cached method decorator applied to a
984
method without optional arguments is faster than a hand-written cache
985
in Python, and a cached method without any arguments (except ``self``)
986
is actually faster than a Python method that does nothing more but
987
to return ``1``. A cached method can also be inherited from the parent
988
or element class of a category.
989
990
However, this holds true only if attribute assignment is supported.
991
If you write an extension class in Cython that does not accept attribute
992
assignment then a cached method inherited from the category will be
993
slower (for :class:`~sage.structure.parent.Parent`) or the cache would
994
even break (for :class:`Element`).
995
996
This class should be used if you write an element class, can not provide
997
it with attribute assignment, but want that it inherits a cached method
998
from the category. Under these conditions, your class should inherit
999
from this class rather than :class:`Element`. Then, the cache will work,
1000
but certainly slower than with attribute assignment. Lazy attributes
1001
work as well.
1002
1003
EXAMPLE:
1004
1005
We define three element extension classes. The first inherits from
1006
:class:`Element`, the second from this class, and the third simply
1007
is a Python class. We also define a parent class and, in Python, a
1008
category whose element and parent classes define cached methods.
1009
::
1010
1011
sage: cython_code = ["from sage.structure.element cimport Element, ElementWithCachedMethod",
1012
... "cdef class MyBrokenElement(Element):",
1013
... " cdef public object x",
1014
... " def __init__(self,P,x):",
1015
... " self.x=x",
1016
... " Element.__init__(self,P)",
1017
... " def __neg__(self):",
1018
... " return MyBrokenElement(self.parent(),-self.x)",
1019
... " def _repr_(self):",
1020
... " return '<%s>'%self.x",
1021
... " def __hash__(self):",
1022
... " return hash(self.x)",
1023
... " def __cmp__(left, right):",
1024
... " return (<Element>left)._cmp(right)",
1025
... " def __richcmp__(left, right, op):",
1026
... " return (<Element>left)._richcmp(right,op)",
1027
... " cdef int _cmp_c_impl(left, Element right) except -2:",
1028
... " return cmp(left.x,right.x)",
1029
... " def raw_test(self):",
1030
... " return -self",
1031
... "cdef class MyElement(ElementWithCachedMethod):",
1032
... " cdef public object x",
1033
... " def __init__(self,P,x):",
1034
... " self.x=x",
1035
... " Element.__init__(self,P)",
1036
... " def __neg__(self):",
1037
... " return MyElement(self.parent(),-self.x)",
1038
... " def _repr_(self):",
1039
... " return '<%s>'%self.x",
1040
... " def __hash__(self):",
1041
... " return hash(self.x)",
1042
... " def __cmp__(left, right):",
1043
... " return (<Element>left)._cmp(right)",
1044
... " def __richcmp__(left, right, op):",
1045
... " return (<Element>left)._richcmp(right,op)",
1046
... " cdef int _cmp_c_impl(left, Element right) except -2:",
1047
... " return cmp(left.x,right.x)",
1048
... " def raw_test(self):",
1049
... " return -self",
1050
... "class MyPythonElement(MyBrokenElement): pass",
1051
... "from sage.structure.parent cimport Parent",
1052
... "cdef class MyParent(Parent):",
1053
... " Element = MyElement"]
1054
sage: cython('\n'.join(cython_code))
1055
sage: cython_code = ["from sage.all import cached_method, cached_in_parent_method, Category, Objects",
1056
... "class MyCategory(Category):",
1057
... " @cached_method",
1058
... " def super_categories(self):",
1059
... " return [Objects()]",
1060
... " class ElementMethods:",
1061
... " @cached_method",
1062
... " def element_cache_test(self):",
1063
... " return -self",
1064
... " @cached_in_parent_method",
1065
... " def element_via_parent_test(self):",
1066
... " return -self",
1067
... " class ParentMethods:",
1068
... " @cached_method",
1069
... " def one(self):",
1070
... " return self.element_class(self,1)",
1071
... " @cached_method",
1072
... " def invert(self, x):",
1073
... " return -x"]
1074
sage: cython('\n'.join(cython_code))
1075
sage: C = MyCategory()
1076
sage: P = MyParent(category=C)
1077
sage: ebroken = MyBrokenElement(P,5)
1078
sage: e = MyElement(P,5)
1079
1080
The cached methods inherited by ``MyElement`` works::
1081
1082
sage: e.element_cache_test()
1083
<-5>
1084
sage: e.element_cache_test() is e.element_cache_test()
1085
True
1086
sage: e.element_via_parent_test()
1087
<-5>
1088
sage: e.element_via_parent_test() is e.element_via_parent_test()
1089
True
1090
1091
The other element class can only inherit a
1092
``cached_in_parent_method``, since the cache is stored in the
1093
parent. In fact, equal elements share the cache, even if they are
1094
of different types::
1095
1096
sage: e == ebroken
1097
True
1098
sage: type(e) == type(ebroken)
1099
False
1100
sage: ebroken.element_via_parent_test() is e.element_via_parent_test()
1101
True
1102
1103
However, the cache of the other inherited method breaks, although the method
1104
as such works::
1105
1106
sage: ebroken.element_cache_test()
1107
<-5>
1108
sage: ebroken.element_cache_test() is ebroken.element_cache_test()
1109
False
1110
1111
Since ``e`` and ``ebroken`` share the cache, when we empty it for one element
1112
it is empty for the other as well::
1113
1114
sage: b = ebroken.element_via_parent_test()
1115
sage: e.element_via_parent_test.clear_cache()
1116
sage: b is ebroken.element_via_parent_test()
1117
False
1118
1119
Note that the cache only breaks for elements that do no allow attribute assignment.
1120
A Python version of ``MyBrokenElement`` therefore allows for cached methods::
1121
1122
sage: epython = MyPythonElement(P,5)
1123
sage: epython.element_cache_test()
1124
<-5>
1125
sage: epython.element_cache_test() is epython.element_cache_test()
1126
True
1127
1128
"""
1129
def __getattr__(self, name):
1130
"""
1131
This getattr method ensures that cached methods and lazy attributes
1132
can be inherited from the element class of a category.
1133
1134
NOTE:
1135
1136
The use of cached methods is demonstrated in the main doc string of
1137
this class. Here, we demonstrate lazy attributes.
1138
1139
EXAMPLE::
1140
1141
sage: cython_code = ["from sage.structure.element cimport ElementWithCachedMethod",
1142
... "cdef class MyElement(ElementWithCachedMethod):",
1143
... " cdef public object x",
1144
... " def __init__(self,P,x):",
1145
... " self.x=x",
1146
... " ElementWithCachedMethod.__init__(self,P)",
1147
... " def _repr_(self):",
1148
... " return '<%s>'%self.x",
1149
... "from sage.structure.parent cimport Parent",
1150
... "cdef class MyParent(Parent):",
1151
... " Element = MyElement",
1152
... "from sage.all import cached_method, lazy_attribute, Category, Objects",
1153
... "class MyCategory(Category):",
1154
... " @cached_method",
1155
... " def super_categories(self):",
1156
... " return [Objects()]",
1157
... " class ElementMethods:",
1158
... " @lazy_attribute",
1159
... " def my_lazy_attr(self):",
1160
... " return 'lazy attribute of <%d>'%self.x"]
1161
sage: cython('\n'.join(cython_code))
1162
sage: C = MyCategory()
1163
sage: P = MyParent(category=C)
1164
sage: e = MyElement(P,5)
1165
sage: e.my_lazy_attr
1166
'lazy attribute of <5>'
1167
sage: e.my_lazy_attr is e.my_lazy_attr
1168
True
1169
1170
"""
1171
if name.startswith('__') and not name.endswith('_'):
1172
dummy_error_message.cls = type(self)
1173
dummy_error_message.name = name
1174
raise dummy_attribute_error
1175
try:
1176
return self.__cached_methods[name]
1177
except KeyError:
1178
attr = getattr_from_other_class(self,
1179
self._parent.category().element_class,
1180
name)
1181
self.__cached_methods[name] = attr
1182
return attr
1183
except TypeError:
1184
attr = getattr_from_other_class(self,
1185
self._parent.category().element_class,
1186
name)
1187
self.__cached_methods = {name : attr}
1188
return attr
1189
1190
cdef class ModuleElement(Element):
1191
"""
1192
Generic element of a module.
1193
"""
1194
1195
##################################################
1196
# Addition
1197
##################################################
1198
def __add__(left, right):
1199
"""
1200
Top-level addition operator for ModuleElements.
1201
1202
See extensive documentation at the top of element.pyx.
1203
"""
1204
# Try fast pathway if they are both ModuleElements and the parents
1205
# match.
1206
1207
# (We know at least one of the arguments is a ModuleElement. So if
1208
# their types are *equal* (fast to check) then they are both
1209
# ModuleElements. Otherwise use the slower test via PY_TYPE_CHECK.)
1210
if have_same_parent(left, right):
1211
# If we hold the only references to this object, we can
1212
# safely mutate it. NOTE the threshold is different by one
1213
# for __add__ and __iadd__.
1214
if (<RefPyObject *>left).ob_refcnt < inplace_threshold:
1215
return (<ModuleElement>left)._iadd_(<ModuleElement>right)
1216
else:
1217
return (<ModuleElement>left)._add_(<ModuleElement>right)
1218
1219
global coercion_model
1220
return coercion_model.bin_op(left, right, add)
1221
1222
cpdef ModuleElement _add_(left, ModuleElement right):
1223
raise TypeError, arith_error_message(left, right, add)
1224
1225
def __iadd__(ModuleElement self, right):
1226
if have_same_parent(self, right):
1227
if (<RefPyObject *>self).ob_refcnt <= inplace_threshold:
1228
return self._iadd_(<ModuleElement>right)
1229
else:
1230
return self._add_(<ModuleElement>right)
1231
else:
1232
global coercion_model
1233
return coercion_model.bin_op(self, right, iadd)
1234
1235
cpdef ModuleElement _iadd_(self, ModuleElement right):
1236
return self._add_(right)
1237
1238
##################################################
1239
# Subtraction
1240
##################################################
1241
1242
def __sub__(left, right):
1243
"""
1244
Top-level subtraction operator for ModuleElements.
1245
See extensive documentation at the top of element.pyx.
1246
"""
1247
if have_same_parent(left, right):
1248
if (<RefPyObject *>left).ob_refcnt < inplace_threshold:
1249
return (<ModuleElement>left)._isub_(<ModuleElement>right)
1250
else:
1251
return (<ModuleElement>left)._sub_(<ModuleElement>right)
1252
global coercion_model
1253
return coercion_model.bin_op(left, right, sub)
1254
1255
cpdef ModuleElement _sub_(left, ModuleElement right):
1256
# default implementation is to use the negation and addition
1257
# dispatchers:
1258
return left._add_(-right)
1259
1260
def __isub__(ModuleElement self, right):
1261
if have_same_parent(self, right):
1262
if (<RefPyObject *>self).ob_refcnt <= inplace_threshold:
1263
return self._isub_(<ModuleElement>right)
1264
else:
1265
return self._sub_(<ModuleElement>right)
1266
else:
1267
global coercion_model
1268
return coercion_model.bin_op(self, right, isub)
1269
1270
cpdef ModuleElement _isub_(self, ModuleElement right):
1271
return self._sub_(right)
1272
1273
##################################################
1274
# Negation
1275
##################################################
1276
1277
def __neg__(self):
1278
"""
1279
Top-level negation operator for ModuleElements, which
1280
may choose to implement _neg_ rather than __neg__ for
1281
consistency.
1282
"""
1283
return self._neg_()
1284
1285
cpdef ModuleElement _neg_(self):
1286
# default implementation is to try multiplying by -1.
1287
global coercion_model
1288
if self._parent._base is None:
1289
return coercion_model.bin_op(-1, self, mul)
1290
else:
1291
return coercion_model.bin_op(self._parent._base(-1), self, mul)
1292
1293
##################################################
1294
# Module element multiplication (scalars, etc.)
1295
##################################################
1296
def __mul__(left, right):
1297
if PyInt_CheckExact(right):
1298
return (<ModuleElement>left)._mul_long(PyInt_AS_LONG(right))
1299
if PyInt_CheckExact(left):
1300
return (<ModuleElement>right)._mul_long(PyInt_AS_LONG(left))
1301
if have_same_parent(left, right):
1302
raise TypeError, arith_error_message(left, right, mul)
1303
# Always do this
1304
global coercion_model
1305
return coercion_model.bin_op(left, right, mul)
1306
1307
def __imul__(left, right):
1308
if have_same_parent(left, right):
1309
raise TypeError
1310
# Always do this
1311
global coercion_model
1312
return coercion_model.bin_op(left, right, imul)
1313
1314
# rmul -- left * self
1315
cpdef ModuleElement _rmul_(self, RingElement left):
1316
"""
1317
Default module left scalar multiplication, which is to try to
1318
canonically coerce the scalar to the integers and do that
1319
multiplication, which is always defined.
1320
1321
Returning None indicates that this action is not implemented here.
1322
"""
1323
return None
1324
1325
# lmul -- self * right
1326
1327
cpdef ModuleElement _lmul_(self, RingElement right):
1328
"""
1329
Default module left scalar multiplication, which is to try to
1330
canonically coerce the scalar to the integers and do that
1331
multiplication, which is always defined.
1332
1333
Returning None indicates that this action is not implemented here.
1334
"""
1335
return None
1336
1337
cdef ModuleElement _mul_long(self, long n):
1338
"""
1339
Generic path for multiplying by a C long, assumed to commute.
1340
"""
1341
return coercion_model.bin_op(self, n, mul)
1342
1343
cpdef ModuleElement _ilmul_(self, RingElement right):
1344
return self._lmul_(right)
1345
1346
cdef RingElement coerce_to_base_ring(self, x):
1347
if PY_TYPE_CHECK(x, Element) and (<Element>x)._parent is self._parent._base:
1348
return x
1349
try:
1350
return self._parent._base._coerce_c(x)
1351
except AttributeError:
1352
return self._parent._base(x)
1353
1354
##################################################
1355
# Other properties
1356
##################################################
1357
def order(self): ### DO NOT OVERRIDE THIS!!! Instead, override additive_order.
1358
"""
1359
Return the additive order of self.
1360
"""
1361
return self.additive_order()
1362
1363
def additive_order(self):
1364
"""
1365
Return the additive order of self.
1366
"""
1367
raise NotImplementedError
1368
1369
########################################################################
1370
# Monoid
1371
########################################################################
1372
1373
def is_MonoidElement(x):
1374
"""
1375
Return True if x is of type MonoidElement.
1376
"""
1377
return IS_INSTANCE(x, MonoidElement)
1378
1379
cdef class MonoidElement(Element):
1380
"""
1381
Generic element of a monoid.
1382
"""
1383
1384
#############################################################
1385
# Multiplication
1386
#############################################################
1387
def __mul__(left, right):
1388
"""
1389
Top-level multiplication operator for monoid elements.
1390
See extensive documentation at the top of element.pyx.
1391
"""
1392
global coercion_model
1393
if have_same_parent(left, right):
1394
return (<MonoidElement>left)._mul_(<MonoidElement>right)
1395
try:
1396
return coercion_model.bin_op(left, right, mul)
1397
except TypeError, msg:
1398
if isinstance(left, (int, long)) and left==1:
1399
return right
1400
elif isinstance(right, (int, long)) and right==1:
1401
return left
1402
raise
1403
1404
1405
cpdef MonoidElement _mul_(left, MonoidElement right):
1406
"""
1407
Cython classes should override this function to implement multiplication.
1408
See extensive documentation at the top of element.pyx.
1409
"""
1410
raise TypeError
1411
1412
#############################################################
1413
# Other generic functions that should be available to
1414
# any monoid element.
1415
#############################################################
1416
def order(self):
1417
"""
1418
Return the multiplicative order of self.
1419
"""
1420
return self.multiplicative_order()
1421
1422
def multiplicative_order(self):
1423
"""
1424
Return the multiplicative order of self.
1425
"""
1426
raise NotImplementedError
1427
1428
def __pow__(self, n, dummy):
1429
"""
1430
Return the (integral) power of self.
1431
"""
1432
if dummy is not None:
1433
raise RuntimeError, "__pow__ dummy argument not used"
1434
return generic_power_c(self,n,None)
1435
1436
def __nonzero__(self):
1437
return True
1438
1439
def is_AdditiveGroupElement(x):
1440
"""
1441
Return True if x is of type AdditiveGroupElement.
1442
"""
1443
return IS_INSTANCE(x, AdditiveGroupElement)
1444
1445
cdef class AdditiveGroupElement(ModuleElement):
1446
"""
1447
Generic element of an additive group.
1448
"""
1449
def order(self):
1450
"""
1451
Return additive order of element
1452
"""
1453
return self.additive_order()
1454
1455
def __invert__(self):
1456
raise NotImplementedError, "multiplicative inverse not defined for additive group elements"
1457
1458
cpdef ModuleElement _rmul_(self, RingElement left):
1459
return self._lmul_(left)
1460
1461
cpdef ModuleElement _lmul_(self, RingElement right):
1462
"""
1463
Default module left scalar multiplication, which is to try to
1464
canonically coerce the scalar to the integers and do that
1465
multiplication, which is always defined.
1466
1467
Returning None indicates this action is not implemented.
1468
"""
1469
return None
1470
1471
def is_MultiplicativeGroupElement(x):
1472
"""
1473
Return True if x is of type MultiplicativeGroupElement.
1474
"""
1475
return IS_INSTANCE(x, MultiplicativeGroupElement)
1476
1477
cdef class MultiplicativeGroupElement(MonoidElement):
1478
"""
1479
Generic element of a multiplicative group.
1480
"""
1481
def order(self):
1482
"""
1483
Return the multiplicative order of self.
1484
"""
1485
return self.multiplicative_order()
1486
1487
def _add_(self, x):
1488
raise ArithmeticError, "addition not defined in a multiplicative group"
1489
1490
def __div__(left, right):
1491
if have_same_parent(left, right):
1492
return left._div_(right)
1493
global coercion_model
1494
return coercion_model.bin_op(left, right, div)
1495
1496
cpdef MultiplicativeGroupElement _div_(self, MultiplicativeGroupElement right):
1497
"""
1498
Cython classes should override this function to implement division.
1499
See extensive documentation at the top of element.pyx.
1500
"""
1501
return self * ~right
1502
1503
def __invert__(self):
1504
if self.is_one():
1505
return self
1506
return 1/self
1507
1508
1509
def is_RingElement(x):
1510
"""
1511
Return True if x is of type RingElement.
1512
"""
1513
return IS_INSTANCE(x, RingElement)
1514
1515
cdef class RingElement(ModuleElement):
1516
##################################################
1517
def is_one(self):
1518
return self == self._parent.one_element()
1519
1520
##################################
1521
# Fast long add/sub path.
1522
##################################
1523
1524
def __add__(left, right):
1525
"""
1526
Top-level addition operator for RingElements.
1527
1528
See extensive documentation at the top of element.pyx.
1529
"""
1530
if have_same_parent(left, right):
1531
if (<RefPyObject *>left).ob_refcnt < inplace_threshold:
1532
return (<ModuleElement>left)._iadd_(<ModuleElement>right)
1533
else:
1534
return (<ModuleElement>left)._add_(<ModuleElement>right)
1535
if PyInt_CheckExact(right):
1536
return (<RingElement>left)._add_long(PyInt_AS_LONG(right))
1537
elif PyInt_CheckExact(left):
1538
return (<RingElement>right)._add_long(PyInt_AS_LONG(left))
1539
return coercion_model.bin_op(left, right, add)
1540
1541
cdef RingElement _add_long(self, long n):
1542
"""
1543
Generic path for adding a C long, assumed to commute.
1544
"""
1545
return coercion_model.bin_op(self, n, add)
1546
1547
def __sub__(left, right):
1548
"""
1549
Top-level subtraction operator for RingElements.
1550
1551
See extensive documentation at the top of element.pyx.
1552
"""
1553
cdef long n
1554
if have_same_parent(left, right):
1555
if (<RefPyObject *>left).ob_refcnt < inplace_threshold:
1556
return (<ModuleElement>left)._isub_(<ModuleElement>right)
1557
else:
1558
return (<ModuleElement>left)._sub_(<ModuleElement>right)
1559
if PyInt_CheckExact(right):
1560
n = PyInt_AS_LONG(right)
1561
# See UNARY_NEG_WOULD_OVERFLOW in Python's intobject.c
1562
if (n == 0) | (<unsigned long>n != 0 - <unsigned long>n):
1563
return (<RingElement>left)._add_long(-n)
1564
return coercion_model.bin_op(left, right, sub)
1565
1566
##################################
1567
# Multiplication
1568
##################################
1569
1570
cpdef ModuleElement _lmul_(self, RingElement right):
1571
# We return None to invoke the default action of coercing into self
1572
return None
1573
1574
cpdef ModuleElement _rmul_(self, RingElement left):
1575
# We return None to invoke the default action of coercing into self
1576
return None
1577
1578
def __mul__(left, right):
1579
"""
1580
Top-level multiplication operator for ring elements.
1581
See extensive documentation at the top of element.pyx.
1582
1583
AUTHOR:
1584
1585
- Gonzalo Tornaria (2007-06-25) - write base-extending test cases and fix them
1586
1587
TESTS:
1588
1589
Here we test (scalar * vector) multiplication::
1590
1591
sage: x, y = var('x, y')
1592
1593
sage: parent(ZZ(1)*vector(ZZ,[1,2]))
1594
Ambient free module of rank 2 over the principal ideal domain Integer Ring
1595
sage: parent(QQ(1)*vector(ZZ,[1,2]))
1596
Vector space of dimension 2 over Rational Field
1597
sage: parent(ZZ(1)*vector(QQ,[1,2]))
1598
Vector space of dimension 2 over Rational Field
1599
sage: parent(QQ(1)*vector(QQ,[1,2]))
1600
Vector space of dimension 2 over Rational Field
1601
1602
sage: parent(QQ(1)*vector(ZZ[x],[1,2]))
1603
Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field
1604
sage: parent(ZZ[x](1)*vector(QQ,[1,2]))
1605
Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field
1606
1607
sage: parent(QQ(1)*vector(ZZ[x][y],[1,2]))
1608
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
1609
sage: parent(ZZ[x][y](1)*vector(QQ,[1,2]))
1610
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
1611
1612
sage: parent(QQ[x](1)*vector(ZZ[x][y],[1,2]))
1613
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
1614
sage: parent(ZZ[x][y](1)*vector(QQ[x],[1,2]))
1615
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
1616
1617
sage: parent(QQ[y](1)*vector(ZZ[x][y],[1,2]))
1618
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
1619
sage: parent(ZZ[x][y](1)*vector(QQ[y],[1,2]))
1620
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
1621
1622
sage: parent(ZZ[x](1)*vector(ZZ[y],[1,2]))
1623
Traceback (most recent call last):
1624
...
1625
TypeError: unsupported operand parent(s) for '*': 'Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring'
1626
sage: parent(ZZ[x](1)*vector(QQ[y],[1,2]))
1627
Traceback (most recent call last):
1628
...
1629
TypeError: unsupported operand parent(s) for '*': 'Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field'
1630
sage: parent(QQ[x](1)*vector(ZZ[y],[1,2]))
1631
Traceback (most recent call last):
1632
...
1633
TypeError: unsupported operand parent(s) for '*': 'Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring'
1634
sage: parent(QQ[x](1)*vector(QQ[y],[1,2]))
1635
Traceback (most recent call last):
1636
...
1637
TypeError: unsupported operand parent(s) for '*': 'Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field'
1638
1639
Here we test (scalar * matrix) multiplication::
1640
1641
sage: parent(ZZ(1)*matrix(ZZ,2,2,[1,2,3,4]))
1642
Full MatrixSpace of 2 by 2 dense matrices over Integer Ring
1643
sage: parent(QQ(1)*matrix(ZZ,2,2,[1,2,3,4]))
1644
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
1645
sage: parent(ZZ(1)*matrix(QQ,2,2,[1,2,3,4]))
1646
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
1647
sage: parent(QQ(1)*matrix(QQ,2,2,[1,2,3,4]))
1648
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
1649
1650
sage: parent(QQ(1)*matrix(ZZ[x],2,2,[1,2,3,4]))
1651
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field
1652
sage: parent(ZZ[x](1)*matrix(QQ,2,2,[1,2,3,4]))
1653
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field
1654
1655
sage: parent(QQ(1)*matrix(ZZ[x][y],2,2,[1,2,3,4]))
1656
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
1657
sage: parent(ZZ[x][y](1)*matrix(QQ,2,2,[1,2,3,4]))
1658
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
1659
1660
sage: parent(QQ[x](1)*matrix(ZZ[x][y],2,2,[1,2,3,4]))
1661
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
1662
sage: parent(ZZ[x][y](1)*matrix(QQ[x],2,2,[1,2,3,4]))
1663
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
1664
1665
sage: parent(QQ[y](1)*matrix(ZZ[x][y],2,2,[1,2,3,4]))
1666
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
1667
sage: parent(ZZ[x][y](1)*matrix(QQ[y],2,2,[1,2,3,4]))
1668
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
1669
1670
sage: parent(ZZ[x](1)*matrix(ZZ[y],2,2,[1,2,3,4]))
1671
Traceback (most recent call last):
1672
...
1673
TypeError: unsupported operand parent(s) for '*': 'Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring'
1674
sage: parent(ZZ[x](1)*matrix(QQ[y],2,2,[1,2,3,4]))
1675
Traceback (most recent call last):
1676
...
1677
TypeError: unsupported operand parent(s) for '*': 'Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field'
1678
sage: parent(QQ[x](1)*matrix(ZZ[y],2,2,[1,2,3,4]))
1679
Traceback (most recent call last):
1680
...
1681
TypeError: unsupported operand parent(s) for '*': 'Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring'
1682
sage: parent(QQ[x](1)*matrix(QQ[y],2,2,[1,2,3,4]))
1683
Traceback (most recent call last):
1684
...
1685
TypeError: unsupported operand parent(s) for '*': 'Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field'
1686
1687
"""
1688
# Try fast pathway if they are both RingElements and the parents match.
1689
# (We know at least one of the arguments is a RingElement. So if their
1690
# types are *equal* (fast to check) then they are both RingElements.
1691
# Otherwise use the slower test via PY_TYPE_CHECK.)
1692
if have_same_parent(left, right):
1693
if (<RefPyObject *>left).ob_refcnt < inplace_threshold:
1694
return (<RingElement>left)._imul_(<RingElement>right)
1695
else:
1696
return (<RingElement>left)._mul_(<RingElement>right)
1697
if PyInt_CheckExact(right):
1698
return (<ModuleElement>left)._mul_long(PyInt_AS_LONG(right))
1699
elif PyInt_CheckExact(left):
1700
return (<ModuleElement>right)._mul_long(PyInt_AS_LONG(left))
1701
return coercion_model.bin_op(left, right, mul)
1702
1703
cpdef RingElement _mul_(self, RingElement right):
1704
"""
1705
Cython classes should override this function to implement multiplication.
1706
See extensive documentation at the top of element.pyx.
1707
"""
1708
raise TypeError, arith_error_message(self, right, mul)
1709
1710
def __imul__(left, right):
1711
if have_same_parent(left, right):
1712
if (<RefPyObject *>left).ob_refcnt <= inplace_threshold:
1713
return (<RingElement>left)._imul_(<RingElement>right)
1714
else:
1715
return (<RingElement>left)._mul_(<RingElement>right)
1716
1717
global coercion_model
1718
return coercion_model.bin_op(left, right, imul)
1719
1720
cpdef RingElement _imul_(RingElement self, RingElement right):
1721
return self._mul_(right)
1722
1723
def __pow__(self, n, dummy):
1724
"""
1725
Return the (integral) power of self.
1726
1727
EXAMPLE::
1728
1729
sage: a = Integers(389)['x']['y'](37)
1730
sage: p = sage.structure.element.RingElement.__pow__
1731
sage: p(a,2)
1732
202
1733
sage: p(a,2,1)
1734
Traceback (most recent call last):
1735
...
1736
RuntimeError: __pow__ dummy argument not used
1737
sage: p(a,388)
1738
1
1739
sage: p(a,2^120)
1740
81
1741
sage: p(a,0)
1742
1
1743
sage: p(a,1) == a
1744
True
1745
sage: p(a,2) * p(a,3) == p(a,5)
1746
True
1747
sage: p(a,3)^2 == p(a,6)
1748
True
1749
sage: p(a,57) * p(a,43) == p(a,100)
1750
True
1751
sage: p(a,-1) == 1/a
1752
True
1753
sage: p(a,200) * p(a,-64) == p(a,136)
1754
True
1755
sage: p(2, 1/2)
1756
Traceback (most recent call last):
1757
...
1758
NotImplementedError: non-integral exponents not supported
1759
1760
TESTS::
1761
1762
These aren't testing this code, but they are probably good to have around.
1763
1764
sage: 2r**(SR(2)-1-1r)
1765
1
1766
sage: 2r^(1/2)
1767
sqrt(2)
1768
1769
Exponent overflow should throw an OverflowError (trac #2956)::
1770
1771
sage: K.<x,y> = AA[]
1772
sage: x^(2^64 + 12345)
1773
Traceback (most recent call last):
1774
...
1775
OverflowError: Exponent overflow (2147483648).
1776
1777
Another example from trac #2956; this should overflow on x32
1778
and succeed on x64::
1779
1780
sage: K.<x,y> = ZZ[]
1781
sage: (x^12345)^54321
1782
x^670592745 # 64-bit
1783
Traceback (most recent call last): # 32-bit
1784
... # 32-bit
1785
OverflowError: Exponent overflow (670592745). # 32-bit
1786
1787
"""
1788
if dummy is not None:
1789
raise RuntimeError, "__pow__ dummy argument not used"
1790
return generic_power_c(self,n,None)
1791
1792
##################################
1793
# Division
1794
##################################
1795
1796
def __truediv__(self, right):
1797
# in sage all divs are true
1798
if not PY_TYPE_CHECK(self, Element):
1799
return coercion_model.bin_op(self, right, div)
1800
return self.__div__(right)
1801
1802
def __div__(self, right):
1803
"""
1804
Top-level multiplication operator for ring elements.
1805
See extensive documentation at the top of element.pyx.
1806
"""
1807
if have_same_parent(self, right):
1808
if (<RefPyObject *>self).ob_refcnt < inplace_threshold:
1809
return (<RingElement>self)._idiv_(<RingElement>right)
1810
else:
1811
return (<RingElement>self)._div_(<RingElement>right)
1812
global coercion_model
1813
return coercion_model.bin_op(self, right, div)
1814
1815
cpdef RingElement _div_(self, RingElement right):
1816
"""
1817
Cython classes should override this function to implement division.
1818
See extensive documentation at the top of element.pyx.
1819
"""
1820
try:
1821
return self._parent.fraction_field()(self, right)
1822
except AttributeError:
1823
if not right:
1824
raise ZeroDivisionError, "Cannot divide by zero"
1825
else:
1826
raise TypeError, arith_error_message(self, right, div)
1827
1828
def __idiv__(self, right):
1829
"""
1830
Top-level division operator for ring elements.
1831
See extensive documentation at the top of element.pyx.
1832
"""
1833
if have_same_parent(self, right):
1834
if (<RefPyObject *>self).ob_refcnt <= inplace_threshold:
1835
return (<RingElement>self)._idiv_(<RingElement>right)
1836
else:
1837
return (<RingElement>self)._div_(<RingElement>right)
1838
global coercion_model
1839
return coercion_model.bin_op(self, right, idiv)
1840
1841
cpdef RingElement _idiv_(RingElement self, RingElement right):
1842
return self._div_(right)
1843
1844
def __invert__(self):
1845
if self.is_one():
1846
return self
1847
return 1/self
1848
1849
def additive_order(self):
1850
"""
1851
Return the additive order of self.
1852
"""
1853
raise NotImplementedError
1854
1855
def multiplicative_order(self):
1856
r"""
1857
Return the multiplicative order of self, if self is a unit, or raise
1858
``ArithmeticError`` otherwise.
1859
"""
1860
if not self.is_unit():
1861
raise ArithmeticError, "self (=%s) must be a unit to have a multiplicative order."
1862
raise NotImplementedError
1863
1864
def is_nilpotent(self):
1865
"""
1866
Return True if self is nilpotent, i.e., some power of self
1867
is 0.
1868
"""
1869
if self.is_unit():
1870
return False
1871
if self.is_zero():
1872
return True
1873
raise NotImplementedError
1874
1875
def abs(self):
1876
"""
1877
Return the absolute value of self. (This just calls the __abs__
1878
method, so it is equivalent to the abs() built-in function.)
1879
1880
EXAMPLES::
1881
1882
sage: RR(-1).abs()
1883
1.00000000000000
1884
sage: ZZ(-1).abs()
1885
1
1886
sage: CC(I).abs()
1887
1.00000000000000
1888
sage: Mod(-15, 37).abs()
1889
Traceback (most recent call last):
1890
...
1891
ArithmeticError: absolute valued not defined on integers modulo n.
1892
"""
1893
return self.__abs__()
1894
1895
1896
1897
def is_CommutativeRingElement(x):
1898
"""
1899
Return True if x is of type CommutativeRingElement.
1900
"""
1901
return IS_INSTANCE(x, CommutativeRingElement)
1902
1903
cdef class CommutativeRingElement(RingElement):
1904
def _im_gens_(self, codomain, im_gens):
1905
if len(im_gens) == 1 and self._parent.gen(0) == 1:
1906
return codomain(self)
1907
raise NotImplementedError
1908
1909
def inverse_mod(self, I):
1910
r"""
1911
Return an inverse of self modulo the ideal `I`, if defined,
1912
i.e., if `I` and self together generate the unit ideal.
1913
"""
1914
raise NotImplementedError
1915
1916
def divides(self, x):
1917
"""
1918
Return True if self divides x.
1919
1920
EXAMPLES::
1921
1922
sage: P.<x> = PolynomialRing(QQ)
1923
sage: x.divides(x^2)
1924
True
1925
sage: x.divides(x^2+2)
1926
False
1927
sage: (x^2+2).divides(x)
1928
False
1929
sage: P.<x> = PolynomialRing(ZZ)
1930
sage: x.divides(x^2)
1931
True
1932
sage: x.divides(x^2+2)
1933
False
1934
sage: (x^2+2).divides(x)
1935
False
1936
1937
Ticket \#5347 has been fixed::
1938
1939
sage: K = GF(7)
1940
sage: K(3).divides(1)
1941
True
1942
sage: K(3).divides(K(1))
1943
True
1944
1945
::
1946
1947
sage: R = Integers(128)
1948
sage: R(0).divides(1)
1949
False
1950
sage: R(0).divides(0)
1951
True
1952
sage: R(0).divides(R(0))
1953
True
1954
sage: R(1).divides(0)
1955
True
1956
sage: R(121).divides(R(120))
1957
True
1958
sage: R(120).divides(R(121))
1959
Traceback (most recent call last):
1960
...
1961
ZeroDivisionError: reduction modulo right not defined.
1962
1963
If x has different parent than `self`, they are first coerced to a
1964
common parent if possible. If this coercion fails, it returns a
1965
TypeError. This fixes \#5759
1966
1967
::
1968
sage: Zmod(2)(0).divides(Zmod(2)(0))
1969
True
1970
sage: Zmod(2)(0).divides(Zmod(2)(1))
1971
False
1972
sage: Zmod(5)(1).divides(Zmod(2)(1))
1973
Traceback (most recent call last):
1974
...
1975
TypeError: no common canonical parent for objects with parents: 'Ring of integers modulo 5' and 'Ring of integers modulo 2'
1976
sage: Zmod(35)(4).divides(Zmod(7)(1))
1977
True
1978
sage: Zmod(35)(7).divides(Zmod(7)(1))
1979
False
1980
"""
1981
#Check if the parents are the same:
1982
1983
if have_same_parent(self, x):
1984
# First we test some generic conditions:
1985
try:
1986
if x.is_zero():
1987
return True # everything divides 0
1988
except (AttributeError, NotImplementedError):
1989
pass
1990
1991
try:
1992
if self.is_zero():
1993
return False # 0 divides nothing else
1994
except (AttributeError, NotImplementedError):
1995
pass
1996
1997
try:
1998
if self.is_unit():
1999
return True # units divide everything
2000
except (AttributeError, NotImplementedError):
2001
pass
2002
2003
try:
2004
if self.is_one():
2005
return True # 1 divides everything
2006
# (is_unit() may not be implemented)
2007
except (AttributeError, NotImplementedError):
2008
pass
2009
2010
return (x % self) == 0
2011
2012
else:
2013
#Different parents, use coercion
2014
global coercion_model
2015
a, b = coercion_model.canonical_coercion(self, x)
2016
return a.divides(b)
2017
2018
def mod(self, I):
2019
r"""
2020
Return a representative for self modulo the ideal I (or the ideal
2021
generated by the elements of I if I is not an ideal.)
2022
2023
EXAMPLE: Integers
2024
Reduction of 5 modulo an ideal::
2025
2026
sage: n = 5
2027
sage: n.mod(3*ZZ)
2028
2
2029
2030
Reduction of 5 modulo the ideal generated by 3::
2031
2032
sage: n.mod(3)
2033
2
2034
2035
Reduction of 5 modulo the ideal generated by 15 and 6, which is `(3)`.
2036
2037
::
2038
2039
sage: n.mod([15,6])
2040
2
2041
2042
2043
EXAMPLE: Univariate polynomials
2044
2045
::
2046
2047
sage: R.<x> = PolynomialRing(QQ)
2048
sage: f = x^3 + x + 1
2049
sage: f.mod(x + 1)
2050
-1
2051
2052
When little is implemented about a given ring, then mod may
2053
return simply return `f`. For example, reduction is not
2054
implemented for `\ZZ[x]` yet. (TODO!)
2055
2056
sage: R.<x> = PolynomialRing(ZZ)
2057
sage: f = x^3 + x + 1
2058
sage: f.mod(x + 1)
2059
x^3 + x + 1
2060
2061
2062
EXAMPLE: Multivariate polynomials
2063
We reduce a polynomial in two variables modulo a polynomial
2064
and an ideal::
2065
2066
sage: R.<x,y,z> = PolynomialRing(QQ, 3)
2067
sage: (x^2 + y^2 + z^2).mod(x+y+z)
2068
2*y^2 + 2*y*z + 2*z^2
2069
2070
Notice above that `x` is eliminated. In the next example,
2071
both `y` and `z` are eliminated::
2072
2073
sage: (x^2 + y^2 + z^2).mod( (x - y, y - z) )
2074
3*z^2
2075
sage: f = (x^2 + y^2 + z^2)^2; f
2076
x^4 + 2*x^2*y^2 + y^4 + 2*x^2*z^2 + 2*y^2*z^2 + z^4
2077
sage: f.mod( (x - y, y - z) )
2078
9*z^4
2079
2080
In this example `y` is eliminated::
2081
2082
sage: (x^2 + y^2 + z^2).mod( (x^3, y - z) )
2083
x^2 + 2*z^2
2084
"""
2085
from sage.rings.ideal import is_Ideal
2086
if not is_Ideal(I) or not I.ring() is self._parent:
2087
I = self._parent.ideal(I)
2088
#raise TypeError, "I = %s must be an ideal in %s"%(I, self.parent())
2089
return I.reduce(self)
2090
2091
##################################################
2092
# square roots
2093
##################################################
2094
2095
def is_square(self, root=False):
2096
"""
2097
Returns whether or not ring element is a square. If the optional
2098
argument root is True, then also returns the square root (or None,
2099
if the it is not a square).
2100
2101
INPUT:
2102
2103
2104
- ``root`` - whether or not to also return a square
2105
root (default: False)
2106
2107
2108
OUTPUT:
2109
2110
2111
- ``bool`` - whether or not a square
2112
2113
- ``object`` - (optional) an actual square root if
2114
found, and None otherwise.
2115
2116
2117
EXAMPLES::
2118
2119
sage: R.<x> = PolynomialRing(QQ)
2120
sage: f = 12*(x+1)^2 * (x+3)^2
2121
sage: f.is_square()
2122
False
2123
sage: f.is_square(root=True)
2124
(False, None)
2125
sage: h = f/3
2126
sage: h.is_square()
2127
True
2128
sage: h.is_square(root=True)
2129
(True, 2*x^2 + 8*x + 6)
2130
2131
.. NOTE:
2132
2133
This is the is_square implementation for general commutative ring
2134
elements. It's implementation is to raise a NotImplementedError.
2135
The function definition is here to show what functionality is expected and
2136
provide a general framework.
2137
"""
2138
raise NotImplementedError("is_square() not implemented for elements of %s" %self.parent())
2139
2140
2141
def sqrt(self, extend = True, all = False, name=None ):
2142
"""
2143
It computes the square root.
2144
2145
INPUT:
2146
2147
- ``extend`` - Whether to make a ring extension containing a square root if self is not a square (default: True)
2148
2149
- ``all`` - Whether to return a list of all square roots or just a square root (default: False)
2150
2151
- ``name`` - Required when extend=True and self is not a square. This will be the name of the generator extension.
2152
2153
OUTPUT:
2154
2155
- if all=False it returns a square root. (throws an error if extend=False and self is not a square)
2156
2157
- if all=True it returns a list of all the square roots (could be empty if extend=False and self is not a square)
2158
2159
ALGORITHM:
2160
2161
It uses is_square(root=true) for the hard part of the work, the rest is just wrapper code.
2162
2163
EXAMPLES::
2164
2165
sage: R.<x> = ZZ[]
2166
sage: (x^2).sqrt()
2167
x
2168
sage: f=x^2-4*x+4; f.sqrt(all=True)
2169
[x - 2, -x + 2]
2170
sage: sqrtx=x.sqrt(name="y"); sqrtx
2171
y
2172
sage: sqrtx^2
2173
x
2174
sage: x.sqrt(all=true,name="y")
2175
[y, -y]
2176
sage: x.sqrt(extend=False,all=True)
2177
[]
2178
sage: x.sqrt()
2179
Traceback (most recent call last):
2180
...
2181
TypeError: Polynomial is not a square. You must specify the name of the square root when using the default extend = True
2182
sage: x.sqrt(extend=False)
2183
Traceback (most recent call last):
2184
...
2185
ValueError: trying to take square root of non-square x with extend = False
2186
2187
TESTS::
2188
2189
sage: f = (x+3)^2; f.sqrt()
2190
x + 3
2191
sage: f = (x+3)^2; f.sqrt(all=True)
2192
[x + 3, -x - 3]
2193
sage: f = (x^2 - x + 3)^2; f.sqrt()
2194
x^2 - x + 3
2195
sage: f = (x^2 - x + 3)^6; f.sqrt()
2196
x^6 - 3*x^5 + 12*x^4 - 19*x^3 + 36*x^2 - 27*x + 27
2197
sage: g = (R.random_element(15))^2
2198
sage: g.sqrt()^2 == g
2199
True
2200
2201
sage: R.<x> = GF(250037)[]
2202
sage: f = x^2/(x+1)^2; f.sqrt()
2203
x/(x + 1)
2204
sage: f = 9 * x^4 / (x+1)^2; f.sqrt()
2205
3*x^2/(x + 1)
2206
sage: f = 9 * x^4 / (x+1)^2; f.sqrt(all=True)
2207
[3*x^2/(x + 1), 250034*x^2/(x + 1)]
2208
2209
sage: R.<x> = QQ[]
2210
sage: a = 2*(x+1)^2 / (2*(x-1)^2); a.sqrt()
2211
(2*x + 2)/(2*x - 2)
2212
sage: sqrtx=(1/x).sqrt(name="y"); sqrtx
2213
y
2214
sage: sqrtx^2
2215
1/x
2216
sage: (1/x).sqrt(all=true,name="y")
2217
[y, -y]
2218
sage: (1/x).sqrt(extend=False,all=True)
2219
[]
2220
sage: (1/(x^2-1)).sqrt()
2221
Traceback (most recent call last):
2222
...
2223
TypeError: Polynomial is not a square. You must specify the name of the square root when using the default extend = True
2224
sage: (1/(x^2-3)).sqrt(extend=False)
2225
Traceback (most recent call last):
2226
...
2227
ValueError: trying to take square root of non-square 1/(x^2 - 3) with extend = False
2228
2229
"""
2230
#This code is very general, it works for all integral domains that have the
2231
#is_square(root = True) option
2232
2233
from sage.rings.integral_domain import is_IntegralDomain
2234
P=self._parent
2235
is_sqr, sq_rt = self.is_square( root = True )
2236
if is_sqr:
2237
if all:
2238
if not is_IntegralDomain(P):
2239
raise NotImplementedError('sqrt() with all=True is only implemented for integral domains, not for %s' % P)
2240
if P.characteristic()==2 or sq_rt==0:
2241
#0 has only one square root, and in charasteristic 2 everything also has only 1 root
2242
return [ sq_rt ]
2243
return [ sq_rt, -sq_rt ]
2244
return sq_rt
2245
#from now on we know that self is not a square
2246
if not is_IntegralDomain(P):
2247
raise NotImplementedError('sqrt() of non squares is only implemented for integral domains, not for %s' % P)
2248
if not extend:
2249
#all square roots of a non-square should be an empty list
2250
if all:
2251
return []
2252
raise ValueError, 'trying to take square root of non-square %s with extend = False' % self
2253
2254
if name == None:
2255
raise TypeError ("Polynomial is not a square. You must specify the name of the square root when using the default extend = True")
2256
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
2257
PY = PolynomialRing(P,'y')
2258
y = PY.gen()
2259
sq_rt = PY.quotient(y**2-self, names = name)(y)
2260
if all:
2261
if P.characteristic() == 2:
2262
return [ sq_rt ]
2263
return [ sq_rt, -sq_rt ]
2264
return sq_rt
2265
2266
##############################################
2267
2268
cdef class Vector(ModuleElement):
2269
cdef bint is_sparse_c(self):
2270
raise NotImplementedError
2271
2272
cdef bint is_dense_c(self):
2273
raise NotImplementedError
2274
2275
def __imul__(left, right):
2276
if have_same_parent(left, right):
2277
return (<Vector>left)._dot_product_(<Vector>right)
2278
# Always do this
2279
global coercion_model
2280
return coercion_model.bin_op(left, right, imul)
2281
2282
2283
def __mul__(left, right):
2284
"""
2285
Multiplication of vector by vector, matrix, or scalar
2286
2287
AUTHOR:
2288
2289
- Gonzalo Tornaria (2007-06-21) - write test cases and fix them
2290
2291
.. note::
2292
2293
scalar * vector is implemented (and tested) in class RingElement
2294
matrix * vector is implemented (and tested) in class Matrix
2295
2296
TESTS:
2297
2298
Here we test (vector * vector) multiplication::
2299
2300
sage: x, y = var('x, y')
2301
2302
sage: parent(vector(ZZ,[1,2])*vector(ZZ,[1,2]))
2303
Integer Ring
2304
sage: parent(vector(ZZ,[1,2])*vector(QQ,[1,2]))
2305
Rational Field
2306
sage: parent(vector(QQ,[1,2])*vector(ZZ,[1,2]))
2307
Rational Field
2308
sage: parent(vector(QQ,[1,2])*vector(QQ,[1,2]))
2309
Rational Field
2310
2311
sage: parent(vector(QQ,[1,2,3,4])*vector(ZZ[x],[1,2,3,4]))
2312
Univariate Polynomial Ring in x over Rational Field
2313
sage: parent(vector(ZZ[x],[1,2,3,4])*vector(QQ,[1,2,3,4]))
2314
Univariate Polynomial Ring in x over Rational Field
2315
2316
sage: parent(vector(QQ,[1,2,3,4])*vector(ZZ[x][y],[1,2,3,4]))
2317
Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2318
sage: parent(vector(ZZ[x][y],[1,2,3,4])*vector(QQ,[1,2,3,4]))
2319
Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2320
2321
sage: parent(vector(QQ[x],[1,2,3,4])*vector(ZZ[x][y],[1,2,3,4]))
2322
Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2323
sage: parent(vector(ZZ[x][y],[1,2,3,4])*vector(QQ[x],[1,2,3,4]))
2324
Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2325
2326
sage: parent(vector(QQ[y],[1,2,3,4])*vector(ZZ[x][y],[1,2,3,4]))
2327
Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2328
sage: parent(vector(ZZ[x][y],[1,2,3,4])*vector(QQ[y],[1,2,3,4]))
2329
Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2330
2331
sage: parent(vector(ZZ[x],[1,2,3,4])*vector(ZZ[y],[1,2,3,4]))
2332
Traceback (most recent call last):
2333
...
2334
TypeError: unsupported operand parent(s) for '*': 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring'
2335
sage: parent(vector(ZZ[x],[1,2,3,4])*vector(QQ[y],[1,2,3,4]))
2336
Traceback (most recent call last):
2337
...
2338
TypeError: unsupported operand parent(s) for '*': 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field'
2339
sage: parent(vector(QQ[x],[1,2,3,4])*vector(ZZ[y],[1,2,3,4]))
2340
Traceback (most recent call last):
2341
...
2342
TypeError: unsupported operand parent(s) for '*': 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring'
2343
sage: parent(vector(QQ[x],[1,2,3,4])*vector(QQ[y],[1,2,3,4]))
2344
Traceback (most recent call last):
2345
...
2346
TypeError: unsupported operand parent(s) for '*': 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field'
2347
2348
Here we test (vector * matrix) multiplication::
2349
2350
sage: parent(vector(ZZ,[1,2])*matrix(ZZ,2,2,[1,2,3,4]))
2351
Ambient free module of rank 2 over the principal ideal domain Integer Ring
2352
sage: parent(vector(QQ,[1,2])*matrix(ZZ,2,2,[1,2,3,4]))
2353
Vector space of dimension 2 over Rational Field
2354
sage: parent(vector(ZZ,[1,2])*matrix(QQ,2,2,[1,2,3,4]))
2355
Vector space of dimension 2 over Rational Field
2356
sage: parent(vector(QQ,[1,2])*matrix(QQ,2,2,[1,2,3,4]))
2357
Vector space of dimension 2 over Rational Field
2358
2359
sage: parent(vector(QQ,[1,2])*matrix(ZZ[x],2,2,[1,2,3,4]))
2360
Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field
2361
sage: parent(vector(ZZ[x],[1,2])*matrix(QQ,2,2,[1,2,3,4]))
2362
Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field
2363
2364
sage: parent(vector(QQ,[1,2])*matrix(ZZ[x][y],2,2,[1,2,3,4]))
2365
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2366
sage: parent(vector(ZZ[x][y],[1,2])*matrix(QQ,2,2,[1,2,3,4]))
2367
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2368
2369
sage: parent(vector(QQ[x],[1,2])*matrix(ZZ[x][y],2,2,[1,2,3,4]))
2370
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2371
sage: parent(vector(ZZ[x][y],[1,2])*matrix(QQ[x],2,2,[1,2,3,4]))
2372
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2373
2374
sage: parent(vector(QQ[y],[1,2])*matrix(ZZ[x][y],2,2,[1,2,3,4]))
2375
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2376
sage: parent(vector(ZZ[x][y],[1,2])*matrix(QQ[y],2,2,[1,2,3,4]))
2377
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2378
2379
sage: parent(vector(ZZ[x],[1,2])*matrix(ZZ[y],2,2,[1,2,3,4]))
2380
Traceback (most recent call last):
2381
...
2382
TypeError: unsupported operand parent(s) for '*': 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring'
2383
sage: parent(vector(ZZ[x],[1,2])*matrix(QQ[y],2,2,[1,2,3,4]))
2384
Traceback (most recent call last):
2385
...
2386
TypeError: unsupported operand parent(s) for '*': 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field'
2387
sage: parent(vector(QQ[x],[1,2])*matrix(ZZ[y],2,2,[1,2,3,4]))
2388
Traceback (most recent call last):
2389
...
2390
TypeError: unsupported operand parent(s) for '*': 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring'
2391
sage: parent(vector(QQ[x],[1,2])*matrix(QQ[y],2,2,[1,2,3,4]))
2392
Traceback (most recent call last):
2393
...
2394
TypeError: unsupported operand parent(s) for '*': 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field'
2395
2396
Here we test (vector * scalar) multiplication::
2397
2398
sage: parent(vector(ZZ,[1,2])*ZZ(1))
2399
Ambient free module of rank 2 over the principal ideal domain Integer Ring
2400
sage: parent(vector(QQ,[1,2])*ZZ(1))
2401
Vector space of dimension 2 over Rational Field
2402
sage: parent(vector(ZZ,[1,2])*QQ(1))
2403
Vector space of dimension 2 over Rational Field
2404
sage: parent(vector(QQ,[1,2])*QQ(1))
2405
Vector space of dimension 2 over Rational Field
2406
2407
sage: parent(vector(QQ,[1,2])*ZZ[x](1))
2408
Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field
2409
sage: parent(vector(ZZ[x],[1,2])*QQ(1))
2410
Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field
2411
2412
sage: parent(vector(QQ,[1,2])*ZZ[x][y](1))
2413
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2414
sage: parent(vector(ZZ[x][y],[1,2])*QQ(1))
2415
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2416
2417
sage: parent(vector(QQ[x],[1,2])*ZZ[x][y](1))
2418
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2419
sage: parent(vector(ZZ[x][y],[1,2])*QQ[x](1))
2420
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2421
2422
sage: parent(vector(QQ[y],[1,2])*ZZ[x][y](1))
2423
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2424
sage: parent(vector(ZZ[x][y],[1,2])*QQ[y](1))
2425
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2426
2427
sage: parent(vector(ZZ[x],[1,2])*ZZ[y](1))
2428
Traceback (most recent call last):
2429
...
2430
TypeError: unsupported operand parent(s) for '*': 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Integer Ring'
2431
sage: parent(vector(ZZ[x],[1,2])*QQ[y](1))
2432
Traceback (most recent call last):
2433
...
2434
TypeError: unsupported operand parent(s) for '*': 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Rational Field'
2435
sage: parent(vector(QQ[x],[1,2])*ZZ[y](1))
2436
Traceback (most recent call last):
2437
...
2438
TypeError: unsupported operand parent(s) for '*': 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Integer Ring'
2439
sage: parent(vector(QQ[x],[1,2])*QQ[y](1))
2440
Traceback (most recent call last):
2441
...
2442
TypeError: unsupported operand parent(s) for '*': 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Rational Field'
2443
2444
"""
2445
if have_same_parent(left, right):
2446
return (<Vector>left)._dot_product_(<Vector>right)
2447
# Always do this
2448
global coercion_model
2449
return coercion_model.bin_op(left, right, mul)
2450
2451
cpdef Element _dot_product_(Vector left, Vector right):
2452
raise TypeError, arith_error_message(left, right, mul)
2453
2454
cpdef Vector _pairwise_product_(Vector left, Vector right):
2455
raise TypeError, "unsupported operation for '%s' and '%s'"%(parent_c(left), parent_c(right))
2456
2457
def __div__(self, right):
2458
if PY_IS_NUMERIC(right):
2459
right = py_scalar_to_element(right)
2460
if PY_TYPE_CHECK(right, RingElement):
2461
# Let __mul__ do the job
2462
return self.__mul__(~right)
2463
if PY_TYPE_CHECK(right, Vector):
2464
try:
2465
W = right.parent().submodule([right])
2466
return W.coordinates(self)[0] / W.coordinates(right)[0]
2467
except ArithmeticError:
2468
if right.is_zero():
2469
raise ZeroDivisionError, "division by zero vector"
2470
else:
2471
raise ArithmeticError, "vector is not in free module"
2472
raise TypeError, arith_error_message(self, right, div)
2473
2474
def _magma_init_(self, magma):
2475
"""
2476
Return string that evaluates in Magma to something equivalent
2477
to this vector.
2478
2479
EXAMPLES::
2480
2481
sage: v = vector([1,2,3])
2482
sage: v._magma_init_(magma) # optional - magma
2483
'_sage_[...]![1,2,3]'
2484
sage: mv = magma(v); mv # optional - magma
2485
(1 2 3)
2486
sage: mv.Type() # optional - magma
2487
ModTupRngElt
2488
sage: mv.Parent() # optional - magma
2489
Full RSpace of degree 3 over Integer Ring
2490
2491
sage: v = vector(QQ, [1/2, 3/4, 5/6])
2492
sage: mv = magma(v); mv # optional - magma
2493
(1/2 3/4 5/6)
2494
sage: mv.Type() # optional - magma
2495
ModTupFldElt
2496
sage: mv.Parent() # optional - magma
2497
Full Vector space of degree 3 over Rational Field
2498
2499
A more demanding example::
2500
2501
sage: R.<x,y,z> = QQ[]
2502
sage: v = vector([x^3, y, 2/3*z + x/y])
2503
sage: magma(v) # optional - magma
2504
( x^3 y (2/3*y*z + x)/y)
2505
sage: magma(v).Parent() # optional - magma
2506
Full Vector space of degree 3 over Multivariate rational function field of rank 3 over Rational Field
2507
"""
2508
V = magma(self._parent)
2509
v = [x._magma_init_(magma) for x in self.list()]
2510
return '%s![%s]'%(V.name(), ','.join(v))
2511
2512
def is_Vector(x):
2513
return IS_INSTANCE(x, Vector)
2514
2515
cdef class Matrix(AlgebraElement):
2516
2517
cdef bint is_sparse_c(self):
2518
raise NotImplementedError
2519
2520
cdef bint is_dense_c(self):
2521
raise NotImplementedError
2522
2523
def __imul__(left, right):
2524
if have_same_parent(left, right):
2525
return (<Matrix>left)._matrix_times_matrix_(<Matrix>right)
2526
else:
2527
global coercion_model
2528
return coercion_model.bin_op(left, right, imul)
2529
2530
cpdef RingElement _mul_(left, RingElement right):
2531
"""
2532
TESTS::
2533
2534
sage: m = matrix
2535
sage: a = m([[m([[1,2],[3,4]]),m([[5,6],[7,8]])],[m([[9,10],[11,12]]),m([[13,14],[15,16]])]])
2536
sage: 3*a
2537
[[ 3 6]
2538
[ 9 12] [15 18]
2539
[21 24]]
2540
[[27 30]
2541
[33 36] [39 42]
2542
[45 48]]
2543
2544
sage: m = matrix
2545
sage: a = m([[m([[1,2],[3,4]]),m([[5,6],[7,8]])],[m([[9,10],[11,12]]),m([[13,14],[15,16]])]])
2546
sage: a*3
2547
[[ 3 6]
2548
[ 9 12] [15 18]
2549
[21 24]]
2550
[[27 30]
2551
[33 36] [39 42]
2552
[45 48]]
2553
"""
2554
if have_same_parent(left, right):
2555
return (<Matrix>left)._matrix_times_matrix_(<Matrix>right)
2556
else:
2557
global coercion_model
2558
return coercion_model.bin_op(left, right, mul)
2559
2560
def __mul__(left, right):
2561
"""
2562
Multiplication of matrix by matrix, vector, or scalar
2563
2564
AUTHOR:
2565
2566
- Gonzalo Tornaria (2007-06-25) - write test cases and fix them
2567
2568
.. note::
2569
2570
scalar * matrix is implemented (and tested) in class RingElement
2571
vector * matrix is implemented (and tested) in class Vector
2572
2573
TESTS:
2574
2575
Here we test (matrix * matrix) multiplication::
2576
2577
sage: x, y = var('x, y')
2578
2579
sage: parent(matrix(ZZ,2,2,[1,2,3,4])*matrix(ZZ,2,2,[1,2,3,4]))
2580
Full MatrixSpace of 2 by 2 dense matrices over Integer Ring
2581
sage: parent(matrix(QQ,2,2,[1,2,3,4])*matrix(ZZ,2,2,[1,2,3,4]))
2582
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
2583
sage: parent(matrix(ZZ,2,2,[1,2,3,4])*matrix(QQ,2,2,[1,2,3,4]))
2584
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
2585
sage: parent(matrix(QQ,2,2,[1,2,3,4])*matrix(QQ,2,2,[1,2,3,4]))
2586
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
2587
2588
sage: parent(matrix(QQ,2,2,[1,2,3,4])*matrix(ZZ[x],2,2,[1,2,3,4]))
2589
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field
2590
sage: parent(matrix(ZZ[x],2,2,[1,2,3,4])*matrix(QQ,2,2,[1,2,3,4]))
2591
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field
2592
2593
sage: parent(matrix(QQ,2,2,[1,2,3,4])*matrix(ZZ[x][y],2,2,[1,2,3,4]))
2594
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2595
sage: parent(matrix(ZZ[x][y],2,2,[1,2,3,4])*matrix(QQ,2,2,[1,2,3,4]))
2596
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2597
2598
sage: parent(matrix(QQ[x],2,2,[1,2,3,4])*matrix(ZZ[x][y],2,2,[1,2,3,4]))
2599
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2600
sage: parent(matrix(ZZ[x][y],2,2,[1,2,3,4])*matrix(QQ[x],2,2,[1,2,3,4]))
2601
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2602
2603
sage: parent(matrix(QQ[y],2,2,[1,2,3,4])*matrix(ZZ[x][y],2,2,[1,2,3,4]))
2604
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2605
sage: parent(matrix(ZZ[x][y],2,2,[1,2,3,4])*matrix(QQ[y],2,2,[1,2,3,4]))
2606
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2607
2608
sage: parent(matrix(ZZ[x],2,2,[1,2,3,4])*matrix(ZZ[y],2,2,[1,2,3,4]))
2609
Traceback (most recent call last):
2610
...
2611
TypeError: unsupported operand parent(s) for '*': 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring'
2612
sage: parent(matrix(ZZ[x],2,2,[1,2,3,4])*matrix(QQ[y],2,2,[1,2,3,4]))
2613
Traceback (most recent call last):
2614
...
2615
TypeError: unsupported operand parent(s) for '*': 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field'
2616
sage: parent(matrix(QQ[x],2,2,[1,2,3,4])*matrix(ZZ[y],2,2,[1,2,3,4]))
2617
Traceback (most recent call last):
2618
...
2619
TypeError: unsupported operand parent(s) for '*': 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring'
2620
sage: parent(matrix(QQ[x],2,2,[1,2,3,4])*matrix(QQ[y],2,2,[1,2,3,4]))
2621
Traceback (most recent call last):
2622
...
2623
TypeError: unsupported operand parent(s) for '*': 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field'
2624
2625
Here we test (matrix * vector) multiplication::
2626
2627
sage: parent(matrix(ZZ,2,2,[1,2,3,4])*vector(ZZ,[1,2]))
2628
Ambient free module of rank 2 over the principal ideal domain Integer Ring
2629
sage: parent(matrix(QQ,2,2,[1,2,3,4])*vector(ZZ,[1,2]))
2630
Vector space of dimension 2 over Rational Field
2631
sage: parent(matrix(ZZ,2,2,[1,2,3,4])*vector(QQ,[1,2]))
2632
Vector space of dimension 2 over Rational Field
2633
sage: parent(matrix(QQ,2,2,[1,2,3,4])*vector(QQ,[1,2]))
2634
Vector space of dimension 2 over Rational Field
2635
2636
sage: parent(matrix(QQ,2,2,[1,2,3,4])*vector(ZZ[x],[1,2]))
2637
Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field
2638
sage: parent(matrix(ZZ[x],2,2,[1,2,3,4])*vector(QQ,[1,2]))
2639
Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field
2640
2641
sage: parent(matrix(QQ,2,2,[1,2,3,4])*vector(ZZ[x][y],[1,2]))
2642
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2643
sage: parent(matrix(ZZ[x][y],2,2,[1,2,3,4])*vector(QQ,[1,2]))
2644
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2645
2646
sage: parent(matrix(QQ[x],2,2,[1,2,3,4])*vector(ZZ[x][y],[1,2]))
2647
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2648
sage: parent(matrix(ZZ[x][y],2,2,[1,2,3,4])*vector(QQ[x],[1,2]))
2649
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2650
2651
sage: parent(matrix(QQ[y],2,2,[1,2,3,4])*vector(ZZ[x][y],[1,2]))
2652
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2653
sage: parent(matrix(ZZ[x][y],2,2,[1,2,3,4])*vector(QQ[y],[1,2]))
2654
Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2655
2656
sage: parent(matrix(ZZ[x],2,2,[1,2,3,4])*vector(ZZ[y],[1,2]))
2657
Traceback (most recent call last):
2658
...
2659
TypeError: unsupported operand parent(s) for '*': 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring'
2660
sage: parent(matrix(ZZ[x],2,2,[1,2,3,4])*vector(QQ[y],[1,2]))
2661
Traceback (most recent call last):
2662
...
2663
TypeError: unsupported operand parent(s) for '*': 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field'
2664
sage: parent(matrix(QQ[x],2,2,[1,2,3,4])*vector(ZZ[y],[1,2]))
2665
Traceback (most recent call last):
2666
...
2667
TypeError: unsupported operand parent(s) for '*': 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring'
2668
sage: parent(matrix(QQ[x],2,2,[1,2,3,4])*vector(QQ[y],[1,2]))
2669
Traceback (most recent call last):
2670
...
2671
TypeError: unsupported operand parent(s) for '*': 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field'
2672
2673
Here we test (matrix * scalar) multiplication::
2674
2675
sage: parent(matrix(ZZ,2,2,[1,2,3,4])*ZZ(1))
2676
Full MatrixSpace of 2 by 2 dense matrices over Integer Ring
2677
sage: parent(matrix(QQ,2,2,[1,2,3,4])*ZZ(1))
2678
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
2679
sage: parent(matrix(ZZ,2,2,[1,2,3,4])*QQ(1))
2680
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
2681
sage: parent(matrix(QQ,2,2,[1,2,3,4])*QQ(1))
2682
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
2683
2684
sage: parent(matrix(QQ,2,2,[1,2,3,4])*ZZ[x](1))
2685
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field
2686
sage: parent(matrix(ZZ[x],2,2,[1,2,3,4])*QQ(1))
2687
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field
2688
2689
sage: parent(matrix(QQ,2,2,[1,2,3,4])*ZZ[x][y](1))
2690
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2691
sage: parent(matrix(ZZ[x][y],2,2,[1,2,3,4])*QQ(1))
2692
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2693
2694
sage: parent(matrix(QQ[x],2,2,[1,2,3,4])*ZZ[x][y](1))
2695
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2696
sage: parent(matrix(ZZ[x][y],2,2,[1,2,3,4])*QQ[x](1))
2697
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2698
2699
sage: parent(matrix(QQ[y],2,2,[1,2,3,4])*ZZ[x][y](1))
2700
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2701
sage: parent(matrix(ZZ[x][y],2,2,[1,2,3,4])*QQ[y](1))
2702
Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
2703
2704
sage: parent(matrix(ZZ[x],2,2,[1,2,3,4])*ZZ[y](1))
2705
Traceback (most recent call last):
2706
...
2707
TypeError: unsupported operand parent(s) for '*': 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Integer Ring'
2708
sage: parent(matrix(ZZ[x],2,2,[1,2,3,4])*QQ[y](1))
2709
Traceback (most recent call last):
2710
...
2711
TypeError: unsupported operand parent(s) for '*': 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Rational Field'
2712
sage: parent(matrix(QQ[x],2,2,[1,2,3,4])*ZZ[y](1))
2713
Traceback (most recent call last):
2714
...
2715
TypeError: unsupported operand parent(s) for '*': 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Integer Ring'
2716
sage: parent(matrix(QQ[x],2,2,[1,2,3,4])*QQ[y](1))
2717
Traceback (most recent call last):
2718
...
2719
TypeError: unsupported operand parent(s) for '*': 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Rational Field'
2720
2721
"""
2722
if have_same_parent(left, right):
2723
return (<Matrix>left)._matrix_times_matrix_(<Matrix>right)
2724
else:
2725
global coercion_model
2726
return coercion_model.bin_op(left, right, mul)
2727
2728
cdef Vector _vector_times_matrix_(matrix_right, Vector vector_left):
2729
raise TypeError
2730
2731
cdef Vector _matrix_times_vector_(matrix_left, Vector vector_right):
2732
raise TypeError
2733
2734
cdef Matrix _matrix_times_matrix_(left, Matrix right):
2735
raise TypeError
2736
2737
2738
2739
def is_Matrix(x):
2740
return IS_INSTANCE(x, Matrix)
2741
2742
def is_IntegralDomainElement(x):
2743
"""
2744
Return True if x is of type IntegralDomainElement.
2745
"""
2746
return IS_INSTANCE(x, IntegralDomainElement)
2747
2748
cdef class IntegralDomainElement(CommutativeRingElement):
2749
def is_nilpotent(self):
2750
return self.is_zero()
2751
2752
2753
def is_DedekindDomainElement(x):
2754
"""
2755
Return True if x is of type DedekindDomainElement.
2756
"""
2757
return IS_INSTANCE(x, DedekindDomainElement)
2758
2759
cdef class DedekindDomainElement(IntegralDomainElement):
2760
pass
2761
2762
def is_PrincipalIdealDomainElement(x):
2763
"""
2764
Return True if x is of type PrincipalIdealDomainElement.
2765
"""
2766
return IS_INSTANCE(x, PrincipalIdealDomainElement)
2767
2768
cdef class PrincipalIdealDomainElement(DedekindDomainElement):
2769
def lcm(self, right):
2770
"""
2771
Returns the least common multiple of self and right.
2772
"""
2773
if not PY_TYPE_CHECK(right, Element) or not ((<Element>right)._parent is self._parent):
2774
return coercion_model.bin_op(self, right, lcm)
2775
return self._lcm(right)
2776
2777
# This is pretty nasty low level stuff. The idea is to speed up construction
2778
# of EuclideanDomainElements (in particular Integers) by skipping some tp_new
2779
# calls up the inheritance tree.
2780
PY_SET_TP_NEW(EuclideanDomainElement, Element)
2781
2782
def is_EuclideanDomainElement(x):
2783
"""
2784
Return True if x is of type EuclideanDomainElement.
2785
"""
2786
return IS_INSTANCE(x, EuclideanDomainElement)
2787
2788
cdef class EuclideanDomainElement(PrincipalIdealDomainElement):
2789
2790
def degree(self):
2791
raise NotImplementedError
2792
2793
def leading_coefficient(self):
2794
raise NotImplementedError
2795
2796
def quo_rem(self, other):
2797
raise NotImplementedError
2798
2799
def __divmod__(self, other):
2800
"""
2801
Return the quotient and remainder of self divided by other.
2802
2803
EXAMPLES::
2804
2805
sage: divmod(5,3)
2806
(1, 2)
2807
sage: divmod(25r,12)
2808
(2, 1)
2809
sage: divmod(25,12r)
2810
(2, 1)
2811
2812
"""
2813
if PY_TYPE_CHECK(self, Element):
2814
return self.quo_rem(other)
2815
else:
2816
x, y = canonical_coercion(self, other)
2817
return x.quo_rem(y)
2818
2819
def __floordiv__(self,right):
2820
"""
2821
Quotient of division of self by other. This is denoted //.
2822
"""
2823
Q, _ = self.quo_rem(right)
2824
return Q
2825
2826
def __mod__(self, other):
2827
"""
2828
Remainder of division of self by other.
2829
2830
EXAMPLES::
2831
2832
sage: R.<x> = ZZ[]
2833
sage: x % (x+1)
2834
-1
2835
sage: (x**3 + x - 1) % (x**2 - 1)
2836
2*x - 1
2837
"""
2838
_, R = self.quo_rem(other)
2839
return R
2840
2841
def is_FieldElement(x):
2842
"""
2843
Return True if x is of type FieldElement.
2844
"""
2845
return IS_INSTANCE(x, FieldElement)
2846
2847
cdef class FieldElement(CommutativeRingElement):
2848
2849
def __floordiv__(self, other):
2850
return self / other
2851
2852
def is_unit(self):
2853
"""
2854
Return True if self is a unit in its parent ring.
2855
2856
EXAMPLES::
2857
2858
sage: a = 2/3; a.is_unit()
2859
True
2860
2861
On the other hand, 2 is not a unit, since its parent is ZZ.
2862
2863
::
2864
2865
sage: a = 2; a.is_unit()
2866
False
2867
sage: parent(a)
2868
Integer Ring
2869
2870
However, a is a unit when viewed as an element of QQ::
2871
2872
sage: a = QQ(2); a.is_unit()
2873
True
2874
"""
2875
return not not self
2876
2877
def _lcm(self, FieldElement other):
2878
"""
2879
Return the least common multiple of self and other.
2880
"""
2881
if self.is_zero() and other.is_zero():
2882
return self
2883
else:
2884
return self._parent(1)
2885
2886
def quo_rem(self, right):
2887
r"""
2888
Return the quotient and remainder obtained by dividing `self` by
2889
`other`. Since this element lives in a field, the remainder is always
2890
zero and the quotient is `self/right`.
2891
2892
TESTS:
2893
2894
Test if #8671 is fixed::
2895
2896
sage: R.<x,y> = QQ[]
2897
sage: S.<a,b> = R.quo(y^2 + 1)
2898
sage: S.is_field = lambda : False
2899
sage: F = Frac(S); u = F.one_element()
2900
sage: u.quo_rem(u)
2901
(1, 0)
2902
"""
2903
if not isinstance(right, FieldElement) or not (parent(right) is self._parent):
2904
right = self.parent()(right)
2905
return self/right, 0
2906
2907
def divides(self, FieldElement other):
2908
r"""
2909
Check whether self divides other, for field elements.
2910
2911
Since this is a field, all values divide all other values,
2912
except that zero does not divide any non-zero values.
2913
2914
EXAMPLES::
2915
2916
sage: K.<rt3> = QQ[sqrt(3)]
2917
sage: K(0).divides(rt3)
2918
False
2919
sage: rt3.divides(K(17))
2920
True
2921
sage: K(0).divides(K(0))
2922
True
2923
sage: rt3.divides(K(0))
2924
True
2925
"""
2926
if not (other._parent is self._parent):
2927
other = self.parent()(other)
2928
return bool(self) or other.is_zero()
2929
2930
def is_AlgebraElement(x):
2931
"""
2932
Return True if x is of type AlgebraElement.
2933
"""
2934
return IS_INSTANCE(x, AlgebraElement)
2935
2936
cdef class AlgebraElement(RingElement):
2937
pass
2938
2939
def is_CommutativeAlgebraElement(x):
2940
"""
2941
Return True if x is of type CommutativeAlgebraElement.
2942
"""
2943
return IS_INSTANCE(x, CommutativeAlgebraElement)
2944
2945
cdef class CommutativeAlgebraElement(CommutativeRingElement):
2946
pass
2947
2948
def is_InfinityElement(x):
2949
"""
2950
Return True if x is of type InfinityElement.
2951
"""
2952
return IS_INSTANCE(x, InfinityElement)
2953
2954
cdef class InfinityElement(RingElement):
2955
def __invert__(self):
2956
from sage.rings.all import ZZ
2957
return ZZ(0)
2958
2959
cdef class PlusInfinityElement(InfinityElement):
2960
pass
2961
2962
cdef class MinusInfinityElement(InfinityElement):
2963
pass
2964
2965
include "coerce.pxi"
2966
2967
2968
#################################################################################
2969
#
2970
# Coercion of elements
2971
#
2972
#################################################################################
2973
2974
cpdef canonical_coercion(x, y):
2975
"""
2976
canonical_coercion(x,y) is what is called before doing an
2977
arithmetic operation between x and y. It returns a pair (z,w)
2978
such that z is got from x and w from y via canonical coercion and
2979
the parents of z and w are identical.
2980
2981
EXAMPLES::
2982
2983
sage: A = Matrix([[0,1],[1,0]])
2984
sage: canonical_coercion(A,1)
2985
(
2986
[0 1] [1 0]
2987
[1 0], [0 1]
2988
)
2989
"""
2990
global coercion_model
2991
return coercion_model.canonical_coercion(x,y)
2992
2993
cpdef bin_op(x, y, op):
2994
global coercion_model
2995
return coercion_model.bin_op(x,y,op)
2996
2997
2998
def coerce(Parent p, x):
2999
try:
3000
return p._coerce_c(x)
3001
except AttributeError:
3002
return p(x)
3003
3004
def coerce_cmp(x,y):
3005
global coercion_model
3006
cdef int c
3007
try:
3008
x, y = coercion_model.canonical_coercion(x, y)
3009
return cmp(x,y)
3010
except TypeError:
3011
c = cmp(type(x), type(y))
3012
if c == 0: c = -1
3013
return c
3014
3015
# We define this base class here to avoid circular cimports.
3016
cdef class CoercionModel:
3017
"""
3018
Most basic coercion scheme. If it doesn't already match, throw an error.
3019
"""
3020
cpdef canonical_coercion(self, x, y):
3021
if parent_c(x) is parent_c(y):
3022
return x,y
3023
raise TypeError, "no common canonical parent for objects with parents: '%s' and '%s'"%(parent_c(x), parent_c(y))
3024
3025
cpdef bin_op(self, x, y, op):
3026
if parent_c(x) is parent_c(y):
3027
return op(x,y)
3028
raise TypeError, arith_error_message(x,y,op)
3029
3030
import coerce
3031
cdef CoercionModel coercion_model = coerce.CoercionModel_cache_maps()
3032
3033
def get_coercion_model():
3034
"""
3035
Return the global coercion model.
3036
3037
EXAMPLES::
3038
3039
sage: import sage.structure.element as e
3040
sage: cm = e.get_coercion_model()
3041
sage: cm
3042
<sage.structure.coerce.CoercionModel_cache_maps object at ...>
3043
"""
3044
return coercion_model
3045
3046
def set_coercion_model(cm):
3047
global coercion_model
3048
coercion_model = cm
3049
3050
def coercion_traceback(dump=True):
3051
r"""
3052
This function is very helpful in debugging coercion errors. It prints
3053
the tracebacks of all the errors caught in the coercion detection. Note
3054
that failure is cached, so some errors may be omitted the second time
3055
around (as it remembers not to retry failed paths for speed reasons.
3056
3057
For performance and caching reasons, exception recording must be
3058
explicitly enabled before using this function.
3059
3060
EXAMPLES::
3061
3062
sage: cm = sage.structure.element.get_coercion_model()
3063
sage: cm.record_exceptions()
3064
sage: 1 + 1/5
3065
6/5
3066
sage: coercion_traceback() # Should be empty, as all went well.
3067
sage: 1/5 + GF(5).gen()
3068
Traceback (most recent call last):
3069
...
3070
TypeError: unsupported operand parent(s) for '+': 'Rational Field' and 'Finite Field of size 5'
3071
sage: coercion_traceback()
3072
Traceback (most recent call last):
3073
...
3074
TypeError: no common canonical parent for objects with parents: 'Rational Field' and 'Finite Field of size 5'
3075
"""
3076
if dump:
3077
for traceback in coercion_model.exception_stack():
3078
print traceback
3079
else:
3080
return coercion_model.exception_stack()
3081
3082
3083
cdef class NamedBinopMethod:
3084
"""
3085
A decorator to be used on binary operation methods that should operate
3086
on elements of the same parent. If the parents of the arguments differ,
3087
coercion is performed, then the method is re-looked up by name on the
3088
first argument.
3089
3090
In short, using the ``NamedBinopMethod`` (alias ``coerce_binop``) decorator
3091
on a method gives it the exact same semantics of the basic arithmetic
3092
operations like ``_add_``, ``_sub_``, etc. in that both operands are
3093
guaranteed to have exactly the same parent.
3094
"""
3095
cdef _self
3096
cdef _func
3097
cdef _name
3098
3099
def __init__(self, func, name=None, obj=None):
3100
"""
3101
TESTS::
3102
3103
sage: from sage.structure.element import NamedBinopMethod
3104
sage: NamedBinopMethod(gcd)(12, 15)
3105
3
3106
"""
3107
self._func = func
3108
if name is None:
3109
if isinstance(func, types.FunctionType):
3110
name = func.func_name
3111
if isinstance(func, types.UnboundMethodType):
3112
name = func.im_func.func_name
3113
else:
3114
name = func.__name__
3115
self._name = name
3116
self._self = obj
3117
3118
def __call__(self, x, y=None, **kwds):
3119
"""
3120
TESTS::
3121
3122
sage: from sage.structure.element import NamedBinopMethod
3123
sage: test_func = NamedBinopMethod(lambda x, y, **kwds: (x, y, kwds), '_add_')
3124
sage: class test_class(Rational):
3125
....: def __init__(self,value):
3126
....: self.v = value
3127
....: @NamedBinopMethod
3128
....: def test_add(self, other, keyword='z'):
3129
....: return (self.v, other, keyword)
3130
3131
Calls func directly if the two arguments have the same parent::
3132
3133
sage: test_func(1, 2)
3134
(1, 2, {})
3135
sage: x = test_class(1)
3136
sage: x.test_add(1/2)
3137
(1, 1/2, 'z')
3138
sage: x.test_add(1/2, keyword=3)
3139
(1, 1/2, 3)
3140
3141
Passes through coercion and does a method lookup if the
3142
left operand is not the same::
3143
3144
sage: test_func(0.5, 1)
3145
(0.500000000000000, 1.00000000000000, {})
3146
sage: test_func(1, 2, algorithm='fast')
3147
(1, 2, {'algorithm': 'fast'})
3148
sage: test_func(1, 1/2)
3149
3/2
3150
sage: x.test_add(2)
3151
(1, 2, 'z')
3152
sage: x.test_add(2, keyword=3)
3153
(1, 2, 3)
3154
3155
A real example::
3156
3157
sage: R1=QQ['x,y']
3158
sage: R2=QQ['x,y,z']
3159
sage: f=R1(1)
3160
sage: g=R1(2)
3161
sage: h=R2(1)
3162
sage: f.gcd(g)
3163
1
3164
sage: f.gcd(g,algorithm='modular')
3165
1
3166
sage: f.gcd(h)
3167
1
3168
sage: f.gcd(h,algorithm='modular')
3169
1
3170
sage: h.gcd(f)
3171
1
3172
sage: h.gcd(f,algorithm='modular')
3173
1
3174
"""
3175
if y is None:
3176
if self._self is None:
3177
self._func(x, **kwds)
3178
else:
3179
x, y = self._self, x
3180
if not have_same_parent(x, y):
3181
old_x = x
3182
x,y = coercion_model.canonical_coercion(x, y)
3183
if old_x is x:
3184
return self._func(x,y, **kwds)
3185
else:
3186
return getattr(x, self._name)(y, **kwds)
3187
else:
3188
return self._func(x,y, **kwds)
3189
3190
def __get__(self, obj, objtype):
3191
"""
3192
Used to transform from an unbound to a bound method.
3193
3194
TESTS::
3195
sage: from sage.structure.element import NamedBinopMethod
3196
sage: R.<x> = ZZ[]
3197
sage: isinstance(x.quo_rem, NamedBinopMethod)
3198
True
3199
sage: x.quo_rem(x)
3200
(1, 0)
3201
sage: type(x).quo_rem(x,x)
3202
(1, 0)
3203
"""
3204
return NamedBinopMethod(self._func, self._name, obj)
3205
3206
def _sage_doc_(self):
3207
"""
3208
Return the docstring of the wrapped object for introspection.
3209
3210
EXAMPLES::
3211
3212
sage: from sage.structure.element import NamedBinopMethod
3213
sage: g = NamedBinopMethod(gcd)
3214
sage: from sage.misc.sageinspect import sage_getdoc
3215
sage: sage_getdoc(g) == sage_getdoc(gcd)
3216
True
3217
"""
3218
return sageinspect._sage_getdoc_unformatted(self._func)
3219
3220
def _sage_src_(self):
3221
"""
3222
Returns the source of the wrapped object for introspection.
3223
3224
EXAMPLES::
3225
3226
sage: from sage.structure.element import NamedBinopMethod
3227
sage: g = NamedBinopMethod(gcd)
3228
sage: 'def gcd(' in g._sage_src_()
3229
True
3230
"""
3231
return sageinspect.sage_getsource(self._func)
3232
3233
def _sage_argspec_(self):
3234
"""
3235
Returns the argspec of the wrapped object for introspection.
3236
3237
EXAMPLES::
3238
3239
sage: from sage.structure.element import NamedBinopMethod
3240
sage: g = NamedBinopMethod(gcd)
3241
sage: g._sage_argspec_()
3242
ArgSpec(args=['a', 'b'], varargs=None, keywords='kwargs', defaults=(None,))
3243
"""
3244
return sageinspect.sage_getargspec(self._func)
3245
3246
coerce_binop = NamedBinopMethod
3247
3248
###############################################################################
3249
3250
def lcm(x,y):
3251
from sage.rings.arith import lcm
3252
return lcm(x,y)
3253
3254
def gcd(x,y):
3255
from sage.rings.arith import gcd
3256
return gcd(x,y)
3257
3258
def xgcd(x,y):
3259
from sage.rings.arith import xgcd
3260
return xgcd(x,y)
3261
3262
3263
3264
3265
######################
3266
3267
def generic_power(a, n, one=None):
3268
"""
3269
Computes `a^n`, where `n` is an integer, and `a` is an object which
3270
supports multiplication. Optionally an additional argument,
3271
which is used in the case that n == 0:
3272
3273
- ``one`` - the "unit" element, returned directly (can be anything)
3274
3275
If this is not supplied, int(1) is returned.
3276
3277
EXAMPLES::
3278
3279
sage: from sage.structure.element import generic_power
3280
sage: generic_power(int(12),int(0))
3281
1
3282
sage: generic_power(int(0),int(100))
3283
0
3284
sage: generic_power(Integer(10),Integer(0))
3285
1
3286
sage: generic_power(Integer(0),Integer(23))
3287
0
3288
sage: sum([generic_power(2,i) for i in range(17)]) #test all 4-bit combinations
3289
131071
3290
sage: F = Zmod(5)
3291
sage: a = generic_power(F(2), 5); a
3292
2
3293
sage: a.parent() is F
3294
True
3295
sage: a = generic_power(F(1), 2)
3296
sage: a.parent() is F
3297
True
3298
3299
sage: generic_power(int(5), 0)
3300
1
3301
"""
3302
3303
return generic_power_c(a,n,one)
3304
3305
cdef generic_power_c(a, nn, one):
3306
try:
3307
n = PyNumber_Index(nn)
3308
except TypeError:
3309
try:
3310
# Try harder, since many things coerce to Integer.
3311
from sage.rings.integer import Integer
3312
n = int(Integer(nn))
3313
except TypeError:
3314
raise NotImplementedError, "non-integral exponents not supported"
3315
3316
if not n:
3317
if one is None:
3318
if PY_TYPE_CHECK(a, Element):
3319
return (<Element>a)._parent.one()
3320
try:
3321
try:
3322
return a.parent().one()
3323
except AttributeError:
3324
return type(a)(1)
3325
except Exception:
3326
return 1 #oops, the one sucks
3327
else:
3328
return one
3329
elif n < 0:
3330
# I don't think raising division by zero is really my job. It should
3331
# be the one of ~a. Moreover, this does not handle the case of monoids
3332
# with partially defined division (e.g. the multiplicative monoid of a
3333
# ring such as ZZ/12ZZ)
3334
# if not a:
3335
# raise ZeroDivisionError
3336
a = ~a
3337
n = -n
3338
3339
if n < 4:
3340
# These cases will probably be called often
3341
# and don't benefit from the code below
3342
if n == 1:
3343
return a
3344
elif n == 2:
3345
return a*a
3346
elif n == 3:
3347
return a*a*a
3348
3349
# check for idempotence, and store the result otherwise
3350
aa = a*a
3351
if aa == a:
3352
return a
3353
3354
# since we've computed a^2, let's start squaring there
3355
# so, let's keep the least-significant bit around, just
3356
# in case.
3357
m = n & 1
3358
n = n >> 1
3359
3360
# One multiplication can be saved by starting with
3361
# the second-smallest power needed rather than with 1
3362
# we've already squared a, so let's start there.
3363
apow = aa
3364
while n&1 == 0:
3365
apow = apow*apow
3366
n = n >> 1
3367
power = apow
3368
n = n >> 1
3369
3370
# now multiply that least-significant bit in...
3371
if m:
3372
power = power * a
3373
3374
# and this is straight from the book.
3375
while n != 0:
3376
apow = apow*apow
3377
if n&1 != 0:
3378
power = power*apow
3379
n = n >> 1
3380
3381
return power
3382
3383