[pure-lang-svn] SF.net SVN: pure-lang:[851] pure/trunk
Status: Beta
Brought to you by:
agraef
From: <ag...@us...> - 2008-09-25 00:55:21
|
Revision: 851 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=851&view=rev Author: agraef Date: 2008-09-25 00:55:11 +0000 (Thu, 25 Sep 2008) Log Message: ----------- Add Gaussian elimination example. Modified Paths: -------------- pure/trunk/NEWS Added Paths: ----------- pure/trunk/examples/gauss.pure Modified: pure/trunk/NEWS =================================================================== --- pure/trunk/NEWS 2008-09-25 00:54:30 UTC (rev 850) +++ pure/trunk/NEWS 2008-09-25 00:55:11 UTC (rev 851) @@ -78,7 +78,7 @@ - #x total number of elements - dim x number of rows and columns (as a pair) -- x' transposed matrix +- x' transpose of a matrix - x!i ith matrix element in row-major order (zero-based) - x!(i,j) jth element in ith row of the matrix (zero-based) - x!!is, x!!(is,js) slicing (is and js are lists of machine ints) Added: pure/trunk/examples/gauss.pure =================================================================== --- pure/trunk/examples/gauss.pure (rev 0) +++ pure/trunk/examples/gauss.pure 2008-09-25 00:55:11 UTC (rev 851) @@ -0,0 +1,69 @@ + +/* Pure matrix example: Gaussian elimination algorithm. 2008-09-25 AG */ + +/* The Gaussian elimination algorithm brings a matrix into row echelon form, + which makes it possible to solve the original system of linear equations + using back substitution. Our version of the algorithm just returns the row + echelon form of the matrix, along with the corresponding permutation of the + row indices performed during pivoting. */ + +gauss_elimination x::matrix = p,x +when n,m = dim x; p,_,x = foldl step (0..n-1,0,x) (0..m-1) end; + +/* The elimination step. x is our matrix, i the current row index, j the + current column index, and p keeps track of the current permutation of the + row indices performed during pivoting. The algorithm returns the updated + matrix x, row index i and row permutation p. */ + +/* Here is a brief rundown of the algorithm: First we find the pivot element + in column j of the matrix. (We're doing partial pivoting here, i.e., we + only look for the pivot in column j, starting at row i.) If the pivot is + zero then we're done (the pivot column is already zeroed out). Otherwise, + we bring it into the pivot position (swapping row i and the pivot row), + divide the picot row by the pivot, and subtract suitable multiples of the + pivot row to eliminate the pivot column in all subsequent rows. Finally we + update i and p accordingly and return the result. */ + +step (p,i,x) j += if max_x>0 then + // updated row permutation and index: + transp i max_i p, i+1, + {// the top rows of the matrix remain unchanged: + x!!(0..i-1,0..m-1); + // the pivot row, divided by the pivot: + {x!(i,l)/x!(i,j) | l=0..m-1}; + // subtract suitable multiples of the pivot row: + {x!(k,l)-x!(k,j)*x!(i,l)/x!(i,j) | k=i+1..n-1; l=0..m-1}} + else p,i,x +when + n,m = dim x; max_i, max_x = pivot i (col x j); + x = if max_x>0 then swap x i max_i else x; +end with + pivot i x = foldl max (0,0) [j,abs (x!j)|j=i..#x-1]; + max (i,x) (j,y) = if x<y then j,y else i,x; +end; + +/* Swap rows i and j of the matrix x. This operation is used in the partial + pivoting step. (This is not really needed because we could just index the + rows indirectly through the row permutation readily available in our + implementation of the algorithm, but we omitted this here for clarity.) */ + +swap x i j = x!!(transp i j (0..n-1),0..m-1) when n,m = dim x end; + +/* A little helper function to apply a transposition to a permutation. */ + +transp i j p = [p!tr k | k=0..#p-1] +with tr k = if k==i then j else if k==j then i else k end; + +/* For convenience, print a double matrix in "short" format a la Octave. */ + +using system; +__show__ x::matrix += strcat [printd j (x!(i,j))|i=0..n-1; j=0..m-1] + "\n" +with printd 0 = sprintf "\n%10.5f"; printd _ = sprintf "%10.5f" end +when n,m = dim x end if dmatrixp x; + +/* Example: */ + +let x = dmatrix {2,1,-1,8; -3,-1,2,-11; -2,1,2,-3}; +x; gauss_elimination x; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |