2011年11月5日土曜日

eigen3でsvd

1、cmakeのインストール
クロスプラットフォームのconfigureだと。。
$ sudo yum install cmake

cmakeの使い方


2、eigen3のインストール
$ wget http://bitbucket.org/eigen/eigen/get/3.0.3.tar.gz
$ tar -xvzf 3.0.3.tar.gz
$ cd eigen-eigen
$ mkdir build
$ cd build
$ cmake -G "Unix Makefiles" ../
$ make
$ sudo make install

※1 makeした後、make checkしたら
すごく時間かかったから途中でやめた。


3、c++のソースを書いてコンパイルしてみた。
eigen3 - getting started
C++の行列計算ライブラリ

$ cat sample.cc

#include
#include
#include
using Eigen::MatrixXd;

int main(int argc, char const* argv[])
{

    MatrixXd X(2,2);
    X(0,0)=5;
    X(1,0)=5;
    X(0,1)=5;
    X(1,1)=1;
    X(1,1)=X(1,0) + X(0,1);
    std::cout << X << std::endl;
    //printf("karino : %d\n",X(1,2));
    return 0;
}

$ g++ -I/usr/local/include/eigen3 sample.cc (eigen3のヘッダファイルを読み込む)
$ ./a.out
 5  5
 5 10



4、特異値分解

以下みたいな雰囲気で行けた。


    MatrixXf m = MatrixXf::Random(4,3);
    cout << "---------------------" << endl;
    cout << "A:" << endl << m << endl;
    JacobiSVD svd(m, ComputeThinU | ComputeThinV);

    MatrixXf S = svd.singularValues();
    MatrixXf U = svd.matrixU();
    MatrixXf V = svd.matrixV();
    MatrixXf SD = S.asDiagonal();

    cout << "---------------------" << endl;
    cout << "U:" << endl << U << endl;
    cout << "S:" << endl << S << endl;
    cout << "Diag:" << endl << SD << endl;
    cout << "V:" << endl << V << endl;


    //cout << "A:" << endl << U * S.transpose() * V << endl;
    cout << "---------------------" << endl;
    cout << "A:" << endl << U * SD *V.transpose() << endl;



5、次元圧縮
したみたいな感じで部分行列を取り出せばよい。
どれだけの部分を抽出するかは自分で決めなきゃならない。



    MatrixXf UB  = U.block(0,0,4,2);
    MatrixXf SDB = SD.block(0,0,2,2);
    MatrixXf VB  = V.block(0,0,3,2);

    cout << "---------------------" << endl;
    cout << "UB:" << endl << UB << endl;
    cout << "SDB:" << endl << SDB << endl;
    cout << "VB:" << endl << VB << endl;

    cout << "---------------------" << endl;
    cout << "A:" << endl << UB * SDB *VB.transpose() << endl;




6、ベクトルの内積。
後で調べる。
こことかいいと思う。

0 件のコメント:

コメントを投稿