Skip to content

Commit 0143a19

Browse files
author
Release Manager
committed
gh-39374: Updated random_diagonal_matrix function so it works for any ring Fixes #24801. Added functionality to random_diagonal_matrix that allows a random matrix to be generated using an arbitrary ring instead of only the rational numbers. If the matrix of rational numbers is requested the integer ring is used in place of the rational ring to keep most of the functionality the same. Also updated the function documentation to reflect this change and added and extra test with the example from issue #24801. ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> - [ X] The title is concise and informative. - [ X] The description explains in detail what this PR is about. - [ X] I have linked a relevant issue or discussion. - [ X] I have created tests covering the changes. - [ X] I have updated the documentation and checked the documentation preview. ### ⌛ Dependencies URL: #39374 Reported by: Noel-Roemmele Reviewer(s):
2 parents ef0210d + f998c1f commit 0143a19

File tree

1 file changed

+33
-14
lines changed

1 file changed

+33
-14
lines changed

src/sage/matrix/special.py

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,11 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation
241241
242242
- ``'unimodular'`` -- creates a matrix of determinant 1
243243
244-
- ``'diagonalizable'`` -- creates a diagonalizable matrix whose
245-
eigenvectors, if computed by hand, will have only integer entries
244+
- ``'diagonalizable'`` -- creates a diagonalizable matrix. if the
245+
base ring is ``QQ`` creates a diagonalizable matrix whose eigenvectors,
246+
if computed by hand, will have only integer entries. See the
247+
documentation of :meth:`~sage.matrix.special.random_diagonalizable_matrix`
248+
for more information
246249
247250
- ``implementation`` -- (``None`` or string or a matrix class) a possible
248251
implementation. See the documentation of the constructor of
@@ -3054,15 +3057,16 @@ def random_diagonalizable_matrix(parent, eigenvalues=None, dimensions=None):
30543057
"""
30553058
Create a random matrix that diagonalizes nicely.
30563059
3057-
To be used as a teaching tool. Return matrices have only real
3058-
eigenvalues.
3060+
To be used as a teaching tool. The eigenvalues will be elements of the
3061+
base ring. If the base ring used is ``QQ`` then the returned matrix will
3062+
have integer eigenvalues.
30593063
30603064
INPUT:
30613065
30623066
If eigenvalues and dimensions are not specified in a list,
30633067
they will be assigned randomly.
30643068
3065-
- ``parent`` -- the desired size of the square matrix
3069+
- ``parent`` -- the desired parent of the square matrix (a matrix space)
30663070
30673071
- ``eigenvalues`` -- the list of desired eigenvalues (default=None)
30683072
@@ -3071,8 +3075,9 @@ def random_diagonalizable_matrix(parent, eigenvalues=None, dimensions=None):
30713075
30723076
OUTPUT:
30733077
3074-
A square, diagonalizable, matrix with only integer entries. The
3075-
eigenspaces of this matrix, if computed by hand, give basis
3078+
A square, diagonalizable, matrix. Elements of the matrix are elements
3079+
of the base ring. If the ring used is ``QQ`` then we have integer entries,
3080+
and the eigenspaces of this matrix, if computed by hand, gives basis
30763081
vectors with only integer entries.
30773082
30783083
.. NOTE::
@@ -3118,15 +3123,28 @@ def random_diagonalizable_matrix(parent, eigenvalues=None, dimensions=None):
31183123
sage: all(e in eigenvalues for e in eigenvalues2)
31193124
True
31203125
3126+
Matrices over finite fields are also supported::
3127+
3128+
sage: K = GF(3)
3129+
sage: M = random_matrix(K, 3, 3, algorithm="diagonalizable")
3130+
sage: M.parent()
3131+
Full MatrixSpace of 3 by 3 dense matrices over Finite Field of size 3
3132+
sage: M.is_diagonalizable()
3133+
True
3134+
sage: M # random
3135+
[0 0 1]
3136+
[2 1 1]
3137+
[1 0 0]
3138+
31213139
TESTS:
31223140
3123-
Eigenvalues must all be integers. ::
3141+
Eigenvalues must all be elements of the ring. ::
31243142
31253143
sage: random_matrix(QQ, 3, algorithm='diagonalizable', # needs sage.symbolic
31263144
....: eigenvalues=[2+I, 2-I, 2], dimensions=[1,1,1])
31273145
Traceback (most recent call last):
31283146
...
3129-
TypeError: eigenvalues must be integers.
3147+
TypeError: eigenvalues must be elements of the corresponding ring.
31303148
31313149
Diagonal matrices must be square. ::
31323150
@@ -3189,6 +3207,7 @@ def random_diagonalizable_matrix(parent, eigenvalues=None, dimensions=None):
31893207
from sage.misc.prandom import randint
31903208

31913209
size = parent.nrows()
3210+
ring = parent.base_ring()
31923211
if parent.nrows() != parent.ncols():
31933212
raise TypeError("a diagonalizable matrix must be square.")
31943213
if eigenvalues is not None and dimensions is None:
@@ -3199,7 +3218,7 @@ def random_diagonalizable_matrix(parent, eigenvalues=None, dimensions=None):
31993218
values = []
32003219
# create a list with "size" number of entries
32013220
for eigen_index in range(size):
3202-
eigenvalue = randint(-10, 10)
3221+
eigenvalue = ring(randint(-10, 10))
32033222
values.append(eigenvalue)
32043223
values.sort()
32053224
dimensions = []
@@ -3214,8 +3233,8 @@ def random_diagonalizable_matrix(parent, eigenvalues=None, dimensions=None):
32143233
size_check = 0
32153234
for check in range(len(dimensions)):
32163235
size_check = size_check + dimensions[check]
3217-
if not all(x in ZZ for x in eigenvalues):
3218-
raise TypeError("eigenvalues must be integers.")
3236+
if not all(x in ring for x in eigenvalues):
3237+
raise TypeError("eigenvalues must be elements of the corresponding ring.")
32193238
if size != size_check:
32203239
raise ValueError("the size of the matrix must equal the sum of the dimensions.")
32213240
if min(dimensions) < 1:
@@ -3227,7 +3246,7 @@ def random_diagonalizable_matrix(parent, eigenvalues=None, dimensions=None):
32273246
dimensions = [x[0] for x in dimensions_sort]
32283247
eigenvalues = [x[1] for x in dimensions_sort]
32293248
# Create the matrix of eigenvalues on the diagonal. Use a lower limit and upper limit determined by the eigenvalue dimensions.
3230-
diagonal_matrix = matrix(QQ, size)
3249+
diagonal_matrix = matrix(ring, size)
32313250
up_bound = 0
32323251
low_bound = 0
32333252
for row_index in range(len(dimensions)):
@@ -3237,7 +3256,7 @@ def random_diagonalizable_matrix(parent, eigenvalues=None, dimensions=None):
32373256
low_bound = low_bound+dimensions[row_index]
32383257
# Create a matrix to hold each of the eigenvectors as its columns, begin with an identity matrix so that after row and column
32393258
# operations the resulting matrix will be unimodular.
3240-
eigenvector_matrix = matrix(QQ, size, size, 1)
3259+
eigenvector_matrix = matrix.identity(ring, size)
32413260
upper_limit = 0
32423261
lower_limit = 0
32433262
# run the routine over the necessary number of columns corresponding eigenvalue dimension.

0 commit comments

Comments
 (0)