Re: [eigen] why does the result of the col member function behave so different?

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


On Sat, May 7, 2011 at 10:22 AM, Helmut Jarausch
<jarausch@xxxxxxxxxxxxxxxxxxx> wrote:
> On 05/06/2011 10:14:38 PM, Gael Guennebaud wrote:
>> Hi,
>>
>> regarding: A.col(1)= A.col(0).square(); this is because there is no
>> square() method in the matrix world, otherwise it would mean A.col(0)
>> * A.col(0) with "*" the matrix product operator...
>>
>> So you have to write:
>>
>> A.col(1)= A.col(0).array().square();
>
> Yes, thanks. But wouldn't there be any ambiguity offering methods like
> square, cube, ... for a (single) column vector, as well.

not sure, because on paper we often simply write v^2 to mean v^Tv or
|v[^2. So one could expect that v.square() be equivalent to
v.squaredNorm()...

>>
>> The other issue,  Inp >> A.col(0);, is a C++ limitation. The problem
>> is that A.col(0) is a temporary object and it cannot be passed as a
>> non const reference to a function (or operator). So you have to name
>> it:
>>
>> MatrixXd::ColXpr A0(A.col(0));
>> Inp >> A0;
>>
>> Another ugly solution is to declare your operator >> with a const
>> ref:
>>
>> std::istream & operator >>(std::istream & s, const
>> Eigen::MatrixBase<Derived> & m)
>>
>> and const_cast m... yes very ugly and not safe.
>>
>
> Yes, but how did you write operator= then? (It works for a column
> temporary!)

the difference here is that operator= is a member of MatrixBase, and
this is where this C++ rule is really stupid because it allows you
pass a non const temporary reference to a method as "this" but not as
a standard argument... In your case you cannot write your operator >>
as a member function of MatrixBase, whence the problem...

> By the way, I did "solve" this problem in my own matrix class by having
> a special L_Vector class which is returned by slicing functions/
> operators. This L_Vector class represents a temporary Lvalue, it has no
> own storage but refers to storage elsewhere (like a column of a matrix)
> Now, I do have
> istream& operator>>(istream&, const L_Vector&)
> but that's no problem, since it matches such Lvalue vectors (or
> L_Matrix, rsp) only. I have used the same with my operator= .

Yes our .col(i) method also returns a proxy object, and as I said you
could also declare your operator >> with a const ref as you did for
your own matrix class.

However this is not safe regarding constness, e.g.:

void foo(const Matrix& mat) {
  data >> mat.col(i);
}

will work while it should not!

gael
> Regards,
> Helmut.
>
>
>



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