
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[k1][k1] if k!=0


end


end


det/=a[k1][k1] 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
