# 基础

eigen库是纯模板库。

# Matrix

  • Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
  • typedef Matrix<float, 4, 4> Matrix4f;
  • 成员变量
    • rows()
    • cols()
    • size() = rows()xcols()

# Vector

  • 向量定义为特殊的矩阵。
  • 默认为列向量,typedef Matrix<float, 3, 1> Vector3f;
  • 行向量,typedef Matrix<int, 1, 2> RowVector2i;

# 特殊值Dynamic

  • 矩阵的维度在编译时不能确定时,用Dynamic表示。
  • typedef Matrix<double, Dynamic, Dynamic> MatrixXd; 行列都未知
  • Matrix<float, 3, Dynamic> 可以只有一维是未知的

# 构造器

只分配内存,不会初始化。指定大小时先行后列。

# 访问

矩阵和向量都可以使用小括号访问。向量还可以使用中括号访问,因为C++不允许中括号操作符有两个参数,所以矩阵不能用中括号访问。

# comma-initializer

Matrix3f m;
m << 1, 2, 3, 4, 5, 6, 7, 8, 9;
/*
  1 2 3
  4 5 6
  7 8 9
*/
1
2
3
4
5
6
7

# 算术运算

  • 矩阵维度必须相同,元素类型也必须相同。eigen不会自动做类型转换。
  • 矩阵和标量的除法,标量必须是除数。
  • eigen在运算时返回的不是Matrix对象,而是"experssion object",运算符重载中没有实际进行运算,最后赋值时统一进行,以便于计算的优化。
  • 转置,共轭,伴随,逆
    • m.transpose()
    • m.transposeInPlace() eigen实现中a=a.transpose()不会正常工作,需要使用该方法。
    • m.conjugate()
    • m.adjoint() For real matrices, conjugate() is a no-operation, and so adjoint() is equivalent to transpose().
    • m.inverse()
  • 点积,叉积
    • v.dot(w) 点击可以使用任意维度的向量
    • v.cross(w) 叉积只能用于三维向量
  • reduction operations
    • m.sum() 所有元素之和
    • m.prod() 所有元素之积
    • m.mean() 所有元素的均值
    • m.maxCoeff() 矩阵中的最大元素的值
    • m.maxCoeff(&i, &j) 矩阵中的最大元素的位置存储于i,j中。
    • m.minCoeff() 矩阵中的最小元素的值
    • m.minCoeff(&i, &j) 矩阵中的最小元素的位置存储于i,j中。
    • m.trace() 矩阵的迹。对角线元素之和
  • Matrix3d.Random() 生成[-1, 1]之间的随机数填充矩阵。对于Dynamic的矩阵,需要制定行列数。

# Array

不同于Matrix用于实现线性代数的运算。Array主要用于做一些逐元素的操作,比如向量的每个元素同时加上某个值,或两个向量逐元素相乘。

  • Array<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
  • typedef Array<float,Dynamic,1> ArrayXf
  • typedef Array<float,3,1> Array3f
  • typedef Array<double,Dynamic,Dynamic> ArrayXXd
  • typedef Array<double,3,3> Array33d

# Block

# Matrix

Block of size (p,q), starting at (i,j)

  • matrix.block(i,j,p,q);
  • matrix.block<p,q>(i,j);

# Vector

Block containing the first n elements *

  • vector.head(n);
  • vector.head(); Block containing the last n elements *
  • vector.tail(n);
  • vector.tail(); Block containing n elements, starting at position i *
  • vector.segment(i,n);
  • vector.segment(i);

# 示例

#include <iostream>
#include <Eigen/Eigen>

using namespace std;
using namespace Eigen;

#define printe(x) cout << endl << x << endl;

void test1()
{
    Matrix2i mat;
    mat(0, 0) = 1;
    mat(0, 1) = 2;
    mat(1, 0) = 3;
    mat(1, 1) = 4;
    printe(mat);

    // 矩阵常见初始化操作
    // 方式一
    mat.setZero();  // 全设为0
    printe(mat);

    mat.setOnes(); // 全设为1
    printe(mat);

    mat.setIdentity(); // 单位矩阵
    printe(mat);

    mat.setConstant(7); // 全设为某个值
    printe(mat);

    // 方式二
    mat = MatrixXi::Zero(2, 2);
    printe(mat);

    mat = MatrixXi::Ones(2, 2);
    printe(mat);

    mat = MatrixXi::Identity(2, 2);
    printe(mat);

    mat = MatrixXi::Constant(2, 2, 7);
    printe(mat);
}

void test2()
{
    // block 操作
    Matrix4i mat;
    int k = 1;
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            mat(i, j) = k++;
        }
    }
    printe(mat);

    MatrixXi mat_partitions;
    mat_partitions = mat.block(0, 0, 2, 2); // 左上角2x2矩阵
    //mat_partitions = mat.block(1, 1, 2, 2); // 中间2x2矩阵
    printe(mat_partitions);

    mat.block(1, 1, 2, 2) = MatrixXi::Constant(2, 2, 9);
    printe(mat);

    printe(mat.row(0));

    printe(mat.col(0));

    // 使用向量构造对角矩阵
    Vector3i vec;
    vec << 1, 3, 5;
    MatrixXi diag;
    diag = vec.asDiagonal();
    printe(diag);
}

void test3()
{
    Matrix2d A;
    A << 1, 2, 3, 4;
    Matrix2d G;
    G = A.inverse();
    printe(G);
    printe(A * G);
    A.transposeInPlace();
    printe(A);
}

int main()
{ 
    //test1();
    test2();
    //test3();
    cin.get();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98