* lib/matrix.rb: New method Matrix.build [ruby-core:28272]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27315 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3a1c0be67f
commit
17fa2ce73a
@ -1,3 +1,7 @@
|
|||||||
|
Mon Apr 12 05:10:20 2010 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
|
||||||
|
|
||||||
|
* lib/matrix.rb: New method Matrix.build [ruby-core:28272]
|
||||||
|
|
||||||
Mon Apr 12 03:45:25 2010 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
|
Mon Apr 12 03:45:25 2010 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
|
||||||
|
|
||||||
* lib/matrix.rb: Deprecate elements_to_{f/i/r}
|
* lib/matrix.rb: Deprecate elements_to_{f/i/r}
|
||||||
|
@ -48,6 +48,7 @@ end
|
|||||||
# * <tt> Matrix.[](*rows) </tt>
|
# * <tt> Matrix.[](*rows) </tt>
|
||||||
# * <tt> Matrix.rows(rows, copy = true) </tt>
|
# * <tt> Matrix.rows(rows, copy = true) </tt>
|
||||||
# * <tt> Matrix.columns(columns) </tt>
|
# * <tt> Matrix.columns(columns) </tt>
|
||||||
|
# * <tt> Matrix.build(row_size, column_size, &block) </tt>
|
||||||
# * <tt> Matrix.diagonal(*values) </tt>
|
# * <tt> Matrix.diagonal(*values) </tt>
|
||||||
# * <tt> Matrix.scalar(n, value) </tt>
|
# * <tt> Matrix.scalar(n, value) </tt>
|
||||||
# * <tt> Matrix.identity(n) </tt>
|
# * <tt> Matrix.identity(n) </tt>
|
||||||
@ -165,6 +166,30 @@ class Matrix
|
|||||||
Matrix.rows(columns, false).transpose
|
Matrix.rows(columns, false).transpose
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Creates a matrix of size +row_size+ x +column_size+.
|
||||||
|
# It fills the values by calling the given block,
|
||||||
|
# passing the current row and column.
|
||||||
|
# Returns an enumerator if no block is given.
|
||||||
|
#
|
||||||
|
# m = Matrix.build(2, 4) {|row, col| col - row }
|
||||||
|
# => Matrix[[0, 1, 2, 3], [-1, 0, 1, 2]]
|
||||||
|
# m = Matrix.build(3) { rand }
|
||||||
|
# => a 3x3 matrix with random elements
|
||||||
|
#
|
||||||
|
def Matrix.build(row_size, column_size = row_size)
|
||||||
|
row_size = CoercionHelper.coerce_to_int(row_size)
|
||||||
|
column_size = CoercionHelper.coerce_to_int(column_size)
|
||||||
|
raise ArgumentError if row_size < 0 || column_size < 0
|
||||||
|
return to_enum :build, row_size, column_size unless block_given?
|
||||||
|
rows = row_size.times.map do |i|
|
||||||
|
column_size.times.map do |j|
|
||||||
|
yield i, j
|
||||||
|
end
|
||||||
|
end
|
||||||
|
new rows, column_size
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Creates a matrix where the diagonal elements are composed of +values+.
|
# Creates a matrix where the diagonal elements are composed of +values+.
|
||||||
# Matrix.diagonal(9, 5, -3)
|
# Matrix.diagonal(9, 5, -3)
|
||||||
@ -1074,7 +1099,7 @@ class Matrix
|
|||||||
|
|
||||||
# Private helper module
|
# Private helper module
|
||||||
|
|
||||||
module CoercionHelper
|
module CoercionHelper # :nodoc:
|
||||||
def apply_through_coercion(obj, oper)
|
def apply_through_coercion(obj, oper)
|
||||||
coercion = obj.coerce(self)
|
coercion = obj.coerce(self)
|
||||||
raise TypeError unless coercion.is_a?(Array) && coercion.length == 2
|
raise TypeError unless coercion.is_a?(Array) && coercion.length == 2
|
||||||
@ -1083,6 +1108,27 @@ class Matrix
|
|||||||
raise TypeError, "#{obj.inspect} can't be coerced into #{self.class}"
|
raise TypeError, "#{obj.inspect} can't be coerced into #{self.class}"
|
||||||
end
|
end
|
||||||
private :apply_through_coercion
|
private :apply_through_coercion
|
||||||
|
|
||||||
|
# Helper method to coerce a value into a specific class.
|
||||||
|
# Raises a TypeError if the coercion fails or the returned value
|
||||||
|
# is not of the right class.
|
||||||
|
# (from Rubinius)
|
||||||
|
def self.coerce_to(obj, cls, meth) # :nodoc:
|
||||||
|
return obj if obj.kind_of?(cls)
|
||||||
|
|
||||||
|
begin
|
||||||
|
ret = obj.__send__(meth)
|
||||||
|
rescue Exception => e
|
||||||
|
raise TypeError, "Coercion error: #{obj.inspect}.#{meth} => #{cls} failed:\n" \
|
||||||
|
"(#{e.message})"
|
||||||
|
end
|
||||||
|
raise TypeError, "Coercion error: obj.#{meth} did NOT return a #{cls} (was #{ret.class})" unless ret.kind_of? cls
|
||||||
|
ret
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.coerce_to_int(obj)
|
||||||
|
coerce_to(obj, Integer, :to_int)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
include CoercionHelper
|
include CoercionHelper
|
||||||
|
Loading…
x
Reference in New Issue
Block a user