16

我在 C++ 中使用 Eigen 库:我目前正在自己​​计算协方差矩阵,如下所示:

Eigen::MatrixXd covariance_matrix = Eigen::MatrixXd::Constant(21, 21, 0);
data mean = calc_mean(all_data)
for(int j = 0; j < 21; j++){
    for(int k = 0; k < 21; k++){
        for(std::vector<data>::iterator it = all_data.begin(); it!= all_data.end(); it++){
            covariance_matrix(j,k) += ((*it)[j] - mean[j]) * ((*it)[k] - mean[k]);
        }
        covariance_matrix(j,k) /= all_data.size() - 1;
    }
}

是否有内置/更优化的方法可以使用 Eigen 库执行此操作?例如,如果我将数据存储MatrixXd在每行是一个观察值而每列是一个特征的位置?

谢谢

4

2 回答 2

55

使用 Eigen 表达式将利用 SIMD 和缓存优化算法,所以是的,它肯定会更快,并且无论如何,编写起来要简单得多:

MatrixXd centered = mat.rowwise() - mat.colwise().mean();
MatrixXd cov = (centered.adjoint() * centered) / double(mat.rows() - 1);

此外,假设“data”是 double[21] 的 typedef,那么您可以使用 Map<> 功能将 std::vector 视为 Eigen 对象:

Map<Matrix<double,Dynamic,21,RowMajor> > mat(&(all_data[0][0], all_data.size(), 21);
于 2013-02-28T18:01:40.847 回答
7

当每一行都是一个观察值时,您可以使用 wikipedia ( http://en.wikipedia.org/wiki/Sample_mean_and_sample_covariance#Sample_covariance )上显示的样本协方差矩阵的矩阵公式

样本协方差,来源:上面链接的维基百科文章.

就特征矩阵乘法等而言,这相当容易编写。对我来说,它是否会更高效并不明显,我怀疑优化器必须做得非常好(确保至少使用 -O2)。可能值得尝试和分析它。

于 2013-02-28T15:37:18.330 回答