Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/libs/cremona/mat.pyx
4096 views
1
from sage.matrix.all import MatrixSpace
2
from sage.rings.all import ZZ
3
4
from sage.matrix.matrix_integer_sparse cimport Matrix_integer_sparse
5
from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense
6
from sage.rings.integer cimport Integer
7
8
9
cdef class Matrix:
10
"""
11
A Cremona Matrix.
12
13
EXAMPLES::
14
15
sage: M = CremonaModularSymbols(225)
16
sage: t = M.hecke_matrix(2)
17
sage: type(t)
18
<type 'sage.libs.cremona.mat.Matrix'>
19
sage: t
20
61 x 61 Cremona matrix over Rational Field
21
"""
22
def __init__(self):
23
"""
24
Called when the matrix is being created.
25
26
EXAMPLES::
27
28
sage: t = CremonaModularSymbols(11).hecke_matrix(2); t
29
3 x 3 Cremona matrix over Rational Field
30
sage: type(t)
31
<type 'sage.libs.cremona.mat.Matrix'>
32
"""
33
self.M = NULL
34
35
def __repr__(self):
36
"""
37
String representation of this matrix. Use print self.str() to
38
print out the matrix entries on the screen.
39
40
EXAMPLES::
41
42
sage: M = CremonaModularSymbols(23)
43
sage: t = M.hecke_matrix(2); t
44
5 x 5 Cremona matrix over Rational Field
45
sage: print t.str()
46
[ 3 0 0 0 0]
47
[-1 -1 0 0 -1]
48
[ 1 1 0 1 1]
49
[-1 1 1 -1 0]
50
[ 0 -1 0 0 0]
51
"""
52
return "%s x %s Cremona matrix over Rational Field"%(self.nrows(), self.ncols())
53
54
def str(self):
55
"""
56
Return full string representation of this matrix, never in compact form.
57
58
EXAMPLES::
59
60
sage: M = CremonaModularSymbols(22, sign=1)
61
sage: t = M.hecke_matrix(13)
62
sage: t.str()
63
'[14 0 0 0 0]\n[-4 12 0 8 4]\n[ 0 -6 4 -6 0]\n[ 4 2 0 6 -4]\n[ 0 0 0 0 14]'
64
"""
65
return self.sage_matrix_over_ZZ(sparse=False).str()
66
67
cdef set(self, mat* M):
68
if self.M:
69
raise RuntimeError, "self.M is already set."
70
self.M = M
71
72
def __dealloc__(self):
73
if self.M:
74
delete_mat(self.M)
75
76
def __getitem__(self, ij):
77
"""
78
Return the (i,j) entry of this matrix.
79
80
Here, ij is a 2-tuple (i,j) and the row and column indices start
81
at 1 and not 0.
82
83
EXAMPLES::
84
85
sage: M = CremonaModularSymbols(19, sign=1)
86
sage: t = M.hecke_matrix(13); t
87
2 x 2 Cremona matrix over Rational Field
88
sage: t.sage_matrix_over_ZZ()
89
[ 28 0]
90
[-12 -8]
91
sage: [[t.__getitem__((i,j)) for j in [1,2]] for i in [1,2]]
92
[[28, 0], [-12, -8]]
93
sage: t.__getitem__((0,0))
94
Traceback (most recent call last):
95
...
96
IndexError: matrix indices out of range
97
"""
98
cdef long i, j
99
if self.M:
100
i, j = ij
101
if 0<i and i<=nrows(self.M[0]) and 0<j and j<=ncols(self.M[0]):
102
return self.M.sub(i,j)
103
raise IndexError, "matrix indices out of range"
104
raise IndexError, "cannot index into an undefined matrix"
105
106
def nrows(self):
107
"""
108
Return the number of rows of this matrix.
109
110
EXAMPLES::
111
112
sage: M = CremonaModularSymbols(19, sign=1)
113
sage: t = M.hecke_matrix(13); t
114
2 x 2 Cremona matrix over Rational Field
115
sage: t.nrows()
116
2
117
"""
118
return nrows(self.M[0])
119
120
def ncols(self):
121
"""
122
Return the number of columns of this matrix.
123
124
EXAMPLES::
125
126
sage: M = CremonaModularSymbols(1234, sign=1)
127
sage: t = M.hecke_matrix(3); t.ncols()
128
156
129
sage: M.dimension()
130
156
131
"""
132
return ncols(self.M[0])
133
134
# Commented out since it gives very weird
135
# results when sign != 0.
136
## def rank(self):
137
## """
138
## Return the rank of this matrix.
139
140
## EXAMPLES:
141
## sage: M = CremonaModularSymbols(389)
142
## sage: t = M.hecke_matrix(2)
143
## sage: t.rank()
144
## 65
145
## sage: M = CremonaModularSymbols(389, cuspidal=True)
146
## sage: t = M.hecke_matrix(2)
147
## sage: t.rank()
148
## 64
149
150
## sage: M = CremonaModularSymbols(389,sign=1)
151
## sage: t = M.hecke_matrix(2)
152
## sage: t.rank() # known bug.
153
## 16
154
## """
155
## return rank(self.M[0])
156
157
def add_scalar(self, scalar s):
158
"""
159
Return new matrix obtained by adding s to each diagonal entry of self.
160
161
EXAMPLES::
162
163
sage: M = CremonaModularSymbols(23, cuspidal=True, sign=1)
164
sage: t = M.hecke_matrix(2); print t.str()
165
[ 0 1]
166
[ 1 -1]
167
sage: w = t.add_scalar(3); print w.str()
168
[3 1]
169
[1 2]
170
"""
171
return new_Matrix(addscalar(self.M[0], s))
172
173
def charpoly(self, var='x'):
174
"""
175
Return the characteristic polynomial of this matrix, viewed as
176
as a matrix over the integers.
177
178
ALGORITHM:
179
180
Note that currently, this function converts this matrix into a
181
dense matrix over the integers, then calls the charpoly
182
algorithm on that, which I think is LinBox's.
183
184
EXAMPLES::
185
186
sage: M = CremonaModularSymbols(33, cuspidal=True, sign=1)
187
sage: t = M.hecke_matrix(2)
188
sage: t.charpoly()
189
x^3 + 3*x^2 - 4
190
sage: t.charpoly().factor()
191
(x - 1) * (x + 2)^2
192
"""
193
return self.sage_matrix_over_ZZ(sparse=False).charpoly(var)
194
195
def sage_matrix_over_ZZ(self, sparse=True):
196
"""
197
Return corresponding Sage matrix over the integers.
198
199
INPUT:
200
201
- ``sparse`` -- (default: True) whether the return matrix has
202
a sparse representation
203
204
EXAMPLES::
205
206
sage: M = CremonaModularSymbols(23, cuspidal=True, sign=1)
207
sage: t = M.hecke_matrix(2)
208
sage: s = t.sage_matrix_over_ZZ(); s
209
[ 0 1]
210
[ 1 -1]
211
sage: type(s)
212
<type 'sage.matrix.matrix_integer_sparse.Matrix_integer_sparse'>
213
sage: s = t.sage_matrix_over_ZZ(sparse=False); s
214
[ 0 1]
215
[ 1 -1]
216
sage: type(s)
217
<type 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'>
218
"""
219
cdef long n = self.nrows()
220
cdef long i, j, k
221
cdef scalar* v = <scalar*> self.M.get_entries() # coercion needed to deal with const
222
223
cdef Matrix_integer_dense Td
224
cdef Matrix_integer_sparse Ts
225
226
# Ugly code...
227
if sparse:
228
Ts = MatrixSpace(ZZ, n, sparse=sparse).zero_matrix().__copy__()
229
k = 0
230
for i from 0 <= i < n:
231
for j from 0 <= j < n:
232
if v[k]:
233
Ts.set_unsafe(i, j, Integer(v[k]))
234
k += 1
235
return Ts
236
else:
237
Td = MatrixSpace(ZZ, n, sparse=sparse).zero_matrix().__copy__()
238
k = 0
239
for i from 0 <= i < n:
240
for j from 0 <= j < n:
241
if v[k]:
242
Td.set_unsafe(i, j, Integer(v[k]))
243
k += 1
244
return Td
245
246
cdef class MatrixFactory:
247
cdef new_matrix(self, mat M):
248
return new_Matrix(M)
249
250
251
cdef Matrix new_Matrix(mat M):
252
cdef Matrix A = Matrix()
253
A.set(new_mat(M))
254
return A
255
256