简体   繁体   English

C ++特征库:转换为固定大小的矩阵

[英]C++ Eigen Library: Cast for fixed sized Matrices

following problem: 以下问题:

template<int nDim>
void foo ( ){

    Eigen::Matrix<double, nDim, nDim> bar;

    if ( nDim == 3 ){
        bar = generate_a_special_3x3_Matrix();}
    else if ( nDim == 2 ){
        bar = generate_a_special_2x2_Matrix();}


// ... further math here 
}

So, of course due to the static assertions, this code does not compile. 因此,当然由于静态断言,此代码无法编译。 However, it is guaranteed that at runtime never a problem occurs. 但是,可以保证在运行时不会发生任何问题。

Currently know solutions are assignments via .block(3,3) or via Ref<..> (cf. Cast dynamic matrix to fixed matrix in Eigen ). 目前已知的解决方案是通过.block(3,3)或通过Ref <..>进行赋值(请参见将动态矩阵转换为Eigen中的固定矩阵 )。

.block approach: .block方法:

template<int nDim>
void foo ( ){

    Eigen::Matrix<double, nDim, nDim> bar;

    if ( nDim == 3 ){
        bar.block(3,3) = generate_a_special_3x3_Matrix();}
    else if ( nDim == 2 ){
        bar.block(2,2)  = generate_a_special_2x2_Matrix();}


// ... further math here 
}

However, both approaches involve runtime checks for correct matrix sizes, which are not really necessary, and the written code is not really beautiful. 但是,这两种方法都涉及对正确的矩阵大小进行运行时检查,这并不是真正必要的,并且编写的代码也不是很漂亮。

I don't really care about the runtime overhead (although it would be nice to avoid it), but the written code is not really clean in my eyes, since the intention of .block() is not immediately clear to someone else. 我并不是很在意运行时的开销(尽管最好避免它),但是在我看来,编写的代码并不是很干净,因为.block()的意图不会立即被其他人理解。 Is there a better approach, eg something like a cast? 有没有更好的方法,例如演员表?

Edit: Two good solutions were posted (if constexpr), However, i need a C++11/14 compatible approach! 编辑:发布了两个很好的解决方案(如果constexpr),但是,我需要一种C ++ 11/14兼容的方法!

You can use constexpr if from C++17, according to the value of condition, if the value is true , then statement-false is discarded (if present), otherwise, statement-true is discarded; 如果来自C ++ 17,则可以根据条件的值使用constexpr,如果条件值为true ,则丢弃statement-false(如果存在),否则,丢弃statement-true;否则,使用false。 then the code won't cause compilation error. 那么代码不会导致编译错误。 eg 例如

template<int nDim>
void foo () {

    Eigen::Matrix<double, nDim, nDim> bar;

    if constexpr ( nDim == 3 ) {
        bar = generate_a_special_3x3_Matrix();
    } else constexpr if ( nDim == 2 ) {
        bar = generate_a_special_2x2_Matrix();
    }

    // ... further math here 
}

or make a generate_a_special_Matrix function template, eg 或制作一个generate_a_special_Matrix函数模板,例如

template <int nDim>
Eigen::Matrix<double, nDim, nDim> generate_a_special_Matrix();

template <>
Eigen::Matrix<double, 2, 2> generate_a_special_Matrix<2>() { 
    ... generating ...
    return ...; 
}

template <>
Eigen::Matrix<double, 3, 3> generate_a_special_Matrix<3>() { 
    ... generating ...
    return ...; 
}

then 然后

template<int nDim>
void foo () {

    Eigen::Matrix<double, nDim, nDim> bar;
    bar = generate_a_special_Matrix<nDim>();

    // ... further math here 
}

If you are using C++17, you can write 如果您使用的是C ++ 17,则可以编写

if constexpr ( nDim == 3 ){ bar = generate_a_special_3x3_Matrix();}

etc. But you can easily implement a C++03 compatible solution by templatizing your generate_a_special_nxn_Matrix function: 等等。但是您可以通过模板化generate_a_special_nxn_Matrix函数来轻松实现与C ++ 03兼容的解决方案:

// general declaration (without implementation):
template<int nDim>
Eigen::Matrix<double, nDim, nDim> generate_a_special_nxn_Matrix();
template<>
Eigen::Matrix<double, 2, 2> generate_a_special_nxn_Matrix(){
    return generate_a_special_2x2_Matrix();
}
template<>
Eigen::Matrix<double, 3, 3> generate_a_special_nxn_Matrix(){
    return generate_a_special_3x3_Matrix();
}

And then directly call 然后直接打电话

template<int nDim>
void foo ( ){

    Eigen::Matrix<double, nDim, nDim> bar = generate_a_special_nxn_Matrix<nDim>();

    // ... further math here 
}

To elegantly stick with c++98, you can abuse the comma initializer syntax: 要优雅地使用c ++ 98,可以使用逗号初始化程序语法:

template<int N>
void foo(){
  Eigen::Matrix<double, N, N> bar;
  if(N==3)      bar << Matrix3d();
  else if(N==2) bar << Matrix2d();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM