Eigen: sparse matrices computing sum of all elements in a row - c++

I'm using the Eigen library to work with sparse matrices and I need to process a matrix, i.e. to:
divide every row of a sparse matrix by the sum of all elements in that row +1 (the extra 1 is added to avoid dividing by zero).
I have a hunch that iterating through the rows, then computing the element sum for each row using yet another iteration will be very inefficient.
To illustrate what I need, let's consider this naive (dense example):
input: J = [ 1, 5; 3, 9];
output: Jp = [0.1666, 0.8333; 0.25, 0.75];
Could you provide a faster/cheaper solution for this process?

Related

2D FFT what to do after converting both matrix into FFT-ed form?

Assume that I have 2 matrix: image, filter; with size MxM and NxN.
My regular convolution looks like this and produces matrix output size (M-N+1)x(M-N+1). Basically it places the top-left corner of a filter on a pixel, convolute, then assign the sum onto that pixel:
for (int i=0; i<M-N; i++)
for (int j=0; j<M-N; j++)
{
float sum = 0;
for (int u=0; u<N; u++)
for (int v=0; v<N; v++)
sum += image[i+u][j+v] * filter[u][v];
output[i][j] = sum;
}
Next, to perform FFT:
Apply zero-padding to both image, filter to the right and bottom (that is, adding more zero columns to the right, zero rows to the bottom). Now both have size (M+N)x(M+N); the original image is at
image[0->M-1][0-M-1].
(Do the same for both matrix) Calculate the FFT of each row into a new matrix, then calculate the FFT of each column of that new matrix.
Now, I have 2 matrices imageFreq and filterFreq, both size (M+N)x(M+N), which is the FFT-ed form of the image and the filter.
But how can I get the convolution values that I need (as described in the sample code) from them?
convolution between A,B using FFT is done by per element multiplication in the frequency domain so in 1D something like this:
convert A,B by FFT
assuming the sizes are N,M of A[N],B[M] first zero pad to common size Q which is a power of 2 and at least M+N in size and then apply FFT:
Q = exp2(ceil(log2(M+N)));
zeropad(A,Q);
zeropad(B,Q);
a = FFT(A);
b = FFT(B);
convolute
in frequency domain use just element wise multiplication:
for (i=0;i<Q;i++) a[i]*=b[i];
reconstruct result
simply apply IFFT (inverse of FFT)...
AB = IFFT(a); // crop to first N (real) elements
and use only the first N element (unless algorithm used need more depends on what you are doing...)
For 2D you can either convolute directly in 2D (using 2 nested for loops) or convolve each axis separately. Beware that separating axises need also to normalize the result by some constant (which depends on dimensionality, resolution and kernel used)
So when put together (also assuming the same resolution NxN and MxM) first zero pad to (QxQ) and then:
Q = exp2(ceil(log2(M+N)));
zeropad(A,Q,Q);
zeropad(B,Q,Q);
a = FFT(A);
b = FFT(B);
for (i=0;i<Q;i++)
for (j=0;j<Q;j++) a[i][j]*=b[i][j];
AB = IFFT(a); // crop to first NxN (real) elements
And again crop to AB to NxN size (unless ...) for more info see:
How to compute Discrete Fourier Transform?
and all sublinks there... Also here at the end is 1D convolution example using NTT (its a special form of FFT) to compute bignum multiplication:
Modular arithmetics and NTT (finite field DFT) optimizations
Also if you want real result then just use only the real parts of the result (ignore imaginary part).

The fastest way to normalize matrix by the sum of it rows

I have a matrix(or 2d array if you like) and I need to calculate the sum of it rows and then divide all matrix rows with this vector - the form of normalization. Currently, I am using MKL vsAdd routine to sum every row and then I am dividing every row in the matrix with MKL vsDiv by the sum that I got. This is the hottest point in my program. Any ideas how to optimize this using any tools? ( The size of matrix is 10 * 52)

