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:
parent
af424b17a0
commit
9d3638448e
2 changed files with 55 additions and 77 deletions
|
@ -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.
|
||||
|
|
128
lib/matrix.rb
128
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
|
||||
|
||||
#--
|
||||
|
|
Loading…
Reference in a new issue