## Feature #2772 » bareiss_test.rb

 require 'matrix' class Matrix def det_bareiss Matrix.Raise ErrDimensionMismatch unless square? size = row_size last = row_size - 1 a = to_a det = 1 last_akk = 1 size.times do |k| if (akk = a[k][k]) == 0 i = (k+1 ... size).find {|ii| a[ii][k] != 0 } return 0 if i.nil? a[i], a[k] = a[k], a[i] akk = a[k][k] det = -det end (k+1).upto(last) do |ii| last.downto(k) do |j| a[ii][j] = (akk * a[ii][j] - a[ii][k] * a[k][j]) / last_akk end end det = det / last_akk * akk last_akk = akk end det end def det_b raise '!error: not square!' unless square? n=row_size a=to_a (0...n).inject(1) do |det,k| i=a.transpose[k].slice(k...n).index{|e| e!=0} return 0 if i.nil? #not full ranked if i!=0 then a[k],a[k+i]=a[k+i],a[k] det*=-1 end for i in (k+1)...n for j in (k...n).to_a.reverse a[i][j]=a[k][k]*a[i][j]-a[i][k]*a[k][j] a[i][j]/=a[k-1][k-1] if k!=0 end end det/=a[k-1][k-1] if k!=0 det*a[k][k] end end end class Matrix # # Creates a matrix of +row_size+ x +column_size+. # It fills the values by calling the given block, # passing the current row and column. # # 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 self.build(row_size, column_size = row_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 end # require 'benchmark' # # n = 5 # sz = 44 # methods = [ # :det, # # :det_b, # :det_bareiss # ] # # types = { # Fixnum => 100, # # Bignum => 2 << 80, # Float => nil # } # # res = [] # Benchmark.bmbm do |x| # types.each do |mode, r| # matrices = n.times.map do # Matrix.build(sz) { rand(r) } # end # methods.each do |test| # x.report("#{mode}: #{test}") { res << matrices.map(&test) } # end # end # end
(2-2/3)