mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
2 changed files with 51 additions and 1 deletions
|
@ -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>
|
||||
|
||||
* lib/matrix.rb: Deprecate elements_to_{f/i/r}
|
||||
|
|
|
@ -48,6 +48,7 @@ end
|
|||
# * <tt> Matrix.[](*rows) </tt>
|
||||
# * <tt> Matrix.rows(rows, copy = true) </tt>
|
||||
# * <tt> Matrix.columns(columns) </tt>
|
||||
# * <tt> Matrix.build(row_size, column_size, &block) </tt>
|
||||
# * <tt> Matrix.diagonal(*values) </tt>
|
||||
# * <tt> Matrix.scalar(n, value) </tt>
|
||||
# * <tt> Matrix.identity(n) </tt>
|
||||
|
@ -165,6 +166,30 @@ class Matrix
|
|||
Matrix.rows(columns, false).transpose
|
||||
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+.
|
||||
# Matrix.diagonal(9, 5, -3)
|
||||
|
@ -1074,7 +1099,7 @@ class Matrix
|
|||
|
||||
# Private helper module
|
||||
|
||||
module CoercionHelper
|
||||
module CoercionHelper # :nodoc:
|
||||
def apply_through_coercion(obj, oper)
|
||||
coercion = obj.coerce(self)
|
||||
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}"
|
||||
end
|
||||
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
|
||||
|
||||
include CoercionHelper
|
||||
|
|
Loading…
Reference in a new issue