Mex sparse matrix - c

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.

Related

How to Determine N of an M x N CSR 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();

store a vector as an (i,j) entry of a matrix in matlab

This is a simplified version of the project I am doing. I can get around this using other methods. I was just wondering, is it possible to do this in matlab ?
I want to store a 1*2 vector [100,100] to the (1,1) entry of a given matrix a. The following is the code.
a=zeros(2,2);
a(1,1)=[100,100];
Then I get Subscripted assignment dimension mismatch error.
I could use cell array instead. But there are not so many handy functions (like tril) for cell array compared with matrix. So, I was just wondering, does anyone know how to handle this situation or this is just a trivial case not need to mention at all. Many thanks for your time and attention.
You can use 3-d matrix instead of 2-d matrix if you already know the length of vector.
a = zeros (2,2,2) ;
a(1,1,:) = [100, 100] ;
or
a = [];
a (1,1,:) = [100,100];
In above example, you have to take care of indexing by yourself and matrix a can be in arbitrary dimensions.

Creating a cell array of different randomized matrices

I'm trying to create a cell array of size N,
where every cell is a randomized Matrix of size M,
I've tried using deal or simple assignments, but the end result is always N identical Matrices of size M
for example:
N=20;
M=10;
CellArray=cell(1,N);
CellArray(1:20)={rand(M)};
this yields identical matrices in each cell, iv'e tried writing the assignment like so:
CellArray{1:20}={rand(M)};
but this yields the following error:
The right hand side of this assignment has too few values to satisfy the left hand side.
the ends results should be a set of transition probability matrices to be used for a model i'm constructing,
there's a currently working version of the model, but it uses loops to create the matrices, and works rather slowly,
i'd be thankful for any help
If you don't want to use loops because you are interested in a low execution time, get rid of the cells.
RandomArray=rand(M,M,N)
You can access each slice, which is your intended MxM matrix, using RandomArray(:,:,index)
Use cellfun:
N = 20;
M = 10;
CellArray = cellfun(#(x) rand(M), cell(1,N), 'uni',0)
For every cell it newly calls rand(M) - unlike before, you were assigning the same rand(M) to every cell, which was just computed once.

How does an N dimensional array with c-dimensional objects perform differently from an N dimensional array with C objects?

Excerpt from the O'Reilly book :
From the above excerpt the author explain in performance terms why there should be a performance difference in big oh or other terms and the basis for the formula to find any element in n by c dimensional array.
Additional: Why are different data types used in the three dimensional example? Why would you even bother to represent this in different ways ?
The article seems to point out different ways to represent matrix data structures and the performance gains of a single array representation, although it doesn't really explain why you get the performance gains.
For example, to represent a NxNxN matrix:
In object form:
Cell {
int x,y,z;
}
Matrix {
int size = 10;
Cell[] cells = new Cell[size];
}
In three-arrays form:
Matrix {
int size = 10;
int[][][] data = new int[size][size][size];
}
In a single array:
Matrx {
int size = 10;
int[] data = new int[size*size*size];
}
To your question, there is a performance gain by representing a NxN matrix as a single array of N*N length, you gain performance because of caching (assuming you cannot fit the entire matrix in one chunk); a single array representation guarantees the entire matrix will be in a contiguous chunk of memory. When data is moved from memory into cache (or disk into memory), it is moved in chunks, you sometimes grabs more data than you need. The extra data you grab contains the area surrounding the data you need.
Say, you are processing the matrix row by row. When getting new data, the OS can grab N+10 items per chunk. In the NxN case, the extra data (+10) may be unrelated data. In the case of a N*N length array, the extra data (+10) is most likely from the matrix.
This article from SGI seems to give a bit more detail, specifically the Principles of Good Cache Use:
http://techpubs.sgi.com/library/dynaweb_docs/0640/SGI_Developer/books/OrOn2_PfTune/sgi_html/ch06.html

C Programming : Sum of third upper anti-diagonal a squared matrix , help badly needed please

im doing a short course in c programming and i have been so busy lately with my other classes and and helping my bother prepare for his wedding (as im his best man)that I have fallen behind and need help. any help towards this short assignment would be much appreciated as im not familiar at all with matrixs and its due in a few days.
the assignment is to Sum of third upper anti-diagonal a squared matrix .
i have been given this information:
The matrix should be a square, integer matrix of size N. In this assignment the matrix will be stored
in a 1d block of memory. You will have to convert between the conceptual 2d matrix addressing and
1d block addressing with pointer arithmetic.
Note on random numbers:
rand() function returns the next integer a sequence of pseudo-random integers in the range
[0, RAND_MAX]. RAND_MAX is a very large number and varies from system to system. To get an
integer in the range [min, max]:
(int)((min)+rand()/(RAND_MAX+1.0) * ((max)-(min)+1))
srand(SEED) is used to set the seed for rand. If srand() is called with the same seed value, the
sequence of pseudo-random numbers is repeated. To get different random numbers each time a
programme runs use time(NULL) as the seed. Rand is in stdlib.h, which needs to be included.
The program should be structured as follows.
#define N 32 // Matrix size
#define MYSEED 1234 // Last 4 digits of your student number.
int *initialise( ) // Allocate memory for the matrix using malloc
// Initialise the matrix with random integers x, 1≤ x ≤ 9
// Use 'MYSEED' as the seed in the random generator.
// Return a pointer to the matrix
void print_matrix(int *) // Print matrix on screen
int compute_diagonal(int *) // Compute your required calculation using pointer arithmetic.
// (square bracket [ ] array indexes shouldn't be used)
// Return the solution.
void finalise(int *) //free the allocated memory.
int main() // The main function should print the solution to screen.
Without doing your homework assignment for you, here's a tip:
Make a functions that abstract storing and retrieving values out of the matrix. One of the signatures should look a lot like this:
int retrieve(int* matrix, int row, int col);
Ok since this is homework and you still have a few days I will not give you an exact answer here. But I will give you some thoughts with which it should be pretty easy to come to your answer.
Indexing a matrix 1D-way: You are not allowed to use matrix[x][y] here, but only a one-dimensional array. So just take a minute and think of how the index (x,y) can be computed within a 1D array. Keep in mind that C stores elements rowwise (i.e. the elements matrix[0][0], matrix[0][1], matrix[0][2] refer to matrix[0], matrix[1], matrix[2]). It is a simply forumla in terms of X, Y and N
Filling the matrix randomly is easy, the function to create a random int is already given, just walk the matrix along and fill every element
Adding the third anti-upper diagonal. This isn really a programming question. Just sketch a small matrix on a piece of paper and see what elements you have to add. Look at their indices and than combine your newly gained knowledge with your result from my point 1 and you will know what to add up
Edit: Since you are not allowed to use the bracket operator, keep in mind that matrix[5] is the same as *(matrix+5).
I think it's fair to tell you this ;)

Resources