Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/matrix/matrix0.pyx
4057 views
1
"""
2
Base class for matrices, part 0
3
4
.. note::
5
6
For design documentation see matrix/docs.py.
7
8
EXAMPLES::
9
10
sage: matrix(2,[1,2,3,4])
11
[1 2]
12
[3 4]
13
"""
14
15
################################################################################
16
# Copyright (C) 2005, 2006 William Stein <[email protected]>
17
#
18
# Distributed under the terms of the GNU General Public License (GPL).
19
# The full text of the GPL is available at:
20
#
21
# http://www.gnu.org/licenses/
22
################################################################################
23
24
include "../ext/stdsage.pxi"
25
include "../ext/cdefs.pxi"
26
include "../ext/python.pxi"
27
include "../ext/python_list.pxi"
28
include "../ext/python_object.pxi"
29
include "../ext/python_slice.pxi"
30
include "../ext/python_tuple.pxi"
31
32
import sage.modules.free_module
33
import sage.misc.latex
34
import sage.rings.integer
35
36
from sage.misc.misc import verbose, get_verbose
37
from sage.structure.sequence import Sequence
38
39
cimport sage.structure.element
40
from sage.structure.element cimport ModuleElement, Element, RingElement, Vector
41
from sage.structure.mutability cimport Mutability
42
from sage.misc.misc_c cimport normalize_index
43
44
from sage.rings.ring cimport CommutativeRing
45
from sage.rings.ring import is_Ring
46
from sage.rings.finite_rings.integer_mod_ring import is_IntegerModRing
47
48
import sage.modules.free_module
49
50
import matrix_misc
51
52
cdef extern from "Python.h":
53
bint PySlice_Check(PyObject* ob)
54
55
cdef class Matrix(sage.structure.element.Matrix):
56
r"""
57
A generic matrix.
58
59
The ``Matrix`` class is the base class for all matrix
60
classes. To create a ``Matrix``, first create a
61
``MatrixSpace``, then coerce a list of elements into
62
the ``MatrixSpace``. See the documentation of
63
``MatrixSpace`` for more details.
64
65
EXAMPLES:
66
67
We illustrate matrices and matrix spaces. Note that no actual
68
matrix that you make should have class Matrix; the class should
69
always be derived from Matrix.
70
71
::
72
73
sage: M = MatrixSpace(CDF,2,3); M
74
Full MatrixSpace of 2 by 3 dense matrices over Complex Double Field
75
sage: a = M([1,2,3, 4,5,6]); a
76
[1.0 2.0 3.0]
77
[4.0 5.0 6.0]
78
sage: type(a)
79
<type 'sage.matrix.matrix_complex_double_dense.Matrix_complex_double_dense'>
80
sage: parent(a)
81
Full MatrixSpace of 2 by 3 dense matrices over Complex Double Field
82
83
::
84
85
sage: matrix(CDF, 2,3, [1,2,3, 4,5,6])
86
[1.0 2.0 3.0]
87
[4.0 5.0 6.0]
88
sage: Mat(CDF,2,3)(range(1,7))
89
[1.0 2.0 3.0]
90
[4.0 5.0 6.0]
91
92
::
93
94
sage: Q.<i,j,k> = QuaternionAlgebra(QQ, -1,-1)
95
sage: matrix(Q,2,1,[1,2])
96
[1]
97
[2]
98
"""
99
def __init__(self, parent):
100
"""
101
EXAMPLES::
102
103
sage: import sage.matrix.matrix0
104
sage: A = sage.matrix.matrix0.Matrix(MatrixSpace(QQ,2))
105
sage: type(A)
106
<type 'sage.matrix.matrix0.Matrix'>
107
"""
108
self._parent = parent
109
self._base_ring = parent.base_ring()
110
self._nrows = parent.nrows()
111
self._ncols = parent.ncols()
112
self._mutability = Mutability(False)
113
self._cache = {}
114
115
def copy(self):
116
"""
117
Make a copy of self. If self is immutable, the copy will be
118
mutable.
119
120
.. warning::
121
122
This method is deprecated and will be removed from a future
123
version of Sage. Please use the ``copy()`` function
124
instead. In other words, instead of doing ``m.copy()``, do ``copy(m)``.
125
126
.. warning::
127
128
The individual elements aren't themselves copied (though
129
the list is copied). This shouldn't matter, since ring
130
elements are (almost!) always immutable in Sage.
131
132
EXAMPLES:
133
134
135
The :meth:`.copy` method is deprecated. Instead, use the
136
:func:`copy` function::
137
138
sage: a = matrix([[1,2],[3,4]])
139
sage: b = a.copy()
140
doctest:...: DeprecationWarning: the .copy() method is deprecated; please use the copy() function instead, for example, copy(M)
141
sage: b = copy(a)
142
143
::
144
145
sage: R.<x> = QQ['x']
146
sage: a = matrix(R,2,[x+1,2/3, x^2/2, 1+x^3]); a
147
[ x + 1 2/3]
148
[1/2*x^2 x^3 + 1]
149
sage: b = copy(a)
150
sage: b[0,0] = 5
151
sage: b
152
[ 5 2/3]
153
[1/2*x^2 x^3 + 1]
154
sage: a
155
[ x + 1 2/3]
156
[1/2*x^2 x^3 + 1]
157
158
::
159
160
sage: b = copy(a)
161
sage: f = b[0,0]; f[0] = 10
162
Traceback (most recent call last):
163
...
164
IndexError: polynomials are immutable
165
"""
166
import sage.misc.misc
167
sage.misc.misc.deprecation("the .copy() method is deprecated; please use the copy() function instead, for example, copy(M)")
168
return self.__copy__()
169
170
def list(self):
171
"""
172
List of the elements of self ordered by elements in each
173
row. It is safe to change the returned list.
174
175
.. warning::
176
177
This function returns a list of the entries in the matrix
178
self. It does not return a list of the rows of self, so it
179
is different than the output of list(self), which returns
180
``[self[0],self[1],...]``.
181
182
EXAMPLES::
183
184
sage: R.<x,y> = QQ[]
185
sage: a = matrix(R,2,[x,y,x*y, y,x,2*x+y]); a
186
[ x y x*y]
187
[ y x 2*x + y]
188
sage: v = a.list(); v
189
[x, y, x*y, y, x, 2*x + y]
190
191
Note that list(a) is different than a.list()::
192
193
sage: a.list()
194
[x, y, x*y, y, x, 2*x + y]
195
sage: list(a)
196
[(x, y, x*y), (y, x, 2*x + y)]
197
198
Notice that changing the returned list does not change a (the list
199
is a copy)::
200
201
sage: v[0] = 25
202
sage: a
203
[ x y x*y]
204
[ y x 2*x + y]
205
"""
206
return list(self._list())
207
208
def _list(self):
209
"""
210
Unsafe version of the list method, mainly for internal use. This
211
may return the list of elements, but as an *unsafe* reference to
212
the underlying list of the object. It is might be dangerous if you
213
change entries of the returned list.
214
215
EXAMPLES: Using _list is potentially fast and memory efficient,
216
but very dangerous (at least for generic dense matrices).
217
218
::
219
220
sage: a = matrix(QQ['x,y'],2,range(6)); a
221
[0 1 2]
222
[3 4 5]
223
sage: v = a._list(); v
224
[0, 1, 2, 3, 4, 5]
225
226
If you change an entry of the list, the corresponding entry of the
227
matrix will be changed (but without clearing any caches of
228
computing information about the matrix)::
229
230
sage: v[0] = -2/3; v
231
[-2/3, 1, 2, 3, 4, 5]
232
sage: a._list()
233
[-2/3, 1, 2, 3, 4, 5]
234
235
Now the 0,0 entry of the matrix is `-2/3`, which is weird.
236
237
::
238
239
sage: a[0,0]
240
-2/3
241
242
See::
243
244
sage: a
245
[-2/3 1 2]
246
[ 3 4 5]
247
"""
248
cdef Py_ssize_t i, j
249
250
x = self.fetch('list')
251
if not x is None:
252
return x
253
x = []
254
for i from 0 <= i < self._nrows:
255
for j from 0 <= j < self._ncols:
256
x.append(self.get_unsafe(i, j))
257
return x
258
259
def dict(self):
260
"""
261
Dictionary of the elements of self with keys pairs (i,j) and values
262
the nonzero entries of self.
263
264
It is safe to change the returned dictionary.
265
266
EXAMPLES::
267
268
sage: R.<x,y> = QQ[]
269
sage: a = matrix(R,2,[x,y,0, 0,0,2*x+y]); a
270
[ x y 0]
271
[ 0 0 2*x + y]
272
sage: d = a.dict(); d
273
{(0, 1): y, (1, 2): 2*x + y, (0, 0): x}
274
275
Notice that changing the returned list does not change a (the list
276
is a copy)::
277
278
sage: d[0,0] = 25
279
sage: a
280
[ x y 0]
281
[ 0 0 2*x + y]
282
"""
283
return dict(self._dict())
284
285
def _dict(self):
286
"""
287
Unsafe version of the dict method, mainly for internal use.
288
This may return the dict of elements, but as an *unsafe*
289
reference to the underlying dict of the object. It might
290
dangerous if you change entries of the returned dict.
291
292
EXAMPLES: Using _dict is potentially fast and memory efficient,
293
but very dangerous (at least for generic sparse matrices).
294
295
::
296
297
sage: a = matrix(QQ['x,y'],2,range(6), sparse=True); a
298
[0 1 2]
299
[3 4 5]
300
sage: v = a._dict(); v
301
{(0, 1): 1, (1, 2): 5, (1, 0): 3, (0, 2): 2, (1, 1): 4}
302
303
If you change a key of the dictionary, the corresponding entry of
304
the matrix will be changed (but without clearing any caches of
305
computing information about the matrix)::
306
307
sage: v[0,1] = -2/3; v
308
{(0, 1): -2/3, (1, 2): 5, (1, 0): 3, (0, 2): 2, (1, 1): 4}
309
sage: a._dict()
310
{(0, 1): -2/3, (1, 2): 5, (1, 0): 3, (0, 2): 2, (1, 1): 4}
311
sage: a[0,1]
312
-2/3
313
314
But the matrix doesn't know the entry changed, so it returns the
315
cached version of its print representation::
316
317
sage: a
318
[0 1 2]
319
[3 4 5]
320
321
If we change an entry, the cache is cleared, and the correct print
322
representation appears::
323
324
sage: a[1,2]=10
325
sage: a
326
[ 0 -2/3 2]
327
[ 3 4 10]
328
"""
329
d = self.fetch('dict')
330
if not d is None:
331
return d
332
333
cdef Py_ssize_t i, j
334
d = {}
335
for i from 0 <= i < self._nrows:
336
for j from 0 <= j < self._ncols:
337
x = self.get_unsafe(i, j)
338
if x != 0:
339
d[(int(i),int(j))] = x
340
self.cache('dict', d)
341
return d
342
343
###########################################################
344
# Cache
345
###########################################################
346
def _clear_cache(self):
347
"""
348
Clear anything cached about this matrix.
349
350
EXAMPLES::
351
352
sage: m=Matrix(QQ,2,range(0,4))
353
sage: m._clear_cache()
354
355
"""
356
self.clear_cache()
357
358
cdef clear_cache(self):
359
"""
360
Clear the properties cache.
361
"""
362
self._cache = None
363
364
cdef fetch(self, key):
365
"""
366
Try to get an element from the cache; if there isn't anything
367
there, return None.
368
"""
369
if self._cache is None:
370
return None
371
try:
372
return self._cache[key]
373
except KeyError:
374
return None
375
376
cdef cache(self, key, x):
377
"""
378
Record x in the cache with given key.
379
"""
380
if self._cache is None:
381
self._cache = {}
382
self._cache[key] = x
383
384
def _get_cache(self):
385
"""
386
Return the cache.
387
388
EXAMPLES::
389
390
sage: m=Matrix(QQ,2,range(0,4))
391
sage: m._get_cache()
392
{}
393
394
"""
395
return self._cache
396
397
###########################################################
398
# Mutability and bounds checking
399
###########################################################
400
401
cdef check_bounds(self, Py_ssize_t i, Py_ssize_t j):
402
"""
403
This function gets called when you're about to access the i,j entry
404
of this matrix. If i, j are out of range, an IndexError is
405
raised.
406
"""
407
if i<0 or i >= self._nrows or j<0 or j >= self._ncols:
408
raise IndexError("matrix index out of range")
409
410
cdef check_mutability(self):
411
"""
412
This function gets called when you're about to change this matrix.
413
414
If self is immutable, a ValueError is raised, since you should
415
never change a mutable matrix.
416
417
If self is mutable, the cache of results about self is deleted.
418
"""
419
if self._mutability._is_immutable:
420
raise ValueError("matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M).")
421
else:
422
self._cache = {}
423
424
cdef check_bounds_and_mutability(self, Py_ssize_t i, Py_ssize_t j):
425
"""
426
This function gets called when you're about to set the i,j entry of
427
this matrix. If i or j is out of range, an IndexError exception is
428
raised.
429
430
If self is immutable, a ValueError is raised, since you should
431
never change a mutable matrix.
432
433
If self is mutable, the cache of results about self is deleted.
434
"""
435
if self._mutability._is_immutable:
436
raise ValueError("matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M).")
437
else:
438
self._cache = {}
439
440
if i<0 or i >= self._nrows or j<0 or j >= self._ncols:
441
raise IndexError("matrix index out of range")
442
443
def set_immutable(self):
444
r"""
445
Call this function to set the matrix as immutable.
446
447
Matrices are always mutable by default, i.e., you can change their
448
entries using ``A[i,j] = x``. However, mutable matrices
449
aren't hashable, so can't be used as keys in dictionaries, etc.
450
Also, often when implementing a class, you might compute a matrix
451
associated to it, e.g., the matrix of a Hecke operator. If you
452
return this matrix to the user you're really returning a reference
453
and the user could then change an entry; this could be confusing.
454
Thus you should set such a matrix immutable.
455
456
EXAMPLES::
457
458
sage: A = Matrix(QQ, 2, 2, range(4))
459
sage: A.is_mutable()
460
True
461
sage: A[0,0] = 10
462
sage: A
463
[10 1]
464
[ 2 3]
465
466
Mutable matrices are not hashable, so can't be used as keys for
467
dictionaries::
468
469
sage: hash(A)
470
Traceback (most recent call last):
471
...
472
TypeError: mutable matrices are unhashable
473
sage: v = {A:1}
474
Traceback (most recent call last):
475
...
476
TypeError: mutable matrices are unhashable
477
478
If we make A immutable it suddenly is hashable.
479
480
::
481
482
sage: A.set_immutable()
483
sage: A.is_mutable()
484
False
485
sage: A[0,0] = 10
486
Traceback (most recent call last):
487
...
488
ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M).
489
sage: hash(A) #random
490
12
491
sage: v = {A:1}; v
492
{[10 1]
493
[ 2 3]: 1}
494
"""
495
self._mutability.set_immutable()
496
497
def is_immutable(self):
498
"""
499
Return True if this matrix is immutable.
500
501
See the documentation for self.set_immutable for more details
502
about mutability.
503
504
EXAMPLES::
505
506
sage: A = Matrix(QQ['t','s'], 2, 2, range(4))
507
sage: A.is_immutable()
508
False
509
sage: A.set_immutable()
510
sage: A.is_immutable()
511
True
512
"""
513
return self._mutability._is_immutable
514
515
def is_mutable(self):
516
"""
517
Return True if this matrix is mutable.
518
519
See the documentation for self.set_immutable for more details
520
about mutability.
521
522
EXAMPLES::
523
524
sage: A = Matrix(QQ['t','s'], 2, 2, range(4))
525
sage: A.is_mutable()
526
True
527
sage: A.set_immutable()
528
sage: A.is_mutable()
529
False
530
"""
531
return self._mutability.is_mutable()
532
533
###########################################################
534
# Entry access
535
# The first two must be overloaded in the derived class
536
###########################################################
537
cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, object x):
538
"""
539
Set entry quickly without doing any bounds checking. Calling this
540
with invalid arguments is allowed to produce a segmentation fault.
541
542
This is fast since it is a cdef function and there is no bounds
543
checking.
544
"""
545
raise NotImplementedError("this must be defined in the derived class (type=%s)"%type(self))
546
547
cdef get_unsafe(self, Py_ssize_t i, Py_ssize_t j):
548
"""
549
Entry access, but fast since it might be without bounds checking.
550
551
This is fast since it is a cdef function and there is no bounds
552
checking.
553
"""
554
raise NotImplementedError("this must be defined in the derived type.")
555
556
## def _get_very_unsafe(self, i, j):
557
## r"""
558
## Entry access, but potentially fast since it might be without
559
## bounds checking. (I know of no cases where this is actually
560
## faster.)
561
562
## This function it can very easily !! SEG FAULT !! if you call
563
## it with invalid input. Use with *extreme* caution.
564
565
## EXAMPLES:
566
## sage: a = matrix(ZZ,2,range(4))
567
## sage: a._get_very_unsafe(0,1)
568
## 1
569
570
## If you do \code{a.\_get\_very\_unsafe(0,10)} you'll very likely crash Sage
571
## completely.
572
## """
573
## return self.get_unsafe(i, j)
574
575
def __iter__(self):
576
"""
577
Return an iterator for the rows of self
578
579
EXAMPLES::
580
581
sage: m=matrix(2,[1,2,3,4])
582
sage: m.__iter__().next()
583
(1, 2)
584
"""
585
586
return matrix_misc.row_iterator(self)
587
588
def __getitem__(self, key):
589
"""
590
Return element, row, or slice of self.
591
592
INPUT:
593
594
- ``key``- tuple (i,j) where i, j can be integers, slices or lists
595
596
USAGE:
597
598
- ``A[i, j]`` - the i,j element (or elements, if i or j are
599
slices or lists) of A, or
600
601
- ``A[i:j]`` - rows of A, according to slice notation
602
603
EXAMPLES::
604
605
sage: A = Matrix(Integers(2006),2,2,[-1,2,3,4])
606
sage: A[0,0]
607
2005
608
sage: A[0]
609
(2005, 2)
610
611
The returned row is immutable (mainly to avoid confusion)::
612
613
sage: A[0][0] = 123
614
Traceback (most recent call last):
615
...
616
ValueError: vector is immutable; please change a copy instead (use copy())
617
sage: A[0].is_immutable()
618
True
619
sage: a = matrix(ZZ,3,range(9)); a
620
[0 1 2]
621
[3 4 5]
622
[6 7 8]
623
sage: a[1,2]
624
5
625
sage: a[0]
626
(0, 1, 2)
627
sage: a[4,7]
628
Traceback (most recent call last):
629
...
630
IndexError: matrix index out of range
631
sage: a[-1,0]
632
6
633
634
::
635
636
sage: a[2.7]
637
Traceback (most recent call last):
638
...
639
TypeError: index must be an integer
640
sage: a[1, 2.7]
641
Traceback (most recent call last):
642
...
643
TypeError: index must be an integer
644
sage: a[2.7, 1]
645
Traceback (most recent call last):
646
...
647
TypeError: index must be an integer
648
649
sage: m=[(1, -2, -1, -1,9), (1, 8, 6, 2,2), (1, 1, -1, 1,4), (-1, 2, -2, -1,4)];M= matrix(m)
650
sage: M
651
[ 1 -2 -1 -1 9]
652
[ 1 8 6 2 2]
653
[ 1 1 -1 1 4]
654
[-1 2 -2 -1 4]
655
656
Get the 2 x 2 submatrix of M, starting at row index and column
657
index 1
658
659
::
660
661
sage: M[1:3,1:3]
662
[ 8 6]
663
[ 1 -1]
664
665
Get the 2 x 3 submatrix of M starting at row index and column index
666
1::
667
668
sage: M[1:3,[1..3]]
669
[ 8 6 2]
670
[ 1 -1 1]
671
672
Get the second column of M::
673
674
sage: M[:,1]
675
[-2]
676
[ 8]
677
[ 1]
678
[ 2]
679
680
Get the first row of M::
681
682
sage: M[0,:]
683
[ 1 -2 -1 -1 9]
684
685
More examples::
686
687
sage: M[range(2),:]
688
[ 1 -2 -1 -1 9]
689
[ 1 8 6 2 2]
690
sage: M[range(2),4]
691
[9]
692
[2]
693
sage: M[range(3),range(5)]
694
[ 1 -2 -1 -1 9]
695
[ 1 8 6 2 2]
696
[ 1 1 -1 1 4]
697
698
::
699
700
sage: M[3,range(5)]
701
[-1 2 -2 -1 4]
702
sage: M[3,:]
703
[-1 2 -2 -1 4]
704
sage: M[3,4]
705
4
706
707
sage: M[-1,:]
708
[-1 2 -2 -1 4]
709
710
sage: A = matrix(ZZ,3,4, [3, 2, -5, 0, 1, -1, 1, -4, 1, 0, 1, -3]); A
711
[ 3 2 -5 0]
712
[ 1 -1 1 -4]
713
[ 1 0 1 -3]
714
715
::
716
717
sage: A[:,0:4:2]
718
[ 3 -5]
719
[ 1 1]
720
[ 1 1]
721
722
::
723
724
sage: A[1:,0:4:2]
725
[1 1]
726
[1 1]
727
728
sage: A[2::-1,:]
729
[ 1 0 1 -3]
730
[ 1 -1 1 -4]
731
[ 3 2 -5 0]
732
733
sage: A[1:,3::-1]
734
[-4 1 -1 1]
735
[-3 1 0 1]
736
737
sage: A[1:,3::-2]
738
[-4 -1]
739
[-3 0]
740
741
sage: A[2::-1,3:1:-1]
742
[-3 1]
743
[-4 1]
744
[ 0 -5]
745
746
::
747
748
sage: A= matrix(3,4,[1, 0, -3, -1, 3, 0, -2, 1, -3, -5, -1, -5])
749
sage: A[range(2,-1,-1),:]
750
[-3 -5 -1 -5]
751
[ 3 0 -2 1]
752
[ 1 0 -3 -1]
753
754
::
755
756
sage: A[range(2,-1,-1),range(3,-1,-1)]
757
[-5 -1 -5 -3]
758
[ 1 -2 0 3]
759
[-1 -3 0 1]
760
761
::
762
763
sage: A = matrix(2, [1, 2, 3, 4])
764
sage: A[[0,0],[0,0]]
765
[1 1]
766
[1 1]
767
768
::
769
770
sage: M = matrix(3, 4, range(12))
771
sage: M[0:0, 0:0]
772
[]
773
sage: M[0:0, 1:4]
774
[]
775
sage: M[2:3, 3:3]
776
[]
777
sage: M[range(2,2), :3]
778
[]
779
sage: M[(1,2), 3]
780
[ 7]
781
[11]
782
sage: M[(1,2),(0,1,1)]
783
[4 5 5]
784
[8 9 9]
785
sage: m=[(1, -2, -1, -1), (1, 8, 6, 2), (1, 1, -1, 1), (-1, 2, -2, -1)]
786
sage: M= matrix(m);M
787
[ 1 -2 -1 -1]
788
[ 1 8 6 2]
789
[ 1 1 -1 1]
790
[-1 2 -2 -1]
791
792
sage: M[:2]
793
[ 1 -2 -1 -1]
794
[ 1 8 6 2]
795
sage: M[:]
796
[ 1 -2 -1 -1]
797
[ 1 8 6 2]
798
[ 1 1 -1 1]
799
[-1 2 -2 -1]
800
sage: M[1:3]
801
[ 1 8 6 2]
802
[ 1 1 -1 1]
803
804
sage: A=matrix(QQ,10,range(100))
805
sage: A[0:3]
806
[ 0 1 2 3 4 5 6 7 8 9]
807
[10 11 12 13 14 15 16 17 18 19]
808
[20 21 22 23 24 25 26 27 28 29]
809
sage: A[:2]
810
[ 0 1 2 3 4 5 6 7 8 9]
811
[10 11 12 13 14 15 16 17 18 19]
812
sage: A[8:]
813
[80 81 82 83 84 85 86 87 88 89]
814
[90 91 92 93 94 95 96 97 98 99]
815
sage: A[1:10:3]
816
[10 11 12 13 14 15 16 17 18 19]
817
[40 41 42 43 44 45 46 47 48 49]
818
[70 71 72 73 74 75 76 77 78 79]
819
sage: A[-1]
820
(90, 91, 92, 93, 94, 95, 96, 97, 98, 99)
821
sage: A[-1:-6:-2]
822
[90 91 92 93 94 95 96 97 98 99]
823
[70 71 72 73 74 75 76 77 78 79]
824
[50 51 52 53 54 55 56 57 58 59]
825
826
sage: A[3].is_immutable()
827
True
828
sage: A[1:3].is_immutable()
829
True
830
831
TESTS:
832
833
If we're given lists as arguments, we should throw an
834
appropriate error when those lists do not contain valid
835
indices (trac #6569)::
836
837
sage: A = matrix(4, range(1,17))
838
sage: A[[1.5], [1]]
839
Traceback (most recent call last):
840
...
841
IndexError: row indices must be integers
842
sage: A[[1], [1.5]]
843
Traceback (most recent call last):
844
...
845
IndexError: column indices must be integers
846
sage: A[[1.5]]
847
Traceback (most recent call last):
848
...
849
IndexError: row indices must be integers
850
851
Before trac #6569 was fixed, sparse/dense matrices behaved
852
differently due to implementation details. Given invalid
853
indices, they should fail in the same manner. These tests
854
just repeat the previous set with a sparse matrix::
855
856
sage: A = matrix(4, range(1,17), sparse=True)
857
sage: A[[1.5], [1]]
858
Traceback (most recent call last):
859
...
860
IndexError: row indices must be integers
861
sage: A[[1], [1.5]]
862
Traceback (most recent call last):
863
...
864
IndexError: column indices must be integers
865
sage: A[[1.5]]
866
Traceback (most recent call last):
867
...
868
IndexError: row indices must be integers
869
870
"""
871
cdef list row_list
872
cdef list col_list
873
cdef Py_ssize_t i
874
cdef int row, col
875
cdef int nrows = self._nrows
876
cdef int ncols = self._ncols
877
cdef tuple key_tuple
878
cdef object row_index, col_index
879
cdef int ind
880
881
# used to keep track of when an index is a
882
# single number
883
cdef int single_row = 0, single_col = 0
884
885
if PyTuple_CheckExact(key):
886
key_tuple = <tuple>key
887
#if PyTuple_Size(key_tuple) != 2:
888
if len(key_tuple) != 2:
889
raise IndexError("index must be an integer or pair of integers")
890
891
row_index = <object>PyTuple_GET_ITEM(key_tuple, 0)
892
col_index = <object>PyTuple_GET_ITEM(key_tuple, 1)
893
894
if PyList_CheckExact(row_index) or PyTuple_CheckExact(row_index):
895
if PyTuple_CheckExact(row_index):
896
row_list = list(row_index)
897
else:
898
row_list = row_index
899
900
for i from 0 <= i < len(row_list):
901
# The 'ind' variable is 'cdef int' and will
902
# truncate a float to a valid index. So, we have
903
# to test row_list[i] instead.
904
if not PyIndex_Check(row_list[i]):
905
raise IndexError('row indices must be integers')
906
907
ind = row_list[i]
908
if ind < 0:
909
ind += nrows
910
row_list[i] = ind
911
912
if ind < 0 or ind >= nrows:
913
raise IndexError("matrix index out of range")
914
elif PySlice_Check(<PyObject *>row_index):
915
row_list = range(*row_index.indices(nrows))
916
else:
917
if not PyIndex_Check(row_index):
918
raise TypeError("index must be an integer")
919
row = row_index
920
if row < 0:
921
row += nrows
922
if row < 0 or row >= nrows:
923
raise IndexError("matrix index out of range")
924
single_row = 1
925
926
if PyList_CheckExact(col_index) or PyTuple_CheckExact(col_index):
927
if PyTuple_CheckExact(col_index):
928
col_list = list(col_index)
929
else:
930
col_list = col_index
931
932
for i from 0 <= i < len(col_list):
933
# The 'ind' variable is 'cdef int' and will
934
# truncate a float to a valid index. So, we have
935
# to test col_list[i] instead.
936
if not PyIndex_Check(col_list[i]):
937
raise IndexError('column indices must be integers')
938
939
ind = col_list[i]
940
if ind < 0:
941
ind += ncols
942
col_list[i] = ind
943
944
if ind < 0 or ind >= ncols:
945
raise IndexError("matrix index out of range")
946
elif PySlice_Check(<PyObject *>col_index):
947
col_list = range(*col_index.indices(ncols))
948
else:
949
if not PyIndex_Check(col_index):
950
raise TypeError("index must be an integer")
951
col = col_index
952
if col < 0:
953
col += ncols
954
if col < 0 or col >= ncols:
955
raise IndexError("matrix index out of range")
956
single_col = 1
957
958
# if we had a single row entry and a single column entry,
959
# we want to just do a get_unsafe
960
if single_row and single_col:
961
return self.get_unsafe(row, col)
962
963
# otherwise, prep these for the call to
964
# matrix_from_rows_and_columns
965
if single_row:
966
row_list = [row]
967
if single_col:
968
col_list = [col]
969
970
if len(row_list) == 0 or len(col_list) == 0:
971
return self.new_matrix(nrows=0,ncols=0)
972
973
return self.matrix_from_rows_and_columns(row_list,col_list)
974
975
976
row_index = key
977
if PyList_CheckExact(row_index) or PyTuple_CheckExact(row_index):
978
if PyTuple_CheckExact(row_index):
979
row_list = list(row_index)
980
else:
981
row_list = row_index
982
983
for i from 0 <= i < len(row_list):
984
# The 'ind' variable is 'cdef int' and will
985
# truncate a float to a valid index. So, we have
986
# to test row_list[i] instead.
987
if not PyIndex_Check(row_list[i]):
988
raise IndexError('row indices must be integers')
989
990
ind = row_list[i]
991
if ind < 0:
992
ind += nrows
993
row_list[i] = ind
994
995
if ind < 0 or ind >= nrows:
996
raise IndexError("matrix index out of range")
997
r = self.matrix_from_rows(row_list)
998
elif PySlice_Check(<PyObject *>row_index):
999
row_list = range(*row_index.indices(nrows))
1000
r = self.matrix_from_rows(row_list)
1001
else:
1002
if not PyIndex_Check(row_index):
1003
raise TypeError("index must be an integer")
1004
row = row_index
1005
if row < 0:
1006
row += nrows
1007
if row < 0 or row >= nrows:
1008
raise IndexError("matrix index out of range")
1009
r = self.row(row)
1010
1011
r.set_immutable()
1012
return r
1013
1014
def __setitem__(self, key, value):
1015
"""
1016
Set elements of this matrix to values given in value.
1017
1018
INPUT:
1019
1020
- ``key`` - any legal indexing (i.e., such that self[key] works)
1021
1022
- ``value`` - values that are used to set the elements indicated by key.
1023
1024
EXAMPLES::
1025
1026
sage: A = Matrix(Integers(2006),2,2,[-1,2,3,4])
1027
sage: A[0,0]=43; A
1028
[43 2]
1029
[ 3 4]
1030
1031
sage: A[0]=[10,20]; A
1032
[10 20]
1033
[ 3 4]
1034
1035
sage: M=matrix([(1, -2, -1, -1,9), (1, 8, 6, 2,2), (1, 1, -1, 1,4), (-1, 2, -2, -1,4)]); M
1036
[ 1 -2 -1 -1 9]
1037
[ 1 8 6 2 2]
1038
[ 1 1 -1 1 4]
1039
[-1 2 -2 -1 4]
1040
1041
Set the 2 x 2 submatrix of M, starting at row index and column
1042
index 1::
1043
1044
sage: M[1:3,1:3] = [[1,0],[0,1]]; M
1045
[ 1 -2 -1 -1 9]
1046
[ 1 1 0 2 2]
1047
[ 1 0 1 1 4]
1048
[-1 2 -2 -1 4]
1049
1050
Set the 2 x 3 submatrix of M starting at row index and column
1051
index 1::
1052
1053
sage: M[1:3,[1..3]] = M[2:4,0:3]; M
1054
[ 1 -2 -1 -1 9]
1055
[ 1 1 0 1 2]
1056
[ 1 -1 2 -2 4]
1057
[-1 2 -2 -1 4]
1058
1059
Set part of the first column of M::
1060
1061
sage: M[1:,0]=[[2],[3],[4]]; M
1062
[ 1 -2 -1 -1 9]
1063
[ 2 1 0 1 2]
1064
[ 3 -1 2 -2 4]
1065
[ 4 2 -2 -1 4]
1066
1067
Or do a similar thing with a vector::
1068
1069
sage: M[1:,0]=vector([-2,-3,-4]); M
1070
[ 1 -2 -1 -1 9]
1071
[-2 1 0 1 2]
1072
[-3 -1 2 -2 4]
1073
[-4 2 -2 -1 4]
1074
1075
Or a constant::
1076
1077
sage: M[1:,0]=30; M
1078
[ 1 -2 -1 -1 9]
1079
[30 1 0 1 2]
1080
[30 -1 2 -2 4]
1081
[30 2 -2 -1 4]
1082
1083
1084
Set the first row of M::
1085
1086
sage: M[0,:]=[[20,21,22,23,24]]; M
1087
[20 21 22 23 24]
1088
[30 1 0 1 2]
1089
[30 -1 2 -2 4]
1090
[30 2 -2 -1 4]
1091
sage: M[0,:]=vector([0,1,2,3,4]); M
1092
[ 0 1 2 3 4]
1093
[30 1 0 1 2]
1094
[30 -1 2 -2 4]
1095
[30 2 -2 -1 4]
1096
sage: M[0,:]=-3; M
1097
[-3 -3 -3 -3 -3]
1098
[30 1 0 1 2]
1099
[30 -1 2 -2 4]
1100
[30 2 -2 -1 4]
1101
1102
1103
sage: A = matrix(ZZ,3,4, [3, 2, -5, 0, 1, -1, 1, -4, 1, 0, 1, -3]); A
1104
[ 3 2 -5 0]
1105
[ 1 -1 1 -4]
1106
[ 1 0 1 -3]
1107
1108
We can use the step feature of slices to set every other column::
1109
1110
sage: A[:,0:3:2] = 5; A
1111
[ 5 2 5 0]
1112
[ 5 -1 5 -4]
1113
[ 5 0 5 -3]
1114
1115
sage: A[1:,0:4:2] = [[100,200],[300,400]]; A
1116
[ 5 2 5 0]
1117
[100 -1 200 -4]
1118
[300 0 400 -3]
1119
1120
We can also count backwards to flip the matrix upside down.
1121
1122
::
1123
1124
sage: A[::-1,:]=A; A
1125
[300 0 400 -3]
1126
[100 -1 200 -4]
1127
[ 5 2 5 0]
1128
1129
1130
sage: A[1:,3::-1]=[[2,3,0,1],[9,8,7,6]]; A
1131
[300 0 400 -3]
1132
[ 1 0 3 2]
1133
[ 6 7 8 9]
1134
1135
sage: A[1:,::-2] = A[1:,::2]; A
1136
[300 0 400 -3]
1137
[ 1 3 3 1]
1138
[ 6 8 8 6]
1139
1140
sage: A[::-1,3:1:-1] = [[4,3],[1,2],[-1,-2]]; A
1141
[300 0 -2 -1]
1142
[ 1 3 2 1]
1143
[ 6 8 3 4]
1144
1145
1146
TESTS::
1147
1148
sage: A = MatrixSpace(ZZ,3)(range(9)); A
1149
[0 1 2]
1150
[3 4 5]
1151
[6 7 8]
1152
sage: A[1,2]=100; A
1153
[ 0 1 2]
1154
[ 3 4 100]
1155
[ 6 7 8]
1156
sage: A[0]=(10,20,30); A
1157
[ 10 20 30]
1158
[ 3 4 100]
1159
[ 6 7 8]
1160
sage: A[4,7]=45
1161
Traceback (most recent call last):
1162
...
1163
IndexError: index out of range
1164
sage: A[-1,0]=63; A[-1,0]
1165
63
1166
sage: A[2.7]=3
1167
Traceback (most recent call last):
1168
...
1169
TypeError: index must be an integer or slice or a tuple/list of integers and slices
1170
sage: A[1, 2.7]=3
1171
Traceback (most recent call last):
1172
...
1173
TypeError: index must be an integer or slice or a tuple/list of integers and slices
1174
sage: A[2.7, 1]=3
1175
Traceback (most recent call last):
1176
...
1177
TypeError: index must be an integer or slice or a tuple/list of integers and slices
1178
sage: A.set_immutable()
1179
sage: A[0,0] = 7
1180
Traceback (most recent call last):
1181
...
1182
ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M).
1183
sage: A=matrix([[1,2],[3,4]]); B=matrix([[1,3],[5,7]])
1184
sage: A[1:2,1:2]=B[1:2,1:2]
1185
sage: A
1186
[1 2]
1187
[3 7]
1188
sage: A=matrix([[1,2],[3,4]]); B=matrix([[1,3],[5,7]])
1189
sage: A[1,0:1]=B[1,1:2]
1190
sage: A
1191
[1 2]
1192
[7 4]
1193
1194
1195
More examples::
1196
1197
sage: M[range(2),:]=[[1..5], [6..10]]; M
1198
[ 1 2 3 4 5]
1199
[ 6 7 8 9 10]
1200
[30 -1 2 -2 4]
1201
[30 2 -2 -1 4]
1202
1203
sage: M[range(2),4]=0; M
1204
[ 1 2 3 4 0]
1205
[ 6 7 8 9 0]
1206
[30 -1 2 -2 4]
1207
[30 2 -2 -1 4]
1208
1209
sage: M[range(3),range(5)]=M[range(1,4), :]; M
1210
[ 6 7 8 9 0]
1211
[30 -1 2 -2 4]
1212
[30 2 -2 -1 4]
1213
[30 2 -2 -1 4]
1214
1215
1216
sage: M[3,range(5)]=vector([-2,3,4,-5,4]); M
1217
[ 6 7 8 9 0]
1218
[30 -1 2 -2 4]
1219
[30 2 -2 -1 4]
1220
[-2 3 4 -5 4]
1221
sage: M[3,:]=2*M[2,:]; M
1222
[ 6 7 8 9 0]
1223
[30 -1 2 -2 4]
1224
[30 2 -2 -1 4]
1225
[60 4 -4 -2 8]
1226
sage: M[3,4]=M[3,2]; M
1227
[ 6 7 8 9 0]
1228
[30 -1 2 -2 4]
1229
[30 2 -2 -1 4]
1230
[60 4 -4 -2 -4]
1231
1232
sage: M[-1,:]=M[-3,:]; M
1233
[ 6 7 8 9 0]
1234
[30 -1 2 -2 4]
1235
[30 2 -2 -1 4]
1236
[30 -1 2 -2 4]
1237
1238
1239
sage: A= matrix(3,4,[1, 0, -3, -1, 3, 0, -2, 1, -3, -5, -1, -5]); A
1240
[ 1 0 -3 -1]
1241
[ 3 0 -2 1]
1242
[-3 -5 -1 -5]
1243
1244
sage: A[range(2,-1,-1),:]=A; A
1245
[-3 -5 -1 -5]
1246
[ 3 0 -2 1]
1247
[ 1 0 -3 -1]
1248
1249
sage: A[range(2,-1,-1),range(3,-1,-1)]=A; A
1250
[-1 -3 0 1]
1251
[ 1 -2 0 3]
1252
[-5 -1 -5 -3]
1253
1254
sage: A = matrix(2, [1, 2, 3, 4])
1255
sage: A[[0,0],[0,0]]=10; A
1256
[10 2]
1257
[ 3 4]
1258
1259
sage: M = matrix(3, 4, range(12))
1260
sage: M[0:0, 0:0]=20; M
1261
[ 0 1 2 3]
1262
[ 4 5 6 7]
1263
[ 8 9 10 11]
1264
sage: M[0:0, 1:4]=20; M
1265
[ 0 1 2 3]
1266
[ 4 5 6 7]
1267
[ 8 9 10 11]
1268
sage: M[2:3, 3:3]=20; M
1269
[ 0 1 2 3]
1270
[ 4 5 6 7]
1271
[ 8 9 10 11]
1272
sage: M[range(2,2), :3]=20; M
1273
[ 0 1 2 3]
1274
[ 4 5 6 7]
1275
[ 8 9 10 11]
1276
sage: M[(1,2), 3]=vector([-1,-2]); M
1277
[ 0 1 2 3]
1278
[ 4 5 6 -1]
1279
[ 8 9 10 -2]
1280
sage: M[(1,2),(0,1,1)]=[[-1,-2,-3],[-4,-5,-6]]; M
1281
[ 0 1 2 3]
1282
[-1 -3 6 -1]
1283
[-4 -6 10 -2]
1284
sage: M=matrix([(1, -2, -1, -1), (1, 8, 6, 2), (1, 1, -1, 1), (-1, 2, -2, -1)]); M
1285
[ 1 -2 -1 -1]
1286
[ 1 8 6 2]
1287
[ 1 1 -1 1]
1288
[-1 2 -2 -1]
1289
1290
sage: M[:2]=M[2:]; M
1291
[ 1 1 -1 1]
1292
[-1 2 -2 -1]
1293
[ 1 1 -1 1]
1294
[-1 2 -2 -1]
1295
1296
sage: M[:] = M.transpose(); M
1297
[ 1 -1 1 -1]
1298
[ 1 2 1 2]
1299
[-1 -2 -1 -2]
1300
[ 1 -1 1 -1]
1301
sage: M = matrix(ZZ,4,range(16)); M
1302
[ 0 1 2 3]
1303
[ 4 5 6 7]
1304
[ 8 9 10 11]
1305
[12 13 14 15]
1306
sage: M[::2]=M[::-2]; M
1307
[12 13 14 15]
1308
[ 4 5 6 7]
1309
[ 4 5 6 7]
1310
[12 13 14 15]
1311
sage: M[::2]=2; M
1312
[ 2 2 2 2]
1313
[ 4 5 6 7]
1314
[ 2 2 2 2]
1315
[12 13 14 15]
1316
1317
sage: M[2:]=10; M
1318
[ 2 2 2 2]
1319
[ 4 5 6 7]
1320
[10 10 10 10]
1321
[10 10 10 10]
1322
1323
sage: M=matrix(3,1,[1,2,3]); M
1324
[1]
1325
[2]
1326
[3]
1327
sage: M[1] = vector([20]); M
1328
[ 1]
1329
[20]
1330
[ 3]
1331
sage: M = matrix(3, 2, srange(6)); M[1] = 15; M
1332
[ 0 1]
1333
[15 15]
1334
[ 4 5]
1335
sage: M = matrix(3, 1, srange(3)); M[1] = 15; M
1336
[ 0]
1337
[15]
1338
[ 2]
1339
sage: M = matrix(3, 1, srange(3)); M[1] = [15]; M
1340
[ 0]
1341
[15]
1342
[ 2]
1343
"""
1344
cdef list row_list
1345
cdef list col_list
1346
cdef object index
1347
cdef Py_ssize_t row_list_len, col_list_len
1348
cdef list value_list
1349
cdef bint value_list_one_dimensional = 0
1350
cdef Py_ssize_t i
1351
cdef Py_ssize_t row, col
1352
cdef Py_ssize_t nrows = self._nrows
1353
cdef Py_ssize_t ncols = self._ncols
1354
cdef tuple key_tuple
1355
cdef object row_index, col_index
1356
cdef object value_row
1357
1358
# used to keep track of when an index is a
1359
# single number
1360
cdef bint single_row = 0, single_col = 0
1361
cdef bint no_col_index = 0
1362
1363
# If the matrix is immutable, check_mutability will raise an
1364
# exception.
1365
self.check_mutability()
1366
1367
if PyTuple_CheckExact(key):
1368
key_tuple = <tuple>key
1369
#if PyTuple_Size(key_tuple) != 2:
1370
if len(key_tuple) != 2:
1371
raise IndexError("index can't have more than two components")
1372
1373
row_index = <object>PyTuple_GET_ITEM(key_tuple, 0)
1374
col_index = <object>PyTuple_GET_ITEM(key_tuple, 1)
1375
1376
1377
if PyIndex_Check(col_index):
1378
col = col_index
1379
if col < 0:
1380
col += ncols
1381
if col < 0 or col >= ncols:
1382
raise IndexError("index out of range")
1383
single_col = 1
1384
col_list_len = 1
1385
else:
1386
col_list = normalize_index(col_index, ncols)
1387
col_list_len = len(col_list)
1388
if col_list_len==0:
1389
return
1390
1391
else:
1392
no_col_index = 1
1393
row_index = key
1394
col_list_len = ncols
1395
if col_list_len==0:
1396
return
1397
1398
# Special-case a single-row.
1399
if PyIndex_Check(row_index):
1400
row = row_index
1401
if row < 0:
1402
row += nrows
1403
if row < 0 or row >= nrows:
1404
raise IndexError("index out of range")
1405
single_row = 1
1406
row_list_len = 1
1407
else:
1408
row_list = normalize_index(row_index, nrows)
1409
row_list_len = len(row_list)
1410
if row_list_len==0:
1411
return
1412
1413
if single_row and single_col and not no_col_index:
1414
self.set_unsafe(row, col, self._coerce_element(value))
1415
return
1416
1417
if PyList_CheckExact(value):
1418
if single_row and no_col_index:
1419
# A convenience addition, so we can set a row by
1420
# M[1] = [1,2,3] or M[1,:]=[1,2,3]
1421
value_list_one_dimensional = 1
1422
value_list = value
1423
elif PyTuple_CheckExact(value):
1424
if single_row and no_col_index:
1425
# A convenience addition, so we can set a row by
1426
# M[1] = [1,2,3] or M[1,:]=[1,2,3]
1427
value_list_one_dimensional = 1
1428
value_list = list(value)
1429
elif IS_INSTANCE(value, Matrix):
1430
value_list = list(value)
1431
elif IS_INSTANCE(value, Vector):
1432
if single_row or single_col:
1433
value_list_one_dimensional = 1
1434
value_list = list(value)
1435
else:
1436
raise IndexError("value does not have the right dimensions")
1437
else:
1438
# If value is not a list, tuple, matrix, or vector, try
1439
# broadcasting the element to all positions.
1440
value_element = self._coerce_element(value)
1441
if single_row:
1442
if no_col_index:
1443
for col in range(col_list_len):
1444
self.set_unsafe(row, col, value_element)
1445
else:
1446
for col in col_list:
1447
self.set_unsafe(row, col, value_element)
1448
elif single_col:
1449
for row in row_list:
1450
self.set_unsafe(row, col, value_element)
1451
else:
1452
if no_col_index:
1453
for row in row_list:
1454
for col in range(col_list_len):
1455
self.set_unsafe(row, col, value_element)
1456
else:
1457
for row in row_list:
1458
for col in col_list:
1459
self.set_unsafe(row, col, value_element)
1460
return
1461
1462
if value_list_one_dimensional:
1463
# This will break when assigning a vector to a column
1464
if single_row and col_list_len != len(value_list):
1465
raise IndexError("value does not have the right number of columns")
1466
elif single_col and row_list_len != len(value_list):
1467
raise IndexError("value does not have the right number of rows")
1468
else:
1469
if row_list_len != len(value_list):
1470
raise IndexError("value does not have the right number of rows")
1471
for value_row in value_list:
1472
if col_list_len != len(value_row):
1473
raise IndexError("value does not have the right number of columns")
1474
1475
1476
if single_row:
1477
if value_list_one_dimensional:
1478
value_row = value_list
1479
else:
1480
value_row = value_list[0]
1481
1482
if no_col_index:
1483
for col in range(col_list_len):
1484
self.set_unsafe(row, col, self._coerce_element(value_row[col]))
1485
else:
1486
for col in range(col_list_len):
1487
self.set_unsafe(row, col_list[col], self._coerce_element(value_row[col]))
1488
elif single_col:
1489
if value_list_one_dimensional:
1490
for row in range(row_list_len):
1491
self.set_unsafe(row_list[row], col, self._coerce_element(value_list[row]))
1492
else:
1493
for row in range(row_list_len):
1494
self.set_unsafe(row_list[row], col, self._coerce_element(value_list[row][0]))
1495
else:
1496
if no_col_index:
1497
for i in range(row_list_len):
1498
row = row_list[i]
1499
value_row = value_list[i]
1500
for col in range(col_list_len):
1501
self.set_unsafe(row, col, self._coerce_element(value_row[col]))
1502
else:
1503
for i in range(row_list_len):
1504
row = row_list[i]
1505
value_row = value_list[i]
1506
for col in range(col_list_len):
1507
self.set_unsafe(row, col_list[col], self._coerce_element(value_row[col]))
1508
return
1509
1510
1511
1512
1513
cdef _coerce_element(self, x):
1514
"""
1515
Return coercion of x into the base ring of self.
1516
"""
1517
if PY_TYPE_CHECK(x, Element) and (<Element> x)._parent is self._base_ring:
1518
return x
1519
return self._base_ring(x)
1520
1521
###########################################################
1522
# Pickling
1523
###########################################################
1524
1525
def __reduce__(self):
1526
"""
1527
EXAMPLES::
1528
1529
sage: a = matrix(Integers(8),3,range(9))
1530
sage: a == loads(dumps(a))
1531
True
1532
"""
1533
data, version = self._pickle()
1534
return unpickle, (self.__class__, self._parent, self._mutability,
1535
self._cache, data, version)
1536
1537
def _pickle(self):
1538
"""
1539
Not yet implemented!
1540
1541
EXAMPLES::
1542
1543
sage: m=matrix(QQ,2,range(0,4))
1544
sage: m._pickle() # todo: not implemented
1545
"""
1546
raise NotImplementedError
1547
1548
def _test_reduce(self, **options):
1549
"""
1550
Checks that the pickling function works.
1551
1552
EXAMPLES::
1553
1554
sage: a=matrix([[1,2],[3,4]])
1555
sage: a._test_reduce()
1556
"""
1557
tester = self._tester(**options)
1558
a, b = self.__reduce__()
1559
tester.assertEqual(a(*b),self)
1560
1561
###########################################################
1562
# Base Change
1563
###########################################################
1564
def base_ring(self):
1565
"""
1566
Returns the base ring of the matrix.
1567
1568
EXAMPLES::
1569
1570
sage: m=matrix(QQ,2,[1,2,3,4])
1571
sage: m.base_ring()
1572
Rational Field
1573
"""
1574
return self._base_ring
1575
1576
def change_ring(self, ring):
1577
"""
1578
Return the matrix obtained by coercing the entries of this matrix
1579
into the given ring.
1580
1581
Always returns a copy (unless self is immutable, in which case
1582
returns self).
1583
1584
EXAMPLES::
1585
1586
sage: A = Matrix(QQ, 2, 2, [1/2, 1/3, 1/3, 1/4])
1587
sage: A.parent()
1588
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
1589
sage: A.change_ring(GF(25,'a'))
1590
[3 2]
1591
[2 4]
1592
sage: A.change_ring(GF(25,'a')).parent()
1593
Full MatrixSpace of 2 by 2 dense matrices over Finite Field in a of size 5^2
1594
sage: A.change_ring(ZZ)
1595
Traceback (most recent call last):
1596
...
1597
TypeError: matrix has denominators so can't change to ZZ.
1598
1599
Changing rings preserves subdivisions::
1600
1601
sage: A.subdivide([1], []); A
1602
[1/2 1/3]
1603
[-------]
1604
[1/3 1/4]
1605
sage: A.change_ring(GF(25,'a'))
1606
[3 2]
1607
[---]
1608
[2 4]
1609
"""
1610
if not is_Ring(ring):
1611
raise TypeError("ring must be a ring")
1612
1613
if ring is self._base_ring:
1614
if self._mutability._is_immutable:
1615
return self
1616
return self.__copy__()
1617
1618
try:
1619
return self._change_ring(ring)
1620
except (AttributeError, NotImplementedError):
1621
M = sage.matrix.matrix_space.MatrixSpace(ring, self._nrows, self._ncols, sparse=self.is_sparse())
1622
mat = M(self.list(), coerce=True, copy=False)
1623
mat.subdivide(self.subdivisions())
1624
return mat
1625
1626
def _test_change_ring(self, **options):
1627
"""
1628
Checks that :meth:`change_ring` works.
1629
1630
EXAMPLES::
1631
1632
sage: a=matrix([[1,2],[3,4]])
1633
sage: a._test_change_ring()
1634
1635
"""
1636
tester = self._tester(**options)
1637
# Test to make sure the returned matrix is a copy
1638
tester.assert_(self.change_ring(self.base_ring()) is not self)
1639
1640
def _matrix_(self, R):
1641
"""
1642
EXAMPLES::
1643
1644
sage: A = Matrix(ZZ[['t']], 2, 2, range(4))
1645
sage: A.parent()
1646
Full MatrixSpace of 2 by 2 dense matrices over Power Series Ring in t over Integer Ring
1647
sage: A._matrix_(QQ[['t']])
1648
[0 1]
1649
[2 3]
1650
sage: A._matrix_(QQ[['t']]).parent()
1651
Full MatrixSpace of 2 by 2 dense matrices over Power Series Ring in t over Rational Field
1652
"""
1653
return self.change_ring(R)
1654
1655
###########################################################
1656
# Representation -- string, latex, etc.
1657
###########################################################
1658
def __repr__(self):
1659
"""
1660
EXAMPLES::
1661
1662
sage: A = matrix([[1,2], [3,4], [5,6]])
1663
sage: A.__repr__()
1664
'[1 2]\n[3 4]\n[5 6]'
1665
sage: print A
1666
[1 2]
1667
[3 4]
1668
[5 6]
1669
1670
If the matrix is too big, don't print all of the elements::
1671
1672
sage: A = random_matrix(ZZ, 100)
1673
sage: A.__repr__()
1674
"100 x 100 dense matrix over Integer Ring (type 'print A.str()' to see all of the entries)"
1675
sage: print A
1676
100 x 100 dense matrix over Integer Ring (type 'print A.str()' to see all of the entries)
1677
1678
If there are several names for the same matrix, write it as "obj"::
1679
1680
sage: B = A; print B
1681
100 x 100 dense matrix over Integer Ring (type 'print obj.str()' to see all of the entries)
1682
1683
If the matrix doesn't have a name, don't print the extra string::
1684
1685
sage: A.transpose()
1686
100 x 100 dense matrix over Integer Ring
1687
sage: T = A.transpose(); T
1688
100 x 100 dense matrix over Integer Ring (type 'print T.str()' to see all of the entries)
1689
"""
1690
from sage.misc.sageinspect import sage_getvariablename
1691
if self._nrows < max_rows and self._ncols < max_cols:
1692
return self.str()
1693
if self.is_sparse():
1694
s = 'sparse'
1695
else:
1696
s = 'dense'
1697
rep = "%s x %s %s matrix over %s"%(self._nrows, self._ncols, s, self.base_ring())
1698
name = sage_getvariablename(self)
1699
if isinstance(name, list) and len(name) == 0:
1700
# don't print the name if the matrix doesn't have a name
1701
return rep
1702
if isinstance(name, list):
1703
name = [x for x in name if not x.startswith('_')]
1704
if len(name) == 1:
1705
name = name[0]
1706
# now name is either a string (if one choice) or a list (if many)
1707
if not isinstance(name, str):
1708
name = "obj"
1709
return rep + " (type 'print %s.str()' to see all of the entries)" % name
1710
1711
def str(self, rep_mapping=None, zero=None, plus_one=None, minus_one=None):
1712
r"""
1713
Return a nice string representation of the matrix.
1714
1715
INPUT:
1716
1717
- ``rep_mapping`` - a dictionary or callable used to override
1718
the usual representation of elements.
1719
1720
If ``rep_mapping`` is a dictionary then keys should be
1721
elements of the base ring and values the desired string
1722
representation. Values sent in via the other keyword
1723
arguments will override values in the dictionary.
1724
Use of a dictionary can potentially take a very long time
1725
due to the need to hash entries of the matrix. Matrices
1726
with entries from ``QQbar`` are one example.
1727
1728
If ``rep_mapping`` is callable then it will be called with
1729
elements of the matrix and must return a string. Simply
1730
call :func:`repr` on elements which should have the default
1731
representation.
1732
1733
- ``zero`` - string (default: ``None``); if not ``None`` use
1734
the value of ``zero`` as the representation of the zero
1735
element.
1736
1737
- ``plus_one`` - string (default: ``None``); if not ``None``
1738
use the value of ``plus_one`` as the representation of the
1739
one element.
1740
1741
- ``minus_one`` - string (default: ``None``); if not ``None``
1742
use the value of ``minus_one`` as the representation of the
1743
negative of the one element.
1744
1745
EXAMPLES::
1746
1747
sage: R = PolynomialRing(QQ,6,'z')
1748
sage: a = matrix(2,3, R.gens())
1749
sage: a.__repr__()
1750
'[z0 z1 z2]\n[z3 z4 z5]'
1751
1752
sage: M = matrix([[1,0],[2,-1]])
1753
sage: M.str()
1754
'[ 1 0]\n[ 2 -1]'
1755
sage: M.str(plus_one='+',minus_one='-',zero='.')
1756
'[+ .]\n[2 -]'
1757
sage: M.str({1:"not this one",2:"II"},minus_one="*",plus_one="I")
1758
'[ I 0]\n[II *]'
1759
1760
sage: def print_entry(x):
1761
... if x>0:
1762
... return '+'
1763
... elif x<0:
1764
... return '-'
1765
... else: return '.'
1766
...
1767
sage: M.str(print_entry)
1768
'[+ .]\n[+ -]'
1769
sage: M.str(repr)
1770
'[ 1 0]\n[ 2 -1]'
1771
1772
TESTS:
1773
1774
Prior to Trac #11544 this could take a full minute to run (2011). ::
1775
1776
sage: A = matrix(QQ, 4, 4, [1, 2, -2, 2, 1, 0, -1, -1, 0, -1, 1, 1, -1, 2, 1/2, 0])
1777
sage: e = A.eigenvalues()[3]
1778
sage: K = (A-e).kernel()
1779
sage: P = K.basis_matrix()
1780
sage: P.str()
1781
'[ 1.000000000000000? + 0.?e-17*I -2.116651487479748? + 0.0255565807096352?*I -0.2585224251020429? + 0.288602340904754?*I -0.4847545623533090? - 1.871890760086142?*I]'
1782
"""
1783
#x = self.fetch('repr') # too confusing!!
1784
#if not x is None: return x
1785
cdef Py_ssize_t nr, nc, r, c
1786
nr = self._nrows
1787
nc = self._ncols
1788
1789
if nr == 0 or nc == 0:
1790
return "[]"
1791
1792
row_divs, col_divs = self.subdivisions()
1793
1794
# Set the mapping based on keyword arguments
1795
if rep_mapping is None:
1796
rep_mapping = {}
1797
if isinstance(rep_mapping, dict):
1798
if zero is not None:
1799
rep_mapping[self.base_ring().zero()] = zero
1800
if plus_one is not None:
1801
rep_mapping[self.base_ring().one()] = plus_one
1802
if minus_one is not None:
1803
rep_mapping[-self.base_ring().one()] = minus_one
1804
1805
# compute column widths
1806
S = []
1807
for x in self.list():
1808
# Override the usual representations with those specified
1809
if callable(rep_mapping):
1810
rep = rep_mapping(x)
1811
# avoid hashing entries, especially algebraic numbers
1812
elif rep_mapping and rep_mapping.has_key(x):
1813
rep = rep_mapping.get(x)
1814
else:
1815
rep = repr(x)
1816
S.append(rep)
1817
1818
tmp = []
1819
for x in S:
1820
tmp.append(len(x))
1821
1822
width = max(tmp)
1823
rows = []
1824
m = 0
1825
1826
left_bracket = "["
1827
right_bracket = "]"
1828
while nc in col_divs:
1829
right_bracket = "|" + right_bracket
1830
col_divs.remove(nc)
1831
while 0 in col_divs:
1832
left_bracket += "|"
1833
col_divs.remove(0)
1834
line = '+'.join(['-'*((width+1)*(b-a)-1) for a,b in zip([0] + col_divs, col_divs + [nc])])
1835
hline = (left_bracket + line + right_bracket).replace('|', '+')
1836
1837
# compute rows
1838
for r from 0 <= r < nr:
1839
rows += [hline] * row_divs.count(r)
1840
s = ""
1841
for c from 0 <= c < nc:
1842
if c+1 in col_divs:
1843
sep = "|"*col_divs.count(c+1)
1844
elif c == nc - 1:
1845
sep=""
1846
else:
1847
sep=" "
1848
entry = S[r*nc+c]
1849
if c == 0:
1850
m = max(m, len(entry))
1851
entry = " "*(width-len(entry)) + entry
1852
s = s + entry + sep
1853
rows.append(left_bracket + s + right_bracket)
1854
1855
rows += [hline] * row_divs.count(nr)
1856
1857
s = "\n".join(rows)
1858
#self.cache('repr',s)
1859
return s
1860
1861
## def _latex_sparse(self, variable="x"):
1862
## r"""
1863
## Return a latex string that represents this matrix as a sparse
1864
## matrix. The rows are printed as sums $\sum a_i x_i$, where
1865
## $x$ is the variable.
1866
1867
## EXAMPLES:
1868
1869
## """
1870
## cdef Py_ssize_t nr, nc, i, j
1871
## nr = self._nrows
1872
## nc = self._ncols
1873
## s = "\\left(\\begin{align*}\n"
1874
## for i from 0 <= i < nr:
1875
## v = []
1876
## for j from 0 <= j < nc:
1877
## x = self.get_unsafe(i, j)
1878
## if x != 0:
1879
## v.append((j, x))
1880
## for j from 0 <= j < len(v):
1881
## s = s + "%s*%s_{%s}"%(v[j][1], variable, v[j][0])
1882
## if j == 0:
1883
## s = s + "& + "
1884
## elif j < len(v) - 1:
1885
## s = s + " + "
1886
## else:
1887
## s = s + "\\\\\n"
1888
## s = s + "\n\\end{align*}"
1889
## return s
1890
1891
def _latex_(self):
1892
r"""
1893
Return latex representation of this matrix. The matrix is
1894
enclosed in parentheses by default, but the delimiters can be
1895
changed using the command
1896
``latex.matrix_delimiters(...)``.
1897
1898
EXAMPLES::
1899
1900
sage: R = PolynomialRing(QQ,4,'z')
1901
sage: a = matrix(2,2, R.gens())
1902
sage: b = a*a
1903
sage: latex(b) # indirect doctest
1904
\left(\begin{array}{rr}
1905
z_{0}^{2} + z_{1} z_{2} & z_{0} z_{1} + z_{1} z_{3} \\
1906
z_{0} z_{2} + z_{2} z_{3} & z_{1} z_{2} + z_{3}^{2}
1907
\end{array}\right)
1908
1909
Latex representation for block matrices::
1910
1911
sage: B = matrix(3,4)
1912
sage: B.subdivide([2,2], [3])
1913
sage: latex(B)
1914
\left(\begin{array}{rrr|r}
1915
0 & 0 & 0 & 0 \\
1916
0 & 0 & 0 & 0 \\
1917
\hline\hline
1918
0 & 0 & 0 & 0
1919
\end{array}\right)
1920
1921
Note that size-zero subdivisions are ignored in the notebook::
1922
1923
sage: sage.server.support.EMBEDDED_MODE = True
1924
sage: latex(B)
1925
\left(\begin{array}{rr}
1926
\left(\begin{array}{rrr}
1927
0 & 0 & 0 \\
1928
0 & 0 & 0
1929
\end{array}\right) & \left(\begin{array}{r}
1930
0 \\
1931
0
1932
\end{array}\right) \\
1933
\\
1934
\left(\begin{array}{rrr}
1935
0 & 0 & 0
1936
\end{array}\right) & \left(\begin{array}{r}
1937
0
1938
\end{array}\right)
1939
\end{array}\right)
1940
sage: sage.server.support.EMBEDDED_MODE = False
1941
"""
1942
latex = sage.misc.latex.latex
1943
matrix_delimiters = latex.matrix_delimiters()
1944
cdef Py_ssize_t nr, nc, r, c
1945
nr = self._nrows
1946
nc = self._ncols
1947
if nr == 0 or nc == 0:
1948
return matrix_delimiters[0] + matrix_delimiters[1]
1949
1950
S = self.list()
1951
rows = []
1952
1953
row_divs, col_divs = self.subdivisions()
1954
1955
from sage.server.support import EMBEDDED_MODE
1956
1957
# jsmath doesn't know the command \hline, so have to do things
1958
# differently (and not as attractively) in embedded mode:
1959
# construct an array with a subarray for each block.
1960
if len(row_divs) + len(col_divs) > 0 and EMBEDDED_MODE:
1961
for r in range(len(row_divs)+1):
1962
s = ""
1963
for c in range(len(col_divs)+1):
1964
if c == len(col_divs):
1965
sep=""
1966
else:
1967
sep=" & "
1968
sub = self.subdivision(r,c)
1969
if sub.nrows() > 0 and sub.ncols() > 0:
1970
entry = latex(self.subdivision(r,c))
1971
s = s + entry + sep
1972
rows.append(s)
1973
1974
# Put brackets around in a single string
1975
tmp = []
1976
for row in rows:
1977
tmp.append(str(row))
1978
1979
s = " \\\\\n".join(tmp)
1980
format = 'r'*len(row_divs)
1981
return "\\left" + matrix_delimiters[0] + "\\begin{array}{%s}\n"%format + s + "\n\\end{array}\\right" + matrix_delimiters[1]
1982
1983
# not in EMBEDDED_MODE, or in EMBEDDED_MODE with just a single
1984
# block: construct one large array, using \hline and vertical
1985
# bars | in the array descriptor to indicate subdivisions.
1986
for r from 0 <= r < nr:
1987
if r in row_divs:
1988
s = "\\hline"*row_divs.count(r) + "\n"
1989
else:
1990
s = ""
1991
for c from 0 <= c < nc:
1992
if c == nc-1:
1993
sep=""
1994
else:
1995
sep=" & "
1996
entry = latex(S[r*nc+c])
1997
s = s + entry + sep
1998
rows.append(s)
1999
2000
# Put brackets around in a single string
2001
tmp = []
2002
for row in rows:
2003
tmp.append(str(row))
2004
s = " \\\\\n".join(tmp)
2005
2006
tmp = ['r'*(b-a) for a,b in zip([0] + col_divs, col_divs + [nc])]
2007
format = '|'.join(tmp)
2008
2009
return "\\left" + matrix_delimiters[0] + "\\begin{array}{%s}\n"%format + s + "\n\\end{array}\\right" + matrix_delimiters[1]
2010
2011
2012
2013
###################################################
2014
## Basic Properties
2015
###################################################
2016
def ncols(self):
2017
"""
2018
Return the number of columns of this matrix.
2019
2020
EXAMPLES::
2021
2022
sage: M = MatrixSpace(QQ, 2, 3)
2023
sage: A = M([1,2,3, 4,5,6])
2024
sage: A
2025
[1 2 3]
2026
[4 5 6]
2027
sage: A.ncols()
2028
3
2029
sage: A.nrows()
2030
2
2031
2032
AUTHORS:
2033
2034
- Naqi Jaffery (2006-01-24): examples
2035
"""
2036
return self._ncols
2037
2038
def nrows(self):
2039
r"""
2040
Return the number of rows of this matrix.
2041
2042
EXAMPLES::
2043
2044
sage: M = MatrixSpace(QQ,6,7)
2045
sage: A = M([1,2,3,4,5,6,7, 22,3/4,34,11,7,5,3, 99,65,1/2,2/3,3/5,4/5,5/6, 9,8/9, 9/8,7/6,6/7,76,4, 0,9,8,7,6,5,4, 123,99,91,28,6,1024,1])
2046
sage: A
2047
[ 1 2 3 4 5 6 7]
2048
[ 22 3/4 34 11 7 5 3]
2049
[ 99 65 1/2 2/3 3/5 4/5 5/6]
2050
[ 9 8/9 9/8 7/6 6/7 76 4]
2051
[ 0 9 8 7 6 5 4]
2052
[ 123 99 91 28 6 1024 1]
2053
sage: A.ncols()
2054
7
2055
sage: A.nrows()
2056
6
2057
2058
AUTHORS:
2059
2060
- Naqi Jaffery (2006-01-24): examples
2061
"""
2062
return self._nrows
2063
2064
def dimensions(self):
2065
r"""
2066
Returns the dimensions of this matrix as the tuple (nrows, ncols).
2067
2068
EXAMPLES::
2069
2070
sage: M = matrix([[1,2,3],[4,5,6]])
2071
sage: N = M.transpose()
2072
sage: M.dimensions()
2073
(2, 3)
2074
sage: N.dimensions()
2075
(3, 2)
2076
2077
AUTHORS:
2078
2079
- Benjamin Lundell (2012-02-09): examples
2080
"""
2081
return (self._nrows,self._ncols)
2082
2083
2084
###################################################
2085
# Functions
2086
###################################################
2087
def act_on_polynomial(self, f):
2088
"""
2089
Returns the polynomial f(self\*x).
2090
2091
INPUT:
2092
2093
2094
- ``self`` - an nxn matrix
2095
2096
- ``f`` - a polynomial in n variables x=(x1,...,xn)
2097
2098
2099
OUTPUT: The polynomial f(self\*x).
2100
2101
EXAMPLES::
2102
2103
sage: R.<x,y> = QQ[]
2104
sage: x, y = R.gens()
2105
sage: f = x**2 - y**2
2106
sage: M = MatrixSpace(QQ, 2)
2107
sage: A = M([1,2,3,4])
2108
sage: A.act_on_polynomial(f)
2109
-8*x^2 - 20*x*y - 12*y^2
2110
"""
2111
cdef Py_ssize_t i, j, n
2112
2113
if self._nrows != self._ncols:
2114
raise ArithmeticError("self must be a square matrix")
2115
2116
F = f.base_ring()
2117
vars = f.parent().gens()
2118
n = len(self.rows())
2119
ans = []
2120
for i from 0 <= i < n:
2121
tmp = []
2122
for j from 0 <= j < n:
2123
tmp.append(self.get_unsafe(i,j)*vars[j])
2124
ans.append( sum(tmp) )
2125
return f(tuple(ans))
2126
2127
def __call__(self, *args, **kwargs):
2128
"""
2129
Calling a matrix returns the result of calling each component.
2130
2131
EXAMPLES::
2132
2133
sage: f(x,y) = x^2+y
2134
sage: m = matrix([[f,f*f],[f^3,f^4]]); m
2135
[ (x, y) |--> x^2 + y (x, y) |--> (x^2 + y)^2]
2136
[(x, y) |--> (x^2 + y)^3 (x, y) |--> (x^2 + y)^4]
2137
sage: m(1,2)
2138
[ 3 9]
2139
[27 81]
2140
sage: m(y=2,x=1)
2141
[ 3 9]
2142
[27 81]
2143
sage: m(2,1)
2144
[ 5 25]
2145
[125 625]
2146
"""
2147
from constructor import matrix
2148
return matrix(self.nrows(), self.ncols(), [e(*args, **kwargs) for e in self.list()])
2149
2150
###################################################
2151
# Arithmetic
2152
###################################################
2153
def commutator(self, other):
2154
"""
2155
Return the commutator self\*other - other\*self.
2156
2157
EXAMPLES::
2158
2159
sage: A = Matrix(ZZ, 2, 2, range(4))
2160
sage: B = Matrix(ZZ, 2, 2, [0, 1, 0, 0])
2161
sage: A.commutator(B)
2162
[-2 -3]
2163
[ 0 2]
2164
sage: A.commutator(B) == -B.commutator(A)
2165
True
2166
"""
2167
return self*other - other*self
2168
2169
###################################################
2170
# Row and column operations
2171
# The _c versions do no bounds checking.
2172
# The with_ versions do not change the input matrix.
2173
# Some of the functions assume that input values
2174
# have parent that is self._base_ring.
2175
# AUTHORS:
2176
# -- Karl-Dieter Crisman (June 2008):
2177
# Improved examples and error messages for methods which could
2178
# involve multiplication outside base ring, including
2179
# with_ versions of these methods for this situation
2180
###################################################
2181
cdef check_row_bounds_and_mutability(self, Py_ssize_t r1, Py_ssize_t r2):
2182
if self._mutability._is_immutable:
2183
raise ValueError("matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M).")
2184
else:
2185
self._cache = {}
2186
if r1<0 or r1 >= self._nrows or r2<0 or r2 >= self._nrows:
2187
raise IndexError("matrix row index out of range")
2188
2189
cdef check_column_bounds_and_mutability(self, Py_ssize_t c1, Py_ssize_t c2):
2190
if self._mutability._is_immutable:
2191
raise ValueError("matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M).")
2192
else:
2193
self._cache = {}
2194
if c1<0 or c1 >= self._ncols or c2<0 or c2 >= self._ncols:
2195
raise IndexError("matrix column index out of range")
2196
2197
def swap_columns(self, Py_ssize_t c1, Py_ssize_t c2):
2198
"""
2199
Swap columns c1 and c2 of self.
2200
2201
EXAMPLES: We create a rational matrix::
2202
2203
sage: M = MatrixSpace(QQ,3,3)
2204
sage: A = M([1,9,-7,4/5,4,3,6,4,3])
2205
sage: A
2206
[ 1 9 -7]
2207
[4/5 4 3]
2208
[ 6 4 3]
2209
2210
Since the first column is numbered zero, this swaps the second and
2211
third columns::
2212
2213
sage: A.swap_columns(1,2); A
2214
[ 1 -7 9]
2215
[4/5 3 4]
2216
[ 6 3 4]
2217
"""
2218
self.check_column_bounds_and_mutability(c1, c2)
2219
if c1 != c2:
2220
self.swap_columns_c(c1, c2)
2221
2222
def with_swapped_columns(self, c1, c2):
2223
r"""
2224
Swap columns ``c1`` and ``c2`` of ``self`` and return a new matrix.
2225
2226
INPUT:
2227
2228
- ``c1``, ``c2`` - integers specifying columns of ``self`` to interchange
2229
2230
OUTPUT:
2231
2232
A new matrix, identical to ``self`` except that columns ``c1`` and ``c2``
2233
are swapped.
2234
2235
EXAMPLES:
2236
2237
Remember that columns are numbered starting from zero. ::
2238
2239
sage: A = matrix(QQ, 4, range(20))
2240
sage: A.with_swapped_columns(1, 2)
2241
[ 0 2 1 3 4]
2242
[ 5 7 6 8 9]
2243
[10 12 11 13 14]
2244
[15 17 16 18 19]
2245
2246
Trying to swap a column with itself will succeed, but still return
2247
a new matrix. ::
2248
2249
sage: A = matrix(QQ, 4, range(20))
2250
sage: B = A.with_swapped_columns(2, 2)
2251
sage: A == B
2252
True
2253
sage: A is B
2254
False
2255
2256
The column specifications are checked. ::
2257
2258
sage: A = matrix(4, range(20))
2259
sage: A.with_swapped_columns(-1, 2)
2260
Traceback (most recent call last):
2261
...
2262
IndexError: matrix column index out of range
2263
2264
sage: A.with_swapped_columns(2, 5)
2265
Traceback (most recent call last):
2266
...
2267
IndexError: matrix column index out of range
2268
"""
2269
cdef Matrix temp
2270
self.check_column_bounds_and_mutability(c1,c2)
2271
temp = self.__copy__()
2272
if c1 != c2:
2273
temp.swap_columns_c(c1,c2)
2274
return temp
2275
2276
cdef swap_columns_c(self, Py_ssize_t c1, Py_ssize_t c2):
2277
cdef Py_ssize_t r
2278
for r from 0 <= r < self._nrows:
2279
a = self.get_unsafe(r, c2)
2280
self.set_unsafe(r, c2, self.get_unsafe(r,c1))
2281
self.set_unsafe(r, c1, a)
2282
2283
def swap_rows(self, r1, r2):
2284
"""
2285
Swap rows r1 and r2 of self.
2286
2287
EXAMPLES: We create a rational matrix::
2288
2289
sage: M = MatrixSpace(QQ,3,3)
2290
sage: A = M([1,9,-7,4/5,4,3,6,4,3])
2291
sage: A
2292
[ 1 9 -7]
2293
[4/5 4 3]
2294
[ 6 4 3]
2295
2296
Since the first row is numbered zero, this swaps the first and
2297
third rows::
2298
2299
sage: A.swap_rows(0,2); A
2300
[ 6 4 3]
2301
[4/5 4 3]
2302
[ 1 9 -7]
2303
"""
2304
self.check_row_bounds_and_mutability(r1, r2)
2305
if r1 != r2:
2306
self.swap_rows_c(r1, r2)
2307
2308
def with_swapped_rows(self, r1, r2):
2309
r"""
2310
Swap rows ``r1`` and ``r2`` of ``self`` and return a new matrix.
2311
2312
INPUT:
2313
2314
- ``r1``, ``r2`` - integers specifying rows of ``self`` to interchange
2315
2316
OUTPUT:
2317
2318
A new matrix, identical to ``self`` except that rows ``r1`` and ``r2``
2319
are swapped.
2320
2321
EXAMPLES:
2322
2323
Remember that rows are numbered starting from zero. ::
2324
2325
sage: A = matrix(QQ, 4, range(20))
2326
sage: A.with_swapped_rows(1, 2)
2327
[ 0 1 2 3 4]
2328
[10 11 12 13 14]
2329
[ 5 6 7 8 9]
2330
[15 16 17 18 19]
2331
2332
Trying to swap a row with itself will succeed, but still return
2333
a new matrix. ::
2334
2335
sage: A = matrix(QQ, 4, range(20))
2336
sage: B = A.with_swapped_rows(2, 2)
2337
sage: A == B
2338
True
2339
sage: A is B
2340
False
2341
2342
The row specifications are checked. ::
2343
2344
sage: A = matrix(4, range(20))
2345
sage: A.with_swapped_rows(-1, 2)
2346
Traceback (most recent call last):
2347
...
2348
IndexError: matrix row index out of range
2349
2350
sage: A.with_swapped_rows(2, 5)
2351
Traceback (most recent call last):
2352
...
2353
IndexError: matrix row index out of range
2354
"""
2355
cdef Matrix temp
2356
self.check_row_bounds_and_mutability(r1,r2)
2357
temp = self.__copy__()
2358
if r1 != r2:
2359
temp.swap_rows_c(r1,r2)
2360
return temp
2361
2362
cdef swap_rows_c(self, Py_ssize_t r1, Py_ssize_t r2):
2363
cdef Py_ssize_t c
2364
for c from 0 <= c < self._ncols:
2365
a = self.get_unsafe(r2, c)
2366
self.set_unsafe(r2, c, self.get_unsafe(r1, c))
2367
self.set_unsafe(r1, c, a)
2368
2369
def add_multiple_of_row(self, Py_ssize_t i, Py_ssize_t j, s, Py_ssize_t start_col=0):
2370
"""
2371
Add s times row j to row i.
2372
2373
EXAMPLES: We add -3 times the first row to the second row of an
2374
integer matrix, remembering to start numbering rows at zero::
2375
2376
sage: a = matrix(ZZ,2,3,range(6)); a
2377
[0 1 2]
2378
[3 4 5]
2379
sage: a.add_multiple_of_row(1,0,-3)
2380
sage: a
2381
[ 0 1 2]
2382
[ 3 1 -1]
2383
2384
To add a rational multiple, we first need to change the base ring::
2385
2386
sage: a = a.change_ring(QQ)
2387
sage: a.add_multiple_of_row(1,0,1/3)
2388
sage: a
2389
[ 0 1 2]
2390
[ 3 4/3 -1/3]
2391
2392
If not, we get an error message::
2393
2394
sage: a.add_multiple_of_row(1,0,i)
2395
Traceback (most recent call last):
2396
...
2397
TypeError: Multiplying row by Symbolic Ring element cannot be done over Rational Field, use change_ring or with_added_multiple_of_row instead.
2398
"""
2399
self.check_row_bounds_and_mutability(i,j)
2400
try:
2401
s = self._coerce_element(s)
2402
self.add_multiple_of_row_c(i, j, s, start_col)
2403
except TypeError:
2404
raise TypeError('Multiplying row by %s element cannot be done over %s, use change_ring or with_added_multiple_of_row instead.' % (s.parent(), self.base_ring()))
2405
2406
cdef add_multiple_of_row_c(self, Py_ssize_t i, Py_ssize_t j, s, Py_ssize_t start_col):
2407
cdef Py_ssize_t c
2408
for c from start_col <= c < self._ncols:
2409
self.set_unsafe(i, c, self.get_unsafe(i, c) + s*self.get_unsafe(j, c))
2410
2411
def with_added_multiple_of_row(self, Py_ssize_t i, Py_ssize_t j, s, Py_ssize_t start_col=0):
2412
"""
2413
Add s times row j to row i, returning new matrix.
2414
2415
EXAMPLES: We add -3 times the first row to the second row of an
2416
integer matrix, remembering to start numbering rows at zero::
2417
2418
sage: a = matrix(ZZ,2,3,range(6)); a
2419
[0 1 2]
2420
[3 4 5]
2421
sage: b = a.with_added_multiple_of_row(1,0,-3); b
2422
[ 0 1 2]
2423
[ 3 1 -1]
2424
2425
The original matrix is unchanged::
2426
2427
sage: a
2428
[0 1 2]
2429
[3 4 5]
2430
2431
Adding a rational multiple is okay, and reassigning a variable is
2432
okay::
2433
2434
sage: a = a.with_added_multiple_of_row(0,1,1/3); a
2435
[ 1 7/3 11/3]
2436
[ 3 4 5]
2437
"""
2438
cdef Matrix temp
2439
self.check_row_bounds_and_mutability(i,j)
2440
try:
2441
s = self._coerce_element(s)
2442
temp = self.__copy__()
2443
temp.add_multiple_of_row_c(i, j, s, start_col)
2444
return temp
2445
# If scaling factor cannot be coerced, change the base ring to
2446
# one acceptable to both the original base ring and the scaling factor.
2447
except TypeError:
2448
temp = self.change_ring(Sequence([s,self.base_ring()(0)]).universe())
2449
s = temp._coerce_element(s)
2450
temp.add_multiple_of_row_c(i, j, s, start_col)
2451
return temp
2452
2453
def add_multiple_of_column(self, Py_ssize_t i, Py_ssize_t j, s, Py_ssize_t start_row=0):
2454
"""
2455
Add s times column j to column i.
2456
2457
EXAMPLES: We add -1 times the third column to the second column of
2458
an integer matrix, remembering to start numbering cols at zero::
2459
2460
sage: a = matrix(ZZ,2,3,range(6)); a
2461
[0 1 2]
2462
[3 4 5]
2463
sage: a.add_multiple_of_column(1,2,-1)
2464
sage: a
2465
[ 0 -1 2]
2466
[ 3 -1 5]
2467
2468
To add a rational multiple, we first need to change the base ring::
2469
2470
sage: a = a.change_ring(QQ)
2471
sage: a.add_multiple_of_column(1,0,1/3)
2472
sage: a
2473
[ 0 -1 2]
2474
[ 3 0 5]
2475
2476
If not, we get an error message::
2477
2478
sage: a.add_multiple_of_column(1,0,i)
2479
Traceback (most recent call last):
2480
...
2481
TypeError: Multiplying column by Symbolic Ring element cannot be done over Rational Field, use change_ring or with_added_multiple_of_column instead.
2482
"""
2483
self.check_column_bounds_and_mutability(i,j)
2484
try:
2485
s = self._coerce_element(s)
2486
self.add_multiple_of_column_c(i, j, s, start_row)
2487
except TypeError:
2488
raise TypeError('Multiplying column by %s element cannot be done over %s, use change_ring or with_added_multiple_of_column instead.' % (s.parent(), self.base_ring()))
2489
2490
cdef add_multiple_of_column_c(self, Py_ssize_t i, Py_ssize_t j, s, Py_ssize_t start_row):
2491
cdef Py_ssize_t r
2492
for r from start_row <= r < self._nrows:
2493
self.set_unsafe(r, i, self.get_unsafe(r, i) + s*self.get_unsafe(r, j))
2494
2495
def with_added_multiple_of_column(self, Py_ssize_t i, Py_ssize_t j, s, Py_ssize_t start_row=0):
2496
"""
2497
Add s times column j to column i, returning new matrix.
2498
2499
EXAMPLES: We add -1 times the third column to the second column of
2500
an integer matrix, remembering to start numbering cols at zero::
2501
2502
sage: a = matrix(ZZ,2,3,range(6)); a
2503
[0 1 2]
2504
[3 4 5]
2505
sage: b = a.with_added_multiple_of_column(1,2,-1); b
2506
[ 0 -1 2]
2507
[ 3 -1 5]
2508
2509
The original matrix is unchanged::
2510
2511
sage: a
2512
[0 1 2]
2513
[3 4 5]
2514
2515
Adding a rational multiple is okay, and reassigning a variable is
2516
okay::
2517
2518
sage: a = a.with_added_multiple_of_column(0,1,1/3); a
2519
[ 1/3 1 2]
2520
[13/3 4 5]
2521
"""
2522
cdef Matrix temp
2523
self.check_column_bounds_and_mutability(i,j)
2524
try:
2525
s = self._coerce_element(s)
2526
temp = self.__copy__()
2527
temp.add_multiple_of_column_c(i, j, s, start_row)
2528
return temp
2529
# If scaling factor cannot be coerced, change the base ring to
2530
# one acceptable to both the original base ring and the scaling factor.
2531
except TypeError:
2532
temp = self.change_ring(Sequence([s,self.base_ring()(0)]).universe())
2533
s = temp._coerce_element(s)
2534
temp.add_multiple_of_column_c(i, j, s, start_row)
2535
return temp
2536
2537
def rescale_row(self, Py_ssize_t i, s, Py_ssize_t start_col=0):
2538
"""
2539
Replace i-th row of self by s times i-th row of self.
2540
2541
INPUT:
2542
2543
2544
- ``i`` - ith row
2545
2546
- ``s`` - scalar
2547
2548
- ``start_col`` - only rescale entries at this column
2549
and to the right
2550
2551
2552
EXAMPLES: We rescale the second row of a matrix over the rational
2553
numbers::
2554
2555
sage: a = matrix(QQ,3,range(6)); a
2556
[0 1]
2557
[2 3]
2558
[4 5]
2559
sage: a.rescale_row(1,1/2); a
2560
[ 0 1]
2561
[ 1 3/2]
2562
[ 4 5]
2563
2564
We rescale the second row of a matrix over a polynomial ring::
2565
2566
sage: R.<x> = QQ[]
2567
sage: a = matrix(R,3,[1,x,x^2,x^3,x^4,x^5]);a
2568
[ 1 x]
2569
[x^2 x^3]
2570
[x^4 x^5]
2571
sage: a.rescale_row(1,1/2); a
2572
[ 1 x]
2573
[1/2*x^2 1/2*x^3]
2574
[ x^4 x^5]
2575
2576
We try and fail to rescale a matrix over the integers by a
2577
non-integer::
2578
2579
sage: a = matrix(ZZ,2,3,[0,1,2, 3,4,4]); a
2580
[0 1 2]
2581
[3 4 4]
2582
sage: a.rescale_row(1,1/2)
2583
Traceback (most recent call last):
2584
...
2585
TypeError: Rescaling row by Rational Field element cannot be done over Integer Ring, use change_ring or with_rescaled_row instead.
2586
2587
To rescale the matrix by 1/2, you must change the base ring to the
2588
rationals::
2589
2590
sage: a = a.change_ring(QQ); a
2591
[0 1 2]
2592
[3 4 4]
2593
sage: a.rescale_col(1,1/2); a
2594
[ 0 1/2 2]
2595
[ 3 2 4]
2596
"""
2597
self.check_row_bounds_and_mutability(i, i)
2598
try:
2599
s = self._coerce_element(s)
2600
self.rescale_row_c(i, s, start_col)
2601
except TypeError:
2602
raise TypeError('Rescaling row by %s element cannot be done over %s, use change_ring or with_rescaled_row instead.' % (s.parent(), self.base_ring()))
2603
2604
cdef rescale_row_c(self, Py_ssize_t i, s, Py_ssize_t start_col):
2605
cdef Py_ssize_t j
2606
for j from start_col <= j < self._ncols:
2607
self.set_unsafe(i, j, self.get_unsafe(i, j)*s)
2608
2609
def with_rescaled_row(self, Py_ssize_t i, s, Py_ssize_t start_col=0):
2610
"""
2611
Replaces i-th row of self by s times i-th row of self, returning
2612
new matrix.
2613
2614
EXAMPLES: We rescale the second row of a matrix over the integers::
2615
2616
sage: a = matrix(ZZ,3,2,range(6)); a
2617
[0 1]
2618
[2 3]
2619
[4 5]
2620
sage: b = a.with_rescaled_row(1,-2); b
2621
[ 0 1]
2622
[-4 -6]
2623
[ 4 5]
2624
2625
The original matrix is unchanged::
2626
2627
sage: a
2628
[0 1]
2629
[2 3]
2630
[4 5]
2631
2632
Adding a rational multiple is okay, and reassigning a variable is
2633
okay::
2634
2635
sage: a = a.with_rescaled_row(2,1/3); a
2636
[ 0 1]
2637
[ 2 3]
2638
[4/3 5/3]
2639
"""
2640
cdef Matrix temp
2641
self.check_row_bounds_and_mutability(i,i)
2642
try:
2643
s = self._coerce_element(s)
2644
temp = self.__copy__()
2645
temp.rescale_row_c(i, s, start_col)
2646
return temp
2647
# If scaling factor cannot be coerced, change the base ring to
2648
# one acceptable to both the original base ring and the scaling factor.
2649
except TypeError:
2650
temp = self.change_ring(Sequence([s,self.base_ring()(0)]).universe())
2651
s = temp._coerce_element(s)
2652
temp.rescale_row_c(i, s, start_col)
2653
return temp
2654
2655
def rescale_col(self, Py_ssize_t i, s, Py_ssize_t start_row=0):
2656
"""
2657
Replace i-th col of self by s times i-th col of self.
2658
2659
INPUT:
2660
2661
2662
- ``i`` - ith column
2663
2664
- ``s`` - scalar
2665
2666
- ``start_row`` - only rescale entries at this row
2667
and lower
2668
2669
2670
EXAMPLES: We rescale the last column of a matrix over the rational
2671
numbers::
2672
2673
sage: a = matrix(QQ,2,3,range(6)); a
2674
[0 1 2]
2675
[3 4 5]
2676
sage: a.rescale_col(2,1/2); a
2677
[ 0 1 1]
2678
[ 3 4 5/2]
2679
sage: R.<x> = QQ[]
2680
2681
We rescale the last column of a matrix over a polynomial ring::
2682
2683
sage: a = matrix(R,2,3,[1,x,x^2,x^3,x^4,x^5]); a
2684
[ 1 x x^2]
2685
[x^3 x^4 x^5]
2686
sage: a.rescale_col(2,1/2); a
2687
[ 1 x 1/2*x^2]
2688
[ x^3 x^4 1/2*x^5]
2689
2690
We try and fail to rescale a matrix over the integers by a
2691
non-integer::
2692
2693
sage: a = matrix(ZZ,2,3,[0,1,2, 3,4,4]); a
2694
[0 1 2]
2695
[3 4 4]
2696
sage: a.rescale_col(2,1/2)
2697
Traceback (most recent call last):
2698
...
2699
TypeError: Rescaling column by Rational Field element cannot be done over Integer Ring, use change_ring or with_rescaled_col instead.
2700
2701
To rescale the matrix by 1/2, you must change the base ring to the
2702
rationals::
2703
2704
sage: a = a.change_ring(QQ); a
2705
[0 1 2]
2706
[3 4 4]
2707
sage: a.rescale_col(2,1/2); a
2708
[0 1 1]
2709
[3 4 2]
2710
"""
2711
self.check_column_bounds_and_mutability(i, i)
2712
try:
2713
s = self._coerce_element(s)
2714
self.rescale_col_c(i, s, start_row)
2715
except TypeError:
2716
raise TypeError('Rescaling column by %s element cannot be done over %s, use change_ring or with_rescaled_col instead.' % (s.parent(), self.base_ring()))
2717
2718
cdef rescale_col_c(self, Py_ssize_t i, s, Py_ssize_t start_row):
2719
cdef Py_ssize_t j
2720
for j from start_row <= j < self._nrows:
2721
self.set_unsafe(j, i, self.get_unsafe(j, i)*s)
2722
2723
def with_rescaled_col(self, Py_ssize_t i, s, Py_ssize_t start_row=0):
2724
"""
2725
Replaces i-th col of self by s times i-th col of self, returning
2726
new matrix.
2727
2728
EXAMPLES: We rescale the last column of a matrix over the
2729
integers::
2730
2731
sage: a = matrix(ZZ,2,3,range(6)); a
2732
[0 1 2]
2733
[3 4 5]
2734
sage: b = a.with_rescaled_col(2,-2); b
2735
[ 0 1 -4]
2736
[ 3 4 -10]
2737
2738
The original matrix is unchanged::
2739
2740
sage: a
2741
[0 1 2]
2742
[3 4 5]
2743
2744
Adding a rational multiple is okay, and reassigning a variable is
2745
okay::
2746
2747
sage: a = a.with_rescaled_col(1,1/3); a
2748
[ 0 1/3 2]
2749
[ 3 4/3 5]
2750
"""
2751
cdef Matrix temp
2752
self.check_column_bounds_and_mutability(i,i)
2753
try:
2754
s = self._coerce_element(s)
2755
temp = self.__copy__()
2756
temp.rescale_col_c(i, s, start_row)
2757
return temp
2758
# If scaling factor cannot be coerced, change the base ring to
2759
# one acceptable to both the original base ring and the scaling factor.
2760
except TypeError:
2761
temp = self.change_ring(Sequence([s,self.base_ring()(0)]).universe())
2762
s = temp._coerce_element(s)
2763
temp.rescale_col_c(i, s, start_row)
2764
return temp
2765
2766
def set_row_to_multiple_of_row(self, Py_ssize_t i, Py_ssize_t j, s):
2767
"""
2768
Set row i equal to s times row j.
2769
2770
EXAMPLES: We change the second row to -3 times the first row::
2771
2772
sage: a = matrix(ZZ,2,3,range(6)); a
2773
[0 1 2]
2774
[3 4 5]
2775
sage: a.set_row_to_multiple_of_row(1,0,-3)
2776
sage: a
2777
[ 0 1 2]
2778
[ 0 -3 -6]
2779
2780
If we try to multiply a row by a rational number, we get an error
2781
message::
2782
2783
sage: a.set_row_to_multiple_of_row(1,0,1/2)
2784
Traceback (most recent call last):
2785
...
2786
TypeError: Multiplying row by Rational Field element cannot be done over Integer Ring, use change_ring or with_row_set_to_multiple_of_row instead.
2787
"""
2788
self.check_row_bounds_and_mutability(i,j)
2789
cdef Py_ssize_t n
2790
try:
2791
s = self._coerce_element(s)
2792
for n from 0 <= n < self._ncols:
2793
self.set_unsafe(i, n, s * self.get_unsafe(j, n)) # self[i] = s*self[j]
2794
except TypeError:
2795
raise TypeError('Multiplying row by %s element cannot be done over %s, use change_ring or with_row_set_to_multiple_of_row instead.' % (s.parent(), self.base_ring()))
2796
2797
def with_row_set_to_multiple_of_row(self, Py_ssize_t i, Py_ssize_t j, s):
2798
"""
2799
Set row i equal to s times row j, returning a new matrix.
2800
2801
EXAMPLES: We change the second row to -3 times the first row::
2802
2803
sage: a = matrix(ZZ,2,3,range(6)); a
2804
[0 1 2]
2805
[3 4 5]
2806
sage: b = a.with_row_set_to_multiple_of_row(1,0,-3); b
2807
[ 0 1 2]
2808
[ 0 -3 -6]
2809
2810
Note that the original matrix is unchanged::
2811
2812
sage: a
2813
[0 1 2]
2814
[3 4 5]
2815
2816
Adding a rational multiple is okay, and reassigning a variable is
2817
okay::
2818
2819
sage: a = a.with_row_set_to_multiple_of_row(1,0,1/2); a
2820
[ 0 1 2]
2821
[ 0 1/2 1]
2822
"""
2823
self.check_row_bounds_and_mutability(i,j)
2824
cdef Matrix temp
2825
cdef Py_ssize_t n
2826
try:
2827
s = self._coerce_element(s)
2828
temp = self.__copy__()
2829
for n from 0 <= n < temp._ncols:
2830
temp.set_unsafe(i, n, s * temp.get_unsafe(j, n)) # temp[i] = s*temp[j]
2831
return temp
2832
# If scaling factor cannot be coerced, change the base ring to
2833
# one acceptable to both the original base ring and the scaling factor.
2834
except TypeError:
2835
temp = self.change_ring(Sequence([s,self.base_ring()(0)]).universe())
2836
s = temp._coerce_element(s)
2837
for n from 0 <= n < temp._ncols:
2838
temp.set_unsafe(i, n, s * temp.get_unsafe(j, n)) # temp[i] = s*temp[j]
2839
return temp
2840
2841
def set_col_to_multiple_of_col(self, Py_ssize_t i, Py_ssize_t j, s):
2842
"""
2843
Set column i equal to s times column j.
2844
2845
EXAMPLES: We change the second column to -3 times the first
2846
column.
2847
2848
::
2849
2850
sage: a = matrix(ZZ,2,3,range(6)); a
2851
[0 1 2]
2852
[3 4 5]
2853
sage: a.set_col_to_multiple_of_col(1,0,-3)
2854
sage: a
2855
[ 0 0 2]
2856
[ 3 -9 5]
2857
2858
If we try to multiply a column by a rational number, we get an
2859
error message::
2860
2861
sage: a.set_col_to_multiple_of_col(1,0,1/2)
2862
Traceback (most recent call last):
2863
...
2864
TypeError: Multiplying column by Rational Field element cannot be done over Integer Ring, use change_ring or with_col_set_to_multiple_of_col instead.
2865
"""
2866
self.check_column_bounds_and_mutability(i,j)
2867
cdef Py_ssize_t n
2868
try:
2869
s = self._coerce_element(s)
2870
for n from 0 <= n < self._nrows:
2871
self.set_unsafe(n, i, s * self.get_unsafe(n, j))
2872
# If scaling factor cannot be coerced, change the base ring to
2873
# one acceptable to both the original base ring and the scaling factor.
2874
except TypeError:
2875
raise TypeError('Multiplying column by %s element cannot be done over %s, use change_ring or with_col_set_to_multiple_of_col instead.' % (s.parent(), self.base_ring()))
2876
2877
def with_col_set_to_multiple_of_col(self, Py_ssize_t i, Py_ssize_t j, s):
2878
"""
2879
Set column i equal to s times column j, returning a new matrix.
2880
2881
EXAMPLES: We change the second column to -3 times the first
2882
column.
2883
2884
::
2885
2886
sage: a = matrix(ZZ,2,3,range(6)); a
2887
[0 1 2]
2888
[3 4 5]
2889
sage: b = a.with_col_set_to_multiple_of_col(1,0,-3); b
2890
[ 0 0 2]
2891
[ 3 -9 5]
2892
2893
Note that the original matrix is unchanged::
2894
2895
sage: a
2896
[0 1 2]
2897
[3 4 5]
2898
2899
Adding a rational multiple is okay, and reassigning a variable is
2900
okay::
2901
2902
sage: a = a.with_col_set_to_multiple_of_col(1,0,1/2); a
2903
[ 0 0 2]
2904
[ 3 3/2 5]
2905
"""
2906
self.check_column_bounds_and_mutability(i,j)
2907
cdef Py_ssize_t n
2908
cdef Matrix temp
2909
try:
2910
s = self._coerce_element(s)
2911
temp = self.__copy__()
2912
for n from 0 <= n < temp._nrows:
2913
temp.set_unsafe(n, i, s * temp.get_unsafe(n, j))
2914
return temp
2915
# If scaling factor cannot be coerced, change the base ring to
2916
# one acceptable to both the original base ring and the scaling factor.
2917
except TypeError:
2918
temp = self.change_ring(Sequence([s,self.base_ring()(0)]).universe())
2919
s = temp._coerce_element(s)
2920
for n from 0 <= n < temp._nrows:
2921
temp.set_unsafe(n, i, s * temp.get_unsafe(n, j))
2922
return temp
2923
2924
def _set_row_to_negative_of_row_of_A_using_subset_of_columns(self, Py_ssize_t i, Matrix A,
2925
Py_ssize_t r, cols,
2926
cols_index=None):
2927
"""
2928
Set row i of self to -(row r of A), but where we only take the
2929
given column positions in that row of A. We do not zero out the
2930
other entries of self's row i either.
2931
2932
INPUT:
2933
2934
2935
- ``i`` - integer, index into the rows of self
2936
2937
- ``A`` - a matrix
2938
2939
- ``r`` - integer, index into rows of A
2940
2941
- ``cols`` - a *sorted* list of integers.
2942
2943
- ``(cols_index`` - ignored)
2944
2945
2946
EXAMPLES::
2947
2948
sage: a = matrix(QQ,2,3,range(6)); a
2949
[0 1 2]
2950
[3 4 5]
2951
sage: a._set_row_to_negative_of_row_of_A_using_subset_of_columns(0,a,1,[1,2])
2952
sage: a
2953
[-4 -5 2]
2954
[ 3 4 5]
2955
"""
2956
self.check_row_bounds_and_mutability(i,i)
2957
if r < 0 or r >= A.nrows():
2958
raise IndexError("invalid row")
2959
# this function exists just because it is useful for modular symbols presentations.
2960
cdef Py_ssize_t l
2961
l = 0
2962
for k in cols:
2963
self.set_unsafe(i,l,-A.get_unsafe(r,k)) #self[i,l] = -A[r,k]
2964
l += 1
2965
2966
###################################################
2967
# Methods needed for quiver and cluster mutations
2968
# - mutate
2969
# - _travel_column
2970
# - is_symmetrizable
2971
# - is_skew_symmetrizable
2972
# - _check_symmetrizability
2973
#
2974
# AUTHORS:
2975
# -- Christian Stump (Jun 2011)
2976
###################################################
2977
2978
def mutate(self, Py_ssize_t k ):
2979
"""
2980
Mutates ``self`` at row and column index ``k``.
2981
2982
.. warning:: Only makes sense if ``self`` is skew-symmetrizable.
2983
2984
INPUT:
2985
2986
- ``k`` -- integer at which row/column ``self`` is mutated.
2987
2988
EXAMPLES:
2989
2990
Mutation of the B-matrix of the quiver of type `A_3`::
2991
2992
sage: M = matrix(ZZ,3,[0,1,0,-1,0,-1,0,1,0]); M
2993
[ 0 1 0]
2994
[-1 0 -1]
2995
[ 0 1 0]
2996
2997
sage: M.mutate(0); M
2998
[ 0 -1 0]
2999
[ 1 0 -1]
3000
[ 0 1 0]
3001
3002
sage: M.mutate(1); M
3003
[ 0 1 -1]
3004
[-1 0 1]
3005
[ 1 -1 0]
3006
3007
sage: M = matrix(ZZ,6,[0,1,0,-1,0,-1,0,1,0,1,0,0,0,1,0,0,0,1]); M
3008
[ 0 1 0]
3009
[-1 0 -1]
3010
[ 0 1 0]
3011
[ 1 0 0]
3012
[ 0 1 0]
3013
[ 0 0 1]
3014
3015
sage: M.mutate(0); M
3016
[ 0 -1 0]
3017
[ 1 0 -1]
3018
[ 0 1 0]
3019
[-1 1 0]
3020
[ 0 1 0]
3021
[ 0 0 1]
3022
3023
REFERENCES:
3024
3025
- [FZ2001] S. Fomin, A. Zelevinsky. Cluster Algebras 1: Foundations, arXiv:math/0104151 (2001).
3026
"""
3027
cdef Py_ssize_t i,j,_
3028
cdef list pairs, k0_pairs, k1_pairs
3029
3030
if k < 0 or k >= self._nrows or k >= self._ncols:
3031
raise IndexError("The mutation index is invalid")
3032
3033
pairs = self.nonzero_positions()
3034
k0_pairs = [ pair for pair in pairs if pair[0] == k ]
3035
k1_pairs = [ pair for pair in pairs if pair[1] == k ]
3036
for _,j in k0_pairs:
3037
self[k,j] = -self.get_unsafe(k,j)
3038
for i,_ in k1_pairs:
3039
self[i,k] = -self.get_unsafe(i,k)
3040
3041
for i,_ in k1_pairs:
3042
ik = self.get_unsafe(i,k)
3043
ineg = True if ik < 0 else False
3044
for _,j in k0_pairs:
3045
kj = self.get_unsafe(k,j)
3046
jneg = True if kj < 0 else False
3047
if ineg == jneg == True:
3048
self[i,j] = self.get_unsafe(i,j) + self.get_unsafe(i,k)*self.get_unsafe(k,j)
3049
elif ineg == jneg == False:
3050
self[i,j] = self.get_unsafe(i,j) - self.get_unsafe(i,k)*self.get_unsafe(k,j)
3051
3052
def _travel_column( self, dict d, int k, int sign, positive ):
3053
r"""
3054
Helper function for testing symmetrizability. Tests dependencies within entries in ``self`` and entries in the dictionary ``d``.
3055
3056
.. warning:: the dictionary ``d`` gets new values for keys in L.
3057
3058
INPUT:
3059
3060
- ``d`` -- dictionary modelling partial entries of a diagonal matrix.
3061
3062
- ``k`` -- integer for which row and column of self should be tested with the dictionary d.
3063
3064
- ``sign`` -- `\pm 1`, depending on symmetric or skew-symmetric is tested.
3065
3066
- ``positive`` -- if True, only positive entries for the values of the dictionary are allowed.
3067
3068
OUTPUT:
3069
3070
- ``L`` -- list of new keys in d
3071
3072
EXAMPLES::
3073
3074
sage: M = matrix(ZZ,3,[0,1,0,-1,0,-1,0,1,0]); M
3075
[ 0 1 0]
3076
[-1 0 -1]
3077
[ 0 1 0]
3078
3079
sage: M._travel_column({0:1},0,-1,True)
3080
[1]
3081
"""
3082
cdef list L = []
3083
cdef int i
3084
3085
for i from 0 <= i < self._ncols:
3086
if i not in d:
3087
self_ik = self.get_unsafe(i,k)
3088
self_ki = self.get_unsafe(k,i)
3089
if bool(self_ik) != bool(self_ki):
3090
return False
3091
if self_ik != 0:
3092
L.append(i)
3093
d[i] = sign * d[k] * self_ki / self_ik
3094
if positive and not d[i] > 0:
3095
return False
3096
for j in d:
3097
if d[i] * self.get_unsafe(i,j) != sign * d[j] * self.get_unsafe(j,i):
3098
return False
3099
return L
3100
3101
def _check_symmetrizability(self, return_diag=False, skew=False, positive=True):
3102
r"""
3103
This function takes a square matrix over an *ordered integral domain* and checks if it is (skew-)symmetrizable.
3104
A matrix `B` is (skew-)symmetrizable iff there exists an invertible diagonal matrix `D` such that `DB` is (skew-)symmetric.
3105
3106
INPUT:
3107
3108
- ``return_diag`` -- bool(default:False) if True and ``self`` is (skew)-symmetrizable the diagonal entries of the matrix `D` are returned.
3109
- ``skew`` -- bool(default:False) if True, (skew-)symmetrizability is checked.
3110
- ``positive`` -- bool(default:True) if True, the condition that `D` has positive entries is added.
3111
3112
OUTPUT:
3113
3114
- True -- if ``self`` is (skew-)symmetrizable and ``return_diag`` is False
3115
- the diagonal entries of the matrix `D` such that `DB` is (skew-)symmetric -- iff ``self`` is (skew-)symmetrizable and ``return_diag`` is True
3116
- False -- iff ``self`` is not (skew-)symmetrizable
3117
3118
EXAMPLES::
3119
3120
sage: matrix([[0,6],[3,0]])._check_symmetrizability(positive=False)
3121
True
3122
sage: matrix([[0,6],[3,0]])._check_symmetrizability(positive=True)
3123
True
3124
sage: matrix([[0,6],[3,0]])._check_symmetrizability(skew=True, positive=False)
3125
True
3126
sage: matrix([[0,6],[3,0]])._check_symmetrizability(skew=True, positive=True)
3127
False
3128
3129
REFERENCES:
3130
3131
- [FZ2001] S. Fomin, A. Zelevinsky. Cluster Algebras 1: Foundations, arXiv:math/0104151 (2001).
3132
"""
3133
cdef dict d = {}
3134
cdef list queue = range( self._ncols )
3135
cdef int l, sign, i, j
3136
3137
if skew:
3138
# testing the diagonal entries to be zero
3139
zero = self.parent().base_ring().zero()
3140
for i from 0 <= i < self._nrows:
3141
if not self.get_unsafe(i,i) == zero:
3142
return False
3143
sign = -1
3144
else:
3145
sign = 1
3146
3147
while queue:
3148
i = queue.pop(0)
3149
d[i] = 1
3150
L = self._travel_column( d, i, sign, positive )
3151
if L is False:
3152
return False
3153
while L:
3154
l = L.pop(0)
3155
queue.remove( l )
3156
L_prime = self._travel_column( d, l, sign, positive )
3157
if L_prime is False:
3158
return False
3159
else:
3160
L.extend( L_prime )
3161
if return_diag:
3162
return [ d[i] for i in xrange(self._nrows) ]
3163
else:
3164
return True
3165
3166
###################################################
3167
# Matrix-vector multiply
3168
###################################################
3169
def linear_combination_of_rows(self, v):
3170
r"""
3171
Return the linear combination of the rows of ``self`` given by the
3172
coefficients in the list ``v``.
3173
3174
INPUT:
3175
3176
- ``v`` - a list of scalars. The length can be less than
3177
the number of rows of ``self`` but not greater.
3178
3179
OUTPUT:
3180
3181
The vector (or free module element) that is a linear
3182
combination of the rows of ``self``. If the list of
3183
scalars has fewer entries than the number of rows,
3184
additional zeros are appended to the list until it
3185
has as many entries as the number of rows.
3186
3187
EXAMPLES::
3188
3189
sage: a = matrix(ZZ,2,3,range(6)); a
3190
[0 1 2]
3191
[3 4 5]
3192
sage: a.linear_combination_of_rows([1,2])
3193
(6, 9, 12)
3194
3195
sage: a.linear_combination_of_rows([0,0])
3196
(0, 0, 0)
3197
3198
sage: a.linear_combination_of_rows([1/2,2/3])
3199
(2, 19/6, 13/3)
3200
3201
The list ``v`` can be anything that is iterable. Perhaps most
3202
naturally, a vector may be used. ::
3203
3204
sage: v = vector(ZZ, [1,2])
3205
sage: a.linear_combination_of_rows(v)
3206
(6, 9, 12)
3207
3208
We check that a matrix with no rows behaves properly. ::
3209
3210
sage: matrix(QQ,0,2).linear_combination_of_rows([])
3211
(0, 0)
3212
3213
The object returned is a vector, or a free module element. ::
3214
3215
sage: B = matrix(ZZ, 4, 3, range(12))
3216
sage: w = B.linear_combination_of_rows([-1,2,-3,4])
3217
sage: w
3218
(24, 26, 28)
3219
sage: w.parent()
3220
Ambient free module of rank 3 over the principal ideal domain Integer Ring
3221
sage: x = B.linear_combination_of_rows([1/2,1/3,1/4,1/5])
3222
sage: x
3223
(43/10, 67/12, 103/15)
3224
sage: x.parent()
3225
Vector space of dimension 3 over Rational Field
3226
3227
The length of v can be less than the number of rows, but not
3228
greater. ::
3229
3230
sage: A = matrix(QQ,3,4,range(12))
3231
sage: A.linear_combination_of_rows([2,3])
3232
(12, 17, 22, 27)
3233
sage: A.linear_combination_of_rows([1,2,3,4])
3234
Traceback (most recent call last):
3235
...
3236
ValueError: length of v must be at most the number of rows of self
3237
"""
3238
if len(v) > self._nrows:
3239
raise ValueError("length of v must be at most the number of rows of self")
3240
if self._nrows == 0:
3241
return self.parent().row_space().zero_vector()
3242
from constructor import matrix
3243
v = matrix(list(v)+[0]*(self._nrows-len(v)))
3244
return (v * self)[0]
3245
3246
def linear_combination_of_columns(self, v):
3247
r"""
3248
Return the linear combination of the columns of ``self`` given by the
3249
coefficients in the list ``v``.
3250
3251
INPUT:
3252
3253
- ``v`` - a list of scalars. The length can be less than
3254
the number of columns of ``self`` but not greater.
3255
3256
OUTPUT:
3257
3258
The vector (or free module element) that is a linear
3259
combination of the columns of ``self``. If the list of
3260
scalars has fewer entries than the number of columns,
3261
additional zeros are appended to the list until it
3262
has as many entries as the number of columns.
3263
3264
EXAMPLES::
3265
3266
sage: a = matrix(ZZ,2,3,range(6)); a
3267
[0 1 2]
3268
[3 4 5]
3269
sage: a.linear_combination_of_columns([1,1,1])
3270
(3, 12)
3271
3272
sage: a.linear_combination_of_columns([0,0,0])
3273
(0, 0)
3274
3275
sage: a.linear_combination_of_columns([1/2,2/3,3/4])
3276
(13/6, 95/12)
3277
3278
The list ``v`` can be anything that is iterable. Perhaps most
3279
naturally, a vector may be used. ::
3280
3281
sage: v = vector(ZZ, [1,2,3])
3282
sage: a.linear_combination_of_columns(v)
3283
(8, 26)
3284
3285
We check that a matrix with no columns behaves properly. ::
3286
3287
sage: matrix(QQ,2,0).linear_combination_of_columns([])
3288
(0, 0)
3289
3290
The object returned is a vector, or a free module element. ::
3291
3292
sage: B = matrix(ZZ, 4, 3, range(12))
3293
sage: w = B.linear_combination_of_columns([-1,2,-3])
3294
sage: w
3295
(-4, -10, -16, -22)
3296
sage: w.parent()
3297
Ambient free module of rank 4 over the principal ideal domain Integer Ring
3298
sage: x = B.linear_combination_of_columns([1/2,1/3,1/4])
3299
sage: x
3300
(5/6, 49/12, 22/3, 127/12)
3301
sage: x.parent()
3302
Vector space of dimension 4 over Rational Field
3303
3304
The length of v can be less than the number of columns, but not
3305
greater. ::
3306
3307
sage: A = matrix(QQ,3,5, range(15))
3308
sage: A.linear_combination_of_columns([1,-2,3,-4])
3309
(-8, -18, -28)
3310
sage: A.linear_combination_of_columns([1,2,3,4,5,6])
3311
Traceback (most recent call last):
3312
...
3313
ValueError: length of v must be at most the number of columns of self
3314
"""
3315
if len(v) > self._ncols:
3316
raise ValueError("length of v must be at most the number of columns of self")
3317
if self._ncols == 0:
3318
return self.parent().column_space().zero_vector()
3319
from constructor import matrix
3320
v = matrix(self._ncols, 1, list(v)+[0]*(self._ncols-len(v)))
3321
return (self * v).column(0)
3322
3323
###################################################
3324
# Predicates
3325
###################################################
3326
3327
def is_symmetric(self):
3328
"""
3329
Returns True if this is a symmetric matrix.
3330
3331
EXAMPLES::
3332
3333
sage: m=Matrix(QQ,2,range(0,4))
3334
sage: m.is_symmetric()
3335
False
3336
3337
sage: m=Matrix(QQ,2,(1,1,1,1,1,1))
3338
sage: m.is_symmetric()
3339
False
3340
3341
sage: m=Matrix(QQ,1,(2,))
3342
sage: m.is_symmetric()
3343
True
3344
3345
"""
3346
if self._ncols != self._nrows: return False
3347
# could be bigger than an int on a 64-bit platform, this
3348
# is the type used for indexing.
3349
cdef Py_ssize_t i,j
3350
3351
for i from 0 <= i < self._nrows:
3352
for j from 0 <= j < i:
3353
if self.get_unsafe(i,j) != self.get_unsafe(j,i):
3354
return False
3355
return True
3356
3357
def is_hermitian(self):
3358
r"""
3359
Returns ``True`` if the matrix is equal to its conjugate-transpose.
3360
3361
OUTPUT:
3362
3363
``True`` if the matrix is square and equal to the transpose
3364
with every entry conjugated, and ``False`` otherwise.
3365
3366
Note that if conjugation has no effect on elements of the base
3367
ring (such as for integers), then the :meth:`is_symmetric`
3368
method is equivalent and faster.
3369
3370
This routine is for matrices over exact rings and so may not
3371
work properly for matrices over ``RR`` or ``CC``. For matrices with
3372
approximate entries, the rings of double-precision floating-point
3373
numbers, ``RDF`` and ``CDF``, are a better choice since the
3374
:meth:`sage.matrix.matrix_double_dense.Matrix_double_dense.is_hermitian`
3375
method has a tolerance parameter. This provides control over
3376
allowing for minor discrepancies between entries when checking
3377
equality.
3378
3379
The result is cached.
3380
3381
EXAMPLES::
3382
3383
sage: A = matrix(QQbar, [[ 1 + I, 1 - 6*I, -1 - I],
3384
... [-3 - I, -4*I, -2],
3385
... [-1 + I, -2 - 8*I, 2 + I]])
3386
sage: A.is_hermitian()
3387
False
3388
sage: B = A*A.conjugate_transpose()
3389
sage: B.is_hermitian()
3390
True
3391
3392
Sage has several fields besides the entire complex numbers
3393
where conjugation is non-trivial. ::
3394
3395
sage: F.<b> = QuadraticField(-7)
3396
sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3],
3397
... [-2*b - 3, -3*b + 2, -2*b],
3398
... [ b + 1, 0, -2]])
3399
sage: C.is_hermitian()
3400
False
3401
sage: C = C*C.conjugate_transpose()
3402
sage: C.is_hermitian()
3403
True
3404
3405
A matrix that is nearly Hermitian, but for a non-real
3406
diagonal entry. ::
3407
3408
sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I],
3409
... [ 2+I, 3+I, 2-6*I],
3410
... [1-4*I, 2+6*I, 5]])
3411
sage: A.is_hermitian()
3412
False
3413
sage: A[1,1] = 132
3414
sage: A.is_hermitian()
3415
True
3416
3417
Rectangular matrices are never Hermitian. ::
3418
3419
sage: A = matrix(QQbar, 3, 4)
3420
sage: A.is_hermitian()
3421
False
3422
3423
A square, empty matrix is trivially Hermitian. ::
3424
3425
sage: A = matrix(QQ, 0, 0)
3426
sage: A.is_hermitian()
3427
True
3428
"""
3429
key = 'hermitian'
3430
h = self.fetch(key)
3431
if not h is None:
3432
return h
3433
if not self.is_square():
3434
self.cache(key, False)
3435
return False
3436
if self._nrows == 0:
3437
self.cache(key, True)
3438
return True
3439
3440
cdef Py_ssize_t i,j
3441
hermitian = True
3442
for i in range(self._nrows):
3443
for j in range(i+1):
3444
if self.get_unsafe(i,j) != self.get_unsafe(j,i).conjugate():
3445
hermitian = False
3446
break
3447
if not hermitian:
3448
break
3449
self.cache(key, hermitian)
3450
return hermitian
3451
3452
def is_skew_symmetric(self):
3453
"""
3454
Returns True if this is a skew symmetric matrix.
3455
3456
EXAMPLES::
3457
3458
sage: m = matrix(QQ, [[0,2], [-2,0]])
3459
sage: m.is_skew_symmetric()
3460
True
3461
sage: m = matrix(QQ, [[1,2], [2,1]])
3462
sage: m.is_skew_symmetric()
3463
False
3464
"""
3465
if self._ncols != self._nrows: return False
3466
# could be bigger than an int on a 64-bit platform, this
3467
# is the type used for indexing.
3468
cdef Py_ssize_t i,j
3469
3470
for i from 0 <= i < self._nrows:
3471
for j from 0 <= j <= i:
3472
if self.get_unsafe(i,j) != -self.get_unsafe(j,i):
3473
return False
3474
return True
3475
3476
def is_symmetrizable(self, return_diag=False, positive=True):
3477
r"""
3478
This function takes a square matrix over an *ordered integral domain* and checks if it is symmetrizable.
3479
A matrix `B` is symmetrizable iff there exists an invertible diagonal matrix `D` such that `DB` is symmetric.
3480
3481
.. warning:: Expects ``self`` to be a matrix over an *ordered integral domain*.
3482
3483
INPUT:
3484
3485
- ``return_diag`` -- bool(default:False) if True and ``self`` is symmetrizable the diagonal entries of the matrix `D` are returned.
3486
- ``positive`` -- bool(default:True) if True, the condition that `D` has positive entries is added.
3487
3488
OUTPUT:
3489
3490
- True -- if ``self`` is symmetrizable and ``return_diag`` is False
3491
- the diagonal entries of a matrix `D` such that `DB` is symmetric -- iff ``self`` is symmetrizable and ``return_diag`` is True
3492
- False -- iff ``self`` is not symmetrizable
3493
3494
EXAMPLES::
3495
3496
sage: matrix([[0,6],[3,0]]).is_symmetrizable(positive=False)
3497
True
3498
3499
sage: matrix([[0,6],[3,0]]).is_symmetrizable(positive=True)
3500
True
3501
3502
sage: matrix([[0,6],[0,0]]).is_symmetrizable(return_diag=True)
3503
False
3504
3505
sage: matrix([2]).is_symmetrizable(positive=True)
3506
True
3507
3508
sage: matrix([[1,2],[3,4]]).is_symmetrizable(return_diag=true)
3509
[1, 2/3]
3510
3511
REFERENCES:
3512
3513
- [FZ2001] S. Fomin, A. Zelevinsky. Cluster Algebras 1: Foundations, arXiv:math/0104151 (2001).
3514
"""
3515
if self._ncols != self._nrows:
3516
raise ValueError, "The matrix is not a square matrix"
3517
return self._check_symmetrizability(return_diag=return_diag, skew=False, positive=positive)
3518
3519
def is_skew_symmetrizable(self, return_diag=False, positive=True):
3520
r"""
3521
This function takes a square matrix over an *ordered integral domain* and checks if it is skew-symmetrizable.
3522
A matrix `B` is skew-symmetrizable iff there exists an invertible diagonal matrix `D` such that `DB` is skew-symmetric.
3523
3524
.. warning:: Expects ``self`` to be a matrix over an *ordered integral domain*.
3525
3526
INPUT:
3527
3528
- ``return_diag`` -- bool(default:False) if True and ``self`` is skew-symmetrizable the diagonal entries of the matrix `D` are returned.
3529
- ``positive`` -- bool(default:True) if True, the condition that `D` has positive entries is added.
3530
3531
OUTPUT:
3532
3533
- True -- if ``self`` is skew-symmetrizable and ``return_diag`` is False
3534
- the diagonal entries of a matrix `D` such that `DB` is skew-symmetric -- iff ``self`` is skew-symmetrizable and ``return_diag`` is True
3535
- False -- iff ``self`` is not skew-symmetrizable
3536
3537
EXAMPLES::
3538
3539
sage: matrix([[0,6],[3,0]]).is_skew_symmetrizable(positive=False)
3540
True
3541
sage: matrix([[0,6],[3,0]]).is_skew_symmetrizable(positive=True)
3542
False
3543
3544
sage: M = matrix(4,[0,1,0,0,-1,0,-1,0,0,2,0,1,0,0,-1,0]); M
3545
[ 0 1 0 0]
3546
[-1 0 -1 0]
3547
[ 0 2 0 1]
3548
[ 0 0 -1 0]
3549
3550
sage: M.is_skew_symmetrizable(return_diag=True)
3551
[1, 1, 1/2, 1/2]
3552
3553
sage: M2 = diagonal_matrix([1,1,1/2,1/2])*M; M2
3554
[ 0 1 0 0]
3555
[ -1 0 -1 0]
3556
[ 0 1 0 1/2]
3557
[ 0 0 -1/2 0]
3558
3559
sage: M2.is_skew_symmetric()
3560
True
3561
3562
REFERENCES:
3563
3564
- [FZ2001] S. Fomin, A. Zelevinsky. Cluster Algebras 1: Foundations, arXiv:math/0104151 (2001).
3565
"""
3566
if self._ncols != self._nrows:
3567
raise ValueError, "The matrix is not a square matrix"
3568
return self._check_symmetrizability(return_diag=return_diag, skew=True, positive=positive)
3569
3570
def is_dense(self):
3571
"""
3572
Returns True if this is a dense matrix.
3573
3574
In Sage, being dense is a property of the underlying
3575
representation, not the number of nonzero entries.
3576
3577
EXAMPLES::
3578
3579
sage: matrix(QQ,2,2,range(4)).is_dense()
3580
True
3581
sage: matrix(QQ,2,2,range(4),sparse=True).is_dense()
3582
False
3583
"""
3584
return self.is_dense_c()
3585
3586
def is_sparse(self):
3587
"""
3588
Return True if this is a sparse matrix.
3589
3590
In Sage, being sparse is a property of the underlying
3591
representation, not the number of nonzero entries.
3592
3593
EXAMPLES::
3594
3595
sage: matrix(QQ,2,2,range(4)).is_sparse()
3596
False
3597
sage: matrix(QQ,2,2,range(4),sparse=True).is_sparse()
3598
True
3599
"""
3600
return self.is_sparse_c()
3601
3602
def is_square(self):
3603
"""
3604
Return True precisely if this matrix is square, i.e., has the same
3605
number of rows and columns.
3606
3607
EXAMPLES::
3608
3609
sage: matrix(QQ,2,2,range(4)).is_square()
3610
True
3611
sage: matrix(QQ,2,3,range(6)).is_square()
3612
False
3613
"""
3614
return self._nrows == self._ncols
3615
3616
def is_invertible(self):
3617
r"""
3618
Return True if this matrix is invertible.
3619
3620
EXAMPLES: The following matrix is invertible over
3621
`\QQ` but not over `\ZZ`.
3622
3623
::
3624
3625
sage: A = MatrixSpace(ZZ, 2)(range(4))
3626
sage: A.is_invertible()
3627
False
3628
sage: A.matrix_over_field().is_invertible()
3629
True
3630
3631
The inverse function is a constructor for matrices over the
3632
fraction field, so it can work even if A is not invertible.
3633
3634
::
3635
3636
sage: ~A # inverse of A
3637
[-3/2 1/2]
3638
[ 1 0]
3639
3640
The next matrix is invertible over `\ZZ`.
3641
3642
::
3643
3644
sage: A = MatrixSpace(IntegerRing(),2)([1,10,0,-1])
3645
sage: A.is_invertible()
3646
True
3647
sage: ~A # compute the inverse
3648
[ 1 10]
3649
[ 0 -1]
3650
3651
The following nontrivial matrix is invertible over
3652
`\ZZ[x]`.
3653
3654
::
3655
3656
sage: R.<x> = PolynomialRing(IntegerRing())
3657
sage: A = MatrixSpace(R,2)([1,x,0,-1])
3658
sage: A.is_invertible()
3659
True
3660
sage: ~A
3661
[ 1 x]
3662
[ 0 -1]
3663
"""
3664
return self.is_square() and self.determinant().is_unit()
3665
3666
def is_singular(self):
3667
r"""
3668
Returns ``True`` if ``self`` is singular.
3669
3670
OUTPUT:
3671
3672
A square matrix is singular if it has a zero
3673
determinant and this method will return ``True``
3674
in exactly this case. When the entries of the
3675
matrix come from a field, this is equivalent
3676
to having a nontrivial kernel, or lacking an
3677
inverse, or having linearly dependent rows,
3678
or having linearly dependent columns.
3679
3680
For square matrices over a field the methods
3681
:meth:`is_invertible` and :meth:`is_singular`
3682
are logical opposites. However, it is an error
3683
to apply :meth:`is_singular` to a matrix that
3684
is not square, while :meth:`is_invertible` will
3685
always return ``False`` for a matrix that is not
3686
square.
3687
3688
EXAMPLES:
3689
3690
A singular matrix over the field ``QQ``. ::
3691
3692
sage: A = matrix(QQ, 4, [-1,2,-3,6,0,-1,-1,0,-1,1,-5,7,-1,6,5,2])
3693
sage: A.is_singular()
3694
True
3695
sage: A.right_kernel().dimension()
3696
1
3697
3698
A matrix that is not singular, i.e. nonsingular, over a field. ::
3699
3700
sage: B = matrix(QQ, 4, [1,-3,-1,-5,2,-5,-2,-7,-2,5,3,4,-1,4,2,6])
3701
sage: B.is_singular()
3702
False
3703
sage: B.left_kernel().dimension()
3704
0
3705
3706
For "rectangular" matrices, invertibility is always
3707
``False``, but asking about singularity will give an error. ::
3708
3709
sage: C = matrix(QQ, 5, range(30))
3710
sage: C.is_invertible()
3711
False
3712
sage: C.is_singular()
3713
Traceback (most recent call last):
3714
...
3715
ValueError: self must be a square matrix
3716
3717
When the base ring is not a field, then a matrix
3718
may be both not invertible and not singular. ::
3719
3720
sage: D = matrix(ZZ, 4, [2,0,-4,8,2,1,-2,7,2,5,7,0,0,1,4,-6])
3721
sage: D.is_invertible()
3722
False
3723
sage: D.is_singular()
3724
False
3725
sage: d = D.determinant(); d
3726
2
3727
sage: d.is_unit()
3728
False
3729
"""
3730
if self.ncols() == self.nrows():
3731
return self.rank() != self.nrows()
3732
else:
3733
raise ValueError("self must be a square matrix")
3734
3735
###################################################
3736
# Invariants of a matrix
3737
###################################################
3738
3739
def pivots(self):
3740
"""
3741
Return the pivot column positions of this matrix.
3742
3743
OUTPUT: a tuple of Python integers: the position of the
3744
first nonzero entry in each row of the echelon form.
3745
3746
This returns a tuple so it is immutable; see #10752.
3747
3748
EXAMPLES:
3749
3750
sage: A = matrix(QQ, 2, 2, range(4))
3751
sage: A.pivots()
3752
(0, 1)
3753
"""
3754
x = self.fetch('pivots')
3755
if not x is None: return tuple(x)
3756
self.echelon_form()
3757
x = self.fetch('pivots')
3758
if x is None:
3759
print self
3760
print self.nrows()
3761
print self.dict()
3762
raise RuntimeError("BUG: matrix pivots should have been set but weren't, matrix parent = '%s'"%self.parent())
3763
return tuple(x)
3764
3765
def rank(self):
3766
"""
3767
3768
TESTS:
3769
3770
We should be able to compute the rank of a matrix whose
3771
entries are polynomials over a finite field (trac #5014)::
3772
3773
sage: P.<x> = PolynomialRing(GF(17))
3774
sage: m = matrix(P, [ [ 6*x^2 + 8*x + 12, 10*x^2 + 4*x + 11],
3775
... [8*x^2 + 12*x + 15, 8*x^2 + 9*x + 16] ])
3776
sage: m.rank()
3777
2
3778
3779
"""
3780
x = self.fetch('rank')
3781
if not x is None: return x
3782
if self._nrows == 0 or self._ncols == 0:
3783
return 0
3784
r = len(self.pivots())
3785
self.cache('rank', r)
3786
return r
3787
3788
cdef _set_pivots(self, X):
3789
self.cache('pivots', X)
3790
3791
def nonpivots(self):
3792
"""
3793
Return the list of i such that the i-th column of self is NOT a
3794
pivot column of the reduced row echelon form of self.
3795
3796
OUTPUT: sorted tuple of (Python) integers
3797
3798
EXAMPLES::
3799
3800
sage: a = matrix(QQ,3,3,range(9)); a
3801
[0 1 2]
3802
[3 4 5]
3803
[6 7 8]
3804
sage: a.echelon_form()
3805
[ 1 0 -1]
3806
[ 0 1 2]
3807
[ 0 0 0]
3808
sage: a.nonpivots()
3809
(2,)
3810
"""
3811
x = self.fetch('nonpivots')
3812
if not x is None: return tuple(x)
3813
3814
X = set(self.pivots())
3815
np = []
3816
for j in xrange(self.ncols()):
3817
if not (j in X):
3818
np.append(j)
3819
np = tuple(np)
3820
self.cache('nonpivots',np)
3821
return np
3822
3823
def nonzero_positions(self, copy=True, column_order=False):
3824
"""
3825
Returns the sorted list of pairs (i,j) such that self[i,j] != 0.
3826
3827
INPUT:
3828
3829
3830
- ``copy`` - (default: True) It is safe to change the
3831
resulting list (unless you give the option copy=False).
3832
3833
- ``column_order`` - (default: False) If true,
3834
returns the list of pairs (i,j) such that self[i,j] != 0, but
3835
sorted by columns, i.e., column j=0 entries occur first, then
3836
column j=1 entries, etc.
3837
3838
3839
EXAMPLES::
3840
3841
sage: a = matrix(QQ, 2,3, [1,2,0,2,0,0]); a
3842
[1 2 0]
3843
[2 0 0]
3844
sage: a.nonzero_positions()
3845
[(0, 0), (0, 1), (1, 0)]
3846
sage: a.nonzero_positions(copy=False)
3847
[(0, 0), (0, 1), (1, 0)]
3848
sage: a.nonzero_positions(column_order=True)
3849
[(0, 0), (1, 0), (0, 1)]
3850
sage: a = matrix(QQ, 2,3, [1,2,0,2,0,0], sparse=True); a
3851
[1 2 0]
3852
[2 0 0]
3853
sage: a.nonzero_positions()
3854
[(0, 0), (0, 1), (1, 0)]
3855
sage: a.nonzero_positions(copy=False)
3856
[(0, 0), (0, 1), (1, 0)]
3857
sage: a.nonzero_positions(column_order=True)
3858
[(0, 0), (1, 0), (0, 1)]
3859
"""
3860
if column_order:
3861
return self._nonzero_positions_by_column(copy)
3862
else:
3863
return self._nonzero_positions_by_row(copy)
3864
3865
def _nonzero_positions_by_row(self, copy=True):
3866
"""
3867
Returns the list of pairs (i,j) such that self[i,j] != 0.
3868
3869
It is safe to change the resulting list (unless you give the option copy=False).
3870
3871
EXAMPLE::
3872
3873
sage: M = Matrix(CC, [[1,0],[0,1]], sparse=True)
3874
sage: M._nonzero_positions_by_row()
3875
[(0, 0), (1, 1)]
3876
3877
"""
3878
x = self.fetch('nonzero_positions')
3879
if not x is None:
3880
if copy:
3881
return list(x)
3882
return x
3883
cdef Py_ssize_t i, j
3884
z = self._base_ring(0)
3885
nzp = []
3886
for i from 0 <= i < self._nrows:
3887
for j from 0 <= j < self._ncols:
3888
if self.get_unsafe(i,j) != z:
3889
nzp.append((i,j))
3890
self.cache('nonzero_positions', nzp)
3891
if copy:
3892
return list(nzp)
3893
return nzp
3894
3895
def _nonzero_positions_by_column(self, copy=True):
3896
"""
3897
Returns the list of pairs (i,j) such that self[i,j] != 0, but
3898
sorted by columns, i.e., column j=0 entries occur first, then
3899
column j=1 entries, etc.
3900
3901
It is safe to change the resulting list (unless you give the option
3902
copy=False).
3903
3904
EXAMPLES::
3905
3906
sage: m=matrix(QQ,2,[1,0,1,1,1,0])
3907
sage: m._nonzero_positions_by_column()
3908
[(0, 0), (1, 0), (1, 1), (0, 2)]
3909
3910
"""
3911
x = self.fetch('nonzero_positions_by_column')
3912
if not x is None:
3913
if copy:
3914
return list(x)
3915
return x
3916
cdef Py_ssize_t i, j
3917
z = self._base_ring(0)
3918
nzp = []
3919
for j from 0 <= j < self._ncols:
3920
for i from 0 <= i < self._nrows:
3921
if self.get_unsafe(i,j) != z:
3922
nzp.append((i,j))
3923
self.cache('nonzero_positions_by_column', nzp)
3924
if copy:
3925
return list(nzp)
3926
return nzp
3927
3928
def nonzero_positions_in_column(self, Py_ssize_t i):
3929
"""
3930
Return a sorted list of the integers j such that self[j,i] is
3931
nonzero, i.e., such that the j-th position of the i-th column is
3932
nonzero.
3933
3934
INPUT:
3935
3936
3937
- ``i`` - an integer
3938
3939
3940
OUTPUT: list
3941
3942
EXAMPLES::
3943
3944
sage: a = matrix(QQ, 3,2, [1,2,0,2,0,0]); a
3945
[1 2]
3946
[0 2]
3947
[0 0]
3948
sage: a.nonzero_positions_in_column(0)
3949
[0]
3950
sage: a.nonzero_positions_in_column(1)
3951
[0, 1]
3952
3953
You'll get an IndexError, if you select an invalid column::
3954
3955
sage: a.nonzero_positions_in_column(2)
3956
Traceback (most recent call last):
3957
...
3958
IndexError: matrix column index out of range
3959
"""
3960
cdef Py_ssize_t j
3961
z = self._base_ring(0)
3962
tmp = []
3963
3964
if i<0 or i >= self._ncols:
3965
raise IndexError("matrix column index out of range")
3966
for j from 0 <= j < self._nrows:
3967
if self.get_unsafe(j,i) != z:
3968
tmp.append(j)
3969
return tmp
3970
3971
def nonzero_positions_in_row(self, Py_ssize_t i):
3972
"""
3973
Return the integers j such that self[i,j] is nonzero, i.e., such
3974
that the j-th position of the i-th row is nonzero.
3975
3976
INPUT:
3977
3978
3979
- ``i`` - an integer
3980
3981
3982
OUTPUT: list
3983
3984
EXAMPLES::
3985
3986
sage: a = matrix(QQ, 3,2, [1,2,0,2,0,0]); a
3987
[1 2]
3988
[0 2]
3989
[0 0]
3990
sage: a.nonzero_positions_in_row(0)
3991
[0, 1]
3992
sage: a.nonzero_positions_in_row(1)
3993
[1]
3994
sage: a.nonzero_positions_in_row(2)
3995
[]
3996
"""
3997
cdef Py_ssize_t j
3998
3999
if i<0 or i >= self._nrows:
4000
raise IndexError("matrix row index out of range")
4001
4002
z = self._base_ring(0)
4003
tmp = []
4004
4005
for j from 0 <= j < self._ncols:
4006
if self.get_unsafe(i,j) != z:
4007
tmp.append(j)
4008
return tmp
4009
4010
def multiplicative_order(self):
4011
"""
4012
Return the multiplicative order of this matrix, which must
4013
therefore be invertible.
4014
4015
EXAMPLES::
4016
4017
sage: A = matrix(GF(59),3,[10,56,39,53,56,33,58,24,55])
4018
sage: A.multiplicative_order()
4019
580
4020
sage: (A^580).is_one()
4021
True
4022
4023
::
4024
4025
sage: B = matrix(GF(10007^3,'b'),0)
4026
sage: B.multiplicative_order()
4027
1
4028
4029
::
4030
4031
sage: C = matrix(GF(2^10,'c'),2,3,[1]*6)
4032
sage: C.multiplicative_order()
4033
Traceback (most recent call last):
4034
...
4035
ArithmeticError: self must be invertible ...
4036
4037
::
4038
4039
sage: D = matrix(IntegerModRing(6),3,[5,5,3,0,2,5,5,4,0])
4040
sage: D.multiplicative_order()
4041
Traceback (most recent call last):
4042
...
4043
NotImplementedError: ... only ... over finite fields
4044
4045
::
4046
4047
sage: E = MatrixSpace(GF(11^2,'e'),5).random_element()
4048
sage: (E^E.multiplicative_order()).is_one()
4049
True
4050
4051
REFERENCES:
4052
4053
- Frank Celler and C. R. Leedham-Green, "Calculating the Order of an Invertible Matrix", 1997
4054
4055
"""
4056
if not self.is_invertible():
4057
raise ArithmeticError("self must be invertible to have a multiplicative order")
4058
K = self.base_ring()
4059
if not (K.is_field() and K.is_finite()):
4060
raise NotImplementedError("multiplicative order is only implemented for matrices over finite fields")
4061
from sage.rings.integer import Integer
4062
from sage.groups.generic import order_from_multiple
4063
P = self.minimal_polynomial()
4064
if P.degree()==0: #the empty square matrix
4065
return 1
4066
R = P.parent()
4067
P = P.factor()
4068
q = K.cardinality()
4069
p = K.characteristic()
4070
a = 0
4071
res = Integer(1)
4072
for f,m in P:
4073
a = max(a,m)
4074
S = R.quotient(f,'y')
4075
res = res._lcm(order_from_multiple(S.gen(),q**f.degree()-1,operation='*'))
4076
ppart = p**Integer(a).exact_log(p)
4077
if ppart<a: ppart*=p
4078
return res*ppart
4079
4080
###################################################
4081
# Arithmetic
4082
###################################################
4083
cdef Vector _vector_times_matrix_(self, Vector v):
4084
"""
4085
Returns the vector times matrix product.
4086
4087
INPUT:
4088
4089
4090
- ``v`` - a free module element.
4091
4092
4093
OUTPUT: The vector times matrix product v\*A.
4094
4095
EXAMPLES::
4096
4097
sage: B = matrix(QQ,2, [1,2,3,4])
4098
sage: V = VectorSpace(QQ, 2)
4099
sage: v = V([-1,5])
4100
sage: v*B
4101
(14, 18)
4102
sage: -1*B.row(0) + 5*B.row(1)
4103
(14, 18)
4104
sage: B*v # computes B*v, where v is interpreted as a column vector.
4105
(9, 17)
4106
sage: -1*B.column(0) + 5*B.column(1)
4107
(9, 17)
4108
4109
We mix dense and sparse over different rings::
4110
4111
sage: v = FreeModule(ZZ, 3, sparse=True)([1, 2, 3])
4112
sage: m = matrix(QQ, 3, 4, range(12))
4113
sage: v * m
4114
(32, 38, 44, 50)
4115
sage: v = FreeModule(ZZ, 3, sparse=False)([1, 2, 3])
4116
sage: m = matrix(QQ, 3, 4, range(12), sparse=True)
4117
sage: v * m
4118
(32, 38, 44, 50)
4119
sage: (v * m).parent() is m.row(0).parent()
4120
True
4121
"""
4122
M = sage.modules.free_module.FreeModule(self._base_ring, self.ncols(), sparse=self.is_sparse())
4123
if self.nrows() != v.degree():
4124
raise ArithmeticError("number of rows of matrix must equal degree of vector")
4125
s = M(0)
4126
zero = self.base_ring()(0)
4127
cdef Py_ssize_t i
4128
for i from 0 <= i < self._nrows:
4129
if v[i] != zero:
4130
s += v[i]*self.row(i, from_list=True)
4131
return s
4132
4133
cdef Vector _matrix_times_vector_(self, Vector v):
4134
"""
4135
EXAMPLES::
4136
4137
sage: v = FreeModule(ZZ, 3, sparse=True)([1, 2, 3])
4138
sage: m = matrix(QQ, 4, 3, range(12))
4139
sage: m * v
4140
(8, 26, 44, 62)
4141
sage: v = FreeModule(ZZ, 3, sparse=False)([1, 2, 3])
4142
sage: m = matrix(QQ, 4, 3, range(12), sparse=True)
4143
sage: m * v
4144
(8, 26, 44, 62)
4145
sage: (m * v).parent() is m.column(0).parent()
4146
True
4147
"""
4148
M = sage.modules.free_module.FreeModule(self._base_ring, self.nrows(), sparse=self.is_sparse())
4149
if not PY_TYPE_CHECK(v, sage.modules.free_module_element.FreeModuleElement):
4150
v = M(v)
4151
if self.ncols() != v.degree():
4152
raise ArithmeticError("number of columns of matrix must equal degree of vector")
4153
s = M(0)
4154
for i in xrange(self.ncols()):
4155
if v[i] != 0:
4156
s = s + self.column(i, from_list=True)*v[i]
4157
return s
4158
4159
def iterates(self, v, n, rows=True):
4160
r"""
4161
Let `A` be this matrix and `v` be a free module
4162
element. If rows is True, return a matrix whose rows are the
4163
entries of the following vectors:
4164
4165
.. math::
4166
4167
v, v A, v A^2, \ldots, v A^{n-1}.
4168
4169
If rows is False, return a matrix whose columns are the entries of
4170
the following vectors:
4171
4172
.. math::
4173
4174
v, Av, A^2 v, \ldots, A^{n-1} v.
4175
4176
INPUT:
4177
4178
- ``v`` - free module element
4179
4180
- ``n`` - nonnegative integer
4181
4182
EXAMPLES::
4183
4184
sage: A = matrix(ZZ,2, [1,1,3,5]); A
4185
[1 1]
4186
[3 5]
4187
sage: v = vector([1,0])
4188
sage: A.iterates(v,0)
4189
[]
4190
sage: A.iterates(v,5)
4191
[ 1 0]
4192
[ 1 1]
4193
[ 4 6]
4194
[ 22 34]
4195
[124 192]
4196
4197
Another example::
4198
4199
sage: a = matrix(ZZ,3,range(9)); a
4200
[0 1 2]
4201
[3 4 5]
4202
[6 7 8]
4203
sage: v = vector([1,0,0])
4204
sage: a.iterates(v,4)
4205
[ 1 0 0]
4206
[ 0 1 2]
4207
[ 15 18 21]
4208
[180 234 288]
4209
sage: a.iterates(v,4,rows=False)
4210
[ 1 0 15 180]
4211
[ 0 3 42 558]
4212
[ 0 6 69 936]
4213
"""
4214
n = int(n)
4215
if n >= 2 and self.nrows() != self.ncols():
4216
raise ArithmeticError("matrix must be square if n >= 2.")
4217
if n == 0:
4218
return self.matrix_space(n, self.ncols())(0)
4219
m = self.nrows()
4220
M = sage.modules.free_module.FreeModule(self._base_ring, m, sparse=self.is_sparse())
4221
v = M(v)
4222
X = [v]
4223
4224
if rows:
4225
for _ in range(n-1):
4226
X.append(X[len(X)-1]*self)
4227
MS = self.matrix_space(n, m)
4228
return MS(X)
4229
else:
4230
for _ in range(n-1):
4231
X.append(self*X[len(X)-1])
4232
MS = self.matrix_space(n, m)
4233
return MS(X).transpose()
4234
4235
cpdef ModuleElement _add_(self, ModuleElement right):
4236
"""
4237
Add two matrices with the same parent.
4238
4239
EXAMPLES::
4240
4241
sage: R.<x,y> = FreeAlgebra(QQ,2)
4242
sage: a = matrix(2,2, [1,2,x*y,y*x])
4243
sage: b = matrix(2,2, [1,2,y*x,y*x])
4244
sage: a+b # indirect doctest
4245
[ 2 4]
4246
[x*y + y*x 2*y*x]
4247
4248
"""
4249
cdef Py_ssize_t i, j
4250
cdef Matrix A
4251
A = self.new_matrix()
4252
for i from 0 <= i < self._nrows:
4253
for j from 0 <= j < self._ncols:
4254
A.set_unsafe(i,j, self.get_unsafe(i,j) + (<Matrix>right).get_unsafe(i,j))
4255
return A
4256
4257
cpdef ModuleElement _sub_(self, ModuleElement right):
4258
"""
4259
Subtract two matrices with the same parent.
4260
4261
EXAMPLES::
4262
4263
sage: R.<x,y> = FreeAlgebra(QQ,2)
4264
sage: a = matrix(2,2, [1,2,x*y,y*x])
4265
sage: b = matrix(2,2, [1,2,y*x,y*x])
4266
sage: a-b # indirect doctest
4267
[ 0 0]
4268
[x*y - y*x 0]
4269
4270
"""
4271
cdef Py_ssize_t i, j
4272
cdef Matrix A
4273
A = self.new_matrix()
4274
for i from 0 <= i < self._nrows:
4275
for j from 0 <= j < self._ncols:
4276
A.set_unsafe(i,j, self.get_unsafe(i,j) - (<Matrix>right).get_unsafe(i,j))
4277
return A
4278
4279
4280
def __mod__(self, p):
4281
r"""
4282
Return matrix mod `p`, returning again a matrix over the
4283
same base ring.
4284
4285
.. note::
4286
4287
Use ``A.Mod(p)`` to obtain a matrix over the residue class
4288
ring modulo `p`.
4289
4290
EXAMPLES::
4291
4292
sage: M = Matrix(ZZ, 2, 2, [5, 9, 13, 15])
4293
sage: M % 7
4294
[5 2]
4295
[6 1]
4296
sage: parent(M % 7)
4297
Full MatrixSpace of 2 by 2 dense matrices over Integer Ring
4298
"""
4299
cdef Py_ssize_t i
4300
v = self.list()
4301
for i from 0 <= i < len(v):
4302
v[i] = v[i] % p
4303
return self.new_matrix(entries = v, copy=False, coerce=True)
4304
4305
def mod(self, p):
4306
"""
4307
Return matrix mod `p`, over the reduced ring.
4308
4309
EXAMPLES::
4310
4311
sage: M = matrix(ZZ, 2, 2, [5, 9, 13, 15])
4312
sage: M.mod(7)
4313
[5 2]
4314
[6 1]
4315
sage: parent(M.mod(7))
4316
Full MatrixSpace of 2 by 2 dense matrices over Ring of integers modulo 7
4317
"""
4318
return self.change_ring(self._base_ring.quotient_ring(p))
4319
4320
4321
cpdef ModuleElement _rmul_(self, RingElement left):
4322
"""
4323
EXAMPLES::
4324
4325
sage: a = matrix(QQ['x'],2,range(6))
4326
sage: (3/4) * a
4327
[ 0 3/4 3/2]
4328
[ 9/4 3 15/4]
4329
4330
sage: R.<x,y> = QQ[]
4331
sage: a = matrix(R,2,3,[1,x,y,-x*y,x+y,x-y]); a
4332
[ 1 x y]
4333
[ -x*y x + y x - y]
4334
sage: (x*y) * a
4335
[ x*y x^2*y x*y^2]
4336
[ -x^2*y^2 x^2*y + x*y^2 x^2*y - x*y^2]
4337
4338
sage: R.<x,y> = FreeAlgebra(ZZ,2)
4339
sage: a = matrix(R,2,3,[1,x,y,-x*y,x+y,x-y]); a
4340
[ 1 x y]
4341
[ -x*y x + y x - y]
4342
sage: (x*y) * a # indirect doctest
4343
[ x*y x*y*x x*y^2]
4344
[ -x*y*x*y x*y*x + x*y^2 x*y*x - x*y^2]
4345
"""
4346
# derived classes over a commutative base *just* overload _lmul_ (!!)
4347
if PY_TYPE_CHECK(self._base_ring, CommutativeRing):
4348
return self._lmul_(left)
4349
cdef Py_ssize_t r,c
4350
cpdef RingElement x
4351
x = self._base_ring(left)
4352
cdef Matrix ans
4353
ans = self._parent.zero_matrix().__copy__()
4354
for r from 0 <= r < self._nrows:
4355
for c from 0 <= c < self._ncols:
4356
ans.set_unsafe(r, c, x._mul_(<RingElement>self.get_unsafe(r, c)))
4357
return ans
4358
4359
cpdef ModuleElement _lmul_(self, RingElement right):
4360
"""
4361
EXAMPLES:
4362
4363
A simple example in which the base ring is commutative::
4364
4365
sage: a = matrix(QQ['x'],2,range(6))
4366
sage: a*(3/4)
4367
[ 0 3/4 3/2]
4368
[ 9/4 3 15/4]
4369
4370
An example in which the base ring is not commutative::
4371
4372
sage: F.<x,y> = FreeAlgebra(QQ,2)
4373
sage: a = matrix(2,[x,y,x^2,y^2]); a
4374
[ x y]
4375
[x^2 y^2]
4376
sage: x * a # indirect doctest
4377
[ x^2 x*y]
4378
[ x^3 x*y^2]
4379
sage: a * y
4380
[ x*y y^2]
4381
[x^2*y y^3]
4382
4383
sage: R.<x,y> = FreeAlgebra(ZZ,2)
4384
sage: a = matrix(R,2,3,[1,x,y,-x*y,x+y,x-y]); a
4385
[ 1 x y]
4386
[ -x*y x + y x - y]
4387
sage: a * (x*y)
4388
[ x*y x^2*y y*x*y]
4389
[ -x*y*x*y x^2*y + y*x*y x^2*y - y*x*y]
4390
"""
4391
# derived classes over a commutative base *just* overload this and not _rmul_
4392
cdef Py_ssize_t r,c
4393
cpdef RingElement x
4394
x = self._base_ring(right)
4395
cdef Matrix ans
4396
ans = self._parent.zero_matrix().__copy__()
4397
for r from 0 <= r < self._nrows:
4398
for c from 0 <= c < self._ncols:
4399
ans.set_unsafe(r, c, (<RingElement>self.get_unsafe(r, c))._mul_(x))
4400
return ans
4401
4402
cdef sage.structure.element.Matrix _matrix_times_matrix_(self, sage.structure.element.Matrix right):
4403
r"""
4404
Return the product of two matrices.
4405
4406
EXAMPLE of matrix times matrix over same base ring: We multiply
4407
matrices over `\QQ[x,y]`.
4408
4409
::
4410
4411
sage: R.<x,y> = QQ[]
4412
sage: a = matrix(R,2,3,[1,x,y,-x*y,x+y,x-y]); a
4413
[ 1 x y]
4414
[ -x*y x + y x - y]
4415
sage: b = a.transpose(); b
4416
[ 1 -x*y]
4417
[ x x + y]
4418
[ y x - y]
4419
sage: a*b # indirect doctest
4420
[ x^2 + y^2 + 1 x^2 + x*y - y^2]
4421
[ x^2 + x*y - y^2 x^2*y^2 + 2*x^2 + 2*y^2]
4422
sage: b*a # indirect doctest
4423
[ x^2*y^2 + 1 -x^2*y - x*y^2 + x -x^2*y + x*y^2 + y]
4424
[ -x^2*y - x*y^2 + x 2*x^2 + 2*x*y + y^2 x^2 + x*y - y^2]
4425
[ -x^2*y + x*y^2 + y x^2 + x*y - y^2 x^2 - 2*x*y + 2*y^2]
4426
4427
We verify that the matrix multiplies are correct by comparing them
4428
with what PARI gets::
4429
4430
sage: gp(a)*gp(b) - gp(a*b)
4431
[0, 0; 0, 0]
4432
sage: gp(b)*gp(a) - gp(b*a)
4433
[0, 0, 0; 0, 0, 0; 0, 0, 0]
4434
4435
EXAMPLE of matrix times matrix over different base rings::
4436
4437
sage: a = matrix(ZZ,2,2,range(4))
4438
sage: b = matrix(GF(7),2,2,range(4))
4439
sage: c = matrix(QQ,2,2,range(4))
4440
sage: d = a*b; d
4441
[2 3]
4442
[6 4]
4443
sage: parent(d)
4444
Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7
4445
sage: parent(b*a)
4446
Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7
4447
sage: d = a*c; d
4448
[ 2 3]
4449
[ 6 11]
4450
sage: parent(d)
4451
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
4452
sage: d = b+c
4453
Traceback (most recent call last):
4454
...
4455
TypeError: unsupported operand parent(s) for '+': 'Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7' and 'Full MatrixSpace of 2 by 2 dense matrices over Rational Field'
4456
sage: d = b+c.change_ring(GF(7)); d
4457
[0 2]
4458
[4 6]
4459
4460
EXAMPLE of matrix times matrix where one matrix is sparse and the
4461
other is dense (in such mixed cases, the result is always dense)::
4462
4463
sage: a = matrix(ZZ,2,2,range(4),sparse=True)
4464
sage: b = matrix(GF(7),2,2,range(4),sparse=False)
4465
sage: c = a*b; c
4466
[2 3]
4467
[6 4]
4468
sage: parent(c)
4469
Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7
4470
sage: c = b*a; c
4471
[2 3]
4472
[6 4]
4473
sage: parent(c)
4474
Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7
4475
4476
EXAMPLE of matrix multiplication over a noncommutative base ring::
4477
4478
sage: R.<x,y> = FreeAlgebra(QQ,2)
4479
sage: x*y - y*x
4480
x*y - y*x
4481
sage: a = matrix(2,2, [1,2,x,y])
4482
sage: b = matrix(2,2, [x,y,x^2,y^2])
4483
sage: a*b
4484
[ x + 2*x^2 y + 2*y^2]
4485
[x^2 + y*x^2 x*y + y^3]
4486
sage: b*a
4487
[ x + y*x 2*x + y^2]
4488
[x^2 + y^2*x 2*x^2 + y^3]
4489
4490
EXAMPLE of row vector times matrix (vectors are row vectors, so
4491
matrices act from the right)::
4492
4493
sage: a = matrix(2,3, range(6)); a
4494
[0 1 2]
4495
[3 4 5]
4496
sage: V = ZZ^2
4497
sage: v = V([-2,3]); v
4498
(-2, 3)
4499
sage: v*a
4500
(9, 10, 11)
4501
4502
This is not allowed, since v is a *row* vector::
4503
4504
sage: a*v
4505
Traceback (most recent call last):
4506
...
4507
TypeError: unsupported operand parent(s) for '*': 'Full MatrixSpace of 2 by 3 dense matrices over Integer Ring' and 'Ambient free module of rank 2 over the principal ideal domain Integer Ring'
4508
4509
This illustrates how coercion works::
4510
4511
sage: V = QQ^2
4512
sage: v = V([-2,3]); v
4513
(-2, 3)
4514
sage: parent(v*a)
4515
Vector space of dimension 3 over Rational Field
4516
4517
EXAMPLE of matrix times column vector: (column vectors are not
4518
implemented yet) TODO TODO
4519
4520
EXAMPLE of scalar times matrix::
4521
4522
sage: a = matrix(2,3, range(6)); a
4523
[0 1 2]
4524
[3 4 5]
4525
sage: b = 3*a; b
4526
[ 0 3 6]
4527
[ 9 12 15]
4528
sage: parent(b)
4529
Full MatrixSpace of 2 by 3 dense matrices over Integer Ring
4530
sage: b = (2/3)*a; b
4531
[ 0 2/3 4/3]
4532
[ 2 8/3 10/3]
4533
sage: parent(b)
4534
Full MatrixSpace of 2 by 3 dense matrices over Rational Field
4535
4536
EXAMPLE of matrix times scalar::
4537
4538
sage: a = matrix(2,3, range(6)); a
4539
[0 1 2]
4540
[3 4 5]
4541
sage: b = a*3; b
4542
[ 0 3 6]
4543
[ 9 12 15]
4544
sage: parent(b)
4545
Full MatrixSpace of 2 by 3 dense matrices over Integer Ring
4546
sage: b = a*(2/3); b
4547
[ 0 2/3 4/3]
4548
[ 2 8/3 10/3]
4549
sage: parent(b)
4550
Full MatrixSpace of 2 by 3 dense matrices over Rational Field
4551
4552
EXAMPLE of scalar multiplication in the noncommutative case::
4553
4554
sage: R.<x,y> = FreeAlgebra(ZZ,2)
4555
sage: a = matrix(2,[x,y,x^2,y^2])
4556
sage: a * x
4557
[ x^2 y*x]
4558
[ x^3 y^2*x]
4559
sage: x * a
4560
[ x^2 x*y]
4561
[ x^3 x*y^2]
4562
sage: a*x - x*a
4563
[ 0 -x*y + y*x]
4564
[ 0 -x*y^2 + y^2*x]
4565
"""
4566
# Both self and right are matrices with compatible dimensions and base ring.
4567
if self._will_use_strassen(right):
4568
return self._multiply_strassen(right)
4569
else:
4570
return self._multiply_classical(right)
4571
4572
cdef bint _will_use_strassen(self, Matrix right) except -2:
4573
"""
4574
Whether or not matrix multiplication of self by right should be
4575
done using Strassen.
4576
4577
Overload _strassen_default_cutoff to return -1 to not use
4578
Strassen by default.
4579
"""
4580
cdef int n
4581
n = self._strassen_default_cutoff(right)
4582
if n == -1:
4583
return 0 # do not use Strassen
4584
if self._nrows > n and self._ncols > n and \
4585
right._nrows > n and right._ncols > n:
4586
return 1
4587
return 0
4588
4589
cdef bint _will_use_strassen_echelon(self) except -2:
4590
"""
4591
Whether or not matrix multiplication of self by right should be
4592
done using Strassen.
4593
4594
Overload this in derived classes to not use Strassen by default.
4595
"""
4596
cdef int n
4597
n = self._strassen_default_echelon_cutoff()
4598
if n == -1:
4599
return 0 # do not use Strassen
4600
if self._nrows > n and self._ncols > n:
4601
return 1
4602
return 0
4603
4604
def __neg__(self):
4605
"""
4606
Return the negative of self.
4607
4608
EXAMPLES::
4609
4610
sage: a = matrix(ZZ,2,range(4))
4611
sage: a.__neg__()
4612
[ 0 -1]
4613
[-2 -3]
4614
sage: -a
4615
[ 0 -1]
4616
[-2 -3]
4617
"""
4618
return self._lmul_(self._base_ring(-1))
4619
4620
def __invert__(self):
4621
r"""
4622
Return this inverse of this matrix, as a matrix over the fraction
4623
field.
4624
4625
Raises a ``ZeroDivisionError`` if the matrix has zero
4626
determinant, and raises an ``ArithmeticError``, if the
4627
inverse doesn't exist because the matrix is nonsquare. Also, note,
4628
e.g., that the inverse of a matrix over `\ZZ` is
4629
always a matrix defined over `\QQ` (even if the
4630
entries are integers).
4631
4632
EXAMPLES::
4633
4634
sage: A = MatrixSpace(ZZ, 2)([1,1,3,5])
4635
sage: ~A
4636
[ 5/2 -1/2]
4637
[-3/2 1/2]
4638
sage: A.__invert__()
4639
[ 5/2 -1/2]
4640
[-3/2 1/2]
4641
4642
Even if the inverse lies in the base field, the result is still a
4643
matrix over the fraction field.
4644
4645
::
4646
4647
sage: I = MatrixSpace(ZZ,2)(1) # identity matrix
4648
sage: ~I
4649
[1 0]
4650
[0 1]
4651
sage: (~I).parent()
4652
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
4653
4654
This is analogous to the situation for ring elements, e.g., for
4655
`\ZZ` we have::
4656
4657
sage: parent(~1)
4658
Rational Field
4659
4660
A matrix with 0 rows and 0 columns is invertible (see trac #3734)::
4661
4662
sage: M = MatrixSpace(RR,0,0)(0); M
4663
[]
4664
sage: M.determinant()
4665
1.00000000000000
4666
sage: M.is_invertible()
4667
True
4668
sage: M.inverse() == M
4669
True
4670
4671
Matrices over the integers modulo a composite modulus::
4672
4673
sage: m = matrix(Zmod(49),2,[2,1,3,3])
4674
sage: type(m)
4675
<type 'sage.matrix.matrix_modn_dense_float.Matrix_modn_dense_float'>
4676
sage: ~m
4677
[ 1 16]
4678
[48 17]
4679
sage: m = matrix(Zmod(2^100),2,[2,1,3,3])
4680
sage: type(m)
4681
<type 'sage.matrix.matrix_generic_dense.Matrix_generic_dense'>
4682
sage: (~m)*m
4683
[1 0]
4684
[0 1]
4685
sage: ~m
4686
[ 1 422550200076076467165567735125]
4687
[1267650600228229401496703205375 422550200076076467165567735126]
4688
4689
This matrix isn't invertible::
4690
4691
sage: m = matrix(Zmod(9),2,[2,1,3,3])
4692
sage: ~m
4693
Traceback (most recent call last):
4694
...
4695
ZeroDivisionError: input matrix must be nonsingular
4696
4697
Check to make sure that trac #2256 is still fixed::
4698
4699
sage: M = MatrixSpace(CC, 2)(-1.10220440881763)
4700
sage: N = ~M
4701
sage: (N*M).norm()
4702
1.0
4703
"""
4704
if not self.base_ring().is_field():
4705
try:
4706
return ~self.matrix_over_field()
4707
except TypeError:
4708
# There is one easy special case -- the integers modulo N.
4709
if is_IntegerModRing(self.base_ring()):
4710
# This is "easy" in that we either get an error or
4711
# the right answer. Note that of course there
4712
# could be a much faster algorithm, e.g., using
4713
# CRT or p-adic lifting.
4714
try:
4715
return (~self.lift()).change_ring(self.base_ring())
4716
except (TypeError, ZeroDivisionError):
4717
raise ZeroDivisionError("input matrix must be nonsingular")
4718
raise
4719
4720
if not self.is_square():
4721
raise ArithmeticError("self must be a square matrix")
4722
if self.nrows()==0:
4723
return self
4724
4725
A = self.augment(self.parent().identity_matrix())
4726
B = A.echelon_form()
4727
4728
# Now we want to make sure that B is of the form [I|X], in
4729
# which case X is the inverse of self. We can simply look at
4730
# the lower right entry of the left half of B, and make sure
4731
# that it's 1.
4732
#
4733
# However, doing this naively causes trouble over inexact
4734
# fields -- see trac #2256. The *right* thing to do would
4735
# probably be to make sure that self.det() is nonzero. That
4736
# doesn't work here, because our det over an arbitrary field
4737
# just does expansion by minors and is unusable for even 10x10
4738
# matrices over CC. Instead, we choose a different band-aid:
4739
# we check to make sure that the lower right entry isn't
4740
# 0. Since we're over a field, we know that it *should* be
4741
# either 1 or 0. This can still cause trouble, but it's
4742
# significantly better than it was before.
4743
#
4744
# Over exact rings, of course, we still want the old
4745
# behavior.
4746
4747
if self.base_ring().is_exact():
4748
if B[self._nrows-1, self._ncols-1] != 1:
4749
raise ZeroDivisionError("input matrix must be nonsingular")
4750
else:
4751
if not B[self._nrows-1, self._ncols-1]:
4752
raise ZeroDivisionError("input matrix must be nonsingular")
4753
4754
return B.matrix_from_columns(range(self._ncols, 2*self._ncols))
4755
4756
def __pos__(self):
4757
"""
4758
Return +self, which is just self, of course.
4759
4760
EXAMPLES::
4761
4762
sage: a = matrix(ZZ,2,range(4))
4763
sage: +a
4764
[0 1]
4765
[2 3]
4766
sage: a.__pos__()
4767
[0 1]
4768
[2 3]
4769
"""
4770
return self
4771
4772
def __pow__(self, n, ignored):
4773
"""
4774
EXAMPLES::
4775
4776
sage: MS = MatrixSpace(QQ, 3, 3)
4777
sage: A = MS([0, 0, 1, 1, 0, '-2/11', 0, 1, '-3/11'])
4778
sage: A * A^(-1) == 1
4779
True
4780
sage: A^4
4781
[ -3/11 -13/121 1436/1331]
4782
[ 127/121 -337/1331 -4445/14641]
4783
[ -13/121 1436/1331 -8015/14641]
4784
sage: A.__pow__(4)
4785
[ -3/11 -13/121 1436/1331]
4786
[ 127/121 -337/1331 -4445/14641]
4787
[ -13/121 1436/1331 -8015/14641]
4788
4789
Sage follows Python's convention 0^0 = 1, as each of the following
4790
examples show::
4791
4792
sage: a = Matrix([[1,0],[0,0]]); a
4793
[1 0]
4794
[0 0]
4795
sage: a^0 # lower right entry is 0^0
4796
[1 0]
4797
[0 1]
4798
sage: Matrix([[0]])^0
4799
[1]
4800
sage: 0^0
4801
1
4802
"""
4803
if not self.is_square():
4804
raise ArithmeticError("self must be a square matrix")
4805
4806
return RingElement.__pow__(self, n, ignored)
4807
4808
###################################################
4809
# Comparison
4810
###################################################
4811
def __hash__(self):
4812
"""
4813
Return the hash of this (immutable) matrix
4814
4815
EXAMPLES::
4816
4817
sage: m=matrix(QQ,2,[1,2,3,4])
4818
sage: m.set_immutable()
4819
sage: m.__hash__()
4820
8
4821
4822
"""
4823
return self._hash()
4824
4825
cdef long _hash(self) except -1:
4826
raise NotImplementedError
4827
4828
cdef int _cmp_c_impl(left,Element right) except -2:
4829
"""
4830
Compare two matrices.
4831
4832
Matrices are compared in lexicographic order on the underlying list
4833
of coefficients. A dense matrix and a sparse matrix are equal if
4834
their coefficients are the same.
4835
4836
EXAMPLES: EXAMPLE comparing sparse and dense matrices::
4837
4838
sage: matrix(QQ,2,range(4)) == matrix(QQ,2,range(4),sparse=True)
4839
True
4840
sage: matrix(QQ,2,range(4)) == matrix(QQ,2,range(4),sparse=True)
4841
True
4842
4843
Dictionary order::
4844
4845
sage: matrix(ZZ,2,[1,2,3,4]) < matrix(ZZ,2,[3,2,3,4])
4846
True
4847
sage: matrix(ZZ,2,[1,2,3,4]) > matrix(ZZ,2,[3,2,3,4])
4848
False
4849
sage: matrix(ZZ,2,[0,2,3,4]) < matrix(ZZ,2,[0,3,3,4], sparse=True)
4850
True
4851
"""
4852
raise NotImplementedError # this is defined in the derived classes
4853
4854
def __nonzero__(self):
4855
"""
4856
EXAMPLES::
4857
4858
sage: M = Matrix(ZZ, 2, 2, [0, 0, 0, 0])
4859
sage: bool(M)
4860
False
4861
sage: M = Matrix(ZZ, 2, 2, [1, 2, 3, 5])
4862
sage: bool(M)
4863
True
4864
"""
4865
z = self._base_ring(0)
4866
cdef Py_ssize_t i, j
4867
for i from 0 <= i < self._nrows:
4868
for j from 0 <= j < self._ncols:
4869
if self.get_unsafe(i,j) != z:
4870
return True
4871
return False
4872
4873
cdef int _strassen_default_cutoff(self, Matrix right) except -2:
4874
return -1
4875
4876
cdef int _strassen_default_echelon_cutoff(self) except -2:
4877
return -1
4878
4879
4880
4881
4882
#######################
4883
# Unpickling
4884
#######################
4885
4886
def unpickle(cls, parent, mutability, cache, data, version):
4887
r"""
4888
Unpickle a matrix. This is only used internally by Sage. Users
4889
should never call this function directly.
4890
4891
EXAMPLES: We illustrating saving and loading several different
4892
types of matrices.
4893
4894
OVER `\ZZ`::
4895
4896
sage: A = matrix(ZZ,2,range(4))
4897
sage: loads(dumps(A)) # indirect doctest
4898
[0 1]
4899
[2 3]
4900
4901
Sparse OVER `\QQ`:
4902
4903
Dense over `\QQ[x,y]`:
4904
4905
Dense over finite field.
4906
"""
4907
cdef Matrix A
4908
A = cls.__new__(cls, parent, 0,0,0)
4909
A._parent = parent # make sure -- __new__ doesn't have to set it, but unpickle may need to know.
4910
A._nrows = parent.nrows()
4911
A._ncols = parent.ncols()
4912
A._mutability = mutability
4913
A._base_ring = parent.base_ring()
4914
A._cache = cache
4915
if version >= 0:
4916
A._unpickle(data, version)
4917
else:
4918
A._unpickle_generic(data, version)
4919
return A
4920
4921
4922
max_rows = 20
4923
max_cols = 50
4924
4925
def set_max_rows(n):
4926
"""
4927
Sets the global variable max_rows (which is used in deciding how to output a matrix).
4928
4929
EXAMPLES::
4930
4931
sage: from sage.matrix.matrix0 import set_max_rows
4932
sage: set_max_rows(20)
4933
4934
"""
4935
4936
global max_rows
4937
max_rows = n
4938
4939
def set_max_cols(n):
4940
"""
4941
Sets the global variable max_cols (which is used in deciding how to output a matrix).
4942
4943
EXAMPLES::
4944
4945
sage: from sage.matrix.matrix0 import set_max_cols
4946
sage: set_max_cols(50)
4947
4948
"""
4949
4950
global max_cols
4951
max_cols = n
4952
4953