c++ - 使用 Eigen 3 库编写一个以转置作为参数的函数

标签 c++ eigen eigen3

我想写一个可以接受的函数:

  1. 一个密集的数组/矩阵,或者
  2. 密集数组/矩阵的转置。

是否可以避免使用完美转发?

我尝试使用 DenseBase 类型参数。但这不能接受矩阵的转置。

我不喜欢使用完美转发,因为用 sfinae 实现类型检查会很乏味。

当前解决方案:

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

using namespace Eigen;

template <typename U>
auto f(U&& x) {
    auto x2 = std::forward<U>(x);
    auto max_x = x2.colwise().maxCoeff().eval();
    x2 = x2.rowwise() + max_x;
    return max_x;
}

int main() {
    Array<float, 3, 3> M1;
    M1 << 1, 2, 3, 
          4, 5, 6, 
          7, 8, 9;
    std::cout << M1 << "\n";
    // auto here might cause problem later ...
    // see eigen.tuxfamily.org/dox/TopicPitfalls.html
    auto max_x = f(M1.transpose());
    std::cout << M1 << "\n";
    std::cout << max_x << "\n";
}

结果:

// original
1 2 3
4 5 6
7 8 9
// Increase each row by max of the row.
 4  5  6
10 11 12
16 17 18
// Max of each row (not a column vector).
3 6 9

我尝试使用以下几行 EigenBase:

template <typename U>
auto f(EigenBase<U>& x) {
...

编译器错误:

test4.cpp:20:32: error: cannot bind non-const lvalue reference of type ‘Eigen::EigenBase<Eigen::Transpose<Eigen::Array<float, 3, 3> > >&’ to an rvalue of type ‘Eigen::EigenBase<Eigen::Transpose<Eigen::Array<float, 3, 3> > >’
     auto max_x = f(M1.transpose());
                    ~~~~~~~~~~~~^~

最佳答案

用左值引用和右值引用参数重载函数似乎可以解决问题。

我怀疑转置是唯一生成临时 C++ 表达式的东西。如果我希望转置版本返回转置结果(列而不是行 vector )并且非转置版本返回非转置结果,这不会解决这个问题。

谢谢 kmdreko的指针。

测试:

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

using namespace Eigen;

template <typename Derived>
auto f(DenseBase<Derived>& x) {
    auto max_x = x.colwise().maxCoeff().eval();
    x = x.rowwise() + max_x;
    return max_x;
}

template <typename Derived>
auto f(DenseBase<Derived>&& x) {
    return f(x).transpose().eval();
}

int main() {
    Array<float, 3, 3> M1, M2;
    M1 << 1, 2, 3, 
          4, 5, 6, 
          7, 8, 9;
    M2 = M1;
    std::cout << M1 << "\n";

    std::cout << "no transpose\n";
    Array<float, 3, 1> max_x = f(M1);
    std::cout << M1 << "\n";
    std::cout << max_x << "\n";

    std::cout << "transpose\n";
    Array<float, 1, 3> max_x2 = f(M2.transpose());
    std::cout << M2 << "\n";
    std::cout << max_x2 << "\n";
}

结果:

1 2 3
4 5 6
7 8 9
no transpose
 8 10 12
11 13 15
14 16 18
// returns column vector
7
8
9
transpose
 4  5  6
10 11 12
16 17 18
// returns row vector
3 6 9

关于c++ - 使用 Eigen 3 库编写一个以转置作为参数的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52141496/

相关文章:

c++ - 在 C++ 中解决稀疏线性系统的最佳方法 - GPU 可能吗?

c++ - 由于固定大小的成员而导致的 Eigen 运行时断言

c++ - 如何在 Eigen 库中获取矩阵的秩?

c++ - Eigen Tensor 示例的编译器警告

c++ - Open GL 在 Codelite Windows 7 上编译,但没有显示输出

C++:将 LPTSTR 转换为字符数组

c++ - 组合函数参数包和默认参数

eigen - 如何切片 TensorMap?

c++ - vector 的 vector 未正确复制 (C++)

c++ - A^T*A稀疏积,结果存储在Dense Matrix/Eigen Lib中