summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarcandre <marcandre@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-09-16 04:36:37 +0000
committermarcandre <marcandre@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-09-16 04:36:37 +0000
commit9d3638448e0d11ba9e4bd1941934c21cf09edc91 (patch)
tree857a24ee1c5a802d40c3caa944c231b1aaa6cae4
parentaf424b17a07b3d78cd7ee8b01edcf1e7a6077d8e (diff)
* lib/matrix.rb: trivial optimizations
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24947 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog4
-rw-r--r--lib/matrix.rb128
2 files changed, 55 insertions, 77 deletions
diff --git a/ChangeLog b/ChangeLog
index dd13d84548..00e107e35d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Wed Sep 16 13:30:20 2009 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
+
+ * lib/matrix.rb: trivial optimizations
+
Wed Sep 16 13:15:17 2009 NAKAMURA Usaku <usa@ruby-lang.org>
* template/Doxyfile.tmpl: RbConfig::CONFIG['DOT'] is sometimes nil.
diff --git a/lib/matrix.rb b/lib/matrix.rb
index 95c8273522..4c94fab9f1 100644
--- a/lib/matrix.rb
+++ b/lib/matrix.rb
@@ -139,8 +139,8 @@ class Matrix
#
#
def Matrix.columns(columns)
- rows = (0 .. columns[0].size - 1).collect {|i|
- (0 .. columns.size - 1).collect {|j|
+ rows = (0 ... columns[0].size).collect {|i|
+ (0 ... columns.size).collect {|j|
columns[j][i]
}
}
@@ -156,7 +156,7 @@ class Matrix
#
def Matrix.diagonal(*values)
size = values.size
- rows = (0 .. size - 1).collect {|j|
+ rows = (0 ... size).collect {|j|
row = Array.new(size).fill(0, 0, size)
row[j] = values[j]
row
@@ -290,11 +290,9 @@ class Matrix
# Returns row vector number +i+ of the matrix as a Vector (starting at 0 like
# an array). When a block is given, the elements of that vector are iterated.
#
- def row(i) # :yield: e
+ def row(i, &block) # :yield: e
if block_given?
- for e in @rows[i]
- yield e
- end
+ @rows[i].each(&block)
else
Vector.elements(@rows[i])
end
@@ -307,11 +305,11 @@ class Matrix
#
def column(j) # :yield: e
if block_given?
- 0.upto(row_size - 1) do |i|
+ row_size.times do |i|
yield @rows[i][j]
end
else
- col = (0 .. row_size - 1).collect {|i|
+ col = (0 ... row_size).collect {|i|
@rows[i][j]
}
Vector.elements(col, false)
@@ -350,10 +348,7 @@ class Matrix
size_col = param[1].end - from_col
size_col += 1 unless param[1].exclude_end?
when 4
- from_row = param[0]
- size_row = param[1]
- from_col = param[2]
- size_col = param[3]
+ from_row, size_row, from_col, size_col = param
else
Matrix.Raise ArgumentError, param.inspect
end
@@ -414,7 +409,7 @@ class Matrix
def compare_by_row_vectors(rows, comparison = :==)
return false unless @rows.size == rows.size
- 0.upto(@rows.size - 1) do |i|
+ @rows.size.times do |i|
return false unless @rows[i].send(comparison, rows[i])
end
true
@@ -432,13 +427,7 @@ class Matrix
# Returns a hash-code for the matrix.
#
def hash
- value = 0
- for row in @rows
- for e in row
- value ^= e.hash
- end
- end
- return value
+ @rows.hash
end
#--
@@ -467,10 +456,10 @@ class Matrix
when Matrix
Matrix.Raise ErrDimensionMismatch if column_size != m.row_size
- rows = (0 .. row_size - 1).collect {|i|
- (0 .. m.column_size - 1).collect {|j|
+ rows = (0 ... row_size).collect {|i|
+ (0 ... m.column_size).collect {|j|
vij = 0
- 0.upto(column_size - 1) do |k|
+ column_size.times do |k|
vij += self[i, k] * m[k, j]
end
vij
@@ -503,8 +492,8 @@ class Matrix
Matrix.Raise 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|
+ rows = (0 ... row_size).collect {|i|
+ (0 ... column_size).collect {|j|
self[i, j] + m[i, j]
}
}
@@ -531,8 +520,8 @@ class Matrix
Matrix.Raise 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|
+ rows = (0 ... row_size).collect {|i|
+ (0 ... column_size).collect {|j|
self[i, j] - m[i, j]
}
}
@@ -578,13 +567,13 @@ class Matrix
# Not for public consumption?
#
def inverse_from(src)
- size = row_size - 1
+ size = row_size
a = src.to_a
- for k in 0..size
+ size.times do |k|
i = k
akk = a[k][k].abs
- ((k+1)..size).each do |j|
+ (k+1 ... size).each do |j|
v = a[j][k].abs
if v > akk
i = j
@@ -598,23 +587,23 @@ class Matrix
end
akk = a[k][k]
- for i in 0 .. size
+ size.times do |i|
next if i == k
q = a[i][k].quo(akk)
a[i][k] = 0
- for j in (k + 1).. size
+ (k + 1 ... size).each do |j|
a[i][j] -= a[k][j] * q
end
- for j in 0..size
+ size.times do |j|
@rows[i][j] -= @rows[k][j] * q
end
end
- for j in (k + 1).. size
+ (k + 1 ... size).each do |j|
a[k][j] = a[k][j].quo(akk)
end
- for j in 0..size
+ size.times do |j|
@rows[k][j] = @rows[k][j].quo(akk)
end
end
@@ -673,12 +662,11 @@ class Matrix
def determinant
return 0 unless square?
- size = row_size - 1
+ size = row_size
a = to_a
det = 1
- k = 0
- loop do
+ size.times do |k|
if (akk = a[k][k]) == 0
i = k
loop do
@@ -690,14 +678,13 @@ class Matrix
det *= -1
end
- for i in k + 1 .. size
+ (k + 1 ... size).each do |i|
q = a[i][k].quo(akk)
- (k + 1).upto(size) do |j|
+ (k + 1 ... size).each do |j|
a[i][j] -= a[k][j] * q
end
end
det *= akk
- break unless (k += 1) <= size
end
det
end
@@ -716,12 +703,11 @@ class Matrix
def determinant_e
return 0 unless square?
- size = row_size - 1
+ size = row_size
a = to_a
det = 1
- k = 0
- loop do
+ size.times do |k|
if a[k][k].zero?
i = k
loop do
@@ -732,9 +718,9 @@ class Matrix
det *= -1
end
- for i in (k + 1)..size
+ (k + 1 ... size).each do |i|
q = a[i][k].quo(a[k][k])
- k.upto(size) do |j|
+ (k ... size).each do |j|
a[i][j] -= a[k][j] * q
end
unless a[i][k].zero?
@@ -744,7 +730,6 @@ class Matrix
end
end
det *= a[k][k]
- break unless (k += 1) <= size
end
det
end
@@ -769,13 +754,12 @@ class Matrix
a_row_size = row_size
end
rank = 0
- k = 0
- begin
+ a_column_size.times do |k|
if (akk = a[k][k]) == 0
i = k
exists = true
loop do
- if (i += 1) > a_column_size - 1
+ if (i += 1) >= a_column_size
exists = false
break
end
@@ -795,7 +779,7 @@ class Matrix
break unless a[k][i] == 0
end
if exists
- k.upto(a_column_size - 1) do |j|
+ (k ... a_column_size).each do |j|
a[j][k], a[j][i] = a[j][i], a[j][k]
end
akk = a[k][k]
@@ -805,14 +789,14 @@ class Matrix
end
end
- for i in (k + 1)..(a_row_size - 1)
+ (k + 1 ... a_row_size).each do |i|
q = a[i][k].quo(akk)
- for j in (k + 1)..(a_column_size - 1)
+ (k + 1... a_column_size).each do |j|
a[i][j] -= a[k][j] * q
end
end
rank += 1
- end while (k += 1) <= a_column_size - 1
+ end
return rank
end
@@ -829,7 +813,7 @@ class Matrix
a_column_size = column_size
a_row_size = row_size
pi = 0
- (0 ... a_column_size).each do |j|
+ a_column_size.times do |j|
if i = (pi ... a_row_size).find{|i0| !a[i0][j].zero?}
if i != pi
a[pi], a[i] = a[i], a[pi]
@@ -858,7 +842,7 @@ class Matrix
#
def trace
tr = 0
- 0.upto(column_size - 1) do |i|
+ column_size.times do |i|
tr += @rows[i][i]
end
tr
@@ -900,27 +884,25 @@ class Matrix
# Returns an array of the row vectors of the matrix. See Vector.
#
def row_vectors
- rows = (0 .. row_size - 1).collect {|i|
+ (0 ... row_size).collect {|i|
row(i)
}
- rows
end
#
# Returns an array of the column vectors of the matrix. See Vector.
#
def column_vectors
- columns = (0 .. column_size - 1).collect {|i|
+ (0 ... column_size).collect {|i|
column(i)
}
- columns
end
#
# Returns an array of arrays that describe the rows of the matrix.
#
def to_a
- @rows.collect{|row| row.collect{|e| e}}
+ @rows.collect{|row| row.dup}
end
def elements_to_f
@@ -1150,7 +1132,7 @@ class Vector
#
def each2(v) # :yield: e1, e2
Vector.Raise ErrDimensionMismatch if size != v.size
- 0.upto(size - 1) do |i|
+ size.times do |i|
yield @elements[i], v[i]
end
end
@@ -1161,7 +1143,7 @@ class Vector
#
def collect2(v) # :yield: e1, e2
Vector.Raise ErrDimensionMismatch if size != v.size
- (0 .. size - 1).collect do |i|
+ (0 ... size).collect do |i|
yield @elements[i], v[i]
end
end
@@ -1284,10 +1266,8 @@ class Vector
#
# Like Array#collect.
#
- def collect # :yield: e
- els = @elements.collect {|v|
- yield v
- }
+ def collect(&block) # :yield: e
+ els = @elements.collect(&block)
Vector.elements(els, false)
end
alias map collect
@@ -1295,10 +1275,8 @@ class Vector
#
# Like Vector#collect2, but returns a Vector instead of an Array.
#
- def map2(v) # :yield: e1, e2
- els = collect2(v) {|v1, v2|
- yield v1, v2
- }
+ def map2(v, &block) # :yield: e1, e2
+ els = collect2(v, &block)
Vector.elements(els, false)
end
@@ -1307,11 +1285,7 @@ class Vector
# Vector[5,8,2].r => 9.643650761
#
def r
- v = 0
- for e in @elements
- v += e*e
- end
- return Math.sqrt(v)
+ Math.sqrt(@elements.inject(0) {|v, e| v + e*e})
end
#--