DenseBase, auto, and binary operation says arrays have different shape










1















I write a function that takes two DenseBase as arguments.



The function uses .derived().array() to convert both Array and Matrix to Array.



I got tired of writing derived for many times and use auto.



But auto leads to strange error. Eigen complains that x2 and y2 don't have same shape.



If I don't want to write .derived().array() for many times, what can I use?



Eigen is from 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.









share|improve this question



















  • 1





    Generally, avoid auto with Eigen expressions, unless you know what you are doing.

    – chtz
    Nov 15 '18 at 20:06











  • I see two options. 1. use lots of .derived().array() within the function. 2. Use ArrayBase instead of DenseBase. Make a function void f(ArrayBase<D>& x) . To call the function, use auto s = big_mat.array(); f(s); where big_mat is a matrix instead of an array. Would option 2 avoid copying the big matrix?

    – R zu
    Nov 15 '18 at 20:36
















1















I write a function that takes two DenseBase as arguments.



The function uses .derived().array() to convert both Array and Matrix to Array.



I got tired of writing derived for many times and use auto.



But auto leads to strange error. Eigen complains that x2 and y2 don't have same shape.



If I don't want to write .derived().array() for many times, what can I use?



Eigen is from 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.









share|improve this question



















  • 1





    Generally, avoid auto with Eigen expressions, unless you know what you are doing.

    – chtz
    Nov 15 '18 at 20:06











  • I see two options. 1. use lots of .derived().array() within the function. 2. Use ArrayBase instead of DenseBase. Make a function void f(ArrayBase<D>& x) . To call the function, use auto s = big_mat.array(); f(s); where big_mat is a matrix instead of an array. Would option 2 avoid copying the big matrix?

    – R zu
    Nov 15 '18 at 20:36














1












1








1








I write a function that takes two DenseBase as arguments.



The function uses .derived().array() to convert both Array and Matrix to Array.



I got tired of writing derived for many times and use auto.



But auto leads to strange error. Eigen complains that x2 and y2 don't have same shape.



If I don't want to write .derived().array() for many times, what can I use?



Eigen is from 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.









share|improve this question
















I write a function that takes two DenseBase as arguments.



The function uses .derived().array() to convert both Array and Matrix to Array.



I got tired of writing derived for many times and use auto.



But auto leads to strange error. Eigen complains that x2 and y2 don't have same shape.



If I don't want to write .derived().array() for many times, what can I use?



Eigen is from 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.






c++ eigen eigen3






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 15 '18 at 18:04







R zu

















asked Nov 15 '18 at 16:43









R zuR zu

759114




759114







  • 1





    Generally, avoid auto with Eigen expressions, unless you know what you are doing.

    – chtz
    Nov 15 '18 at 20:06











  • I see two options. 1. use lots of .derived().array() within the function. 2. Use ArrayBase instead of DenseBase. Make a function void f(ArrayBase<D>& x) . To call the function, use auto s = big_mat.array(); f(s); where big_mat is a matrix instead of an array. Would option 2 avoid copying the big matrix?

    – R zu
    Nov 15 '18 at 20:36













  • 1





    Generally, avoid auto with Eigen expressions, unless you know what you are doing.

    – chtz
    Nov 15 '18 at 20:06











  • I see two options. 1. use lots of .derived().array() within the function. 2. Use ArrayBase instead of DenseBase. Make a function void f(ArrayBase<D>& x) . To call the function, use auto s = big_mat.array(); f(s); where big_mat is a matrix instead of an array. Would option 2 avoid copying the big matrix?

    – R zu
    Nov 15 '18 at 20:36








1




1





Generally, avoid auto with Eigen expressions, unless you know what you are doing.

– chtz
Nov 15 '18 at 20:06





Generally, avoid auto with Eigen expressions, unless you know what you are doing.

– chtz
Nov 15 '18 at 20:06













I see two options. 1. use lots of .derived().array() within the function. 2. Use ArrayBase instead of DenseBase. Make a function void f(ArrayBase<D>& x) . To call the function, use auto s = big_mat.array(); f(s); where big_mat is a matrix instead of an array. Would option 2 avoid copying the big matrix?

– R zu
Nov 15 '18 at 20:36






