Published

27 March 2014

Tags

Contents

最近要做一些和矩阵有关的运算, 因为 matlab 实在用不习惯,找了个比较轻量的 Eigen,轻量到都不需要链接,赞吧~

特征值,SVD分解都有,解线性方程,最小二乘都没问题。

似乎还有些针对稀疏矩阵的优化,不过用不着。

一段简单的 code :

#include <iostream>
#include <Eigen/Core>
#include <Eigen/Dense>
#include <Eigen/Eigen>
#include <Eigen/SVD>

using namespace std;
using namespace Eigen;

#define FOR(i,l,r) for (int i=(l); i<=(r); i++)

int main() {
    Vector4d v1;
    v1 << 1, 2, 3, 4;
    cout << "v1 = \n" << v1 << endl;
    cout << "v1.cols() " << v1.cols() << " v1.rows() " << v1.rows() << endl;
    cout << v1(1) << v1(1,0) << endl;

    VectorXd v2(2);
    v2 << 8, 9;
    cout << "v2 = \n" << v2 << endl;

    cout << "test matrix" << endl;

    MatrixXf m1(2,5);
    FOR(i,0,m1.rows()-1) FOR(j,0,m1.cols()-1) m1(i,j) = i*10+j;
    cout << "m1 =\n" << m1 << endl;

    int rows=5;
    int cols=5;
    MatrixXf m2(rows,cols);
    m2<<( Matrix3f()<<1,2,3,4,5,6,7,8,10 ).finished(),
        MatrixXf::Zero(3,cols-3),
        MatrixXf::Zero(rows-3,3),
        MatrixXf::Identity(rows-3,cols-3);
    cout<<"m2=\n"<<m2<<endl;

    cout<< m1*m2 <<endl;

    cout<<"转置"<<endl;
    cout << m2.transpose() * m1.transpose() << endl;

    cout<<"对每个元素执行 cos"<<endl;
    cout << m2.array().cos() << endl;

    cout<<"行列式"<<endl;
    cout << m2.determinant() << endl;

    cout<<"特征向量"<<endl;
    EigenSolver<decltype(m2)> es(m2);
    cout << es.eigenvectors() << endl;

    cout<<"特征值"<<endl;
    cout << es.eigenvalues() << endl;

    cout<<"特征值分解 V*D*V^(-1)"<<endl;
    cout << es.eigenvectors() * es.eigenvalues().asDiagonal() * es.eigenvectors().inverse() << endl;

    cout<<"SVD 分解"<<endl;
    JacobiSVD<decltype(m2)> svd(m2, ComputeThinU | ComputeThinV);
    cout << svd.matrixU().determinant() << endl << svd.singularValues() << endl << svd.matrixV().determinant() << endl;
    cout << svd.matrixU() * svd.singularValues().asDiagonal() * svd.matrixV().transpose() << endl;
    cout<<"SVD 解最小二乘"<<endl;
    cout << svd.solve(VectorXf::Ones(5));

    cout<<"极分解"<<endl;
    auto rot = svd.matrixU() * svd.matrixV().transpose();
    auto scl = svd.matrixV() * svd.singularValues().asDiagonal() * svd.matrixV().transpose();
    cout<<rot<<endl<<scl<<endl;
    cout<<rot.determinant()<<endl<<rot*scl<<endl;

    cout<<"齐次坐标"<<endl;
    Transform<float, 5, Affine> trans;
    //trans.computeRotationScaling();
    cout << trans.matrix() << endl;

    cout<<"解线性方程"<<endl;
    VectorXf v(5);
    v << 1,2,4,3,5;
    cout<<MatrixXf(v.asDiagonal()).colPivHouseholderQr().solve(VectorXf::Ones(5))<<endl;
}


blog comments powered by Disqus