Bug #2365 ยป matrix_coercion.diff
| lib/matrix.rb | ||
|---|---|---|
|
class Matrix
|
||
|
@RCS_ID='-$Id: matrix.rb,v 1.13 2001/12/09 14:22:23 keiju Exp keiju $-'
|
||
|
module CoercionHelper
|
||
|
def apply_through_coercion(obj, oper)
|
||
|
coercion = obj.coerce(self)
|
||
|
raise TypeError unless coercion.is_a? Array && coercion.length == 2
|
||
|
coercion[0].public_send(oper, coercion[1])
|
||
|
rescue
|
||
|
raise TypeError, "#{obj.inspect} can't be coerced into #{self.class}"
|
||
|
end
|
||
|
private :apply_through_coercion
|
||
|
end
|
||
|
include CoercionHelper
|
||
|
# extend Exception2MessageMapper
|
||
|
include ExceptionForMatrix
|
||
| ... | ... | |
|
}
|
||
|
return new_matrix rows, m.column_size
|
||
|
else
|
||
|
x, y = m.coerce(self)
|
||
|
return x * y
|
||
|
return apply_through_coercion(m, __method__)
|
||
|
end
|
||
|
end
|
||
| ... | ... | |
|
m = Matrix.column_vector(m)
|
||
|
when Matrix
|
||
|
else
|
||
|
x, y = m.coerce(self)
|
||
|
return x + y
|
||
|
return apply_through_coercion(m, __method__)
|
||
|
end
|
||
|
Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
|
||
| ... | ... | |
|
m = Matrix.column_vector(m)
|
||
|
when Matrix
|
||
|
else
|
||
|
x, y = m.coerce(self)
|
||
|
return x - y
|
||
|
return apply_through_coercion(m, __method__)
|
||
|
end
|
||
|
Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
|
||
| ... | ... | |
|
when Matrix
|
||
|
return self * other.inverse
|
||
|
else
|
||
|
x, y = other.coerce(self)
|
||
|
return x / y
|
||
|
return apply_through_coercion(other, __method__)
|
||
|
end
|
||
|
end
|
||
| ... | ... | |
|
class Scalar < Numeric # :nodoc:
|
||
|
include ExceptionForMatrix
|
||
|
include CoercionHelper
|
||
|
def initialize(value)
|
||
|
@value = value
|
||
| ... | ... | |
|
when Scalar
|
||
|
Scalar.new(@value + other.value)
|
||
|
else
|
||
|
x, y = other.coerce(self)
|
||
|
x + y
|
||
|
apply_through_coercion(other, __method__)
|
||
|
end
|
||
|
end
|
||
| ... | ... | |
|
when Scalar
|
||
|
Scalar.new(@value - other.value)
|
||
|
else
|
||
|
x, y = other.coerce(self)
|
||
|
x - y
|
||
|
apply_through_coercion(other, __method__)
|
||
|
end
|
||
|
end
|
||
| ... | ... | |
|
when Vector, Matrix
|
||
|
other.collect{|e| @value * e}
|
||
|
else
|
||
|
x, y = other.coerce(self)
|
||
|
x * y
|
||
|
apply_through_coercion(other, __method__)
|
||
|
end
|
||
|
end
|
||
| ... | ... | |
|
when Matrix
|
||
|
self * other.inverse
|
||
|
else
|
||
|
x, y = other.coerce(self)
|
||
|
x.quo(y)
|
||
|
apply_through_coercion(other, __method__)
|
||
|
end
|
||
|
end
|
||
| ... | ... | |
|
when Matrix
|
||
|
other.powered_by(self)
|
||
|
else
|
||
|
x, y = other.coerce(self)
|
||
|
x ** y
|
||
|
apply_through_coercion(other, __method__)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
| ... | ... | |
|
#
|
||
|
class Vector
|
||
|
include ExceptionForMatrix
|
||
|
include Matrix::CoercionHelper
|
||
|
#INSTANCE CREATION
|
||
|
private_class_method :new
|
||
| ... | ... | |
|
when Matrix
|
||
|
Matrix.column_vector(self) * x
|
||
|
else
|
||
|
s, x = x.coerce(self)
|
||
|
s * x
|
||
|
apply_through_coercion(x, __method__)
|
||
|
end
|
||
|
end
|
||
| ... | ... | |
|
when Matrix
|
||
|
Matrix.column_vector(self) + v
|
||
|
else
|
||
|
s, x = v.coerce(self)
|
||
|
s + x
|
||
|
apply_through_coercion(v, __method__)
|
||
|
end
|
||
|
end
|
||
| ... | ... | |
|
when Matrix
|
||
|
Matrix.column_vector(self) - v
|
||
|
else
|
||
|
s, x = v.coerce(self)
|
||
|
s - x
|
||
|
apply_through_coercion(v, __method__)
|
||
|
end
|
||
|
end
|
||