Column wise initialization and calculation of standard deviation in eigen library
Asked Answered
C

3

7

I did a MATLAB code and I am trying to do it in C++ using Eigen library.In my MATLAB code I had to do a particular function like this

M=10;
s1 = zeros(20,M);
for i=1:M
  s1(:,i) = i*i;%some function 
  s1(:,i) = s1(:,i)/std(s1(:,i));
end

I am confused on using .colwise() and is there an in built function to get standard deviation using Eigen library?

Chibouk answered 10/3, 2018 at 8:4 Comment(0)
D
12

As Yuyao pointed out, there is no standard deviation function built into Eigen (at the moment). You can compute this for a single vector using the following (generally, prefer using Array if you are working more on element-wise operations):

Eigen::ArrayXd vec;
double std_dev = std::sqrt((vec - vec.mean()).square().sum()/(vec.size()-1));

(Since there was an edit request: Note that for an un-biased estimation of the standard deviation you need to divide by vec.size()-1: [1])

If you want to compute the column-wise std-dev of a whole array, the following should work:

Eigen::Index N = 20, M = 10;
Eigen::ArrayXd angles = Eigen::ArrayXd::LinSpaced(N, -M_PI/2, M_PI/2);

Eigen::ArrayXXd s1(N, M);
for(Eigen::Index i=0; i< s1.cols(); ++i)
{
    s1.col(i) = (i+1)*sin(angles+i);
}

Eigen::Array<double, 1, Eigen::Dynamic> std_dev = ((s1.rowwise() - s1.colwise().mean()).square().colwise().sum()/(M-1)).sqrt();
std::cout << std_dev << "\n\n";

s1.rowwise() /= std_dev;

std::cout << s1 << "\n\n";
Diaconate answered 10/3, 2018 at 16:19 Comment(2)
I don't think you need the -1 if vec represents the entire population (as opposed to a sampled sub-portion of it). This is because when you have the entire population, you'd have an exact calculation of the standard deviation, as opposed to an estimate with various biases that needs correcting. Because the OP doesn't specify either way, both solutions should be mentioned.Dramatist
Since you are computing column-wise std, shouldn't you divide by (N-1) instead of (M-1)? Because you have N elements in a single column.Anele
R
0

I am confused on using .colwise()

You might want to use .col(i) instead.

Is there an in built function to get standard deviation using Eigen library?

No, since standard deviation function seems to be listed in this TODO List.

Rubirubia answered 10/3, 2018 at 8:50 Comment(2)
How to generate the C++ equivalent of MATLAB function std()?Chibouk
I defined a matrix MatrixXcd s(181,3); and tried to initialise s.col(0)=sin(angles); //where angles are radian values of -90 to 90, it gave me an error. Is this command incomplete?Chibouk
L
0

Now, if you want to get the standard deviation of each column in the matrix.

For example, your matrix and stdev_vector are like this:

Eigen::MatrixXd matrix;
Eigen::RowVectorXd stdev_vector;

Then, you can write your code to get the standard deviation like this:

stdev_vector = ((matrix.rowwise() - matrix.colwise().mean()).colwise().squaredNorm() / (matrix.rows() - 1)).cwiseSqrt()

Notice the difference between Eigen::Array and Eigen::Matrix

Liz answered 17/1 at 7:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.