SLIP_demo
Date: 2020-05-12

## Contents

- SLIP_DEMO a demo of SLIP_backslash
- SLIP_backslash vs MATLAB backslash: first example
- SLIP_backslash: exact, vs MATLAB backslash: approximate
- SLIP_backslash on ill-conditioned problems
- vpa can find a good but not perfect solution:
- SLIP_backslash computes the exact answer
- SLIP_backslash with exact results
- Converting an exact rational result to vpa or double
- Comparing the VPA and SLIP_BACKSLASH solutions in double

## SLIP_DEMO a demo of SLIP_backslash

SLIP_LU is a package for solving sparse linear systems of equations with a roundoff-free integer-preserving method. The result is always exact, unless the matrix A is perfectly singular.

See also vpa, SLIP_backslash, SLIP_install, SLIP_test.

SLIP_LU: (c) 2019-2020, Chris Lourenco, Jinhao Chen, Erick Moreno-Centeno, Timothy A. Davis, Texas A&M University. All Rights Reserved. See SLIP_LU/License for the license.

    format compact

## SLIP_backslash vs MATLAB backslash: first example

In this first example, x = SLIP_backslash (A,b) returns an approximate solution, but not because it was computed incorrectly in SLIP_backslash. It is computed exactly as a rational result in SLIP_backslash with arbitrary precision, but then converted to double precision on output.

    format long g
    load west0479
    A = west0479 ;
    n = size (A, 1) ;
    xtrue = rand (n,1) ;
    b = A*xtrue ;
    x = SLIP_backslash (A, b) ;
    % error is nonzero: x is computed exactly in rational arbitrary-precision,
    % but then lost precision when returned to MATLAB:
    err_slip = norm (x-xtrue)
    x = A\b ;
    % error is nonzero: MATLAB x=A\b experiences floating-point error
    % throughout its computations:
    err_matlab = norm (x-xtrue)

    err_slip =
          1.04977727546159e-11
    err_matlab =
          4.97118876611495e-11

## SLIP_backslash: exact, vs MATLAB backslash: approximate

In this example, x = SLIP_backslash (A,b) is returned exactly in the MATLAB vector x, because x contains only integers representable exactly in double precision. x = A\b results in floating-point roundoff error.

    amax = max (abs (A), [ ], 'all') ;
    A = floor (2^20 * (A / amax)) + n * speye (n) ;
    xtrue = floor (64 * xtrue) ;
    b = A*xtrue ;
    x = SLIP_backslash (A, b) ;
    % error will be exactly zero:
    err_slip = norm (x-xtrue)
    x = A\b ;
    % error will be small but nonzero:
    err_matlab = norm (x-xtrue)

    err_slip =
         0
    err_matlab =
          1.48961053969038e-10

## SLIP_backslash on ill-conditioned problems

x = SLIP_backslash (A,b) is able to solve problems that x=A\b cannot. Consider the following matrix in the MATLAB gallery:

    [U, b] = gallery ('wilk', 3)

    U =
                         1e-10                       0.9                      -0.4
                             0                       0.9                      -0.4
                             0                         0                     1e-10
    b =
         0
         0
         1

## vpa can find a good but not perfect solution:

    xvpa = vpa (U) \ b

    %     but MATLAB's numerical x = U\b computes a poor solution:
    xapprox = U \ b

    xvpa =
                                     0
     4444444444.4444444444444444444444
                         10000000000.0
    xapprox =
             -2894.21354359042
              4444444444.44444
                   10000000000

## SLIP_backslash computes the exact answer

It returns it to MATLAB as a double vector, obtaining the exact results, except for a final floating-point error in x(2):

    xslip = SLIP_backslash (U, b)
    err = xvpa - xslip
    relerr = double (err (2:3) ./ xvpa (2:3))

    xslip =
                             0
              4444444444.44444
                   10000000000
    err =
                                            0
     0.00000074174669053819444444444514565414
                                            0
    relerr =
          1.66893005371094e-16
                             0

## SLIP_backslash with exact results

SLIP_backslash can also return x as a cell array of strings, which preserves the exact rational result. The printing option is also enabled in this example. The floating-point matrices U and b are converted into a scaled integer matrix before solving U*x=b with SLIP LU.

The value U(1,2)=0.9 is a floating-point number, and 0.9 cannot be exactly represented in IEEE floating-point representation. It is converted exactly into the rational number, fl(0.9) = 45000000000000001 / 50000000000000000.

    option.print = 3 ;          % also print the details
    option.solution = 'char' ;  % return x as a cell array of strings

    xslip = SLIP_backslash (U, b, option)

    Scaled integer input matrix A:
    SLIP_matrix: nrows: 3, ncols: 3, nz:6, nzmax: 6, kind: CSC, type: MPZ
    scale factor: 50000000000000000
    column 0 :
      row 0 : 5000000
    column 1 :
      row 0 : 45000000000000001
      row 1 : 45000000000000001
    column 2 :
      row 0 : -20000000000000001
      row 1 : -20000000000000001
      row 2 : 5000000

    Scaled integer right-hand-side b:
    SLIP_matrix: nrows: 3, ncols: 1, nz:3, nzmax: 3, kind: Dense, type: MPZ
    scale factor: 1
    column 0 :
      row 0 : 0
      row 1 : 0
      row 2 : 1

    ****Column Ordering Information****

    Estimated L and U nonzeros: 60

    Solution x:
    SLIP_matrix: nrows: 3, ncols: 1, nz:3, nzmax: 3, kind: Dense, type: MPQ
    scale factor: 1
    column 0 :
      row 0 : 0
      row 1 : 200000000000000010000000000/45000000000000001
      row 2 : 10000000000
    xslip =
      3×1 cell array
        {'0'                                            }
        {'200000000000000010000000000/45000000000000001'}
        {'10000000000'                                  }

## Converting an exact rational result to vpa or double

If SLIP_backslash returns x as a cell array of strings, it cannot be immediately used in computations in MATLAB. It can be converted into a vpa or double matrix, as illustrated below. The solution differs slightly from the vpa solution xvpa = vpa (U)\b, since the MATLAB vpa converts fl(0.9) into a decimal representation 0.9, or exactly 9/10; this is not exactly equal to fl(0.9), since the value 9/10 is not representable in IEEE floating-point. SLIP_backslash, by contrast, converts fl(0.9) into its exact rational representation, 45000000000000001 / 50000000000000000.

    xslip_as_vpa = vpa (xslip)
    xslip_as_double = double (vpa (xslip))
    xvpa_as_double = double (xvpa)

    xslip_as_vpa =
                                     0
     4444444444.4444445679012345679012
                         10000000000.0
    xslip_as_double =
                             0
              4444444444.44444
                   10000000000
    xvpa_as_double =
                             0
              4444444444.44444
                   10000000000

## Comparing the VPA and SLIP_BACKSLASH solutions in double

Both vpa(U)\b and SLIP_backslash(U,b) compute the same result in the end, when their results are converted to double.

    err = xvpa_as_double - xslip_as_double

    err =
         0
         0
         0