Re: [eigen] Array cwise multiplication

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


you do have a point about the diagonal product; but I could see this
being useful on arrays too. Then, given that there is no ambiguity
thanks to the colwise prefix, we might as well allow it on matrices,
especially as we see that people naturally expect it to work.

Benoit

2010/10/1 Gael Guennebaud <gael.guennebaud@xxxxxxxxx>:
> well, there is no operator * defined in VectorwiseOp so that clearly
> cannot compile. This as never been added because this is precisely a
> diagonal product especially if you are in the linear algebra world (in
> contrast to arrays).
>
> If we add it, I'm really not sure we should enable it for matrices.
>
> gael
>
> On Wed, Sep 29, 2010 at 9:02 PM, Benoit Jacob <jacob.benoit.1@xxxxxxxxx> wrote:
>> the asDiagonal() way is completely optimized.
>>
>> It doesn't hurt to file a bug, I agree that colwise multiplication should work.
>>
>> Benoit
>>
>> 2010/9/29 Carlos Becker <carlosbecker@xxxxxxxxx>:
>>> That's a good idea, should I report this as a bug?
>>> on the other hand, .asDiagonal() will return a diagonal object and it is
>>> evaluated as a diagonal matrix, with its respective optimization?
>>> Thanks
>>>
>>>
>>> On Wed, Sep 29, 2010 at 8:37 PM, Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
>>> wrote:
>>>>
>>>> meanwhile you can do the same with a diagonal product:
>>>>
>>>> a * b.asDiagonal()
>>>>
>>>> or
>>>>
>>>> b.asDiagonal() * a
>>>>
>>>> 2010/9/29 Carlos Becker <carlosbecker@xxxxxxxxx>:
>>>> > The strange things is that operator + and - work, but I guess that might
>>>> > come from Matrix. So there is something strange going on with array
>>>> > colwise() and rowwise() (just tested that too, very quick, and seems to
>>>> > have
>>>> > the same problems).
>>>> >
>>>> >
>>>> > On Wed, Sep 29, 2010 at 8:09 PM, Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
>>>> > wrote:
>>>> >>
>>>> >> erm, ignore me, that didn't make sense.
>>>> >>
>>>> >> 2010/9/29 Benoit Jacob <jacob.benoit.1@xxxxxxxxx>:
>>>> >> > ah, i know.
>>>> >> >
>>>> >> > b is a column-vector. you can't multiply colwise by it.
>>>> >> >
>>>> >> > Either make it a row-vector or multiply rowwise by it.
>>>> >> >
>>>> >> > 2010/9/29 Carlos Becker <carlosbecker@xxxxxxxxx>:
>>>> >> >> I already tried that, and still doesn't work. I get the following
>>>> >> >> error
>>>> >> >> (sorry for the flooding)
>>>> >> >> test.cpp:20: error: no match for ‘operator*’ in
>>>> >> >> ‘((Eigen::DenseBase<Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, -0x00000000000000001, 0, -0x00000000000000001,
>>>> >> >> -0x00000000000000001> >
>>>> >> >> >*)(&((Eigen::MatrixBase<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, -0x00000000000000001, 0, -0x00000000000000001,
>>>> >> >> -0x00000000000000001> >*)(& a))->Eigen::MatrixBase<Derived>::array
>>>> >> >> [with
>>>> >> >> Derived = Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> -0x00000000000000001,
>>>> >> >> 0, -0x00000000000000001,
>>>> >> >> -0x00000000000000001>]()))->Eigen::DenseBase<Derived>::colwise [with
>>>> >> >> Derived
>>>> >> >> = Eigen::ArrayWrapper<Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> -0x00000000000000001, 0, -0x00000000000000001, -0x00000000000000001>
>>>> >> >> >]() *
>>>> >> >> ((Eigen::MatrixBase<Eigen::Matrix<float, -0x00000000000000001, 1, 0,
>>>> >> >> -0x00000000000000001, 1> >*)(&
>>>> >> >> b))->Eigen::MatrixBase<Derived>::array
>>>> >> >> [with
>>>> >> >> Derived = Eigen::Matrix<float, -0x00000000000000001, 1, 0,
>>>> >> >> -0x00000000000000001, 1>]()’
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:95: note:
>>>> >> >> candidates
>>>> >> >> are:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple2_op<float,
>>>> >> >> std::complex<float> >, Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, 1, 0, -0x00000000000000001, 1> > >
>>>> >> >> Eigen::operator*(const std::complex<float>&, const
>>>> >> >> Eigen::ArrayBase<Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, 1, 0, -0x00000000000000001, 1> > >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:91: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple_op<float>,
>>>> >> >> Eigen::ArrayWrapper<Eigen::Matrix<float, -0x00000000000000001, 1, 0,
>>>> >> >> -0x00000000000000001, 1> > > Eigen::operator*(const float&, const
>>>> >> >> Eigen::ArrayBase<Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, 1, 0, -0x00000000000000001, 1> > >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:95: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple2_op<float,
>>>> >> >> std::complex<float> >, Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, -0x00000000000000001, 0, -0x00000000000000001,
>>>> >> >> -0x00000000000000001> > > Eigen::operator*(const
>>>> >> >> std::complex<float>&,
>>>> >> >> const
>>>> >> >> Eigen::ArrayBase<Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, -0x00000000000000001, 0, -0x00000000000000001,
>>>> >> >> -0x00000000000000001> > >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:91: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple_op<float>,
>>>> >> >> Eigen::ArrayWrapper<Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> -0x00000000000000001, 0, -0x00000000000000001, -0x00000000000000001>
>>>> >> >> >
>>>> >> >> >
>>>> >> >> Eigen::operator*(const float&, const
>>>> >> >> Eigen::ArrayBase<Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, -0x00000000000000001, 0, -0x00000000000000001,
>>>> >> >> -0x00000000000000001> > >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:95: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple2_op<float,
>>>> >> >> std::complex<float> >, Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> -0x00000000000000001, 0, -0x00000000000000001, -0x00000000000000001>
>>>> >> >> >
>>>> >> >> Eigen::operator*(const std::complex<float>&, const
>>>> >> >> Eigen::MatrixBase<Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> -0x00000000000000001, 0, -0x00000000000000001, -0x00000000000000001>
>>>> >> >> >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:91: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple_op<float>,
>>>> >> >> Eigen::Matrix<float, -0x00000000000000001, -0x00000000000000001, 0,
>>>> >> >> -0x00000000000000001, -0x00000000000000001> > Eigen::operator*(const
>>>> >> >> float&,
>>>> >> >> const Eigen::MatrixBase<Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> -0x00000000000000001, 0, -0x00000000000000001, -0x00000000000000001>
>>>> >> >> >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:95: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple2_op<float,
>>>> >> >> std::complex<float> >, Eigen::Matrix<float, -0x00000000000000001, 1,
>>>> >> >> 0,
>>>> >> >> -0x00000000000000001, 1> > Eigen::operator*(const
>>>> >> >> std::complex<float>&,
>>>> >> >> const Eigen::MatrixBase<Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> 1,
>>>> >> >> 0,
>>>> >> >> -0x00000000000000001, 1> >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:91: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple_op<float>,
>>>> >> >> Eigen::Matrix<float, -0x00000000000000001, 1, 0,
>>>> >> >> -0x00000000000000001,
>>>> >> >> 1> >
>>>> >> >> Eigen::operator*(const float&, const
>>>> >> >> Eigen::MatrixBase<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, 1, 0, -0x00000000000000001, 1> >&)
>>>> >> >> [2]+  Done                    gedit test.cpp
>>>> >> >> cjb@cjb-laptop:/tmp/eigen$ g++ test.cpp -I.
>>>> >> >> test.cpp: In function ‘int main()’:
>>>> >> >> test.cpp:20: error: no match for ‘operator*’ in
>>>> >> >> ‘((Eigen::DenseBase<Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, -0x00000000000000001, 0, -0x00000000000000001,
>>>> >> >> -0x00000000000000001> >
>>>> >> >> >*)(&((Eigen::MatrixBase<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, -0x00000000000000001, 0, -0x00000000000000001,
>>>> >> >> -0x00000000000000001> >*)(& a))->Eigen::MatrixBase<Derived>::array
>>>> >> >> [with
>>>> >> >> Derived = Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> -0x00000000000000001,
>>>> >> >> 0, -0x00000000000000001,
>>>> >> >> -0x00000000000000001>]()))->Eigen::DenseBase<Derived>::colwise [with
>>>> >> >> Derived
>>>> >> >> = Eigen::ArrayWrapper<Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> -0x00000000000000001, 0, -0x00000000000000001, -0x00000000000000001>
>>>> >> >> >]() *
>>>> >> >> ((Eigen::MatrixBase<Eigen::Matrix<float, -0x00000000000000001, 1, 0,
>>>> >> >> -0x00000000000000001, 1> >*)(&
>>>> >> >> b))->Eigen::MatrixBase<Derived>::array
>>>> >> >> [with
>>>> >> >> Derived = Eigen::Matrix<float, -0x00000000000000001, 1, 0,
>>>> >> >> -0x00000000000000001, 1>]()’
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:95: note:
>>>> >> >> candidates
>>>> >> >> are:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple2_op<float,
>>>> >> >> std::complex<float> >, Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, 1, 0, -0x00000000000000001, 1> > >
>>>> >> >> Eigen::operator*(const std::complex<float>&, const
>>>> >> >> Eigen::ArrayBase<Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, 1, 0, -0x00000000000000001, 1> > >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:91: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple_op<float>,
>>>> >> >> Eigen::ArrayWrapper<Eigen::Matrix<float, -0x00000000000000001, 1, 0,
>>>> >> >> -0x00000000000000001, 1> > > Eigen::operator*(const float&, const
>>>> >> >> Eigen::ArrayBase<Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, 1, 0, -0x00000000000000001, 1> > >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:95: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple2_op<float,
>>>> >> >> std::complex<float> >, Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, -0x00000000000000001, 0, -0x00000000000000001,
>>>> >> >> -0x00000000000000001> > > Eigen::operator*(const
>>>> >> >> std::complex<float>&,
>>>> >> >> const
>>>> >> >> Eigen::ArrayBase<Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, -0x00000000000000001, 0, -0x00000000000000001,
>>>> >> >> -0x00000000000000001> > >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:91: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple_op<float>,
>>>> >> >> Eigen::ArrayWrapper<Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> -0x00000000000000001, 0, -0x00000000000000001, -0x00000000000000001>
>>>> >> >> >
>>>> >> >> >
>>>> >> >> Eigen::operator*(const float&, const
>>>> >> >> Eigen::ArrayBase<Eigen::ArrayWrapper<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, -0x00000000000000001, 0, -0x00000000000000001,
>>>> >> >> -0x00000000000000001> > >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:95: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple2_op<float,
>>>> >> >> std::complex<float> >, Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> -0x00000000000000001, 0, -0x00000000000000001, -0x00000000000000001>
>>>> >> >> >
>>>> >> >> Eigen::operator*(const std::complex<float>&, const
>>>> >> >> Eigen::MatrixBase<Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> -0x00000000000000001, 0, -0x00000000000000001, -0x00000000000000001>
>>>> >> >> >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:91: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple_op<float>,
>>>> >> >> Eigen::Matrix<float, -0x00000000000000001, -0x00000000000000001, 0,
>>>> >> >> -0x00000000000000001, -0x00000000000000001> > Eigen::operator*(const
>>>> >> >> float&,
>>>> >> >> const Eigen::MatrixBase<Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> -0x00000000000000001, 0, -0x00000000000000001, -0x00000000000000001>
>>>> >> >> >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:95: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple2_op<float,
>>>> >> >> std::complex<float> >, Eigen::Matrix<float, -0x00000000000000001, 1,
>>>> >> >> 0,
>>>> >> >> -0x00000000000000001, 1> > Eigen::operator*(const
>>>> >> >> std::complex<float>&,
>>>> >> >> const Eigen::MatrixBase<Eigen::Matrix<float, -0x00000000000000001,
>>>> >> >> 1,
>>>> >> >> 0,
>>>> >> >> -0x00000000000000001, 1> >&)
>>>> >> >> ./Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:91: note:
>>>> >> >> const Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple_op<float>,
>>>> >> >> Eigen::Matrix<float, -0x00000000000000001, 1, 0,
>>>> >> >> -0x00000000000000001,
>>>> >> >> 1> >
>>>> >> >> Eigen::operator*(const float&, const
>>>> >> >> Eigen::MatrixBase<Eigen::Matrix<float,
>>>> >> >> -0x00000000000000001, 1, 0, -0x00000000000000001, 1> >&)
>>>> >> >>
>>>> >> >>
>>>> >> >> On Wed, Sep 29, 2010 at 7:49 PM, Benoit Jacob
>>>> >> >> <jacob.benoit.1@xxxxxxxxx>
>>>> >> >> wrote:
>>>> >> >>>
>>>> >> >>> Does a.array().colwise() * b.array() work ?
>>>> >> >>>
>>>> >> >>> We're a bit pedantic if we require putting array() here since the
>>>> >> >>> colwise() makes it clear what you want to do...
>>>> >> >>>
>>>> >> >>> Benoit
>>>> >> >>>
>>>> >> >>> 2010/9/29 Carlos Becker <carlosbecker@xxxxxxxxx>:
>>>> >> >>> > Hi Benoit. No, it doesn't work and it makes sense, since it would
>>>> >> >>> > be
>>>> >> >>> > like
>>>> >> >>> > multiplying a vector by a vector algebraically, which has no
>>>> >> >>> > sense
>>>> >> >>> > for a
>>>> >> >>> > Matrix type (has it?)
>>>> >> >>> > I wanted to do element-wise multiplication, and I thought that
>>>> >> >>> > .array().colwise() would cope with that. Just to clarify, I want
>>>> >> >>> > to
>>>> >> >>> > do:
>>>> >> >>> > if A = [1 2;
>>>> >> >>> >           3 4]
>>>> >> >>> > and B = [a;b] (matlab notation)
>>>> >> >>> > then I want to get something like:
>>>> >> >>> > result = [ 1*a, 2*a;
>>>> >> >>> >              3*b 4*b ]
>>>> >> >>> > Should I do this another way? I thought that .array().colwise()
>>>> >> >>> > was
>>>> >> >>> > defined
>>>> >> >>> > to apply the element-wise operation for every column vector in A.
>>>> >> >>> > Thanks
>>>> >> >>> >
>>>> >> >>> > On Wed, Sep 29, 2010 at 7:41 PM, Benoit Jacob
>>>> >> >>> > <jacob.benoit.1@xxxxxxxxx>
>>>> >> >>> > wrote:
>>>> >> >>> >>
>>>> >> >>> >> 2010/9/29 Carlos Becker <carlosbecker@xxxxxxxxx>:
>>>> >> >>> >> > Hi all, I was trying to code something like this:
>>>> >> >>> >> > #include <Eigen/Dense>
>>>> >> >>> >> > using namespace Eigen;
>>>> >> >>> >> > using namespace std;
>>>> >> >>> >> > int main()
>>>> >> >>> >> > {
>>>> >> >>> >> > MatrixXf a;
>>>> >> >>> >> > VectorXf b;
>>>> >> >>> >> > a.resize(2,4);
>>>> >> >>> >> > b.resize(2);
>>>> >> >>> >> > a << 1,2,
>>>> >> >>> >> > 3,4,
>>>> >> >>> >> > 5,6,
>>>> >> >>> >> > 7,8;
>>>> >> >>> >> > b << 1,2;
>>>> >> >>> >> > a = a.array().colwise() * b;
>>>> >> >>> >>
>>>> >> >>> >> Here you're multiplying an array by a matrix.
>>>> >> >>> >>
>>>> >> >>> >> Doesn't a.colwise() * b work?
>>>> >> >>> >>
>>>> >> >>> >> Benoit
>>>> >> >>> >>
>>>> >> >>> >> > return 0;
>>>> >> >>> >> > }
>>>> >> >>> >> > Should this compile correctly? I want to multiply every column
>>>> >> >>> >> > in
>>>> >> >>> >> > matrix
>>>> >> >>> >> > a,
>>>> >> >>> >> > element-wise, with vector b, but I cannot make it work
>>>> >> >>> >> > I hope I am not forgetting about something important here.
>>>> >> >>> >> > Cheers,
>>>> >> >>> >> > Carlos
>>>> >> >>> >>
>>>> >> >>> >>
>>>> >> >>> >
>>>> >> >>> >
>>>> >> >>>
>>>> >> >>>
>>>> >> >>
>>>> >> >>
>>>> >> >
>>>> >>
>>>> >>
>>>> >
>>>> >
>>>>
>>>>
>>>
>>>
>>
>>
>>
>
>
>



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/