Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit c7c68cd

Browse files
committed
some progress
1 parent a90423a commit c7c68cd

File tree

1 file changed

+184
-15
lines changed

1 file changed

+184
-15
lines changed

src/sage/matrix/matrix_nmod_dense.pyx

+184-15
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ from cpython.sequence cimport *
1212

1313
from cysignals.signals cimport sig_str, sig_off
1414

15+
from sage.arith.power cimport generic_power
1516
from sage.structure.sage_object cimport SageObject
1617
from sage.structure.element cimport Element, Matrix
1718
from sage.libs.flint.nmod_mat cimport *
@@ -147,11 +148,14 @@ cdef class Matrix_nmod_dense(Matrix_dense):
147148
cdef int k
148149

149150
from sage.structure.richcmp cimport Py_EQ, PY_NE
151+
raise NotImplementedError("I'm here")
150152
if op == PY_EQ:
151153
#FIXME
154+
return rich_to_bool(op, 0)
152155

153156
elif op == PY_NE:
154157
#FIXME
158+
return rich_to_bool(op, 0)
155159

156160
else:
157161
sig_on()
@@ -194,22 +198,186 @@ cdef class Matrix_nmod_dense(Matrix_dense):
194198

195199
# Extra
196200

197-
# add inplace and not inplace versions
201+
def tranpose(self):
202+
cdef Matrix_nmod_dense M = self._new(self._nrows, self._ncols)
203+
sig_on()
204+
nmod_mat_transpose(M._matrix, self._matrix)
205+
sig_off()
206+
return M
207+
208+
209+
def echelonize(self):
210+
"""
211+
Echelon form in place
212+
"""
213+
if not self._parent._base.is_field():
214+
raise NotImplementedError("Only implemented over fields")
215+
self.check_mutability()
216+
self.clear_cache()
217+
rank = nmod_mat_rref(self._matrix)
218+
self.cache('rank', rank)
219+
220+
def echelon_form(self):
221+
key='echelon_form'
222+
ans = self.fetch(key)
223+
if ans is not None:
224+
return ans
225+
ans = self.__copy__()
226+
self.cache(key, ans)
227+
ans.echelonize()
228+
return ans
229+
230+
231+
232+
def rank(self):
233+
key = 'rank'
234+
ans = self.fetch(key)
235+
if ans is not None:
236+
return ans
237+
sig_on()
238+
ans = nmod_mat_rank(self._matrix)
239+
sig_off()
240+
self.cache(key, ans)
241+
return ans
242+
243+
def det(self):
244+
if self._nrows != self._ncols:
245+
raise ValueError("self must be a square matrix")
246+
key = 'det'
247+
ans = self.fetch(key)
248+
if ans is not None:
249+
return ans
250+
sig_on()
251+
ans = nmod_mat_det(self._matrix)
252+
sig_off()
253+
self.cache(key, ans)
254+
return ans
255+
256+
def trace(self):
257+
if self._nrows != self._ncols:
258+
raise ValueError("self must be a square matrix")
259+
key = 'trace'
260+
ans = self.fetch(key)
261+
if ans is not None:
262+
return ans
263+
sig_on()
264+
ans = nmod_mat_trace(self._matrix)
265+
sig_off()
266+
self.cache(key, ans)
267+
return ans
268+
269+
def _strong_echelon_form(self):
270+
"""
271+
In place strong echelon form of self
272+
"""
273+
if self._nrows >= self._ncols:
274+
raise ValueError("self must must have at least as many rows as columns.")
275+
self.check_mutability()
276+
self.clear_cache()
277+
sig_on()
278+
nmod_mat_strong_echelon_form(self._matrix)
279+
sig_off()
198280

