Basics of Rlinsolve

Vignette Author

2017-09-28

Rlinsolve

Rlinsolve is a collection of iterative solvers for (sparse) linear system of equations. It heavily relies on two popular packages, RcppArmadillo for speeding up computation and Matrix for sparse matrix support.

Solving Ax=b

Introducing RcppArmadillo simply added computational boost. Let’s check by comparing with some basic approaches.

and simulate 10000 x 500 system matrix for normal equation form.

A = matrix(rnorm(10000*50),nrow=10000)
x = matrix(rnorm(50))
b = A%*%x

First example is to use a default solve function from R base.

# for SOLVE in R base, it needs to be transformed into normal equation form.
Anormal = t(A)%*%A
bnormal = t(A)%*%b
microbenchmark(solve(Anormal,bnormal))
## Unit: microseconds
##                     expr    min      lq     mean  median      uq     max
##  solve(Anormal, bnormal) 75.297 76.0715 81.21024 76.4845 77.1555 443.356
##  neval
##    100

Let’s compare other available packages(pcg and optR) and their computation time,

microbenchmark(pcg(Anormal,bnormal),
               optR(A,b,method="gauss"),
               times=10)
## Unit: microseconds
##                          expr        min         lq       mean     median
##         pcg(Anormal, bnormal)    176.393    197.616   1684.421    210.376
##  optR(A, b, method = "gauss") 135359.688 135852.412 160230.685 136611.512
##          uq       max neval
##     238.435  14805.32    10
##  144393.710 276537.06    10

Finally, let’s test two functions in our package, lsolve.bicgstab and lsolve.sor,

microbenchmark(lsolve.sor(A,b,verbose=FALSE),
               lsolve.bicgstab(A,b,verbose=FALSE),
               times=10)
## Unit: milliseconds
##                                    expr      min       lq     mean
##       lsolve.sor(A, b, verbose = FALSE) 26.21710 27.14054 39.49382
##  lsolve.bicgstab(A, b, verbose = FALSE) 26.71988 27.49502 31.83477
##    median       uq       max neval
##  27.87296 30.05976 101.44159    10
##  27.85354 28.14653  68.45279    10

where we can witness that our codes are definitely faster by at least several folds.

Solving Ax=b with sparse A

We have an auxiliary function to generate sparse system matrix, aux.fisch, and let’s make a 100 x 100 sparse matrix, and corresponding system.

Psparse = aux.fisch(10,sparse=TRUE) # sparse matrix
Pdense = aux.fisch(10,sparse=FALSE) # dense  matrix
x = matrix(rnorm(100))
b = Pdense %*% x

Again, we perform the test from previously used functions from other packages as well as functions in Rdimtools package,

microbenchmark(solve(Pdense,b),
               optR(Pdense,b,method="gauss"),
               pcg(Pdense,b),
               times=10)
## Unit: microseconds
##                               expr       min        lq       mean
##                   solve(Pdense, b)   283.198   290.888   329.1776
##  optR(Pdense, b, method = "gauss") 72135.468 73038.835 75592.4082
##                     pcg(Pdense, b)   933.511   969.669  1032.7257
##      median        uq       max neval
##    323.8145   362.320   413.387    10
##  74830.3290 78222.845 80787.320    10
##    998.1805  1047.926  1354.509    10
microbenchmark(lsolve.bicg(Psparse,b,verbose=FALSE),
               lsolve.cgs(Psparse,b,verbose=FALSE),
               lsolve.gs(Psparse,b,verbose=FALSE),
               lsolve.sor(Psparse,b,verbose=FALSE),
               times=10)
## Unit: milliseconds
##                                      expr      min       lq     mean
##  lsolve.bicg(Psparse, b, verbose = FALSE) 20.78553 21.51531 26.53134
##   lsolve.cgs(Psparse, b, verbose = FALSE) 16.83871 17.30754 22.38803
##    lsolve.gs(Psparse, b, verbose = FALSE) 19.01142 31.26858 39.28202
##   lsolve.sor(Psparse, b, verbose = FALSE) 16.36028 27.79556 30.34358
##    median       uq      max neval
##  22.12720 22.95007 66.70662    10
##  17.45886 19.57789 63.03436    10
##  32.95994 34.44790 78.12849    10
##  31.61104 35.10524 38.86998    10

where in our case, supporting sparse matrices have shown much superior results. Note that the size has been set to be small since dense solvers are too slow to be manageably visible.