Skip to content

Commit

Permalink
Trac #25504: Implement _an_element_ for matrix spaces
Browse files Browse the repository at this point in the history
Currently, this is a bit too trivial:
{{{
sage: MatrixSpace(QQ, 3, 3).an_element()
[1 0 0]
[0 0 0]
[0 0 0]
}}}

URL: https://trac.sagemath.org/25504
Reported by: jdemeyer
Ticket author(s): Jeroen Demeyer
Reviewer(s): Travis Scrimshaw
  • Loading branch information
Release Manager authored and vbraun committed Jun 7, 2018
2 parents 483e8ef + 779dffb commit a2fa998
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 88 deletions.
4 changes: 2 additions & 2 deletions src/doc/en/thematic_tutorials/coercion_and_categories.rst
Expand Up @@ -450,9 +450,9 @@ And indeed, ``MS2`` has *more* methods than ``MS1``::

sage: import inspect
sage: len([s for s in dir(MS1) if inspect.ismethod(getattr(MS1,s,None))])
78
79
sage: len([s for s in dir(MS2) if inspect.ismethod(getattr(MS2,s,None))])
117
118

This is because the class of ``MS2`` also inherits from the parent
class for algebras::
Expand Down
58 changes: 29 additions & 29 deletions src/sage/matrix/matrix_modn_dense_template.pxi
Expand Up @@ -1037,25 +1037,25 @@ cdef class Matrix_modn_dense_template(Matrix_dense):
::
sage: A = random_matrix(Integers(8),2,2); A
[7 2]
[6 1]
[0 5]
[6 4]
sage: B = random_matrix(Integers(8),2,2); B
[4 0]
[4 4]
[5 6]
sage: A*B
[6 4]
[5 6]
[1 6]
[4 0]
sage: 3*A
[5 6]
[2 3]
[0 7]
[2 4]
sage: MS = parent(A)
sage: MS(3) * A
[5 6]
[2 3]
[0 7]
[2 4]
::
Expand All @@ -1082,25 +1082,25 @@ cdef class Matrix_modn_dense_template(Matrix_dense):
::
sage: A = random_matrix(GF(16007),2,2); A
[ 7856 5786]
[10134 14607]
[ 6194 13327]
[ 5985 5926]
sage: B = random_matrix(GF(16007),2,2); B
[10839 6194]
[13327 5985]
[ 6901 1242]
[13032 859]
sage: A*B
[14254 4853]
[ 8754 15217]
[ 7618 12476]
[14289 6330]
sage: 3*A
[ 7561 1351]
[14395 11807]
[2575 7967]
[1948 1771]
sage: MS = parent(A)
sage: MS(3) * A
[ 7561 1351]
[14395 11807]
[2575 7967]
[1948 1771]
::
Expand Down Expand Up @@ -1129,25 +1129,25 @@ cdef class Matrix_modn_dense_template(Matrix_dense):
::
sage: A = random_matrix(Integers(1008),2,2); A
[354 413]
[307 499]
[ 41 973]
[851 876]
sage: B = random_matrix(Integers(1008),2,2); B
[952 41]
[973 851]
[180 234]
[680 640]
sage: A*B
[1001 73]
[ 623 772]
[716 298]
[924 750]
sage: 3*A
[ 54 231]
[921 489]
[123 903]
[537 612]
sage: MS = parent(A)
sage: MS(3) * A
[ 54 231]
[921 489]
[123 903]
[537 612]
::
Expand Down
128 changes: 74 additions & 54 deletions src/sage/matrix/matrix_space.py
Expand Up @@ -403,11 +403,11 @@ class MatrixSpace(UniqueRepresentation, parent_gens.ParentWithGens):
<type 'sage.matrix.matrix_generic_dense.Matrix_generic_dense'>
sage: M1(M2.an_element())
[1 0]
[0 0]
[ 0 1]
[-1 2]
sage: M2(M1.an_element())
[1 0]
[0 0]
[ 0 1]
[-1 2]
sage: M1.has_coerce_map_from(M1), M1.has_coerce_map_from(M2)
(True, False)
Expand Down Expand Up @@ -1934,6 +1934,68 @@ def random_element(self, density=None, *args, **kwds):
*args, **kwds)
return Z

def _an_element_(self):
"""
Create a typical element of this matrix space.
This uses ``some_elements`` of the base ring.
EXAMPLES::
sage: MatrixSpace(QQ, 3, 3).an_element() # indirect doctest
[ 1/2 -1/2 2]
[ -2 0 1]
[ -1 42 2/3]
TESTS::
sage: MatrixSpace(ZZ, 0, 0).an_element()
[]
Check that this works for large matrices and that it returns a
matrix which is not too trivial::
sage: M = MatrixSpace(GF(2), 100, 100).an_element()
sage: M.rank() >= 2
True
Check that this works for sparse matrices::
sage: M = MatrixSpace(ZZ, 1000, 1000, sparse=True).an_element()
sage: M.density()
99/1000000
"""
from .args import MatrixArgs
dim = self.dimension()
if dim > 100 and self.is_sparse():
# Sparse case: add 100 elements
D = {}
nr = self.nrows()
nc = self.ncols()
from random import randrange
n = 0
while True:
for el in self.base().some_elements():
if n == 100:
ma = MatrixArgs(D, space=self)
del D
return ma.matrix()
D[randrange(nr), randrange(nc)] = el
n += 1
assert D
else:
# Dense case
# Keep appending to L until we have enough elements
L = []
while True:
for el in self.base().some_elements():
if len(L) == dim:
ma = MatrixArgs(L, space=self)
del L # for efficiency: this may avoid a copy of L
return ma.matrix()
L.append(el)
assert L