199281
def strong_echelon_form(self):
200-
# Edgar: fix so not in place
282+
"""
283+
Strong echelon form of self
284+
"""
285+
key='strong_echelon_form'
286+
ans = self.fetch(key)
287+
if ans is not None:
288+
return ans
289+
ans = self.__copy__()
290+
ans._strong_echelon_form()
291+
self.cache(key, ans)
292+
return ans
293+
294+
def _howell_form(self):
295+
"""
296+
In place Howell form of self
297+
"""
201298
if self._nrows >= self._ncols:
202-
nmod_mat_strong_echelon_form(self._matrix)
299+
raise ValueError("self must must have at least as many rows as columns.")
300+
self.check_mutability()
301+
self.clear_cache()
302+
nmod_mat_howell_form(self._matrix)
303+
304+
def howell_form(self):
305+
"""
306+
Howell form of self
307+
"""
308+
key='howell_form'
309+
ans = self.fetch(key)
310+
if ans is not None:
311+
return ans
312+
ans = self.__copy__()
313+
ans._howell_form()
314+
self.cache(key, ans)
315+
return ans
316+
317+
def __pow__(sself, n, dummy):
318+
cdef Matrix_nmod_dense self = <Matrix_nmod_dense?>sself
319+
320+
if dummy is not None:
321+
raise ValueError
322+
if self._nrows != self._ncols:
323+
raise ArithmeticError("self must be a square matrix")
324+
325+
cdef unsigned long e
326+
cdef long e_sgn
327+
cdef int err
328+
329+
if integer_check_long_py(n, &e_sgn, &err) and not err:
330+
if e_sgn < 0:
331+
return (~self) ** (-n)
332+
e = <unsigned long>e_sgn
203333
else:
204-
raise ValueError("Matrix must have at least as many rows as columns.")
334+
if not isinstance(n, Integer):
335+
try:
336+
n = Integer(n)
337+
except TypeError:
338+
from sage.symbolic.expression import Expression
339+
if isinstance(n, Expression):
340+
from sage.matrix.matrix2 import _matrix_power_symbolic
341+
return _matrix_power_symbolic(self, n)
342+
else:
343+
raise NotImplementedError("the given exponent is not supported")
344+
if mpz_sgn((<Integer>n).value) < 0:
345+
return (~self) ** (-n)
346+
347+
if mpz_fits_ulong_p((<Integer>n).value):
348+
e = mpz_get_ui((<Integer>n).value)
349+
else:
350+
# it is very likely that the following will never finish except
351+
# if self has only eigenvalues 0, 1 or -1.
352+
return generic_power(self, n)
353+
354+
if e == 0:
355+
return self._parent.identity_matrix()
356+
if e == 1:
357+
return self
205358

359+
cdef Matrix_nmod_dense M = self._new(self._nrows, self._ncols)
360+
sig_on()
361+
nmod_mat_pow(M._matrix, self._matrix, e)
362+
sig_off()
363+
return M
206364

207-
def howell_form(self):
208-
# Edgar: fix so not in place
209-
if self._nrows >= self._ncols:
210-
nmod_mat_howell_form(self._matrix)
365+
def _right_kernel_matrix(self):
366+
if self._parent._base.is_field():
367+
# nmod_mut_nullspace will do this regardless
368+
# so we are better off to start in echelon form to have the rank
369+
echelon_form = self.echelon_form()
370+
cdef Matrix_nmod_dense X = self._new(self.ncols, self._nrows - self.rank(), self._ncols)
371+
cdef Matrix_nmod_dense ans = self._new(self._nrows - self.rank(), self._ncols)
372+
sig_on()
373+
nmod_mat_nullspace(X._matrix, echelon_form._matrix) # columns of X form a basis
374+
nmod_mat_tranpose(ans._natrix, X._matrix)
375+
sig_off()
376+
return ans
211377
else:
212-
raise ValueError("Matrix must have at least as many rows as columns.")
378+
raise NotImplementedError("I'm here")
379+
strong_echelon_form = self.strong_echelon_form()
380+
213381

214382
# random matrix generation (David)
215383
# swap rows, columns (David)
@@ -218,9 +386,10 @@ cdef class Matrix_nmod_dense(Matrix_dense):
218386

219387

220388

221-
# transpose (Edgar)
222-
# nmod_mat_pow (Edgar)
223-
# nmod_mat_trace (Edgar)
224-
# rank and det (only primes) (Egar)
225-
# right_kernel_matrix (nmod_mat_nullspace) (Edgar)
226-
# row reduction (nmod_mat_rref) (Edgar)
389+
# transpose (Edgar) x
390+
# nmod_mat_pow (Edgar) x
391+
# nmod_mat_trace (Edgar) X
392+
# rank and det (only primes) (Edgar) X
393+
# right_kernel_matrix (nmod_mat_nullspace) (Edgar) x
394+
# row reduction (nmod_mat_rref) (Edgar) ~
395+
# richcmp ~

0 commit comments

Comments
 (0)