import macros, strutils import strfmt type Matrix[M, N: static int] = array[1..M, array[1..N, float]] SquareMatrix[N: static int] = Matrix[N, N] # Templates to allow to use more natural notation for indexing. template `[]`(m: Matrix; i, j: int): float = m[i][j] template `[]=`(m: Matrix; i, j: int; val: float) = m[i][j] = val func `*`[M, N, P: static int](a: Matrix[M, N]; b: Matrix[N, P]): Matrix[M, P] = ## Matrix multiplication. for i in 1..M: for j in 1..P: for k in 1..N: result[i, j] += a[i, k] * b[k, j] func pivotize[N: static int](m: SquareMatrix[N]): SquareMatrix[N] = for i in 1..N: result[i, i] = 1 for i in 1..N: var max = m[i, i] var row = i for j in i..N: if m[j, i] > max: max = m[j, i] row = j if i != row: swap result[i], result[row] func lu[N: static int](m: SquareMatrix[N]): tuple[l, u, p: SquareMatrix[N]] = result.p = m.pivotize() let m2 = result.p * m for j in 1..N: result.l[j, j] = 1 for i in 1..j: var sum = 0.0 for k in 1..