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

さらに、「データ」が 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

各行が観測値の場合、ウィキペディア ( http://en.wikipedia.org/wiki/Sample_mean_and_sample_covariance#Sample_covariance )に示されているように、標本共分散行列の行列式を使用できます。

共分散の例、出典: 上記リンクのウィキペディアの記事.

これは、固有行列の乗算などの観点から書くのはかなり簡単です。パフォーマンスが向上するかどうかは私には明らかではありませんが、オプティマイザーは本当に良い仕事をしなければならないと思います (少なくとも -O2 を使用してください)。試してプロファイリングする価値があるかもしれません。

于 2013-02-28T15:37:18.330 に答える