' ******************************************************************
' Solution of a system of linear equations with
' multiple constant vectors by Gauss-Jordan method
' ******************************************************************
' The algorithm is applied to a matrix A(n x m) such that:
'
' On input:
'   * The first n columns of A contain the system matrix
'   * The other column(s) contain the constant vector(s)
'
' On output:
'   * The first n columns of A contain the inverse matrix
'   * The other column(s) contain the solution vector(s)
'   * The determinant of the system matrix is returned in Det
'
' Function MathErr can be called to check the error code:
'   * MatOk     = no error
'   * MatErrDim = non-compatible dimensions (n < m)
'   * MatSing   = quasi-singular matrix (Det ~ 0)
' ******************************************************************

#INCLUDE "fbmath.bi"

SUB PrintMatrix(Title AS STRING, A() AS DOUBLE,_
                Col1 AS INTEGER, Col2 AS INTEGER)
' ------------------------------------------------------------------
' Print columns Col1 to Col2 of matrix A
' ------------------------------------------------------------------

  DIM AS INTEGER I, J

  PRINT : PRINT Title : PRINT

  FOR I = 1 TO UBOUND(A, 1)
    FOR J = Col1 TO Col2
      PRINT USING "#####.######"; A(I,J);
    NEXT J
    PRINT
  NEXT I
END SUB

CONST N = 4, M = 9  ' Size of matrix

DIM AS DOUBLE A(1 TO N, 1 TO M) = _
{{ 2,  1,   5, -8,   0, -15,  14, -13,   5}, _
 { 7,  6,   2,  2,  17,  50,   1,  84,  30}, _
 {-1, -3, -10,  4, -10,  -5, -12, -51, -15}, _
 { 2,  2,   2,  1,   7,  17,   1,  37,  10}}
' ---------------  -----------------------
'  System matrix       Constant vectors


DIM AS DOUBLE Det ' Determinant

CLS

PrintMatrix "System matrix:", A(), 1, N
PrintMatrix "Constant vectors:", A(), N + 1, M

GaussJordan A(), Det

SELECT CASE MathErr()
  CASE MatOk
    PrintMatrix "Inverse matrix:", A(), 1, N
    PrintMatrix "Solution vectors:", A(), N + 1, M
    PRINT : PRINT USING "Determinant = #####.######"; Det
  CASE MatErrDim
    PRINT "Non-compatible dimensions!"
  CASE MatSing
    PRINT "Quasi-singular matrix!"
END SELECT

SLEEP
