Image reconstruction using SVD Decomposition - c++

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.

Related

Eigen library, Jacobi SVD

I'm trying to estimate a 3D rotation matrix between two sets of points, and I want to do that by computing the SVD of the covariance matrix, say C, as follows:
U,S,V = svd(C)
R = V * U^T
C in my case is 3x3 . I am using the Eigen's JacobiSVD module for this and I only recently found out that it stores matrices in column-major format. So that has had me confused.
So, when using Eigen, should I do:
V*U.transpose() or V.transpose()*U ?
Additionally, the rotation is accurate upto changing the sign of the column of U corresponding to the smallest singular value,such that determinant of R is positive. Let's say the index of the smallest singular value is minIndex .
So when the determinant is negative, because of the column major confusion, should I do:
U.col(minIndex) *= -1 or U.row(minIndex) *= -1
Thanks!
This has nothing to do with matrices being stored row-major or column major. svd(C) gives you:
U * S.asDiagonal() * V.transpose() == C
so the closest rotation R to C is:
R = U * V.transpose();
If you want to apply R to a point p (stored as column-vector), then you do:
q = R * p;
Now whether you are interested R or its inverse R.transpose()==V.transpose()*U is up to you.
The singular values scale the columns of U, so you should invert the columns to get det(U)=1. Again, nothing to do with storage layout.

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);

Rotation of Matrices in Z_p

I want to give the values for a matrix parameter mat_ZZ_p A for the mat_ZZ_p type in NTL. The dimension of my vector is big. So, I am looking at a big square matrix as parameter. So, I cannot assign the values manually. One advantage here to me is that the columns of my matrix are only rotations of the first column. It is of the form
p_0 p_(n-1) p_(n-2) .... p_1
p_1 p_0 p_(n-1) .... p_2
.
.
p_(n-1) p_(n-2) p_(n-3) .... p_0
and I have a variable p which is a vector with the values p_0, p_1, ...,p_(n-1). I have assigned the 1st column of the matrix using a loop through the vector p. but I am not sure how to do the rotation for the other columns. I tried to use that the values when viewed diagonally are the same but in that case, I am not sure how to bound the loop. I tried to use the fact that there is a diagonal downward shift of elements as we move from one column to another. But again in this case, I am not able to assign the value for the 1st row, 2nd column just by referring to the previous column. Is there a standard way to do such rotation of columns?
Since I am trying to solve the system of equations in Z_p, I think the comments in this post does not help me.
Best way to solve a linear equation in code
If you refer to m[i][j] for the generic element of the matrix n x n then what you need is
m[i][j] = m[(i + n - 1) % n][j-1] for every j > 0
For a square matrix with dimensions n * n, to refer to any element not in the first column or first row, use m[i - 1][j - 1], with i and j being the row and cols.

How can I multiply an nxn matrix A in fortran x times to get its power without amplifying rounding errors?

How can I multiply an NxN matrix A in Fortran x times to get its power without amplifying rounding errors?
If A can be diagonalized as
A P = P D,
where P is some NxN matrix (each column is called 'eigenvector'), and D is an NxN diagonal matrix (the diagonal elements are called 'eigenvalues'), then
A = P D P^{-1},
where P^{-1} is the inverse matrix of P. Therefore the second power of A results in
A A= P D P^{-1} P D P^{-1} = P D D P^{-1}.
Repeating multiplication of A for x times yields
A^x = P D^x P^{-1}.
Note here that D^x is still a diagonal matrix. Let the i-th diagonal element of D be D_{ii}. Then, the i-th diagonal element of D^x is
[D^x]_{ii} = (D_{ii})^x.
That is, the elements of D^x is simply x-th power of the elements of D and can be computed without much rounding error, I guess. Now, you multiply P and P^{-1} from left and right, respectively, to this D^x to obtain A^x. The error in A^x depends on the error of P and P^{-1}, which can be calculated by some subroutines in numerical packages such as LAPACK.
as alluded to in the answer by norio, one can employ in general the Jordan (or alternatively Schur) decomposition and proceed in a similar fashion - for details (including brief error analysis) see, e.g., Chapter 11 of Matrix computations by Golub and Loan.

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