Eigen矩阵运算库使用

1. l p l_p lp norm/p范数计算

L2范数 squareNorm(),等价于计算vector的自身点积,norm()返回squareNorm的开方根。

这些操作应用于matrix,norm() 会返回Frobenius或Hilbert-Schmidt范数。

如果你想使用其他Lp范数,可以使用lpNorm< p >()方法。p可以取Infinity,表示L∞范数。

int main()
{
  VectorXf v(2);
  MatrixXf m(2,2), n(2,2);
  
  v << -1,
       2;
  
  m << 1,-2,
       -3,4;
  cout << "v.squaredNorm() = " << v.squaredNorm() << endl;
  cout << "v.norm() = " << v.norm() << endl;
  cout << "v.lpNorm<1>() = " << v.lpNorm<1>() << endl;
  cout << "v.lpNorm<Infinity>() = " << v.lpNorm<Infinity>() << endl;
  cout << endl;
  cout << "m.squaredNorm() = " << m.squaredNorm() << endl;
  cout << "m.norm() = " << m.norm() << endl;
  cout << "m.lpNorm<1>() = " << m.lpNorm<1>() << endl;
  cout << "m.lpNorm<Infinity>() = " << m.lpNorm<Infinity>() << endl;
}

2. colwise()/rowwise()

将矩阵理解成每一列/行进行单独运算

double stop1 = (X-Xo1).colwise().norm().maxCoeff();

3. array()

矩阵的相应位置元素的计算,可以实现卷积,Array的赋值、加法、减法也与Matrix类似,需要说明的是Array相乘,这个操作类似于Matlab中的".*",对应元素做计算,所以两个Array相乘,只能是大小相同的Array。

Array提供了一些操作函数,abs(),求每个元素的绝对值;sqrt(),求每个元素的算术平方根;a.min(b),求a和b中每个位置较小的元素。

4. block< r,c >(i,j) / block(i,j,r,c)

从(i,j)位置开始取 r × c r \times c r×c 大小的矩阵块,并且可以进行赋值

5. cast< T >.()

实现矩阵类型的转换

Eigen::MatrixXf mf;
Eigen::MatrixXd md = mf.cast<double>();

6. noalias() eval() 矩阵赋值混淆问题

参考资料

7. matlab矩阵相关

Eigen全面

8. aligned_allocator

内存对齐,防止出现段错误!

std::vector<Eigen::Matrix4d,Eigen::aligned_allocator<Eigen::Matrix4d>>

Eigen内存对齐原理

9. slerp

球面线性插值(Spherical linear interpolation,通常简称Slerp),是四元数的一种线性插值运算,主要用于在两个表示旋转的四元数之间平滑差值。下面来简单推导一下Slerp的公式。

S l e r p ( q 1 , q 2 , t ) = s i n [ ( 1 − t ) θ ] q 1 + s i n t θ q 2 s i n θ Slerp(q_1, q_2, t) = \frac{sin[(1-t)\theta]{q_1} + sint\theta q_2}{sin\theta} Slerp(q1,q2,t)=sinθsin[(1t)θ]q1+sintθq2

参考原理

#include <iostream>
#include <math.h>

void slerp(float starting[4], float ending[4], float result[4], float t )
{
    float cosa = starting[0]*ending[0] + starting[1]*ending[1] + starting[2]*ending[2] + starting[3]*ending[3];
    
    // If the dot product is negative, the quaternions have opposite handed-ness and slerp won't take
    // the shorter path. Fix by reversing one quaternion.
    if ( cosa < 0.0f ) 
    {
        ending[0] = -ending[0];
        ending[1] = -ending[1];
        ending[2] = -ending[2];
        ending[3] = -ending[3];
        cosa = -cosa;
    }
    
    float k0, k1;
    
    // If the inputs are too close for comfort, linearly interpolate
    if ( cosa > 0.9995f ) 
    {
        k0 = 1.0f - t;
        k1 = t;
    }
    else 
    {
        float sina = sqrt( 1.0f - cosa*cosa );
        float a = atan2( sina, cosa );
        k0 = sin((1.0f - t)*a)  / sina;
        k1 = sin(t*a) / sina;
    }
    result[0] = starting[0]*k0 + ending[0]*k1;
    result[1] = starting[1]*k0 + ending[1]*k1;
    result[2] = starting[2]*k0 + ending[2]*k1;
    result[3] = starting[3]*k0 + ending[3]*k1;
}



int main()
{
     
    float p[4] = {1,0,0,0};
    float q[4] = {0.707,0,0,0.707};
    float r[4] = {0};

    slerp(p,q,r,0.333);
    std::cout<<r[0]<<","<<r[1]<<","<<r[2]<<","<<r[3]<<std::endl;

    slerp(p,q,r,0.667);
    std::cout<<r[0]<<","<<r[1]<<","<<r[2]<<","<<r[3]<<std::endl;

    return 0;
}

10. 矩阵的最大最小值及其位置

double min = mMat.minCoeff(&minRow,&minCol);
double max = mMat.maxCoeff(&maxRow,&maxCol);
    cout << "Max = \n" << max << endl;
	cout << "Min = \n" << min << endl;
	cout << "minRow = " << minRow << "minCol = " <<minCol<<endl;
	cout << "maxRow = " << maxRow << "maxCol = " << maxCol << endl;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值