[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Bug in Vector class?

Dave Baldwin

10/9/2008 9:51:00 AM

[Note: parts of this message were removed to make it a legal post.]

require 'matrix'
m = Matrix.identity(4)
v = Vector[5, 6, 7, 1]
puts m * v

gives the expected answer of [5, 6, 7, 1]

but
puts v * m

gives
ExceptionForMatrix::ErrDimensionMismatch: Matrix dimension mismatch

because the Vector#* method promotes self to a column vector when the
argument is found to be a Matrix. I think it should be promoting self
to a row vector and making this change removes the exception and gives
the correct result. The updated method is:

def *(x)
case x
when Numeric
els = @elements.collect{|e| e * x}
Vector.elements(els, false)
when Matrix
Matrix.row_vector(self) * x
else
s, x = x.coerce(self)
s * x
end
end


Dave.

5 Answers

TPReal

10/9/2008 3:13:00 PM

0

Dave Baldwin wrote:
> because the Vector#* method promotes self to a column vector when the
> argument is found to be a Matrix. I think it should be promoting self
> to a row vector and making this change removes the exception and gives
> the correct result.

I think it should not. Either the programmer knows what he or she is
doing and is able to take care of the matrices dimensions, or no magic
auto-transpositions or other tricks are going to save their project from
falling apart sooner or later. Vector is a column vector, and let it be
this way.

TPR.
--
Posted via http://www.ruby-....

Dave Baldwin

10/9/2008 3:48:00 PM

0

[Note: parts of this message were removed to make it a legal post.]


On 9 Oct 2008, at 10:40, Dave Baldwin wrote:

> require 'matrix'
> m = Matrix.identity(4)
> v = Vector[5, 6, 7, 1]
> puts m * v
>
> gives the expected answer of [5, 6, 7, 1]
>
> but
> puts v * m
>
> gives
> ExceptionForMatrix::ErrDimensionMismatch: Matrix dimension mismatch
>
> because the Vector#* method promotes self to a column vector when
> the argument is found to be a Matrix. I think it should be
> promoting self to a row vector and making this change removes the
> exception and gives the correct result. The updated method is:
>
> def *(x)
> case x
> when Numeric
> els = @elements.collect{|e| e * x}
> Vector.elements(els, false)
> when Matrix
> Matrix.row_vector(self) * x
> else
> s, x = x.coerce(self)
> s * x
> end
> end
>
>
> Dave.
>

Further modification so it returns a Vector instead of a matrix
(Matrix.row_vector(self) * x).row(0)

Dave.




Dave Baldwin

10/9/2008 5:00:00 PM

0


On 9 Oct 2008, at 16:13, Thomas B. wrote:

> Dave Baldwin wrote:
>> because the Vector#* method promotes self to a column vector when the
>> argument is found to be a Matrix. I think it should be promoting
>> self
>> to a row vector and making this change removes the exception and
>> gives
>> the correct result.
>
> I think it should not. Either the programmer knows what he or she is
> doing and is able to take care of the matrices dimensions, or no magic
> auto-transpositions or other tricks are going to save their project
> from
> falling apart sooner or later. Vector is a column vector, and let it
> be
> this way.


The Vector class doesn't seem to have any idea that it is representing
a row or column vector and as the class stands now a vector * matrix
will always fail.

The only way to achieve this operation is to manually convert the
vector into a Matrix with one row but now you are really doing a
matrix * matrix operation and not using the failing path in Vector.

If the intent was for vector * matrix to fail then it would be better
to raise an exception directly rather than rely on the Matrix class to
catch a dimensional error.

I still think it is better to treat it as a row vector in this case.

Dave.

>
>
> TPR.
> --
> Posted via http://www.ruby-....
>


TPReal

10/9/2008 5:12:00 PM

0

Dave Baldwin wrote:
> The Vector class doesn't seem to have any idea that it is representing
> a row or column vector and as the class stands now a vector * matrix
> will always fail.

Vector.elements([1,2,3])*Matrix.identity(1)
#=> Matrix[[1], [2], [3]]

Of course it's not much of a useful operation, but for me it's evident
from it that a vector assumes itself to be a vertical matrix each time
it is required to behave like a matrix.

And now, what will be the result of the above operation if, as you want,
a vector would auto-transpose when sent * with a matrix? A row or a
column matrix? For me, this proves that your idea is inconsistent. It
is not true that vector*matrix operation is never possible, so we
shouldn't automagically make it possible even if it is not. It wouldn't
make debugging any easier.

TPR.
--
Posted via http://www.ruby-....

Dave Baldwin

10/10/2008 7:37:00 AM

0


On 9 Oct 2008, at 18:12, Thomas B. wrote:

> Dave Baldwin wrote:
>> The Vector class doesn't seem to have any idea that it is
>> representing
>> a row or column vector and as the class stands now a vector * matrix
>> will always fail.
>
> Vector.elements([1,2,3])*Matrix.identity(1)
> #=> Matrix[[1], [2], [3]]
>
> Of course it's not much of a useful operation, but for me it's evident
> from it that a vector assumes itself to be a vertical matrix each time
> it is required to behave like a matrix.
>
> And now, what will be the result of the above operation if, as you
> want,
> a vector would auto-transpose when sent * with a matrix? A row or a
> column matrix? For me, this proves that your idea is inconsistent. It
> is not true that vector*matrix operation is never possible, so we
> shouldn't automagically make it possible even if it is not. It
> wouldn't
> make debugging any easier.

OK, so you demonstrated a degenerate case that is not much use as you
point out. How would you do something more useful such as
Vector[1,2,3]*Matrix.identity(3)? I don't think you can unless you
convert the vector to a row vector aka a matrix with one row and do it
as a matrix * matrix operation.

Also a Vector * Matrix should return a Vector and not a Matrix (as the
Matrix * Vector operation does).

Thankfully with open classes I can get the behaviour I think is
desirable.

Dave.



>
>
> TPR.
> --
> Posted via http://www.ruby-....
>