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

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 close merge delete

Sort by ยป oldest newest most voted
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.

more

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'>

more

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).

more

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.

( 2019-03-06 17:17:32 +0200 )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)

( 2019-03-06 17:41:43 +0200 )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).

( 2019-03-06 18:37:30 +0200 )edit