Replacing sparse matrix inserting operation in Matlab by C++ - c++

I am using a optimization toolbox in Matlab R2016a. But it runs very slow. I find that the main reason is the sparse matrix indexing operation when the size of sparse matrix becomes more than 100000.
In a function of the toolbox, a sparse matrix Jcon is allocated space firstly .
Jcon = spalloc(nrows,ncols,nnonzeros);
Then some other code calculate something like derivatives. In the end some new enties are inserted into Jcon using the following code
Jcon(link_row(ii),col0Right) = DLink.x0_right(ii,jj);
ii and jj are loop variables. The right hand side is usually colume vactor with 4 to 30 rows. The size of Jcon may also change during the inserting operation.
How can I improve the inseting part? Is it possible to use C++ to replace the sparse matrix inserting? Will it be quiker?

Related

Eigen: Modify Rows of Row-Major Sparse Matrix

I am using the Eigen library in C++ for solving sparse linear equations: Ax=b where, A is a square sparse matrix and b is a dense vector with ILU-preconditioned BiCGSTAB. I am initializing the matrix A using the setFromTriplets function. The linear system is generated from discretization of partial differential equations in space and time.
My application changes the matrix slightly at every time-step. I want to modify a small number of rows (around 1% rows) in the matrix in the beginning of each time-step. I am storing the matrix in the row-major format so that I can access the row directly. I don't want to re-assemble the entire matrix from triplets since the number of rows to be modified are around 1%. Moreover, the modification is such that the number of non-zeros in the row are exactly identical. I just want to change the column indices and values. Hence, I do not need to allocate extra memory for the row. After going through the Eigen documentation as well as the forum, I found the functions coeffRef and insert. Both of them will allocate extra memory if the element does not exist. I would like to avoid this since the number of non-zeros are not changing.
Any help is appreciated.

Eigen Library: Setting all Non-Zero elements in a SparseMatrix *Row* to Zero

For a matrix A and row 'i' in MATLAB, I would do the following:
A(i,:) = zeros(size(A(i,:));
A stupid way to do the same would be to iterate through the whole row and setting the non-zero values to zero. This is not suitable as I am working with huge matrices (200,000+ columns) here.
Is there a simple and fast way to do this? I am using the SparseMatrix class in Eigen. I also know that there are at most 3 non zero values in each row. I don't know where.
I need this to edit a few rows in the matrix with new values. The idea is that I first make the whole row zero and then assign my values to certain elements on the same row.
The following question on StackOverflow was relevant but unfortunately had no answers.
The equivalent of the Matlab code above can be implemented using the setZero function, as follows:
A.row(i).setZero();
Note that this works for dense matrices, not sparse ones. The MatrixXd class is recommended if you want the size to be dynamic.

How to do element wise exponential for a matrix in Cuda programming

How to do element wise exponential for a matrix in Cuda programming?
for example:
A = [1 3 4; 6 5 2];
I want to compute:
B = [exp(1),exp(3),exp(4); exp(6);exp(5);(2)]
Is there a way of doing it efficiently and doing it in place (i.e, B replaces A)?
It seems cublas does not provide element wise operation on matrix.
I don't know if libraries exist that do element wise operations on matrices, but you could easily set up a CUDA kernel to do this job. You could for instance give one element of the A matrix to each thread, and they could perform the exponential and write the answer in B. You then call your CUDA kernel as usual. Take a look at this to get an idea of how to implement your kernel and how to call it (but instead of multiplying two vectors like they do in gpuMM you would do an exponential).
EDIT: It looks like you can do element wise operations using Thrust and the set of macros Newton, as is shown in this SO question.

Using FFT to compute sumproduct of two 2D arrays

I am doing program to remove noise from image, in it, i need to compute a lot of sums of pointwise multiplications, right now, i do it through direct approach and it takes huge computation cost:
int ret=0, arr1[n][n].arr2[n][n];
for (int i=0;i<n;i++) for (int j=0;j<n;j++) ret+=arr1[i][j]*arr2[i][j];
I was told, that to compute this convolution between two arrays, i should do this (
more details here here ) :
Calculate the DFT of array 1 (via FFT).
Calculate the DFT of array 2 (via FFT).
Multiply the two DFTs element-wise. It should be a complex multiplication.
Calculate the inverse DFT (via FFT) of the multiplied DFTs. That'll be your convolution result.
It seems, that algorithmic part is more or less clear, but i came to a new problem:
I selected fftw for this task, but after a long time, spent by reading it's docs, i still don't see any function for 2D inverse fft which returns not 2D array, but a single value akin to direct approach, not whole 2D array, what am i missing?

Sparse Blas in Fortran 95

I want to use the Sparse Blas in Fortran95 just for the creation of the matrices and I am using the point entry construction. After creation of the matrix using the command
call duscr_begin(n,n,a,istat)
here a is the handle to the matrix n by n. After inserting value in it, how can I see the final matrix using its handles a ? As I want to use the matrix for some other operation, so I want to see the matrix in three vectors (sparse) form (row_index, Col_index, Value).
detail about this Sparse Blas is given in Chapter 3 and can be seen here
http://www.netlib.org/blas/blast-forum/
actually what i have asked is before 16 days and it is not just writing of a variable to thee screen. I was using some library known as Sparse Blas for creation of the Sparse matrices. Later on by digging in to the library i found the solution to my problem that using the handles how can we get the three vectors row, col and Val. The commands are something like
call accessdata_dsp(mat,a_handle,ierr)
call get_infoa(mat%INFOA,'n',nnz,ierr)
allocate(K0_row(nnz),K0_col(nnz),K0_A(nnz))
K0_row=mat%IA1; K0_col=mat%IA2; K0_A=mat%A
so here nnz are the non zeros entries in the sparse matrix while K0_row, K0_col and K0_A are our required three vectors, which can be used in further calculation.