Ask Your Question
0

Convert real matrix into Integer matrix

asked 2019-01-27 16:34:47 +0100

raykan gravatar image

Suppose I have a real matrix with integer entries

A = matrix(RR,[[1,2,3],[4,5,6]])

I would like to convert it to an Integer matrix (ZZ). I can do it element by element but is there a function that will do this for the entire matrix. Doing B=ZZ(A) will return an error message

unable to coerce <type 'sage.matrix.matrix_generic_dense.matrix_generic_dense'=""> to an integer.

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
1

answered 2019-01-27 17:27:49 +0100

tmonteil gravatar image

First, the "standard" way to do this is to change the base ring of the matrix as follows;

sage: B = A.change_ring(ZZ) ; B
[1 2 3]
[4 5 6]
sage: B.parent()
Full MatrixSpace of 2 by 3 dense matrices over Integer Ring

If P is a parent and E is some element, P(E) tries to convert E as an element of P. Hence, when you do B = ZZ(A), Sage tries to transform the matrix into an integer, which leads to an error. If you want to use such a conversion, the parent P you are looking for is the space of integer matrices of size 2*3 :

sage: P = MatrixSpace(ZZ,2,3)
sage: P
Full MatrixSpace of 2 by 3 dense matrices over Integer Ring
sage: P(A)
[1 2 3]
[4 5 6]

Or directly:

sage: MatrixSpace(ZZ,2,3)(A)
[1 2 3]
[4 5 6]

Note that it leads to the same result as with the change_ring method:

sage: P(A) == B
True

sage: P == B.parent()
True
edit flag offensive delete link more
1

answered 2019-01-27 16:43:47 +0100

parzan gravatar image

updated 2019-01-27 20:53:49 +0100

It seems that the most efficient method is A.apply_map(ZZ,ZZ) (in terms of running time).

Note this will not work if you have non-integers in the matrix, then you can use A.apply_map(int,ZZ) or A.apply_map(round,ZZ) to round the entries.

edit flag offensive delete link more

Comments

You should be very careful with timings here, since in all cases, most of the time is spent in creating the parent ; compare:

sage: A = matrix(RR,[[1,2,3],[4,5,6]])
sage: %time A.apply_map(ZZ,ZZ)
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 1.49 ms
[1 2 3]
[4 5 6]

And in another fresh Sage session (to avoid possible caching):

sage: A = matrix(RR,[[1,2,3],[4,5,6]])
sage: P = MatrixSpace(ZZ,2,3)
sage: %time A.apply_map(ZZ,ZZ)
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 367 µs
[1 2 3]
[4 5 6]

Note that each parent is only created once in a session. Once it is created, calling P(A) seems slightly faster than A.apply_map(ZZ,ZZ), probably because Sage does not even have to guess an ...(more)

tmonteil gravatar imagetmonteil ( 2019-01-27 21:31:09 +0100 )edit

This appears to be the correct answer. None of the methods in the previous answer will do the conversion between RR and ZZ. I would upvote, but silly karma policies prevent it.

brianko gravatar imagebrianko ( 2019-06-27 22:47:31 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2019-01-27 16:34:47 +0100

Seen: 1,777 times

Last updated: Jan 27 '19