简体   繁体   English

DenseBase,自动和二进制操作表示数组具有不同的形状

[英]DenseBase, auto, and binary operation says arrays have different shape

I write a function that takes two DenseBase as arguments. 我编写了一个将两个DenseBase作为参数的函数。

The function uses .derived().array() to convert both Array and Matrix to Array . 该函数使用.derived().array()ArrayMatrix都转换为Array

I got tired of writing derived for many times and use auto. 我厌倦了多次编写derived并使用自动。

But auto leads to strange error. 但是auto会导致奇怪的错误。 Eigen complains that x2 and y2 don't have same shape. Eigen抱怨x2y2形状不同。

If I don't want to write .derived().array() for many times, what can I use? 如果我不想.derived().array()编写.derived().array() ,该怎么用?

Eigen is from https://github.com/eigenteam/eigen-git-mirror.git 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; 
}

Run time error: 运行时错误:

CwiseBinaryOp.h:110: ...

Assertion `aLhs.rows() == aRhs.rows() 
           && aLhs.cols() == aRhs.cols()' failed.

You can fix the runtime issue with auto x2 = x.array().derived(); 您可以通过auto x2 = x.array().derived();来解决运行时问题auto x2 = x.array().derived(); , that is: reverse array and derived. ,即:反向数组并派生。 But auto is not desirable here. 但是,此处不建议使用auto Here is why. 这就是为什么。 Say you have: 说您有:

template <typename T> void foo(DenseBase<T> &x);

If T is an Array<> then x.array().derived() is an Array<> and x2 will be a deep copy of x . 如果TArray<>x.array().derived()Array<>并且x2将是x的深层副本。 In this case you would like to use auto& x2 = ... . 在这种情况下,您想使用auto& x2 = ...

If T is something else, eg, a Matrix<> , then auto x2 = x.array().derived(); 如果T是其他东西,例如Matrix<> ,则auto x2 = x.array().derived(); is perfectly fine, but not auto& x2 = ... . 非常好,但不是auto& x2 = ...

So what you really want is something as complicated as: 因此,您真正想要的是一些复杂的东西:

internal::ref_selector<std::decay<decltype(x.array().derived())>::type>::non_const_type
  x2 = x.array().derived();

Not nice :( 不是很好 :(

A simpler solution is to not bother and create an ArrayWrapper even for inputs that are already in the array world: 一个更简单的解决方案是,即使对于数组世界中已经存在的输入,也不必打扰并创建ArrayWrapper

ArrayWrapper<T> x2(x.derived());

Yet another simple solution is to enforce the caller to pass expressions in the array world: 另一个简单的解决方案是强制调用方在数组世界中传递表达式:

template <typename T> void foo(ArrayBase<T> &x) {
  T& x2(x.derived());
  ...
}

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

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