I have 2 sparse matrix files in matrix-market format:
row col val
1 1 3.0
1 2 1.0
2 3 2.0
etc...
Currently, I have split the files into 6 arrays:
row_A[], col_A[], val_A[], row_B[] …
Which contain the row index, column index and value respectively.
I would like to multiply the two matrices easily without having to convert them to dense matrix format first. Is there an algorithm for doing this?
I found this pseudocode on Quora but I'm unsure if its the it's the best implementation, or how it would be implemented in C: https://www.quora.com/What-is-the-C-program-for-the-multiplication-of-two-sparse-matrices
multiply(A,B):
for r in A.rows:
for c in A.rows[r]:
for k in B.rows[c]:
C[r,k] += A[r,c]*B[c,k]
Thanks.
There are sparse packages that do the multiplication for you. Have you tried Csparse inside SuiteSparse?
http://faculty.cse.tamu.edu/davis/suitesparse.html
You don't even need to convert the matrix format. However there are ways to feed in triplet format too.
It is not a good idea to multiply sparse matrices, because the resulting matrix will be dense anyway. You algorithm, apparently, consists of sequential multiplication of sparse matrices by a vector: a matrix is multiplied by a vector, then another matrix is multiplied by the obtained product, and so on. It would be wise to stick to that computational pattern, thus saving CPU time and the amount of RAM (the latter would be large if you intend to obtain and store the product of two sparse matrices).
Related
I am a beginner in Python, trying to implement computer vision algorithms.I have to iterate over image read as a 2 dimensional array several times and I want to avoid using for loops.
For example, I want to multiply camera matrix P(3x4 dimension) with each row of coordinate matrix, where each row is dimension 1x4. I will of course take transpose of the row vector for matrix multiplication. Here is how I have implemented it using for loop. I initialize an empty array. Cameras is an object instance. So I loop over the object to find the total number of cameras. Counter gives me the total number of cameras. Then I read through each row of matrix v_h and perform the multiplication. I would like to accomplish the below task without using for loop in python. I believe it's possible but I don't know how to do it. For the number of points in thousands, using for loop is becoming very inefficient. I know my code is very inefficient and would appreciate any help.
for c in cameras:
counter=counter+1
for c in cameras:
v_to_s=np.zeros((v_h.shape[0],c.P.shape[0],counter),dtype=float)
for i in range(0,v_h.shape[0]):
v_to_s[i,:,cam_count]=np.dot(c.P,v_h[i,:].T)
numpy has matmul() which can perform multiplication
I have a AxBxC array where AXB are pointing to individual grids of a field that i sampled (like coordinates) and C corresponds to the layers underneath. Now I want to calculate the impact of certain activities on these individual points by multiplying it with a 2D matrix.
E.g.
x=5; %x-Dimensions of the sampled area
y=5; %y-Dimensions of the sampled area
z=3; %z-number of layers sampled
Area= zeros(x,y,z);
AreaN= zeros(x,y,z);
now I want to multiply every layer of a given point in X*Y with:
AppA=[0.4,0.4,0.2;0.4,0.5,0.1;0.1,0.2,0.7];
I tried:
for i=1:x
for j=1:y
AreaN(i,j,:)= AppA*Area(i,j,:);
end
end
Unfotunately I get the error:
Error using *
Inputs must be 2-D, or at least one input must be scalar.
To compute elementwise TIMES, use TIMES (.*) instead.
Any help to this is appreciated since I am not yet really familiar with matlab.
Correct Approach
I think, to correct your code, you need to convert that Area(i,j,:) to a column vector, which you can do with squeeze. Thus, the correct loop-based code would look something like this -
AreaN= zeros(x,y,z);
for i=1:x
for j=1:y
AreaN(i,j,:)= AppA*squeeze(Area(i,j,:));
end
end
Now, there are efficient no-loop/vectorized approaches that can be suggested here to get to the output.
Vectorized Approach #1
First approach could be with matrix multiplication and has to be pretty efficient one -
AreaN = reshape(reshape(Area,x*y,z)*AppA.',x,y,z)
Vectorized Approach #2
Second one with bsxfun -
AreaN = squeeze(sum(bsxfun(#times,Area,permute(AppA,[3 4 2 1])),3))
Vectorized Approach #2 Rev 1
If you would like to get rid of the squeeze in the bsxfun code, you need to use an extra permute in there -
AreaN = sum(bsxfun(#times,permute(Area,[1 2 4 3]),permute(AppA,[4 3 1 2])),4)
This would solve the matrix multiplication problem:
AreaN(i,j,:)= AppA*reshape(Area(i,j,:),3,[]);
You might want to consider using bsxfun to aviod loops.
Does anyone know how to do array matrix multiplication in matlab? i.e. I have two 3 dimensional arrays consisting of sets of matrices in the first 2 dimensions and I would like to multiply each matrix in the first array with the corresponding one in the second array. So, i.e. if
A=randn(3,3);
B=cat(3,A,A);
I would like [[operation]] such that
B[[operation]]B = cat(3,A*A, A*A)
done in efficient vector form.
Many thanks in advance.
I have used MULTIPROD from the Mathworks FileExchange for N-D array multiplication before. It is basically an extension of bsxfun to N-D arrays, and works quite nicely (and fast) - although the interface is a bit cumbersome.
I want to have a time series of 2x2 complex matrices,Ot, and I then want to have 1-line commands to multiply an array of complex vectors Vt, by the array Ot where the position in the array is understood as the time instant. I will want Vtprime(i) = Ot(i)*Vt(i). Can anyone suggest a simple way to implement this?
Suppose I have a matrix, M(t), where the elements m(j,k) are functions of t and t is an element of some series (t = 0:0.1:3). Can I create an array of matrices very easily?
I understand how to have an array in Matlab, and even a two dimensional array, where each "i" index holds two complex numbers (j=0,1). That would be a way to have a "time series of complex 2-d vectors". A way to have a time series of complex matrices would be a three dimensional array. (i,j,k) denotes the "ith" matrix and j=0,1 and k=0,1 give the elements of that matrix.
If I go a head and treat matlab like a programming language with no special packages, then I end up having to write the matrix multiplications in terms of loops etc. This then goes towards all the matrix operations. I would prefer to use commands that will make all this very easy if I can.
This could be solved with Matlab array iterations like
vtprime(:) = Ot(:)*Vt(:)
if I understand your problem correctly.
Since Ot and Vt are both changing with time index, I think the best way to do this is in a loop. (If only one of Ot or Vt was changing with time, you could set it up in one big matrix multiplication.)
Here's how I would set it up: Ot is a complex 2x2xI 3D matrix, so that
Ot(:,:,i)
references the matrix at time instant i.
Vt is a complex 2xI matrix, so that
Vt(:,i)
references the vector at time instant i.
To do the multiplication:
for i = 1:I
Vtprime(:,i) = Ot(:,:,i) * Vt(:,i);
end
The resulting Vtprime is a 2xI matrix set up so that Vtprime(:,i) is the output at time instant i.
I'm trying to develop a program in C to convert a sparse matrix file into a dense matrix. From what I've read, the best approach would be the use of linked lists but I have no experience with them and haven't found a good online resource explaining the subject. I'm not looking for a quick solution but rather a website or text source that can explain how the process works so I can apply it to this project. What resources I have seen, suggest using three arrays to handle the values in the matrix (The row, column, and individual value) and two arrays for the vector (one for the row, the other for the column). Thanks!
The file format you've specified is for a dense matrix. A 10x10 matrix with 100 elements is dense. A sparse matrix has fewer than n*m elements and all "missing" elements are assumed to be 0. The point of doing it this way is so that matrices that are almost all zero (which happens in a lot of applications) will use less space. But using a sparse matrix format to store a dense matrix will use far more space than just a plain array.
One common sparse matrix file format is called MatrixMarket and it looks very similar to what you described. The first line has three values, # of rows, # of columns, # of nonzero elements (called nnz). Then you have nnz lines of the actual elements in a triplet: (row #) (column #) (value)
If your sparse matrix is in a similar format then you don't need any sparse matrix in memory. Just scan the values and fill in your dense array directly.
If you do want to have a sparse matrix in memory then there are several options for how to store it. Triplets is the easiest, and it's just an in-memory version of the MatrixMarket file. 3 arrays, or 1 array of structs.
The most common structure for linear algebra operations is Compressed Sparse Columns (CSC) or Compressed Sparse Rows (CSR). I'll let you look that up, but if you want a C implementation to play with you should look at Tim Davis' CSparse. This is also how MatLAB stores sparse matrices, Tim was one of the people who wrote that part of MatLAB.
It sounds like a linked list may not be what you're looking for, but this site offers a pretty comprehensive tutorial on the subject. It may help shed some light on whether or not it would be appropriate for your problem... Good luck!