c++ - 在 Eigen 中实现 Clip()

标签 c++ eigen eigen3

我有一些代码可以将一些值剪切到以 0 为中心的范围之间,如下所示。

Eigen::VectorXd a;
Eigen::VecotrXd b;
a = a.cwiseMin(b).cwiseMax(-b);  // no temporary created here?

我想将逻辑分解成一个函数。 一种解决方案:

Eigen::VectorXd Clip(const Eigen::VectorXd& a, const Eigen::VectorXd& b);

a = Clip(a, b);

但我认为这是低效的,因为它会创建一个额外的临时文件?

另一种解决方案:

void Clip(Eigen::Ref<Eigen::VectorXd> a, const Eigen::VectorXd& b) {
  a = a.cwiseMin(b).cwiseMax(-b);
}

但这有时使用起来似乎不方便:

void SomeFunctionSignatureICannotChange(const Eigen::VectorXd& a, const Eigen::VectorXd& b) {
  // Eigen::VectorXd a_clipped = Clip(a, b); would be cleaner.
  Eigen::VectorXd a_clipped;
  Clip(a_clipped, b);
}

我能想到的最佳解决方案:

template <typename DerivedV, typename DerivedB>
auto Clip(const Eigen::ArrayBase<DerivedV>& v,
          const Eigen::ArrayBase<DerivedB>& bound)
          -> decltype(v.min(bound).max(-bound)) {
  return v.min(bound).max(-bound);
}

(我假设“auto”在这种情况下没问题,而不是 common pitfalls 警告过的那个?)

但是,代码看起来模板繁多且有点复杂。例如,谷歌风格指南不鼓励尾随返回类型 here :

Use the new trailing-return-type form only in cases where it's required (such as lambdas) or where, by putting the type after the function's parameter list, it allows you to write the type in a much more readable way. The latter case should be rare; it's mostly an issue in fairly complicated template code, which is discouraged in most cases.

或者,如果我删除尾随的返回类型,函数返回类型推导将开始。但谷歌风格指南似乎也不鼓励公共(public) header 中的函数返回类型推导here

Furthermore, use it only if the function or lambda has a very narrow scope, because functions with deduced return types don't define abstraction boundaries: the implementation is the interface. In particular, public functions in header files should almost never have deduced return types.

我是 Eigen 和 C++ 的新手,所以不确定我是否遗漏了什么。希望吸取大家的意见和建议。谢谢!

最佳答案

我确认 a = a.cwiseMin(b).cwiseMax(-b); 不会创建任何临时文件。在您的情况下,强烈建议使用 auto 返回类型,我还认为您的用例是上述规则的完全合法异常(exception):

  • 显式编写返回类型将是一场噩梦,而且容易出错。
  • 这是一个非常短的函数,预计会被内联。因此,它应该同时被声明和定义。因此,第二条规则并不适用。

在 c++14 中你甚至可以省略冗余:

template <typename DerivedV, typename DerivedB>
auto Clip(const Eigen::ArrayBase<DerivedV>& v,
          const Eigen::ArrayBase<DerivedB>& bound)
{
  return v.min(bound).max(-bound);
}

关于c++ - 在 Eigen 中实现 Clip(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59440878/

相关文章:

c++11 - 因式分解 Eigen3 临时值以提高计算速度

c++ - 如何在 Eigen 中近似比较 vector ?

Eigen 动态大小矩阵的 C++ 数组

c++ - Eigen 二维叉积

c++ - QT QGraphicsView 旋转

c++ - 带有模板类模板参数的模板类的变量设置为带有变量的派生模板的基本模板

c++ - 从基类方法调用虚方法

c++ - Boost 以自定义方式序列化数据

c++ - 在 Eigen 中复制模板化函数参数

c++ - 在 odeint 中使用 std::vector<Eigen::Vector3d> 作为状态类型