Ask Your Question
1

What an efficient way to construct a n by n matrix with all entries -1?

asked 2019-03-06 03:44:27 +0100

abel gravatar image

you could write create an empty list and then, create a column of -1 and augment it to the previous columns, do this n times but is there a faster way?

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
4

answered 2019-03-06 05:53:43 +0100

nbruin gravatar image
a=QQ(-1)
matrix(QQ,1000,1000,lambda i,j:a)

oddly enough the following is faster:

from itertools import repeat
matrix(QQ,1000,1000,repeat(a,1000000))

Of course, select the appropriate ring in your own applications.

edit flag offensive delete link more
2

answered 2019-03-06 07:28:32 +0100

god.one gravatar image

Or you could try numpy which is roughly 50 times faster

import time
import numpy as np
a=QQ(-1)

elapsed_time=0
for i in range(100):
    start=time.time()
    test = a*np.ones([1000,1000])
    end=time.time()
    elapsed_time=elapsed_time+(end-start)

print(elapsed_time/100)

But keep in mind that the example

from itertools import repeat
matrix(QQ,1000,1000,repeat(a,1000000))

generates a different type than a numpy array does

type(matrix(QQ,1000,1000,repeat(a,1000000)))
<type 'sage.matrix.matrix_rational_dense.Matrix_rational_dense'>

type(a*np.ones([1000,1000]))
<type 'numpy.ndarray'>
edit flag offensive delete link more
0

answered 2019-03-06 16:25:53 +0100

Juanjo gravatar image

updated 2019-03-06 16:28:11 +0100

As another alternative, you can use ones_matrix, which returns a matrix with all entries equal to 1. So, to build, say, an $1000\times1000$ matrix with all entries being $-1$, you can simply write -ones_matrix(1000,1000).

edit flag offensive delete link more

Comments

1

For the sake of comparison, once done all the imports and set m=1000, let us test the time required by each option:

%%timeit
matrix(m,m,lambda i,j:-1)

1 loop, best of 3: 431 ms per loop

%%timeit
matrix(m,m,repeat(-1,m*m))

10 loops, best of 3: 98.3 ms per loop

%%timeit
-np.ones([m,m])

1000 loops, best of 3: 1.79 ms per loop

%%timeit
-ones_matrix(m,m)

10 loops, best of 3: 72 ms per loop

In a different computer, results will be different, of course. Except in the case of the Numpy array, the elements of the resulting matrix belong to the Integer Ring.

Juanjo gravatar imageJuanjo ( 2019-03-06 17:17:32 +0100 )edit

It makes quite a difference to make the element a:=-1 outside of the function and to specify the base ring of the matrix so that sage doesn't have to figure that out itself. So

a=-1
matrix(ZZ,m,m,lambda i,j:a)

is measurably faster. This is mainly because in sage, -1 is not a literal but gets converted to Integer(-1) by the preparser.

If you want to remove a further bit of overhead, you can define the lambda via

def make_lambda():
    a=-1
    return lambda i,j: a
fn=make_lambda()
matrix(ZZ,m,m,fn)
nbruin gravatar imagenbruin ( 2019-03-06 17:41:43 +0100 )edit

@nbruin Yes, you are right. Now %%timeit yields 10 loops, best of 3: 146 ms per loop. To be fair, an analog time reduction happens in the second alternative:

 a = -1
 matrix(ZZ,m,m,repeat(a,m*m))

10 loops, best of 3: 74.2 ms per loop

which is as fast as -ones_matrix(ZZ,m,m).

Juanjo gravatar imageJuanjo ( 2019-03-06 18:37:30 +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-03-06 03:44:27 +0100

Seen: 552 times

Last updated: Mar 06 '19