mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
778 lines
13 KiB
Ruby
778 lines
13 KiB
Ruby
|
#!/usr/local/bin/ruby
|
|||
|
#
|
|||
|
# matrix.rb -
|
|||
|
# $Release Version: 1.0$
|
|||
|
# $Revision: 1.0 $
|
|||
|
# $Date: 97/05/23 11:35:28 $
|
|||
|
# Original Version from Smalltalk-80 version
|
|||
|
# on July 23, 1985 at 8:37:17 am
|
|||
|
# by Keiju ISHITSUKA
|
|||
|
#
|
|||
|
# --
|
|||
|
#
|
|||
|
# Matrix[[1,2,3],
|
|||
|
# :
|
|||
|
# [3,4,5]]
|
|||
|
# Matrix[row0,
|
|||
|
# row1,
|
|||
|
# :
|
|||
|
# rown]
|
|||
|
#
|
|||
|
# column: <20><>
|
|||
|
# row: <20><>
|
|||
|
#
|
|||
|
|
|||
|
require "e2mmap.rb"
|
|||
|
|
|||
|
module ExceptionForMatrix
|
|||
|
Exception2MessageMapper.extend_to(binding)
|
|||
|
|
|||
|
def_e2message(TypeError, "wrong argument type %s (expected %s)")
|
|||
|
def_e2message(ArgumentError, "Wrong # of arguments(%d for %d)")
|
|||
|
|
|||
|
def_exception("ErrDimensionMismatch", "\#{self.type} dimemsion mismatch")
|
|||
|
def_exception("ErrNotRegular", "Not Regular Matrix")
|
|||
|
def_exception("ErrOperationNotDefined", "This operation(%s) can\\'t defined")
|
|||
|
end
|
|||
|
|
|||
|
class Matrix
|
|||
|
RCS_ID='-$Header: ruby-mode,v 1.2 91/04/20 17:24:57 keiju Locked $-'
|
|||
|
|
|||
|
include ExceptionForMatrix
|
|||
|
|
|||
|
# instance creations
|
|||
|
private_class_method :new
|
|||
|
|
|||
|
def Matrix.[](*rows)
|
|||
|
new(:init_rows, rows, FALSE)
|
|||
|
end
|
|||
|
|
|||
|
def Matrix.rows(rows, copy = TRUE)
|
|||
|
new(:init_rows, rows, copy)
|
|||
|
end
|
|||
|
|
|||
|
def Matrix.columns(columns)
|
|||
|
rows = (0 .. columns[0].size - 1).collect {
|
|||
|
|i|
|
|||
|
(0 .. columns.size - 1).collect {
|
|||
|
|j|
|
|||
|
columns[j][i]
|
|||
|
}
|
|||
|
}
|
|||
|
Matrix.rows(rows, FALSE)
|
|||
|
end
|
|||
|
|
|||
|
def Matrix.diagonal(*values)
|
|||
|
size = values.size
|
|||
|
rows = (0 .. size - 1).collect {
|
|||
|
|j|
|
|||
|
row = Array.new(size).fill(0, 0, size)
|
|||
|
row[j] = values[j]
|
|||
|
row
|
|||
|
}
|
|||
|
self
|
|||
|
rows(rows, FALSE)
|
|||
|
end
|
|||
|
|
|||
|
def Matrix.scalar(n, value)
|
|||
|
Matrix.diagonal(*Array.new(n).fill(value, 0, n))
|
|||
|
end
|
|||
|
|
|||
|
def Matrix.identity(n)
|
|||
|
Matrix.scalar(n, 1)
|
|||
|
end
|
|||
|
class << Matrix
|
|||
|
alias unit identity
|
|||
|
alias I identity
|
|||
|
end
|
|||
|
|
|||
|
def Matrix.zero(n)
|
|||
|
Matrix.scalar(n, 0)
|
|||
|
end
|
|||
|
|
|||
|
def Matrix.row_vector(row)
|
|||
|
case row
|
|||
|
when Vector
|
|||
|
Matrix.rows([row.to_a], FALSE)
|
|||
|
when Array
|
|||
|
Matrix.rows([row.dup], FALSE)
|
|||
|
else
|
|||
|
Matrix.row([[row]], FALSE)
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
def Matrix.column_vector(column)
|
|||
|
case column
|
|||
|
when Vector
|
|||
|
Matrix.columns([column.to_a])
|
|||
|
when Array
|
|||
|
Matrix.columns([column])
|
|||
|
else
|
|||
|
Matrix.columns([[column]])
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
# initializing
|
|||
|
def initialize(init_method, *argv)
|
|||
|
self.send(init_method, *argv)
|
|||
|
end
|
|||
|
|
|||
|
def init_rows(rows, copy)
|
|||
|
if copy
|
|||
|
@rows = rows.collect{|row| row.dup}
|
|||
|
else
|
|||
|
@rows = rows
|
|||
|
end
|
|||
|
self
|
|||
|
end
|
|||
|
private :init_rows
|
|||
|
|
|||
|
#accessing
|
|||
|
def [](i, j)
|
|||
|
@rows[i][j]
|
|||
|
end
|
|||
|
|
|||
|
def row_size
|
|||
|
@rows.size
|
|||
|
end
|
|||
|
|
|||
|
def column_size
|
|||
|
@rows[0].size
|
|||
|
end
|
|||
|
|
|||
|
def row(i)
|
|||
|
if iterator?
|
|||
|
for e in @rows[i]
|
|||
|
yield e
|
|||
|
end
|
|||
|
else
|
|||
|
Vector.elements(@rows[i])
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
def column(j)
|
|||
|
if iterator?
|
|||
|
0.upto(row_size - 1) do
|
|||
|
|i|
|
|||
|
yield @rows[i][j]
|
|||
|
end
|
|||
|
else
|
|||
|
col = (0 .. row_size - 1).collect {
|
|||
|
|i|
|
|||
|
@rows[i][j]
|
|||
|
}
|
|||
|
Vector.elements(col, FALSE)
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
def collect
|
|||
|
rows = @rows.collect{|row| row.collect{|e| yield e}}
|
|||
|
Matrix.rows(rows, FALSE)
|
|||
|
end
|
|||
|
alias map collect
|
|||
|
|
|||
|
#
|
|||
|
# param: (from_row, row_size, from_col, size_col)
|
|||
|
# (from_row..to_row, from_col..to_col)
|
|||
|
#
|
|||
|
def minor(*param)
|
|||
|
case param.size
|
|||
|
when 2
|
|||
|
from_row = param[0].first
|
|||
|
size_row = param[0].size
|
|||
|
from_col = param[1].first
|
|||
|
size_col = param[1].size
|
|||
|
when 4
|
|||
|
from_row = param[0]
|
|||
|
size_row = param[1]
|
|||
|
from_col = param[2]
|
|||
|
size_col = param[3]
|
|||
|
else
|
|||
|
Matrix.fail ArgumentError, param.inspect
|
|||
|
end
|
|||
|
|
|||
|
rows = @rows[from_row, size_row].collect{
|
|||
|
|row|
|
|||
|
row[from_col, size_col]
|
|||
|
}
|
|||
|
Matrix.rows(rows, FALSE)
|
|||
|
end
|
|||
|
|
|||
|
# TESTING
|
|||
|
def regular?
|
|||
|
square? and rank == column_size
|
|||
|
end
|
|||
|
|
|||
|
def singular?
|
|||
|
not regular?
|
|||
|
end
|
|||
|
|
|||
|
def square?
|
|||
|
column_size == row_size
|
|||
|
end
|
|||
|
|
|||
|
# ARITHMETIC
|
|||
|
|
|||
|
def *(m) #is matrix or vector or number"
|
|||
|
case(m)
|
|||
|
when Numeric
|
|||
|
rows = @rows.collect {
|
|||
|
|row|
|
|||
|
row.collect {
|
|||
|
|e|
|
|||
|
e * m
|
|||
|
}
|
|||
|
}
|
|||
|
return Matrix.rows(rows, FALSE)
|
|||
|
when Vector
|
|||
|
m = Matrix.column_vector(m)
|
|||
|
r = self * m
|
|||
|
return r.column(0)
|
|||
|
when Matrix
|
|||
|
Matrix.fail ErrDimensionMismatch if column_size != m.row_size
|
|||
|
|
|||
|
rows = (0 .. row_size - 1).collect {
|
|||
|
|i|
|
|||
|
(0 .. m.column_size - 1).collect {
|
|||
|
|j|
|
|||
|
vij = 0
|
|||
|
0.upto(column_size - 1) do
|
|||
|
|k|
|
|||
|
vij += self[i, k] * m[k, j]
|
|||
|
end
|
|||
|
vij
|
|||
|
}
|
|||
|
}
|
|||
|
return Matrix.rows(rows, FALSE)
|
|||
|
else
|
|||
|
x, y = m.coerce(self)
|
|||
|
return x * y
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
def +(m)
|
|||
|
case m
|
|||
|
when Numeric
|
|||
|
Matrix.fail ErrOperationNotDefined, "+"
|
|||
|
when Vector
|
|||
|
m = Matrix.column_vector(m)
|
|||
|
when Matrix
|
|||
|
else
|
|||
|
x, y = m.coerce(self)
|
|||
|
return x + y
|
|||
|
end
|
|||
|
|
|||
|
Matrix.fail ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
|
|||
|
|
|||
|
rows = (0 .. row_size - 1).collect {
|
|||
|
|i|
|
|||
|
(0 .. column_size - 1).collect {
|
|||
|
|j|
|
|||
|
self[i, j] + m[i, j]
|
|||
|
}
|
|||
|
}
|
|||
|
Matrix.rows(rows, FALSE)
|
|||
|
end
|
|||
|
|
|||
|
def -(m)
|
|||
|
case m
|
|||
|
when Numeric
|
|||
|
Matrix.fail ErrOperationNotDefined, "-"
|
|||
|
when Vector
|
|||
|
m = Matrix.column_vector(m)
|
|||
|
when Matrix
|
|||
|
else
|
|||
|
x, y = m.coerce(self)
|
|||
|
return x - y
|
|||
|
end
|
|||
|
|
|||
|
Matrix.fail ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
|
|||
|
|
|||
|
rows = (0 .. row_size - 1).collect {
|
|||
|
|i|
|
|||
|
(0 .. column_size - 1).collect {
|
|||
|
|j|
|
|||
|
self[i, j] - m[i, j]
|
|||
|
}
|
|||
|
}
|
|||
|
Matrix.rows(rows, FALSE)
|
|||
|
end
|
|||
|
|
|||
|
def inverse
|
|||
|
Matrix.fail ErrDimensionMismatch unless square?
|
|||
|
Matrix.I(row_size).inverse_from(self)
|
|||
|
end
|
|||
|
alias inv inverse
|
|||
|
|
|||
|
def inverse_from(src)
|
|||
|
size = row_size - 1
|
|||
|
a = src.to_a
|
|||
|
|
|||
|
for k in 0..size
|
|||
|
if (akk = a[k][k]) == 0
|
|||
|
i = k
|
|||
|
begin
|
|||
|
fail ErrNotRegular if (i += 1) > size
|
|||
|
end while a[i][k] == 0
|
|||
|
a[i], a[k] = a[k], a[i]
|
|||
|
@rows[i], @rows[k] = @rows[k], @rows[i]
|
|||
|
akk = a[k][k]
|
|||
|
end
|
|||
|
|
|||
|
for i in 0 .. size
|
|||
|
next if i == k
|
|||
|
q = a[i][k] / akk
|
|||
|
a[i][k] = 0
|
|||
|
|
|||
|
(k + 1).upto(size) do
|
|||
|
|j|
|
|||
|
a[i][j] -= a[k][j] * q
|
|||
|
end
|
|||
|
0.upto(size) do
|
|||
|
|j|
|
|||
|
@rows[i][j] -= @rows[k][j] * q
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
(k + 1).upto(size) do
|
|||
|
|j|
|
|||
|
a[k][j] /= akk
|
|||
|
end
|
|||
|
0.upto(size) do
|
|||
|
|j|
|
|||
|
@rows[k][j] /= akk
|
|||
|
end
|
|||
|
end
|
|||
|
self
|
|||
|
end
|
|||
|
#alias reciprocal inverse
|
|||
|
|
|||
|
def ** (other)
|
|||
|
if other.kind_of?(Integer)
|
|||
|
x = self
|
|||
|
if other <= 0
|
|||
|
x = self.inverse
|
|||
|
return Matrix.identity(self.column_size) if other == 0
|
|||
|
other = -other
|
|||
|
end
|
|||
|
z = x
|
|||
|
n = other - 1
|
|||
|
while n != 0
|
|||
|
while (div, mod = n.divmod(2)
|
|||
|
mod == 0)
|
|||
|
x = x * x
|
|||
|
n = div
|
|||
|
end
|
|||
|
z *= x
|
|||
|
n -= 1
|
|||
|
end
|
|||
|
z
|
|||
|
elsif other.kind_of?(Float) || defined?(Rational) && other.kind_of?(Rational)
|
|||
|
fail ErrOperationNotDefined, "**"
|
|||
|
else
|
|||
|
fail ErrOperationNotDefined, "**"
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
# Matrix functions
|
|||
|
|
|||
|
def determinant
|
|||
|
return 0 unless square?
|
|||
|
|
|||
|
size = row_size - 1
|
|||
|
a = to_a
|
|||
|
|
|||
|
det = 1
|
|||
|
k = 0
|
|||
|
begin
|
|||
|
if (akk = a[k][k]) == 0
|
|||
|
i = k
|
|||
|
begin
|
|||
|
return 0 if (i += 1) > size
|
|||
|
end while a[i][k] == 0
|
|||
|
a[i], a[k] = a[k], a[i]
|
|||
|
akk = a[k][k]
|
|||
|
end
|
|||
|
(k + 1).upto(size) do
|
|||
|
|i|
|
|||
|
q = a[i][k] / akk
|
|||
|
(k + 1).upto(size) do
|
|||
|
|j|
|
|||
|
a[i][j] -= a[k][j] * q
|
|||
|
end
|
|||
|
end
|
|||
|
det *= akk
|
|||
|
end while (k += 1) <= size
|
|||
|
det
|
|||
|
end
|
|||
|
alias det determinant
|
|||
|
|
|||
|
def rank
|
|||
|
if column_size > row_size
|
|||
|
a = transpose.to_a
|
|||
|
else
|
|||
|
a = to_a
|
|||
|
end
|
|||
|
rank = 0
|
|||
|
k = 0
|
|||
|
begin
|
|||
|
if (akk = a[k][k]) == 0
|
|||
|
i = -1
|
|||
|
nothing = FALSE
|
|||
|
begin
|
|||
|
if (i += 1) > column_size - 1
|
|||
|
nothing = TRUE
|
|||
|
break
|
|||
|
end
|
|||
|
end while a[i][k] == 0
|
|||
|
next if nothing
|
|||
|
a[i], a[k] = a[k], a[i]
|
|||
|
akk = a[k][k]
|
|||
|
end
|
|||
|
(k + 1).upto(row_size - 1) do
|
|||
|
|i|
|
|||
|
q = a[i][k] / akk
|
|||
|
(k + 1).upto(column_size - 1) do
|
|||
|
|j|
|
|||
|
a[i][j] -= a[k][j] * q
|
|||
|
end
|
|||
|
end
|
|||
|
rank += 1
|
|||
|
end while (k += 1) <= column_size - 1
|
|||
|
return rank
|
|||
|
end
|
|||
|
|
|||
|
def trace
|
|||
|
tr = 0
|
|||
|
0.upto(column_size - 1) do
|
|||
|
|i|
|
|||
|
tr += @rows[i][i]
|
|||
|
end
|
|||
|
tr
|
|||
|
end
|
|||
|
alias tr trace
|
|||
|
|
|||
|
def transpose
|
|||
|
Matrix.columns(@rows)
|
|||
|
end
|
|||
|
alias t transpose
|
|||
|
|
|||
|
# CONVERTING
|
|||
|
|
|||
|
def coerce(other)
|
|||
|
case other
|
|||
|
when Numeric
|
|||
|
return Scalar.new(other), self
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
def row_vectors
|
|||
|
rows = (0 .. column_size - 1).collect {
|
|||
|
|i|
|
|||
|
row(i)
|
|||
|
}
|
|||
|
rows
|
|||
|
end
|
|||
|
|
|||
|
def column_vectors
|
|||
|
columns = (0 .. row_size - 1).collect {
|
|||
|
|i|
|
|||
|
column(i)
|
|||
|
}
|
|||
|
columns
|
|||
|
end
|
|||
|
|
|||
|
def to_a
|
|||
|
@rows.collect{|row| row.collect{|e| e}}
|
|||
|
end
|
|||
|
|
|||
|
def to_f
|
|||
|
collect{|e| e.to_f}
|
|||
|
end
|
|||
|
|
|||
|
def to_i
|
|||
|
collect{|e| e.to_i}
|
|||
|
end
|
|||
|
|
|||
|
def to_r
|
|||
|
collect{|e| e.to_r}
|
|||
|
end
|
|||
|
|
|||
|
# PRINTING
|
|||
|
def to_s
|
|||
|
"Matrix[" + @rows.collect{
|
|||
|
|row|
|
|||
|
"[" + row.collect{|e| e.to_s}.join(", ") + "]"
|
|||
|
}.join(", ")+"]"
|
|||
|
end
|
|||
|
|
|||
|
def inspect
|
|||
|
"Matrix"+@rows.inspect
|
|||
|
end
|
|||
|
|
|||
|
# Private CLASS
|
|||
|
|
|||
|
class Scalar < Numeric
|
|||
|
include ExceptionForMatrix
|
|||
|
|
|||
|
def initialize(value)
|
|||
|
@value = value
|
|||
|
end
|
|||
|
|
|||
|
# ARITHMETIC
|
|||
|
def +(other)
|
|||
|
case other
|
|||
|
when Numeric
|
|||
|
Scalar.new(@value + other)
|
|||
|
when Vector, Matrix
|
|||
|
Scalar.fail WrongArgType, other.type, "Numeric or Scalar"
|
|||
|
when Scalar
|
|||
|
Scalar.new(@value + other.value)
|
|||
|
else
|
|||
|
x, y = other.coerce(self)
|
|||
|
x + y
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
def -(other)
|
|||
|
case other
|
|||
|
when Numeric
|
|||
|
Scalar.new(@value - other)
|
|||
|
when Vector, Matrix
|
|||
|
Scalar.fail WrongArgType, other.type, "Numeric or Scalar"
|
|||
|
when Scalar
|
|||
|
Scalar.new(@value - other.value)
|
|||
|
else
|
|||
|
x, y = other.coerce(self)
|
|||
|
x - y
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
def *(other)
|
|||
|
case other
|
|||
|
when Numeric
|
|||
|
Scalar.new(@value * other)
|
|||
|
when Vector, Matrix
|
|||
|
other.collect{|e| @value * e}
|
|||
|
else
|
|||
|
x, y = other.coerce(self)
|
|||
|
x * y
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
def / (other)
|
|||
|
case other
|
|||
|
when Numeric
|
|||
|
Scalar.new(@value / other)
|
|||
|
when Vector
|
|||
|
Scalar.fail WrongArgType, other.type, "Numeric or Scalar or Matrix"
|
|||
|
when Matrix
|
|||
|
self * _M.inverse
|
|||
|
else
|
|||
|
x, y = other.coerce(self)
|
|||
|
x / y
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
def ** (other)
|
|||
|
case other
|
|||
|
when Numeric
|
|||
|
Scalar.new(@value ** other)
|
|||
|
when Vector
|
|||
|
Scalar.fail WrongArgType, other.type, "Numeric or Scalar or Matrix"
|
|||
|
when Matrix
|
|||
|
other.powered_by(self)
|
|||
|
else
|
|||
|
x, y = other.coerce(self)
|
|||
|
x ** y
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
#----------------------------------------------------------------------
|
|||
|
#
|
|||
|
# -
|
|||
|
#
|
|||
|
#----------------------------------------------------------------------
|
|||
|
class Vector
|
|||
|
include ExceptionForMatrix
|
|||
|
|
|||
|
|
|||
|
#INSTANCE CREATION
|
|||
|
|
|||
|
private_class_method :new
|
|||
|
def Vector.[](*array)
|
|||
|
new(:init_elements, array, copy = FALSE)
|
|||
|
end
|
|||
|
|
|||
|
def Vector.elements(array, copy = TRUE)
|
|||
|
new(:init_elements, array, copy)
|
|||
|
end
|
|||
|
|
|||
|
def initialize(method, array, copy)
|
|||
|
self.send(method, array, copy)
|
|||
|
end
|
|||
|
|
|||
|
def init_elements(array, copy)
|
|||
|
if copy
|
|||
|
@elements = array.dup
|
|||
|
else
|
|||
|
@elements = array
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
# ACCSESSING
|
|||
|
|
|||
|
def [](i)
|
|||
|
@elements[i]
|
|||
|
end
|
|||
|
|
|||
|
def size
|
|||
|
@elements.size
|
|||
|
end
|
|||
|
|
|||
|
# ENUMRATIONS
|
|||
|
def each2(v)
|
|||
|
Vector.fail ErrDimensionMismatch if size != v.size
|
|||
|
0.upto(size - 1) do
|
|||
|
|i|
|
|||
|
yield @elements[i], v[i]
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
def collect2(v)
|
|||
|
Vector.fail ErrDimensionMismatch if size != v.size
|
|||
|
(0 .. size - 1).collect do
|
|||
|
|i|
|
|||
|
yield @elements[i], v[i]
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
# ARITHMETIC
|
|||
|
|
|||
|
def *(x) "is matrix or number"
|
|||
|
case x
|
|||
|
when Numeric
|
|||
|
els = @elements.collect{|e| e * x}
|
|||
|
Vector.elements(els, FALSE)
|
|||
|
when Matrix
|
|||
|
self.covector * x
|
|||
|
else
|
|||
|
s, x = X.corece(self)
|
|||
|
s * x
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
def +(v)
|
|||
|
case v
|
|||
|
when Vector
|
|||
|
Vector.fail ErrDimensionMismatch if size != v.size
|
|||
|
els = collect2(v) {
|
|||
|
|v1, v2|
|
|||
|
v1 + v2
|
|||
|
}
|
|||
|
Vector.elements(els, FALSE)
|
|||
|
when Matrix
|
|||
|
Matrix.column_vector(self) + v
|
|||
|
else
|
|||
|
s, x = v.corece(self)
|
|||
|
s + x
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
def -(v)
|
|||
|
case v
|
|||
|
when Vector
|
|||
|
Vector.fail ErrDimensionMismatch if size != v.size
|
|||
|
els = collect2(v) {
|
|||
|
|v1, v2|
|
|||
|
v1 - v2
|
|||
|
}
|
|||
|
Vector.elements(els, FALSE)
|
|||
|
when Matrix
|
|||
|
Matrix.column_vector(self) - v
|
|||
|
else
|
|||
|
s, x = v.corece(self)
|
|||
|
s - x
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
# VECTOR FUNCTIONS
|
|||
|
|
|||
|
def inner_product(v)
|
|||
|
Vector.fail ErrDimensionMismatch if size != v.size
|
|||
|
|
|||
|
p = 0
|
|||
|
each2(v) {
|
|||
|
|v1, v2|
|
|||
|
p += v1 * v2
|
|||
|
}
|
|||
|
p
|
|||
|
end
|
|||
|
|
|||
|
def collect
|
|||
|
els = @elements.collect {
|
|||
|
|v|
|
|||
|
yield v
|
|||
|
}
|
|||
|
Vector.elements(els, FALSE)
|
|||
|
end
|
|||
|
alias map collect
|
|||
|
|
|||
|
def map2(v)
|
|||
|
els = collect2(v) {
|
|||
|
|v1, v2|
|
|||
|
yield v1, v2
|
|||
|
}
|
|||
|
Vector.elements(els, FALSE)
|
|||
|
end
|
|||
|
|
|||
|
def r
|
|||
|
v = 0
|
|||
|
for e in @elements
|
|||
|
v += e*e
|
|||
|
end
|
|||
|
return v.sqrt
|
|||
|
end
|
|||
|
|
|||
|
# CONVERTING
|
|||
|
def covector
|
|||
|
Matrix.row_vector(self)
|
|||
|
end
|
|||
|
|
|||
|
def to_a
|
|||
|
@elements.dup
|
|||
|
end
|
|||
|
|
|||
|
def to_f
|
|||
|
collect{|e| e.to_f}
|
|||
|
end
|
|||
|
|
|||
|
def to_i
|
|||
|
collect{|e| e.to_i}
|
|||
|
end
|
|||
|
|
|||
|
def to_r
|
|||
|
collect{|e| e.to_r}
|
|||
|
end
|
|||
|
|
|||
|
def coerce(other)
|
|||
|
case other
|
|||
|
when Numeric
|
|||
|
return Scalar.new(other), self
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
# PRINTING
|
|||
|
|
|||
|
def to_s
|
|||
|
"Vector[" + @elements.join(", ") + "]"
|
|||
|
end
|
|||
|
|
|||
|
def inspect
|
|||
|
str = "Vector"+@elements.inspect
|
|||
|
end
|
|||
|
end
|
|||
|
|