1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/matrix.rb: trivial optimizations

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24947 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
marcandre 2009-09-16 04:36:37 +00:00
parent af424b17a0
commit 9d3638448e
2 changed files with 55 additions and 77 deletions

View file

@ -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.

View file

@ -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
#--