Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changed Pivot to Use Max #5

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions lua/matrix.lua
Original file line number Diff line number Diff line change
Expand Up @@ -415,30 +415,37 @@ end
-- returns on success: true,
-- returns on failure: false,'rank of matrix'


-- locals
-- checking here for the element nearest but not equal to zero (smallest pivot element).
-- This way the `factor` in `dogauss` will be >= 1, which
-- can give better results.
-- perform an in-place pivot on the given matrix, if possible,
-- returning whether or not a pivot was done

-- we choose the pivot element by checking for the largest element in a column,
-- with an index greater than a specified starting point
-- mtx - the matrix to pivot
-- i - the row to start scan for pivot on
-- j - the column to scan for a pivot in
-- norm2 - a function which gives the square of the norm for a matrix element
local pivotOk = function( mtx,i,j,norm2 )
-- find min value
local iMin
local normMin = math.huge
-- find max value
local iMax
local normMax = 0
for _i = i,#mtx do
local e = mtx[_i][j]
local norm = math.abs(norm2(e))
if norm > 0 and norm < normMin then
iMin = _i
normMin = norm
if norm > normMax then
iMax = _i
normMax = norm
end
end
if iMin then
-- switch lines if not in position.
if iMin ~= i then
mtx[i],mtx[iMin] = mtx[iMin],mtx[i]
if iMax then
-- switch rows, if not in position.
if iMax ~= i then
mtx[i],mtx[iMax] = mtx[iMax],mtx[i]
end
return true
end
return false
end
return false -- column was all zeros below pivot
end

local function copy(x)
Expand Down
23 changes: 20 additions & 3 deletions test/test_matrix.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@ local symbol = matrix.symbol

local mtx, m1,m2,m3,m4,m5, ms,ms1,ms2,ms3,ms4

-- compare matrices of floats using epsilon = 1e-9
-- not perfect, but better than '=='
-- improvements can be found here: http://stackoverflow.com/a/3423299/74291
function matrix.fcompare(m1, m2)
local eps = 0.000000001
mtx = {}
for i = 1,#m1 do
mtx[i] = {}
for j = 1,#m1[1] do
if math.abs(m1[i][j] - m2[i][j]) > eps then
return false
end
end
end
return true
end

-- test matrix:new/matrix call function
-- normal matrix
mtx = matrix {{1,2},{3,4}}
Expand Down Expand Up @@ -72,7 +89,7 @@ assert( m1*m2^-1 == m1/m2 )
m2 = matrix {{4,5},{6,7}}
assert( m2/2 == matrix{{2,2.5},{3,3.5}} )
mtx = matrix {{3,5,1},{2,4,5},{1,2,2}}
assert( 2 / mtx == matrix{{4,16,-42},{-2,-10,26},{0,2,-4}} )
assert( matrix.fcompare( 2 / mtx, matrix{{4,16,-42},{-2,-10,26},{0,2,-4}} ) )
-- matrix.mulnum; symbol
m1 = m1:replace(symbol)
assert( m1*2 == matrix{{"(1)*(2)","(2)*(2)"},{"(3)*(2)","(4)*(2)"}}:replace(symbol) )
Expand Down Expand Up @@ -114,11 +131,11 @@ assert( mtx:det():round(10) == complex "5527+2687i" )
--1
mtx = matrix{{3,5,1},{2,4,5},{1,2,2}}
local mtxinv = matrix{{2,8,-21},{-1,-5,13},{0,1,-2}}
assert( mtx^-1 == mtxinv )
assert( matrix.fcompare( mtx^-1, mtxinv) )
--2
mtx = matrix{{1,0,2},{4,1,1},{3,2,-7}}
local mtxinv = matrix{{-9,4,-2},{31,-13,7},{5,-2,1}}
assert( mtx^-1 == mtxinv )
assert( matrix.fcompare( mtx^-1, mtxinv) )
-- matrix.invert; complex
mtx = {
{ 3,"4-3i",1},
Expand Down