Largest eigenvalues (and corresponding eigenvectors) in ArrayFire - c++

Given a square matrix A, I need to obtain a diagonal matrix D that contains A's 5 largest magnitude eigenvalues and a matrix V whose columns are the corresponding eigenvectors. In Matlab the code is [V,D] = eigs(A,5). Is there a similar function in ArrayFire C++?
In ArrayFire I use af::eigen(Values,Vectors,A). What is the order of elements in Values? In one test I had the elements of Values sorted in the order of increasing magnitude, however in the other case Values was sorted in the order of decreasing magnitude. Essentially, I need to extract 5 eigenvectors that correspond to the largest magnitude eigenvalues. Do I have to use the sort function to achieve this?
UPDATE
Here's a simple example:
// first example
float a[]={1, 2, 5, -2, 1, -5, 3, -2, 1};
array b(3,3,a);
array evalues, evectors;
af::eigen(evalues, evectors, b);
print(evalues); //`evalues` are not in order
// second example
float a2[]={1, -3, 3, 3, -5, 3, 6, -6, 4};
array b2(3,3,a2);
array evalues2, evectors2;
af::eigen(evalues2, evectors2, b2);
print(evalues2); //`evalues2` are in the decreasing order

Related

Eigen::Vector; Initialize Vector with Values of Eigen::Matrix3f in a function, bigger than 4 entries

im interested in building up a 1x6 Vector, which i want to concatenate with another 1x6 Vector to a 2x6 Matrix. I know it will be a Row Vector, so therefore i thought about initializing a Eigen::RowVectorXf vec, but maybe a simple Eigen::VectorXf would be enough, idk.
(Further on, this should be concatenated to an even bigger 2Nx6 Matrix, for SVD-Operations)
My Input is a 3x3 Matrix of type Eigen::Matrix3f Mat
I thought of using a function, because i have in total ~20 (number isn't that important) input matrices, for each i do have to build 2 vectors, in this manner ( Yep, this will be a 40x6 Matrix in the end):
Question:
How do i initialize vec with entries of mat, especially if its not only the entries, but the products of entries, or sums of products of entries.
Example:
// Inputvalue Mat, which i have
Eigen::Matrix<float, 3, 3> mat = [ 1 2 3; 4 5 6; 7 8 9];
// Outputvalue vec, which i need
Eigen::RowVectorXf = ( mat(0,0)*mat(1,1), mat(1,2)*mat(2,1)+mat(1,0)*mat(0,1), .... );
My inputs of mat(col,row) are arbitrary, but i have a pattern for col,row, which i want to test, and therefore i want to build up those vectors. I've already done it in MATLAB, but im interested in doing it with Eigen in C++.
RowVectorXf build_Vec(Eigen::Matrix3f Mat)
{
Eigen::RowVectorCf vec = ( ..., ..., ..., ..., ..., ...;);
return vec;
}
Anyone some hints for me?
Thanks in advance
For dynamically filling a big matrix at runtime you can't use the CommaInitializer (without abusing it). Just allocate a matrix large enough and set individual blocks:
Matrix<float, Dynamic, 6> Vges(2*views, 6);
for(int i=0; i<views; ++i) {
Matrix<float, 2, 6> foo;
foo << 1,2,3,4,5,6,7,8,9,10,11,12; // or combine from two Matrix<float, 1, 6>
Vges.middleRows<2>(2*i) = foo;
}
You may also consider computing Vges.transpose() * Vges on-the-fly (i.e., by accumulating foo.transpose()*foo into a 6x6 matrix and do a SelfAdjointEigendecomposition instead of a SVD (perhaps use double instead of single precision then).
Eigen::Matrix<double, 6, 6> VtV; VtV.setZero();
for(int i=0; i<views; ++i) {
foo = ...;
VtV.selfadjointView<Upper>().rankUpdate(foo);
}

Regular Multiplication of different shaped Eigen Matrices

I have an Nx3 Eigen matrix.
I have an Nx1 Egein marix.
I'm trying to get the coefficient multiplication of each row in the Nx3 by the corresponding scal in the Nx1 so I can scale a bunch of 3d vectors.
I'm sure I'm overlooking something obvious but I can't get it to work.
#include <Eigen/Dense>
MatrixXf m(4, 3);
m << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12;
MatrixXf dots(4, 1)
dots << 2,2,2,2;
I want to resulting matrix to be Nx3 like so:
2,4,6
8,10,12,
14,16,18,
20,22,24
You can use broadcasting:
m = m.colwise().cwiseProduct(dots);
or observe that all you want to do is to apply a non uniform scaling:
m = dots.asDiagonal() * m;
Both expressions will generate similar code.
Okay, so I got something working. I'm probably doing something wrong but this worked for me so I thought I would share. I wrote my first line of c++ a week ago so I figure I deserve some grace. Anyone with a better solution is encouraged to post.
// scalar/coefficient multiplication (not matrix) on Nx3 x N. For multiplying dot products by vectors
void N3xNcoefIP(MatrixXf &A, MatrixXf &B) {
A.array() *= B.replicate(1, A.size()).array();
}

How to calculate a sum of products of array elements using a fast Fourier transform?

I have some binary array. For example, let my array is:
int a[] = {1, 0, 0, 0, 1, 0, 1, 0, 1}
I want to calculate the values based on this formula:
How to calculate this function, using a fast Fourier transform? I have a large array and I have to calculate this function many times. So, I want to be able to calculate this function quick.
The calculation you are making is basically a convolution and convolution in the time domain is simply multiplication in the frequency domain.So just get the FFT of a and multiply it with itself, then perform an IFFT to return to the time domain.So in short, you can calculate b by
b(2*i) = IFFT( FFT(a[0:2*i)]).FFT(a[0:2*i]) )
void main()
{
int i,k,sum=0;
for(i=0;i<9;i++)
{
for(k=0;k<2*i;k++)
{
sum + =(a[k]*a[2*i-k]; // calculating B
}
}
cout<<sum;
}

Transforming a Mat matrix

I am using C++ and opencv. I have to obtain a transformation matrix when I multiply a matrix,A, with another matrix,B. But matrix B needs to change before multiplying it to A. If B is a 2x3 matrix, it needs to be changed to a 3x3 with the first 2 rows containing the same elements as the original B matrix,but with the last row having all 1's. More simple put,I need to add a last row of 1's to the original B matrix. I want to know whether I can achieve this with any specific Mat matrix operation. Thankyou
You need to use Mat::push_back which will adds elements to the bottom of the matrix.
For example
Mat A = (Mat_<uchar>(3,4) << 1, 2, 3, 4,\
5, 6, 7, 8,\
9, 10, 11, 12); // 3X4 matrix.
Mat B = (Mat_<uchar>(1,4) << 13, 14, 15, 16); // 1X4 matrix
A.push_back(B); // Now A become 4X4 matrix
A straight forward way, but probably not the fastest or prettiest
Mat B_new(3,3,CV_32F);
B_new.row(0) = B.row(0);
B_new.row(1) = B.row(1);
B_new.row(2) = Mat::ones(1,3,CV_32F);
You should take a look at the Mat type documentation

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

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?