C++ Armadillo reshape a matrix with only one dimension size

Using Armadillo, how do I reshape a matrix when I only specify one dimension size?
In Matlab documentation, there is this example of such functionality:
Reshape a 6-by-6 magic square matrix into a matrix that has only 3
columns. Specify [] for the first dimension size to let reshape
automatically calculate the appropriate number of rows.
A = magic(6);
B = reshape(A,[],3);
The result is a 12-by-3 matrix, which maintains the same number of
elements (36) as the original 6-by-6 matrix. The elements in B also
maintain their columnwise order from A.
How can that be accomplished with Armadillo?
You can use .size() to get the total number of elements of your matrix and calculate the dimensions yourself.
Example:
B = reshape(A, A.size()/3, 3);

Opencv Multiplication of Large matrices

I have 2 matrices of dimension 1*280000.
I wanted to multiply one matrix with transposed second matrix using opencv.
I tried to multiply them using Multiplication operator(*).
But it is giving me error :'The total size matrix does not fit to size_t type'
As after multiplication the size will be 280000*28000 of matrix.
So,I am thinking multiplication should 32 bit.
Is there any method to do the 32bit multiplication?
Why do you want to multiply them like that? But because this is an answer, I would like to help you thinking more than just do it:
supposing that you have the two matrix: A and B (A.size() == B.size() == [1x280000]).
and A * B.t() = AB (AB is the result)
then AB = [A[0][0]*B A[0][1]*B ... A[0][279999]*B] (each column is the transposed matrix multiplied by the corresponding element of the other matrix)
AB may also be written as:
[ B[0][0]*A
B[0][1]*A
...
B[0][279999]*A]
(each row of the result will be the row matrix multiplied by the corresponding element of the column (transposed) matrix)
Hope that this will help you in what you are doing... Using a for loop you can print, or store, or what you need with the result

Image reconstruction using SVD Decomposition

I have performed block SVD decomposition over image and I stored results.
Now, I need to make reconstruction from this results. I found few examples all written in Matlab, which is a mystery for me.
I only need formula from which I can reconstruct my picture, or example written in C language.
Matrix A is equal U*S*V'. How will look formula, e.g. for calculating first five singular values (product of which rows and columns)? Please provide formula with indexes in C like style. U and V' are matrices and S is vector (not matrix).
Not sure if I get your question right, but if you just need to know singular values, they are the diagonal values of the middle matrix S. S in general is a diagonal matrix, which is stored here as a vector. I mean, only the diagonal is stored, you should imagine it as a matrix if you're thinking in matrix calculations.
Those diagonal values are your singular values, if you need the first biggest singular values, just take the 5 biggest values of the vector S.
Quoting from Wikipedia:
The diagonal entries Σi,i of Σ are known as the singular values of M.
The m columns of U and the n columns of V are called the left-singular
vectors and right-singular vectors of M, respectively.
In the above quote, sigma is your S, and M is the original matrix.
You have asked for C code, yet my hope is that pseudocode will suffice (it's late, I'm tired). The target matrix A has m rows, c columns and rank rho. The variable p = min(m,n).
One strategy is to first form the the intermediate matrix product B = US. This is trivial due to the diagonal-like nature of the matrix of singular values. Assume you have rho ( = 5 ) singular values. You must enforce rho <= p.
Replace column vector u1 with s1u1.
Replace column vector u2 with s2u2.
...
Replace column vector urho with srhourho.
Replace column vector urho+1 with a zero vector of length m.
Replace column vector urho+2 with a zero vector of length m.
...
Replace column vector up with a zero vector of length m.
Next form the new image matrix A = BVT. The matrix element in row r and column c is the dot product of the rth row vector (length rho) of B with the cth column vector (length rho) of VT.
Another strategy is to jump to the form where the matrix elements of A in row r and column c are
ar,c = sum ( skur,kvc,k, { k, 1, rho } )
The row counter r runs from 1 to m; the column counter c runs from 1 to n.