Skip to content

Commit d8a43ff

Browse files
committed
Fix gauss-jordan bug.
Patch submission from Martin Ossmann.
1 parent 8dd7aa2 commit d8a43ff

File tree

6 files changed

+46
-35
lines changed

6 files changed

+46
-35
lines changed

README.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ luamatrix").
1717

1818
http://lua-users.org/wiki/LuaMatrix
1919

20+
== Credits ==
21+
22+
Authors: Michael Lutz (original author), David Manura (maintainer).
23+
Bug fixes/comments: Geoff Richards, SatheeshJM, Martin Ossmann,
24+
and others.
25+
2026
== License ==
2127

2228
See the LICENSE.txt file for licensing details.

dist.info

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
--- This file is part of LuaDist project
22

33
name = "lua-matrix"
4-
version = "0.2.10"
4+
version = "0.2.11.20120416"
55

66
desc = "'LuaMatrix' provides a good selection of matrix functions."
77
author = "Michael Lutz, David Manura"

doc/fit_changelog.txt

Lines changed: 0 additions & 7 deletions
This file was deleted.

doc/matrix_changelog.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
matrix changelog
22

3-
v 0.2.10
3+
v 0.2.11.20120416
4+
- Gauss-Jordan bug fix. Also affects matrix inverse.
5+
6+
v 0.2.10.20111203
47
- Add _VERSION to modules.
58

69
v 0.2.9: 2008-08-26

lua/matrix.lua

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ LICENSE
114114
--// matrix //
115115
--////////////
116116

117-
local matrix = {_TYPE='module', _NAME='matrix', _VERSION='0.2.10.20111203'}
117+
local matrix = {_TYPE='module', _NAME='matrix', _VERSION='0.2.11.20120416'}
118118

119119
-- access to the metatable we set at the end of the file
120120
local matrix_meta = {}
@@ -416,35 +416,29 @@ end
416416
-- returns on failure: false,'rank of matrix'
417417

418418
-- locals
419-
-- checking here for the nearest element to 1 or -1; (smallest pivot element)
420-
-- this way the factor of the evolving number division should be > 1 or the
421-
-- divided number itself, what gives better results
422-
local setelementtosmallest = function( mtx,i,j,zero,one,norm2 )
423-
-- check if element is one
424-
if mtx[i][j] == one then return true end
425-
-- check for lowest value
426-
local _ilow
419+
-- checking here for the element nearest but not equal to zero (smallest pivot element).
420+
-- This way the `factor` in `dogauss` will be >= 1, which
421+
-- can give better results.
422+
local pivotOk = function( mtx,i,j,norm2 )
423+
-- find min value
424+
local iMin
425+
local normMin = math.huge
427426
for _i = i,#mtx do
428427
local e = mtx[_i][j]
429-
if e == one then
430-
break
431-
end
432-
if not _ilow then
433-
if e ~= zero then
434-
_ilow = _i
428+
local norm = math.abs(norm2(e))
429+
if norm > 0 and norm < normMin then
430+
iMin = _i
431+
normMin = norm
435432
end
436-
elseif (e ~= zero) and math.abs(norm2(e)-1) < math.abs(norm2(mtx[_ilow][j])-1) then
437-
_ilow = _i
438433
end
439-
end
440-
if _ilow then
441-
-- switch lines if not input line
442-
-- legal operation
443-
if _ilow ~= i then
444-
mtx[i],mtx[_ilow] = mtx[_ilow],mtx[i]
434+
if iMin then
435+
-- switch lines if not in position.
436+
if iMin ~= i then
437+
mtx[i],mtx[iMin] = mtx[iMin],mtx[i]
445438
end
446439
return true
447-
end
440+
end
441+
return false
448442
end
449443

450444
local function copy(x)
@@ -463,7 +457,7 @@ function matrix.dogauss( mtx )
463457
-- stairs left -> right
464458
for j = 1,rows do
465459
-- check if element can be setted to one
466-
if setelementtosmallest( mtx,j,j,zero,one,norm2 ) then
460+
if pivotOk( mtx,j,j,norm2 ) then
467461
-- start parsing rows
468462
for i = j+1,rows do
469463
-- check if element is not already zero
@@ -540,7 +534,7 @@ function matrix.invert( m1 )
540534
end
541535

542536
--// matrix.sqrt ( m1 [,iters] )
543-
-- calculate the square root of a matrix using "Denman–Beavers square root iteration"
537+
-- calculate the square root of a matrix using "Denman Beavers square root iteration"
544538
-- condition: matrix rows == matrix columns; must have a invers matrix and a square root
545539
-- if called without additional arguments, the function finds the first nearest square root to
546540
-- input matrix, there are others but the error between them is very small

test/test_matrix.lua

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,21 @@ mtxinvcomp = matrix( mtxinvcomp )
135135
mtxinv:round( 5 )
136136
mtxinv = mtxinv:elementstostrings()
137137
assert( mtxinvcomp == mtxinv )
138+
-- Fixed in v0.2.11 failed (Gauss-Jordan)
139+
local mtx = matrix {{ 1, -1, 1 }, {-1, 1, 0 }, { 1, 0, 0 } }
140+
assert((mtx^-1)^-1 == mtx)
141+
-- Fixed in v0.2.11 failed (Gauss-Jordan)
142+
local mtx = matrix {{ 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 } }
143+
assert((mtx^-1)^-1 == mtx)
144+
-- similar to above but with complex
145+
local mtx = matrix.replace({{ 0, 0, "1i" }, { 0, "1i", 0 }, { "1i", 0, 0 } }, complex)
146+
assert((mtx^-1)^-1 == mtx)
147+
-- random
148+
for i=1,10 do
149+
local mtx = matrix(4, 4):random(-20, 20, 5)
150+
assert(matrix.normmax((mtx^-1)^-1 - mtx) < 1E-13)
151+
end
152+
138153

139154
-- matrix.sqrt; number
140155
local m1 = matrix{{4,2,1},{1,5,4},{1,5,2}}

0 commit comments

Comments
 (0)