I see two options. 1. use lots of .derived().array() within the function. 2. Use ArrayBase instead of DenseBase. Make a function void f(ArrayBase<D>& x) . To call the function, use auto s = big_mat.array(); f(s); where big_mat is a matrix instead of an array. Would option 2 avoid copying the big matrix?

– R zu
Nov 15 '18 at 20:36













1 Answer
1






active

oldest

votes


















2














You can fix the runtime issue with auto x2 = x.array().derived();, that is: reverse array and derived. But auto is not desirable here. 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. In this case you would like to use auto& x2 = ....



If T is something else, e.g., a Matrix<>, then auto x2 = x.array().derived(); is perfectly fine, but not 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<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());
...






share|improve this answer























  • Thanks for the answer. Would the ArrayWrapper hurt performance in any possible way?

    – R zu
    Nov 15 '18 at 22:17












  • No impact on runtime, only slightly on compilation time because you create new types, but that's marginal.

    – ggael
    Nov 15 '18 at 22:27










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53324127%2fdensebase-auto-and-binary-operation-says-arrays-have-different-shape%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














You can fix the runtime issue with auto x2 = x.array().derived();, that is: reverse array and derived. But auto is not desirable here. 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. In this case you would like to use auto& x2 = ....



If T is something else, e.g., a Matrix<>, then auto x2 = x.array().derived(); is perfectly fine, but not 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<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());
...






share|improve this answer























  • Thanks for the answer. Would the ArrayWrapper hurt performance in any possible way?

    – R zu
    Nov 15 '18 at 22:17












  • No impact on runtime, only slightly on compilation time because you create new types, but that's marginal.

    – ggael
    Nov 15 '18 at 22:27















2














You can fix the runtime issue with auto x2 = x.array().derived();, that is: reverse array and derived. But auto is not desirable here. 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. In this case you would like to use auto& x2 = ....



If T is something else, e.g., a Matrix<>, then auto x2 = x.array().derived(); is perfectly fine, but not 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<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());
...






share|improve this answer























  • Thanks for the answer. Would the ArrayWrapper hurt performance in any possible way?

    – R zu
    Nov 15 '18 at 22:17












  • No impact on runtime, only slightly on compilation time because you create new types, but that's marginal.

    – ggael
    Nov 15 '18 at 22:27













2












2








2







You can fix the runtime issue with auto x2 = x.array().derived();, that is: reverse array and derived. But auto is not desirable here. 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. In this case you would like to use auto& x2 = ....



If T is something else, e.g., a Matrix<>, then auto x2 = x.array().derived(); is perfectly fine, but not 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<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());
...






share|improve this answer













You can fix the runtime issue with auto x2 = x.array().derived();, that is: reverse array and derived. But auto is not desirable here. 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. In this case you would like to use auto& x2 = ....



If T is something else, e.g., a Matrix<>, then auto x2 = x.array().derived(); is perfectly fine, but not 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<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());
...







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 15 '18 at 22:14









ggaelggael

20.7k23145




20.7k23145












  • Thanks for the answer. Would the ArrayWrapper hurt performance in any possible way?

    – R zu
    Nov 15 '18 at 22:17












  • No impact on runtime, only slightly on compilation time because you create new types, but that's marginal.

    – ggael
    Nov 15 '18 at 22:27

















  • Thanks for the answer. Would the ArrayWrapper hurt performance in any possible way?

    – R zu
    Nov 15 '18 at 22:17












  • No impact on runtime, only slightly on compilation time because you create new types, but that's marginal.

    – ggael
    Nov 15 '18 at 22:27
















Thanks for the answer. Would the ArrayWrapper hurt performance in any possible way?

– R zu
Nov 15 '18 at 22:17






Thanks for the answer. Would the ArrayWrapper hurt performance in any possible way?

– R zu
Nov 15 '18 at 22:17














No impact on runtime, only slightly on compilation time because you create new types, but that's marginal.

– ggael
Nov 15 '18 at 22:27





No impact on runtime, only slightly on compilation time because you create new types, but that's marginal.

– ggael
Nov 15 '18 at 22:27



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53324127%2fdensebase-auto-and-binary-operation-says-arrays-have-different-shape%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Top Tejano songwriter Luis Silva dead of heart attack at 64

政党

天津地下鉄3号線