在 Eigen 中实现 Clip()
Posted
技术标签:
【中文标题】在 Eigen 中实现 Clip()【英文标题】:Implement Clip() in Eigen 【发布时间】:2019-12-22 00:39:39 【问题描述】:我有一些代码可以将一些值剪辑到以 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);
(我认为在这种情况下“自动”很好,而不是 common pitfalls 警告的那个?)
但是,代码似乎模板繁重且有点复杂。例如,谷歌风格指南here不鼓励尾随返回类型:
仅在以下情况下使用新的尾随返回类型表单 需要(例如 lambdas)或 where,通过将类型放在 函数的参数列表,它允许您将类型写在一个多 更具可读性的方式。后一种情况应该很少见;这主要是一个 在相当复杂的模板代码中出现问题,这在 大多数情况。
或者,如果我删除尾随返回类型,函数返回类型推导将开始。但谷歌风格指南似乎也不鼓励在公共标头中进行函数返回类型推导 here
此外,仅当函数或 lambda 具有非常窄的 范围,因为具有推导返回类型的函数没有定义 抽象边界:实现就是接口。在 特别是,头文件中的公共函数几乎不应该有 推导出的返回类型。
我是 Eigen 和 C++ 的新手,所以不确定我是否遗漏了什么。希望学习大家的cmets和建议。谢谢!
【问题讨论】:
【参考方案1】:我确认a = a.cwiseMin(b).cwiseMax(-b);
不会创建任何临时文件。在您的情况下,强烈建议使用 auto
返回类型,我还认为您的用例是上述规则的完全合法的例外:
在 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);
【讨论】:
以上是关于在 Eigen 中实现 Clip()的主要内容,如果未能解决你的问题,请参考以下文章
SimplicialLLT 返回错误的cholesky 因子
使用 qt creator 和 eigen 库编译程序时出现 lnk2019 错误
RNN 的 tf.clip_by_value 和 tf.clip_by_global_norm 之间的区别以及如何确定要剪辑的最大值?