DenseBase、auto 和二进制操作表示数组具有不同的形状
DenseBase, auto, and binary operation says arrays have different shape
我写了一个函数,它接受两个 DenseBase
作为参数。
该函数使用 .derived().array()
将 Array
和 Matrix
都转换为 Array
。
写了很多次derived
写腻了,用auto.
但是auto
会导致奇怪的错误。 Eigen 抱怨 x2
和 y2
没有相同的形状。
如果我不想多次写.derived().array()
,我可以用什么?
Eigen 来自 https://github.com/eigenteam/eigen-git-mirror.git
#include <Eigen/Eigen>
int main() {
Eigen::ArrayXf x(3);
Eigen::ArrayXf y(3);
x << 1, 2, 3;
y << 4, 5, 6;
// x.derived().array() * y.derived().array();
auto x2 = x.derived().array();
auto y2 = y.derived().array();
y2 = x2 * y2;
}
运行时间错误:
CwiseBinaryOp.h:110: ...
Assertion `aLhs.rows() == aRhs.rows()
&& aLhs.cols() == aRhs.cols()' failed.
您可以使用 auto x2 = x.array().derived();
修复运行时问题,即:反向数组和派生。但是 auto
在这里是不可取的。这就是为什么。假设您有:
template <typename T> void foo(DenseBase<T> &x);
如果 T
是 Array<>
,则 x.array().derived()
是 Array<>
,而 x2
将是 x
的深层副本。在这种情况下,您想使用 auto& x2 = ...
.
如果 T
是其他东西,例如 Matrix<>
,那么 auto x2 = x.array().derived();
完全没问题,但 auto& x2 = ...
不是。
所以你真正想要的是像这样复杂的东西:
internal::ref_selector<std::decay<decltype(x.array().derived())>::type>::non_const_type
x2 = x.array().derived();
不好看:(
一个更简单的解决方案是不打扰并创建一个 ArrayWrapper
,即使对于已经在数组世界中的输入也是如此:
ArrayWrapper<T> x2(x.derived());
另一个简单的解决方案是强制调用者在数组世界中传递表达式:
template <typename T> void foo(ArrayBase<T> &x) {
T& x2(x.derived());
...
}
我写了一个函数,它接受两个 DenseBase
作为参数。
该函数使用 .derived().array()
将 Array
和 Matrix
都转换为 Array
。
写了很多次derived
写腻了,用auto.
但是auto
会导致奇怪的错误。 Eigen 抱怨 x2
和 y2
没有相同的形状。
如果我不想多次写.derived().array()
,我可以用什么?
Eigen 来自 https://github.com/eigenteam/eigen-git-mirror.git
#include <Eigen/Eigen>
int main() {
Eigen::ArrayXf x(3);
Eigen::ArrayXf y(3);
x << 1, 2, 3;
y << 4, 5, 6;
// x.derived().array() * y.derived().array();
auto x2 = x.derived().array();
auto y2 = y.derived().array();
y2 = x2 * y2;
}
运行时间错误:
CwiseBinaryOp.h:110: ...
Assertion `aLhs.rows() == aRhs.rows()
&& aLhs.cols() == aRhs.cols()' failed.
您可以使用 auto x2 = x.array().derived();
修复运行时问题,即:反向数组和派生。但是 auto
在这里是不可取的。这就是为什么。假设您有:
template <typename T> void foo(DenseBase<T> &x);
如果 T
是 Array<>
,则 x.array().derived()
是 Array<>
,而 x2
将是 x
的深层副本。在这种情况下,您想使用 auto& x2 = ...
.
如果 T
是其他东西,例如 Matrix<>
,那么 auto x2 = x.array().derived();
完全没问题,但 auto& x2 = ...
不是。
所以你真正想要的是像这样复杂的东西:
internal::ref_selector<std::decay<decltype(x.array().derived())>::type>::non_const_type
x2 = x.array().derived();
不好看:(
一个更简单的解决方案是不打扰并创建一个 ArrayWrapper
,即使对于已经在数组世界中的输入也是如此:
ArrayWrapper<T> x2(x.derived());
另一个简单的解决方案是强制调用者在数组世界中传递表达式:
template <typename T> void foo(ArrayBase<T> &x) {
T& x2(x.derived());
...
}