#include <iostream> #include <string> #include <utility> #include <vector> #include <boost/algorithm/string.hpp> #include <boost/lexical_cast.hpp> #include <eigen3/Eigen/Dense> // #include <redsvd/redsvd.hpp> using namespace std; using namespace boost; int main() { vector<pair<string, vector<float>>> data; for (string line; getline(cin, line); ) { vector<string> row; split(row, line, is_any_of(",")); if (row.size() < 2) continue; auto p = make_pair(move(row.back()), vector<float>()); row.pop_back(); for (const auto& val : row) p.second.push_back(lexical_cast<float>(val)); data.push_back(move(p)); } Eigen::MatrixXf data_matrix(data.size(), data[0].second.size()); for (size_t i = 0; i < data.size(); ++i) { for (size_t j = 0; j < data[i].second.size(); ++j) { data_matrix(i, j) = data[i].second[j]; } } Eigen::JacobiSVD<Eigen::MatrixXf> svd( data_matrix, Eigen::ComputeThinU | Eigen::ComputeThinV); const auto& pca_dat = svd.matrixU() * svd.singularValues().asDiagonal(); // const auto& pca_dat = REDSVD::RedPCA(data_matrix, 2).scores(); for (int i = 0; i < pca_dat.rows(); ++i) { cout << data[i].first; for (int j = 0; j < pca_dat.cols(); ++j) cout << ',' << pca_dat(i, j); cout << endl; } }
g++4.6 -std=c++0x でコンパイルできます。RedSVD を使う方はコメントアウトしてあります (svd, pca_dat の定義を消してコメントを戻せば RedSVD 版になる)。RedSVD の方は上位 2 次元だけ出力しています。Eigen は魔法ですね。チュートリアルも親切。でもリファレンス読むのは難しい。