How to Determine N of an M x N CSR Sparse Matrix - sparse-matrix

I have the CSR sparse matrix arrays representing an M x N matrix:
data
indoor
indices
My question is how do I determine the original dimension N. I understand that indptr has a M + 1 entries, so M is easily determined. But I can't see how to determine N, unless the matrix is square (M = N).
Any assistance would be much appreciated.
Kind regards
John

This heavily depends on the implementation of CRS/CCS. As you have noticed, it is only possible to directly extract the number of rows M when using CRS (or the number of columns N when using CCS) if the matrix has M * N entries. I'll try to answer this using the Eigen SparseMatrix implementation in C++ as you didn't specify for which language.
To initialize a sparse matrix with Eigen, you must first define a container of triplets (which contain information of the value, row and index of a coefficient):
std::vector<Eigen::Triplet<double>> coefficients;
buildProblem(coefficients); //fills the vector according to problem
Then you must declare the sparse matrix for which must include the dimension of the matrix:
Eigen::SparseMatrix<double> A(m,n);
A.setFromTriplets(coefficients.begin(), coefficients.end());
To retrieve the dimension, you can use these methods:
A.rows();
A.cols();
A.size(); // returns rows*cols
A.innerSize(); // returns minor dimension with respect to the storage order, i.e., the number of rows for a column-major matrix
A.outerSize(); // returns major dimension with respect to the storage order, i.e., the number of columns for a column-major matrix
A.nonZeros();

Related

sparse matrix multiplication using MKL libraries

I was looking to find a way to perform a symmetric sparse matrix - matrix multiplication:
X = A B
where the sparse matrix A was previously stored in CSR3 format (upper triangular), while the matrix B is a dense non-symmetric matrix. Is there a routine inside the MKL libraries to do it? or do they all need the full sparse matrix in CSR format (to get the handle from) instead of the triangular one (I built the triangular matrix because I need to use it in MKL Pardiso)? I know about the mkl_sparse_d_mv(...) routine, but I couldn't find a way to get the sparse matrix handle from a symmetric sparse matrix previously stored like an upper triangular matrix in CSR format.
thank you in advance,
Daniele
Could you try the mkl_sparse_?_mm, where [?] == s,d,c and z data types.
This routine performs a matrix-matrix operation:
Y := alpha*op(A)X + betaY
where alpha and beta are scalars, A is a sparse matrix, op is a matrix modifier for matrix A, and X and Y are dense matrices.
In most cases you can easily feed a CSR3-stored matrix into sparse_d_create_csr by passing appropriately offset pointers to your row index for pointerB and pointerE.
You can then tell mkl_sparse_d_mm the sparse matrix is triangular and you'd like it to be filled (I have never done this and can't promise that it works).
ok, I can now say the routine needs the full matrix in CSR format, the matrix struct description it will only tells the routine to take one triangle(upper/lower) from the input full CSR matrix, but still it needs it all.

Vectorizing access to a slice of a three-dimensional matrix in MATLAB

I have a three-dimensional matrix of these sizes, approximately
A = rand(20, 1000, 20);
where the first and third dimensions are always the same length. I want to zero the elements in a main diagonal slice. This does what I mean
for ii = 1:size(A, 1)
A(ii, :, ii) = 0;
end
Is there a vectorized or otherwise faster way to do this? This code runs about 100,000 times, with these approximate sizes, but not the exact same sizes each time.
You can use logical indexing for multible tailing dimensions while using subscript indexing for all previous dimensions individually. This way you can easily do the operation on an 1000 20 20 matrix. To apply this to your matrix, permute is required which might be slow:
n=size(A,3)
A=permute(A,[2,1,3]);
A(:,diag(true(n,1)))=0;
A=permute(A,[2,1,3]);
If it would be possible to permanently swap the dimensions of A in your code and avoid the permute, this would lead to the fastest solution.
Alternatively you can use repmat to expand the index to the dimensions of A
ix=repmat(reshape(diag(true(n,1)),n,1,n),[1,size(A,2),1])
A(ix)=0
For matrices of the same size you could keep ix. Not having access to MATLAB right now, I don't know which solution is faster.
You can use bsxfun to build a linear index of the elements to be zeroed:
ind = bsxfun(#plus, (0:size(A,2)-1).'*size(A,1), 1:size(A,1)*size(A,2)+1:numel(A) );
A(ind) = 0;

how to split a matrix by given criteria

I have a matrix
j=randn(3,17)
M=[1;10;6]
I want to split the j matrix by its first row and the consecutive 10 rows, and then the rest 6. As a result, I want to have three different matrices.
Assume I don't see the size of M, nor its content. In that sense, how can I automate splitting the j matrix according to the unknown size and content of M? I would like to avoid using nested for loops.
You may want to use mat2cell for splitting a matrix.
In your case,
J = randn(3,17)
M = [1;10;6]
C = mat2cell(J, size(J,1), M)
where C{1} to C{3} are your matrices.
By the way it's not a good practice to call a matrix j as it is already defined by matlab.

Extracting a block out of a multidimensional matrix

Consider the multi-dimensional matrix A where size(A) has the identical even elements N. How should one find the matrix B with size(B)=size(A)/2 such that:
B(1,1,...,1)=A(1,1,...,1),
B(1,1,...,2)=A(1,1,...,2),
...
B(N/2,N/2,...,N/2)=A(N/2,N/2,...,N/2).
I generally don't like arrayfun (or loopy functions), but if the number of dimensions is not in the thousands, then this should be just fine:
Nv = size(A)/2;
S = arrayfun(#(x){1:x},Nv);
B = A(S{:});
Should work with different sized dimensions too. Just decide how you want to deal with dimensions where mod(size(A),2)~=0.

Mex sparse matrix

I created a sparse matrix in MEX using mxCreateSparse.
mxArray *W;
W=mxCreateSparse(n*n,n*n,xsize,mxREAL);
double *wpoint;
wpoint=mxGetPr(W);
for(p=0;p<xsize;p++)
{
Wpoint[(returnindex1(xi[p][0],xi[p][1])-1)*n*n + (returnindex1(xj[p][0],xj[p][1]))]= exp(-df[p]/(SIGMAI*SIGMAI)) * exp(-dx[p]/(SIGMAJ*SIGMAJ));
}
the maximum value which comes from (returnindex1(xi[p][0],xi[p][1])-1)*n*n + (returnindex1(xj[p][0],xj[p][1])) is n*n*n*n and I have created the sparse matrix of dimension (n*n)X(n*n)
When I display the whole matrix, some of the zero elements come as junk.
Also for large values of n, segmentation fault occurs at wpoint.
The pr array holds xsize elements and you accessing the array with out of bounds indices . Hence the seg violation.
I think your fundamental problem is that you have not fully grasped how sparse matrices are stored in MATLAB. I'm not an expert on the MATLAB implementation details but my recollection is that it uses compressed column storage.
In essence there are 3 arrays as follows:
double pr[NZMAX] which contains the NZMAX non-zero values.
int ir[NZMAX] which contains the row number of each value in pr.
int jc[m] which indexes into pr and ir identifying the first item in each of the m columns.
That's the executive summary, but I recommend that you read up on the details more carefully.

Resources