Ask Your Question
0

Testing if the entries of a matrix of rational vectors are actually integers

asked 2019-06-18 11:58:39 +0100

I moved from Python to SageMath because it allows me to deal with natural operations in mathematics without having to reinvent the wheel through typing obvious classes and methods. I also suppose the built-in classes and methods do things in more efficient ways that I could do myself.

However, sometimes I find hard to find the right function or class for what I want to do.

I have created several matrices using 'matrix' which may have rational or integer numbers (so I use QQ to define them). I want to check which matrices actually have all entries as integers. I know how to do this by looping through all entries of each matrix and calling 'is_integer', but is there an existing method in 'matrix' doing this for me? I could not find one.

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
2

answered 2019-06-18 17:06:02 +0100

updated 2019-06-18 19:13:33 +0100

If you know that you are dealing with 5x4 matrices, for example:

sage: A = random_matrix(QQ, 5, 4)
sage: A in MatrixSpace(ZZ, 5, 4)
False

Or if you don't know the size:

sage: A in MatrixSpace(ZZ, A.nrows(), A.ncols())
False

This seems to be a little faster than all(x in ZZ for x in A.list()), especially as the matrices get large.

sage: %timeit all(a in ZZ for a in random_matrix(QQ, 200, 200).list())
100 loops, best of 3: 15.5 ms per loop
sage: %timeit random_matrix(QQ, 200, 200) in MatrixSpace(ZZ, 200, 200)
100 loops, best of 3: 3.32 ms per loop

Revised timings to also compare the denominator method (on a different computer, so all of the timings are different):

sage: %timeit all(a in ZZ for a in random_matrix(QQ, 200, 200).list())
100 loops, best of 3: 16.2 ms per loop
sage: %timeit random_matrix(QQ, 200, 200) in MatrixSpace(ZZ, 200, 200)
100 loops, best of 3: 3.44 ms per loop
sage: %timeit random_matrix(QQ, 200, 200).denominator() == 1
100 loops, best of 3: 3.77 ms per loop
edit flag offensive delete link more

Comments

From your last comparison it seems to me that all(a in ZZ for a in random_matrix(QQ, 200, 200).list()) is the fastest as it takes less ms. Am I missing something?

Jesus Martinez Garcia gravatar imageJesus Martinez Garcia ( 2019-06-20 17:20:00 +0100 )edit

That one takes 16.2 ms per loop, and the others are about 3.5 ms per loop, so the others are faster.

John Palmieri gravatar imageJohn Palmieri ( 2019-06-20 20:12:43 +0100 )edit

@john_Palimieri all clear, thanks. I got confused by the line "This seems to be a little faster than[...]".

Jesus Martinez Garcia gravatar imageJesus Martinez Garcia ( 2019-06-23 15:21:58 +0100 )edit
3

answered 2019-06-18 12:39:24 +0100

Juanjo gravatar image

updated 2019-06-18 17:33:42 +0100

Try this example:

sage: set_random_seed(100); # to be able to reproduce this example
sage: A = random_matrix(QQ, 5, 4, num_bound=20, den_bound=4); A
[    0    -1  19/3  -1/4]
[ -1/2     8     1  -5/2]
[ -7/2    -9    -5   3/2]
[-11/4  -1/4    -8 -15/4]
[   -9  14/3     8   4/3]
sage: all(map(lambda x: x.is_integer(),A.list()))
False

Hope that helps.

Edit. I have found the denominator method, which yields the lowest common denominator of the matrix elements. So, all entries are integers if and only if such denominator is 1. As a continuation of the above example, we have:

sage: A.denominator()==1
False
edit flag offensive delete link more

Comments

Simpler:

sage: A.change_ring(ZZ)
FrédéricC gravatar imageFrédéricC ( 2019-06-18 13:24:25 +0100 )edit

@FrédéricC If I do that and the matrix has denominators it will give an error 'matrix has denominators so can't change to ZZ.'

Jesus Martinez Garcia gravatar imageJesus Martinez Garcia ( 2019-06-18 13:29:39 +0100 )edit

@Juanjo Yes, of course that works, but I was interested in seeing if there was a method of the class matrix to deal with this, just as there is for the class Rational (or its parent, wherever is_rational is). Anyway, it is neat, so I vote up. If nobody replies in a few days I will accept the answer.

Jesus Martinez Garcia gravatar imageJesus Martinez Garcia ( 2019-06-18 14:39:31 +0100 )edit
1

A little simpler: all(x in ZZ for x in A.list()).

John Palmieri gravatar imageJohn Palmieri ( 2019-06-18 16:59:08 +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

Stats

Asked: 2019-06-18 11:58:39 +0100

Seen: 762 times

Last updated: Jun 18 '19