Eigen::Map用于Eigen矩阵与casadi::DM矩阵的转换

  Eigen::Map常用于将一串数据映射到一个矩阵或一个向量中,常用方法见此处。常常也用于将Eigen::Vector与Eigen::Matrix互转,如下例:

Eigen::Matrix<double, 9, 1> vec;
vec << 1, 2, 3, 4, 5, 6, 7, 8, 9;
Eigen::Matrix3d m = Eigen::Map<Eigen::Matrix3d>(vec.data());
std::cout << m << std::endl;// column major

// 输出:
// 1 4 7
// 2 5 8
// 3 6 9

  实际上Eigen::Map生成的临时对象可以被赋值,并修改其内部数据,特别是casadi的c++版本中对于casadi::DM没有提供很好的赋值和构造方法,不能像Eigen一样使用<<操作符进行赋值,仅支持()标操作符进行赋值,或者通过std::vector进行赋值,效率较低。借助Eigen::Map可以很好的对casadi::DM进行赋值和修改,如下例:

// 定义一个函数如下
Eigen::Map<Eigen::MatrixXd> toEigen(casadi::DM& input) {
    return Eigen::Map<Eigen::MatrixXd>(input.ptr(), input.rows(), input.columns());
}

int main(){
    casadi::DM input = casadi::DM::zeros(3, 3); // 必须初始化, 否则访问空指针
    Eigen::Matrix<double, 9, 1> vec;
    vec << 1, 2, 3, 4, 5, 6, 7, 8, 9;

    Eigen::Matrix3d m = Eigen::Map<Eigen::Matrix3d>(vec.data());
    toEigen(input) = m;
    std::cout << input << std::endl;
    // 输出:
	// 1 4 7
	// 2 5 8
	// 3 6 9
}

注意casadi::MX::sumsqr函数对于多维矩阵casadi::DM的计算规则如下:
对于矩阵:
M = [ a 1 a 2 a 3 ] ∈ R 3 × 3 M=[a_1 a_2 a_3]\in\mathcal{R}^{3\times3} M=[a1a2a3]R3×3
其中
a i ∈ R 3 , i = 1 , 2 , 3 a_i\in\mathcal{R}^3,i=1,2,3 aiR3,i=1,2,3
casadi::MX::sumsqr计算规则即:
∑ i = 1 3 a i T a i \sum_{i=1}^3a_i^Ta_i i=13aiTai

casadi::SX::diff()函数作用是获取后一行减去前一行,得到比原来矩阵少一行的矩阵,如下例:

casadi::SX DI = casadi::SX::sym("DI", 3, 3);
std::cout << DI << std::endl;
std::cout << casadi::SX::diff(DI) << std::endl;

// [[DI_0, DI_3, DI_6], 
// [DI_1, DI_4, DI_7], 
// [DI_2, DI_5, DI_8]]

// [[(DI_1-DI_0), (DI_4-DI_3), (DI_7-DI_6)], 
// [(DI_2-DI_1), (DI_5-DI_4), (DI_8-DI_7)]]

你可能感兴趣的:(C++学习记录,矩阵,线性代数)