-
#!/usr/bin/env lua
-
-
function Matrix(data,row,column)
-
local size=table.maxn(data)
-
assert(size==row*column)
-
-
local matrix={}
-
matrix.data=data
-
matrix.row=row
-
matrix.column=column
-
-
matrix.at=function(this,row,column)
-
return this.data[(row-1)*this.column+column]
-
end
-
-
matrix.set=function(this,row,column,num)
-
this.data[(row-1)*this.column+column]=num
-
end
-
-
matrix.swaprow=function(this,r1,r2)
-
local temp
-
for i=1,this.column do
-
temp=this:at(r1,i)
-
this:set(r1,i,this:at(r2,i))
-
this:set(r2,i,temp)
-
end
-
end
-
-
matrix.simplifycolumn=function(this,column,layer)
-
if this:at(layer,column) == 0 then
-
for i=layer+1,this.row do
-
if this:at(i,column) ~= 0 then
-
this:swaprow(i,layer)
-
break
-
end
-
end
-
end
-
-
if this:at(layer,column) == 0 then
-
return layer
-
end
-
-
for i=1,this.row do
-
if i~= layer then
-
local tomultiply=-this:at(i,column)/this:at(layer,column)
-
for j=1,this.column do
-
this:set(i,j,this:at(layer,j)*tomultiply+this:at(i,j))
-
end
-
end
-
end
-
-
return layer+1
-
end
-
-
matrix.swapcolumn=function(this,c1,c2)
-
local temp
-
for i=1,this.row do
-
temp=this:at(i,c1)
-
this:set(i,c1,this:at(i,c2))
-
this:set(i,c2,temp)
-
end
-
end
-
-
matrix.simplifyrow=function(this,row,layer)
-
if this:at(row,layer) == 0 then
-
for i=layer+1,this.column do
-
if this:at(row,i) ~= 0 then
-
this:swapcolumn(i,layer)
-
break
-
end
-
end
-
end
-
-
if this:at(row,layer) == 0 then
-
return layer
-
end
-
-
for i=1,this.column do
-
if i ~= layer then
-
local tomultiply=-this:at(row,i)/this:at(row,layer)
-
for j=1,this.row do
-
this:set(j,i,this:at(j,layer)*tomultiply+this:at(j,i))
-
end
-
end
-
end
-
-
return layer+1
-
end
-
-
-- Make the matrix to reduced form
-
matrix.reduce=function(this)
-
local layer=1
-
for i=1,this.column do
-
layer=this:simplifycolumn(i,layer)
-
if layer>this.row then
-
break
-
end
-
end
-
-
-
for i=1,this.row do
-
local tomultiply=nil
-
for j=1,this.column do
-
if tomultiply then
-
this:set(i,j,this:at(i,j)*tomultiply)
-
elseif this:at(i,j)~= 0 then
-
tomultiply=1/this:at(i,j)
-
this:set(i,j,1)
-
end
-
end
-
end
-
end
-
-
-- Make the matrix to canonical form
-
matrix.canonicalize=function(this)
-
this:reduce()
-
local layer=1
-
for i=1,this.row do
-
layer=this:simplifyrow(i,layer)
-
if layer>this.column then
-
break
-
end
-
end
-
end
-
-
-- Get the rank of the matrix
-
-- Matrix should be reduced before.
-
matrix.rank=function(this)
-
local rank=0
-
for i=1,this.row do
-
for j=1,this.column do
-
if this:at(i,j) ~= 0 then
-
rank=rank+1
-
break
-
end
-
end
-
end
-
-
return rank
-
end
-
-
matrix.print=function(this)
-
for i=1,this.row do
-
for j=1,this.column do
-
io.write(this:at(i,j),'\t')
-
end
-
io.write('\n')
-
end
-
end
-
-
return matrix
-
end