diff options
Diffstat (limited to 'ipl/procs/matrix.icn')
-rw-r--r-- | ipl/procs/matrix.icn | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/ipl/procs/matrix.icn b/ipl/procs/matrix.icn new file mode 100644 index 0000000..48007c4 --- /dev/null +++ b/ipl/procs/matrix.icn @@ -0,0 +1,183 @@ +############################################################################ +# +# File: matrix.icn +# +# Subject: Procedures for matrix manipulation +# +# Authors: Stephen B. Wampler and Ralph E. Griswold +# +# Date: December 2, 2000 +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ +# +# This file contains procedures for matrix manipulation. +# +############################################################################ +# +# Links: lu +# +############################################################################ + +link lu + +procedure matrix_width(M) + + return *M[1] + +end + +procedure matrix_height(M) + + return *M + +end + +procedure write_matrix(file, M, x, s) + local r, c, row, col + + r := matrix_height(M) + c := matrix_width(M) + + if /x then { # packed, no punctuation + every row := 1 to r do { + every col := 1 to c do { + writes(file, M[row][col], s) + } + write(file) + } + } + else { + every row := 1 to r do { + writes(file, "[") + every col := 1 to c do { + writes(file, M[row][col], ", ") + } + write(file, "]") + } + } + +end + +procedure copy_matrix(M) + local M1, n, i + + n := *M + + M1 := list(n) + + every i := 1 to n do + M1[i] := copy(M[i]) + + return M1 + +end + +procedure create_matrix(n, m, x) + local M + + M := list(n) + every !M := list(m, x) + + return M + +end + +procedure identity_matrix(n, m) + local r, c, M + + M := create_matrix(n, m, 0) + + every r := 1 to n do { + every c := 1 to m do { + if r = c then M[r][c] := 1 + } + } + + return M + +end + +procedure add_matrix(M1, M2) + local M3, r, c, n, m + + if ((n := *M1) ~= *M2) | ((m := *M1[1]) ~= *M2[1]) then + stop("*** incorrect matrix sizes") + + M3 := create_matrix(n, m) + + every r := 1 to n do + every c := 1 to m do + M3[r][c] := M1[r][c] + M2[r][c] + + return M3 + +end + +procedure mult_matrix(M1, M2) + local M3, r, c, n, k + + if (n := *M1[1]) ~= *M2 then stop("*** incorrect matrix sizes") + + M3 := create_matrix(*M1,*M2[1]) + every r := 1 to *M1 do { + every c := 1 to *M2[1] do { + M3[r][c] := 0 + every k := 1 to n do { + M3[r][c] +:= M1[r][k] * M2[k][c] + } + } + } + + return M3 + +end + +procedure invert_matrix(M) + local M1, Y, I, d, i, n, B, j + + n := *M + if n ~= *M[1] then stop("*** matrix not square") + + M1 := copy_matrix(M) + Y := identity_matrix(n, n) + I := list(n, 0) # index vector + +# First perform LH decomposition on M1 (which changes it and produces +# an index vector, I. + + d := lu_decomp(M1, I) | stop("*** singular matrix") + + every j := 1 to n do { + B := list(n) # work on columns + every i := 1 to n do + B[i] := Y[i][j] + lu_back_sub(M1, I, B) # does not change M1 or I + every i := 1 to n do # put column in result + Y[i][j] := B[i] + } + + return Y + +end + +procedure determinant(M) + local M1, I, result, i, n + + n := *M + if n ~= *M[1] then stop("*** matrix not square") + + M1 := copy_matrix(M) + I := list(n, 0) # not used but required by lu_decomp() + + result := lu_decomp(M1, I) | stop("*** singular matrix") + + every i := 1 to n do # determinant is produce of diagonal + result *:= M1[i][i] # elements of the decomposed matrix + + return result + +end |