conversion of Eigen::matrixXd to Double - c++

I have been trying to reconstruct the input data fed to my RBM program written in C++ with the aid of Eigen library. But in order to keep the matrix elements of the reconstructed matrix into some specific range, i need to apply a sigmoid function to those.
When i do so i get a conversion error and i don't know the way round it.
Here is my Sigmoid function computed in an header file:
double sigmoid(double x)
{
return 1.0 / (1.0 + exp(-x));
}
And here is how i compute the reconstruction:
MatrixXd V;
double well[36];
Map<MatrixXd>( well, V.rows(), V.cols() ) = V;
V = sigmoid(H * result3Eigen.transpose() + onesmat*result2Eigen.transpose());
At last here the error message i get when compiling the code:
error C2664:'utils::sigmoid':cannot convert parameter 1 from 'Eigen::MatrixXd'
to 'double'
Thank you for any hints in solving the issue.

If you want to apply a function to each element of an Eigen matrix, you can use the unaryExpr function:
V = my_matrix.unaryExpr(&sigmoid);
This will run the sigmoid function on each element of the Eigen matrix my_matrix, and then return another matrix as the result.

Related

Rationale for Eigen API for Matrix with Scalar operations

Consider the following code:
#include <Eigen/Core>
using Matrix = Eigen::Matrix<float, 2, 2>;
Matrix func1(const Matrix& mat) { return mat + 0.5; }
Matrix func2(const Matrix& mat) { return mat / 0.5; }
func1() does not compile; you need to replace mat with mat.array() in the function body to fix it ([1]). However, func2() does compile as-is.
My question has to do with why the API is designed this way. Why is addition-with-scalar and division-by-scalar treated differently? What problems would arise if the following method is added to the Matrix class, and why haven't those problems arisen already for the operator/ method?:
auto operator+(Scalar s) const { return this->array() + s; }
From a mathematics perspective, a scalar added to a matrix "should" be the same as adding the scalar only to the diagonal. That is, a math text would usually use M + 0.5 to mean M + 0.5I, for I the identity matrix. There are many ways to justify this. For example, you can appeal to the analogy I = 1, or you can appeal to the desire to say Mx + 0.5x = (M + 0.5)x whenever x is a vector, etc.
Alternatively, you could take M + 0.5 to add 0.5 to every element. This is what you think is right if you don't think of matrices from a "linear algebra mindset" and treat them as just collections (arrays) of numbers, where it is natural to just "broadcast" scalar operations.
Since there are multiple "obvious" ways to handle + between a scalar and a matrix, where someone expecting one may be blindsided by the other, it is a good idea to do as Eigen does and ban such expressions. You are then forced to signify what you want in a less ambiguous way.
The natural definition of / from an algebra perspective coincides with the array perspective, so no reason to ban it.

Complex matrix exponential with Armadillo library

I'm doing some physics simulation in C++ using Armadillo. I need to calculate a product looking like:
Q = R * exp(neg_i*Lambda*t) * R.t() * Q
Where Q,R are cx_mat class of the same size, Lambda is a mat class of the same size as Q,R and is diagonal, neg_i is -i the complex number and t is a double. I should get a unitary matrix as a solution but what I'm getting is non unitary. I was wondering if the exponential function works well with complex matrices? or if not what should I replace it with?
You need to use the expmat() function for a matrix exponential, exp() calculates an element-wise exponential.
For example, some code I'm currently using for a physics simulation:
arma::cx_mat f; // A hermitian matrix
double delta_t ; // A time step
std::complex<double> i_imag(0.0,1.0) ; // i, the imaginary number
std::vector<arma::cx_mat> U; // A vector of complex unitary matrices.
U.push_back(arma::expmat(-i_imag * delta_t * f));
Have tested this code, taking the matrix exponential of anti-hermitian matrices to get unitary transformation and works fine.

Storing the absolute value of an eigen vector in to variable

I seem to have problem with a silly problem as storing a the absolute value of Eigen vector3d.
I want to compute the pow(p.cwiseAbs(),2) but since p.cwiseAbs() isn't a double, the function call doesn't work. i then tried to store it into a variable .. but somehow it doesn't seem possible..
ex.
double p_abs = p.cwiseAbs();
Error message:
error: cannot convert ‘const Eigen::CwiseUnaryOp<Eigen::internal::scalar_abs_op<double>, const Eigen::Matrix<double, 3, 1> >’ to ‘double’ in initialization
double p_abs = p.cwiseAbs();
How do i compute the pow(..,2) of the absolute value of the vector?.
The expression i am trying to write into code is :
The expression i am trying to code is the one explained by the first answer on this post.
https://math.stackexchange.com/questions/1784106/how-do-i-compute-the-closest-points-on-a-sphere-given-a-point-outside-the-sphere/1784159#1784159
How do i compute the pow(..,2) of the absolute value of the vector?
You are probably looking for the squared norm. That is simply:
p.squaredNorm();
To answer the original question "how-do-i-compute-the-closest-points-on-a-sphere-given-a-point-outside-the-sphere" using Eigen:
Vector3d center, P, Q;
double radius;
Q = center + radius * (P-center).normalized()

Armadillo integer eigen decomposition

I am trying to use Armadillo to decompose a matrix consisting of integers (i.e. arma::Mat<int>) into eigenvalues and eigenvectors
However, it always gives me compile error no matter what I put as input matrix and output vector/matrix type
It works when i declare the input matrix as arma::Mat<double>, output vector(eigenvalues) as arma::Col<std::complex<double>> and output matrix(eigenvectors) as arma::Mat<std::complex<double>>
I have tried using int and/or std::complex<int> as types for the inputs and the outputs but neither of them worked.
Is there a way that I can do decompose matrices of integer values?
Thanks
First convert the integer matrix to a double matrix using the conv_to function. For example, imat A = ...; mat B = conv_to<mat>::from(A);. Then you can do eigen decomposition on the converted matrix.

Eigen C++ matrix multiplication between MatrixXd and VectorXd

So below is my code and as you can see I am trying to multiply a square matrix MatrixXd with vectorXd.
When I try this, I get the following error:
"invalid operands to binary expression ('const typename ProductReturnType > >, Matrix >::Type' (aka 'const GeneralProduct
I do not know what is going wrong. I am sorry if this is a bad question, but please help!
void calcMinPortfolio(int num_ofStocks, Eigen::MatrixXd& covMatrix, Eigen::VectorXd& weights){
Eigen::MatrixXd identityMat;
identityMat.resize(num_ofStocks, num_ofStocks);
identityMat.Identity();
weights = (covMatrix.inverse() * identityMat) / (identityMat.transpose() * covMatrix.inverse() * identityMat);
}
There are 2 problems:
1 - The way you construct the identity, you cannot use .Identity() on a dynamic matrix (only on compile-size specified size). Simply use the one-liner
Eigen::MatrixXd identityMat = Eigen::MatrixXd::Identity(num_ofStocks, num_ofStocks);
2 - The denominator is a general matrix product (a type), so you cannot divide a matrix by it. What do you mean by division of a matrix by another one? Use .inverse() for the denominator if this is what you want. Next, multiplying by identities doesn't make any sense unless covMatrix is a scalar, which is not.
PS: even if the denominator is a a size 1 x 1 matrix, it is still a matrix type, and not a scalar, so you cannot divide a matrix by it. If you want to divide it by the scalar represented by the matrix, then use your_expresion(0) to extract the scalar from the 1 x 1 matrix.