Maybe it's ill advised doing this in the first place, but I'm trying to multiply a (k,k) matrix with (k,1) random vector, and I want to do this M times. I want to do this in one calculation, so having a (k,M) matrix and multiplying each column by my (k,K) matrix. Similar to how you would multiply a scalar with a vector. Is this possible without a loop?
Not in pure Python. The numpy package is universally used for numerical computation in Python. It provides several ways of doing this kind of vectorized matrix multiplication, of which the most common is probably numpy.matmul():
https://docs.scipy.org/doc/numpy/reference/generated/numpy.matmul.html
Related
I have a large sparse square non-normal matrix: 73080 rows, but only 6 nonzero entries per row (and all equal to 1.). I'd like to compute the two largest eigenvalues, as well as the operator (2) norm, ideally with Python. The natural way for me to store this matrix is with scipy's csr_matrix, especially since I'll be multiplying it with other sparse matrices. However, I don't see a good way to compute the relevant statistics: scipy.sparse.linalg's norm method doesn't have the 2-norm implemented and converting to a dense matrix seems like it would be a bad idea, and running scipy.sparse.linalg.eigs seems to run extremely, maybe prohibitively, slowly, and in any event it computes lots of data that I just don't need. I suppose I could subtract off the spectral projector corresponding to the top eigenvalue but then I'd still need to know the top eigenvalue of the new matrix, which I'd like to do with an out-of-the-box method if at all possible, and in any event this wouldn't continue to work after multiplying with other large sparse matrices.
However, these kinds of computations seem to be doable: the top of page 6 of this paper seems to have data on the eigenvalues of ~10000-row matrices. If this is not feasible in Python, is there another way I should try to do this? Thanks in advance.
What is the fastest way to multiply a matrix with its transpose (AA^T) in Python?
I don't think NumPy/SciPy take into account the symmetries involved when using e.g. np.dot or np.matmul. The resulting matrix is always symmetric so I can imagine there is a faster solution.
I'm facing the inversion of a 6x6 matrix which can also be represented as a symmetric block matrix as following:
Each of the P sub matrices is then a 3x3 matrix. P12 and P21 are equal so that P is symmetric. I would like to exploit this form to compute the inverse P matrix in an efficient way. Until now I'm using using the inv() function from Scipy directly on P but, having profiled my code and considering that I have to invert this type of matrices thousands of times in the code I would wish for a better way. Looking up online I found a formula using Schur complements as follow:
I'm wondering if using this strategy will be more computationally efficient then inverting the 6x6 matrix after assembling it. Since the blocks are only 3x3 I could also think of using formulas for calculating the inverse of the blocks, and then use them in the formula represented in the second picture.
I have to generate a matrix (propagator in physics) by ordered multiplication of many other matrices. Each matrix is about the size of (30,30), all real entries (floats), but not symmetric. The number of matrices to multiply varies between 1e3 to 1e5. Each matrix is only slightly different from previous, however they are not commutative (and at the end I need the product of all these non-commutative multiplication). Each matrix is for certain time slice, so I know how to generate each of them independently, wherever they are in the multiplication sequence. At the end, I have to produce many such matrix propagators, so any performance enhancement is welcomed.
What is the algorithm for fastest implementation of such matrix multiplication in python?
In particular -
How to structure it? Are there fast axes and so on? preferable dimensions for rows / columns of the matrix?
Assuming memory is not a problem, to allocate and build all matrices before multiplication, or to generate each per time step? To store each matrix in dedicated variable before multiplication, or to generate when needed and directly multiply?
Cumulative effects of function call overheads effects when generating matrices?
As I know how to build each, should it be parallelized? For example maybe to create batch sequences from start of the sequence and from the end, multiply them in parallel and at the end multiply the results in proper order?
Is it preferable to use other module than numpy? Numba can be useful? or some other efficient way to compile in place to C, or use of optimized external libraries? (please give reference if so, I don't have experience in that)
Thanks in advance.
I don't think that the matrix multiplication would take much time. So, I would do it in a single loop. The assembling is probably the costly part here.
If you have bigger matrices, a map-reduce approach could be helpful. (split the set of matrices, apply matrix multiplication to each set and do the same for the resulting matrices)
Numpy is perfectly fine for problems like this as it is pretty optimized. (and is partly in C)
Just test how much time the matrix multiplication takes and how much the assembling. The result should indicate where you need to optimize.
I have a sparse csr matrix, sparse.csr_matrix(A), for which I would like to compute the matrix rank
There are two options that I am aware of: I could convert it to numpy matrix or array (.todense() or .toarray()) and then use np.linalg.matrix_rank(A), which defeats my purpose of using the sparse matrix format, since I have extremely large matrices. The other option is to compute a SVD decomposition (sparse matrix svd in python) for a matrix, then deduce matrix rank from this.
Are there any other options for this? Is there currently a standard, most efficient way for me to compute the rank of a sparse matrix? I am relatively new to doing linear algebra in python, so any alternatives and suggestions with that in mind would be most helpful.
I have been using .todense() method and using rank method of numpy to calculate the answers.
It has given me a satisfactory answer till now.