Project

General

Profile

Bug #1532 » a_matrix_creation.diff

marcandre (Marc-Andre Lafortune), 09/17/2009 02:03 PM

View differences:

lib/matrix.rb
# arithmetically and algebraically, and determining their mathematical properties (trace, rank,
# inverse, determinant).
#
# Note that although matrices should theoretically be rectangular, this is not
# enforced by the class.
# Note that matrices must be rectangular, otherwise an ErrDimensionMismatch is raised.
#
# Also note that the determinant of integer matrices may be incorrectly calculated unless you
# Also note that the determinant of integer matrices may be approximated unless you
# also <tt>require 'mathn'</tt>. This may be fixed in the future.
#
# == Method Catalogue
......
# instance creations
private_class_method :new
attr_reader :rows
protected :rows
#
# Creates a matrix where each argument is a row.
......
# -1 66
#
def Matrix.[](*rows)
new(:init_rows, rows, false)
Matrix.rows(rows, false)
end
#
......
# -1 66
#
def Matrix.rows(rows, copy = true)
new(:init_rows, rows, copy)
rows = Matrix.convert_to_array(rows)
rows.map! do |row|
Matrix.convert_to_array(row, copy)
end
size = (rows[0] || []).size
rows.each do |row|
Matrix.Raise ErrDimensionMismatch, "element size differs (#{row.size} should be #{size})" unless row.size == size
end
new rows
end
#
......
# 93 66
#
def Matrix.columns(columns)
rows = (0 ... columns[0].size).collect {|i|
(0 ... columns.size).collect {|j|
columns[j][i]
}
}
Matrix.rows(rows, false)
Matrix.rows(columns, false).transpose
end
#
......
row[j] = values[j]
row
}
rows(rows, false)
new rows
end
#
......
# => 4 5 6
#
def Matrix.row_vector(row)
case row
when Vector
Matrix.rows([row.to_a], false)
when Array
Matrix.rows([row.dup], false)
else
Matrix.rows([[row]], false)
end
row = Matrix.convert_to_array(row)
new [row]
end
#
......
# 6
#
def Matrix.column_vector(column)
case column
when Vector
Matrix.columns([column.to_a])
when Array
Matrix.columns([column])
else
Matrix.columns([[column]])
end
column = Matrix.convert_to_array(column)
new [column].transpose
end
#
# This method is used by the other methods that create matrices, and is of no
# use to general users.
# Matrix.new is private; use Matrix.rows, columns, [], etc... to create.
#
def initialize(init_method, *argv)
self.send(init_method, *argv)
def initialize(rows)
# No checking is done at this point. rows must be an Array of Arrays.
@rows = rows
end
def init_rows(rows, copy)
if copy
@rows = rows.collect{|row| row.dup}
else
@rows = rows
end
self
def new(rows) # :nodoc:
Matrix.send(:new, rows) # bypass privacy of Matrix.new
end
private :init_rows
private :new
#
# Returns element (+i+,+j+) of the matrix. That is: row +i+, column +j+.
......
end
#
# Returns the number of columns. Note that it is possible to construct a
# matrix with uneven columns (e.g. Matrix[ [1,2,3], [4,5] ]), but this is
# mathematically unsound. This method uses the first row to determine the
# result.
# Returns the number of columns.
#
def column_size
@rows[0].size
......
#
def collect(&block) # :yield: e
rows = @rows.collect{|row| row.collect(&block)}
Matrix.rows(rows, false)
new(rows)
end
alias map collect
......
rows = @rows[from_row, size_row].collect{|row|
row[from_col, size_col]
}
Matrix.rows(rows, false)
new(rows)
end
#--
......
end
#
# Returns +true+ is this is a square matrix. See note in column_size about this
# being unreliable, though.
# Returns +true+ is this is a square matrix.
#
def square?
column_size == row_size
......
#
# Returns a clone of the matrix, so that the contents of each do not reference
# identical objects.
# There should be no good reason to do this since Matrices are immutable.
#
def clone
Matrix.rows(@rows)
new(@rows.map{|row| row.dup})
end
#
......
e * m
}
}
return Matrix.rows(rows, false)
return new(rows)
when Vector
m = Matrix.column_vector(m)
r = self * m
......
end
}
}
return Matrix.rows(rows, false)
return new(rows)
else
x, y = m.coerce(self)
return x * y
......
self[i, j] + m[i, j]
}
}
Matrix.rows(rows, false)
new(rows)
end
#
......
self[i, j] - m[i, j]
}
}
Matrix.rows(rows, false)
new(rows)
end
#
......
e / other
}
}
return Matrix.rows(rows, false)
return new(rows)
when Matrix
return self * other.inverse
else
......
# 2 4 6
#
def transpose
Matrix.columns(@rows)
new @rows.transpose
end
alias t transpose
......
"Matrix"+@rows.inspect
end
#
# Converts the obj to an Array. If copy is set to true
# a copy of obj will be made if necessary.
#
def Matrix.convert_to_array(obj, copy = false)
case obj
when Array
copy ? obj.dup : obj
when Vector
obj.to_a
else
begin
converted = obj.to_ary
rescue Exception => e
raise TypeError, "can't convert #{obj.class} into an Array (#{e.message})"
end
raise TypeError, "#{obj.class}#to_ary should return an Array" unless converted.is_a? Array
converted
end
end
# Private CLASS
class Scalar < Numeric # :nodoc:
(3-3/7)