def some_elements(self):
r"""
Return some elements of this matrix space.
Expand All @@ -1949,67 +2011,25 @@ def some_elements(self):
sage: M = MatrixSpace(ZZ, 2, 2)
sage: tuple(M.some_elements())
(
[1 0] [1 1] [ 0 1] [-2 3] [-4 5] [-6 7] [-8 9] [-10 11]
[0 0], [1 1], [-1 2], [-3 4], [-5 6], [-7 8], [-9 10], [-11 12],
<BLANKLINE>
[-12 13] [-14 15] [-16 17] [-18 19] [-20 21] [-22 23]
[-13 14], [-15 16], [-17 18], [-19 20], [-21 22], [-23 24],
<BLANKLINE>
[-24 25] [-26 27] [-28 29] [-30 31] [-32 33] [-34 35]
[-25 26], [-27 28], [-29 30], [-31 32], [-33 34], [-35 36],
<BLANKLINE>
[-36 37] [-38 39] [-40 41] [-42 43] [-44 45] [-46 47]
[-37 38], [-39 40], [-41 42], [-43 44], [-45 46], [-47 48],
<BLANKLINE>
[-48 49]
[-49 50]
[ 0 1] [1 0] [0 1] [0 0] [0 0]
[-1 2], [0 0], [0 0], [1 0], [0 1]
)
sage: M = MatrixSpace(QQ, 2, 3)
sage: tuple(M.some_elements())
(
[1 0 0] [1/2 1/2 1/2] [ 1/2 -1/2 2] [ -1 42 2/3]
[0 0 0], [1/2 1/2 1/2], [ -2 0 1], [-2/3 3/2 -3/2],
<BLANKLINE>
[ 4/5 -4/5 5/4] [ 7/6 -7/6 8/9] [ 10/11 -10/11 11/10]
[-5/4 6/7 -6/7], [-8/9 9/8 -9/8], [-11/10 12/13 -12/13],
<BLANKLINE>
[ 13/12 -13/12 14/15] [ 16/17 -16/17 17/16]
[-14/15 15/14 -15/14], [-17/16 18/19 -18/19],
<BLANKLINE>
[ 19/18 -19/18 20/441] [ 22/529 -22/529 529/22]
[-20/441 441/20 -441/20], [-529/22 24/625 -24/625],
<BLANKLINE>
[ 625/24 -625/24 26/729] [ 28/841 -28/841 841/28]
[-26/729 729/26 -729/26], [-841/28 30/961 -30/961],
<BLANKLINE>
[ 961/30 -961/30 32/1089] [ 34/1225 -34/1225 1225/34]
[-32/1089 1089/32 -1089/32], [-1225/34 36/1369 -36/1369],
<BLANKLINE>
[ 1369/36 -1369/36 38/1521] [ 40/68921 -40/68921 68921/40]
[-38/1521 1521/38 -1521/38], [-68921/40 42/79507 -42/79507],
<BLANKLINE>
[ 79507/42 -79507/42 44/91125]
[-44/91125 91125/44 -91125/44]
[ 1/2 -1/2 2] [1 0 0] [0 1 0] [0 0 1] [0 0 0] [0 0 0] [0 0 0]
[ -2 0 1], [0 0 0], [0 0 0], [0 0 0], [1 0 0], [0 1 0], [0 0 1]
)
sage: M = MatrixSpace(SR, 2, 2)
sage: tuple(M.some_elements())
(
[1 0] [some_variable some_variable]
[0 0], [some_variable some_variable]
[some_variable some_variable] [1 0] [0 1] [0 0] [0 0]
[some_variable some_variable], [0 0], [0 0], [1 0], [0 1]
)
"""
from itertools import islice
yield self.an_element()
yield self.base().an_element() * sum(self.gens())
some_elements_base = iter(self.base().some_elements())
n = self.dimension()
while True:
L = list(islice(some_elements_base, n))
if len(L) != n:
return
yield self(L)
for g in self.gens():
yield g

def _magma_init_(self, magma):
r"""
Expand Down
4 changes: 2 additions & 2 deletions src/sage/numerical/linear_tensor_element.pyx
Expand Up @@ -235,8 +235,8 @@ cdef class LinearTensor(ModuleElement):
sage: from sage.numerical.linear_functions import LinearFunctionsParent
sage: LT = LinearFunctionsParent(RDF).tensor(RDF^(2,2))
sage: LT.an_element() # indirect doctest
[1 + 5*x_2 + 7*x_5 0]
[0 0]
[1 + 5*x_2 + 7*x_5 1 + 5*x_2 + 7*x_5]
[1 + 5*x_2 + 7*x_5 1 + 5*x_2 + 7*x_5]
"""
MS = self.parent().free_module()
assert self.parent().is_matrix_space()
Expand Down
2 changes: 1 addition & 1 deletion src/sage/rings/polynomial/multi_polynomial_sequence.py
Expand Up @@ -129,7 +129,7 @@
sage: A.rank()
4056
sage: A[4055]*v
(k001*k003)
(k002*k003)
TESTS::
Expand Down

0 comments on commit a2fa998

Please sign in to comment.