These are the beginnings of a set of interfaces to HSL packages for sparse linear algebra.
Certain HSL packages are freely available to all, others are freely available to academics only. Please refer to the website above for licensing information. In all cases, users are responsible for obtaining HSL packages.
There are two parts to installing HSL.jl:
First, we need to install the Julia package:
import Pkg
Pkg.add("HSL")
Second, we need to install the various HSL linear solvers.
As a first step, download the appropriate source archives from HSL.
Store these in a directory such as ~/Downloads/hsl
. Next, set the
HSL_ARCHIVES_PATH
environment variable, and call Pkg.build
:
# Replace the path as appropriate
ENV["HSL_ARCHIVES_PATH"] = "~/Downloads/hsl"
import Pkg
Pkg.build("HSL")
Pkg.test("HSL") # If needed
- Make sure that there isn't a stray METIS library on your library path. You
especially want to make sure that METIS 5 is not accessible because the HSL
libraries support only METIS 4. If you have such library accessible, it is
important to remove it from the library path, at least temporarily. For
example, if you are on OSX and are using Homebrew, you can hide METIS 5 with
brew unlink metis
. After the install procedure is complete, it is fine to linkmetis
again withbrew link metis
. - C and Fortran compilers are required. Should it be necessary, you can set the
compilers to use by setting the environment variables
HSL_FC
: the Fortran 90/95 compiler (default:gfortran
)HSL_F77
: the Fortran 77 compiler (default: the same asFC
)HSL_CC
: the C compiler (default:gcc
).
- If archives are stored in different folders, you can also set the environment
variable
<ALGNAME>_PATH
, e.g.HSL_MA57_PATH
orMC21_PATH
, instead of a singleHSL_ARCHIVES_PATH
. - You can use the
zip
archives as long asunzip
is installed on your system.
Supported versions:
- 2.6.0
- 2.7.0
HSL_MA97: an OpenMP-based direct solver for symmetric linear systems. Example:
using MatrixMarket
using HSL
K = MatrixMarket.mmread("K.mtx") # only the lower triangle
rhs = readdlm("rhs.rhs")
LBL = Ma97(K)
ma97_factorize!(LBL)
x = ma97_solve(LBL, rhs) # or x = LBL \ rhs
There is a convenience interface to solve rectangular systems that complements the sparse QR factorization in Julia.
When A is m-by-n with m < n and has full row rank,
(x, y) = ma97_solve(A, b)
solves for the minimum-norm solution, i.e., x such that Ax = b and x + Aᵀ y = 0. The call
(x, y) = ma97_min_norm(A, b)
is also defined, and is equivalent to the above.
When m > n and has full column rank,
(r, x) = ma97_solve(A, b)
solves for the least-squares solution, i.e., x such that r = b - Ax satisfies Aᵀ r = 0. The call
(r, x) = ma97_least_squares(A, b)
is also defined, and is equivalent to the above.
HSL_MA57 version 5.2.0: a sparse, multifrontal solver for symmetric linear systems. Example:
using MatrixMarket
using HSL
K = MatrixMarket.mmread("examples/K_0.mtx") # only the lower triangle
rhs = readdlm("examples/rhs_0.rhs")
rhss = hcat(rhs, rhs)
## factorize and solve
LDL = Ma57(K)
ma57_factorize!(LDL)
LDL.info.rank
x = ma57_solve(LDL, rhs) # or x = LBL \ rhs
norm(K*x - rhs)
xx = ma57_solve(LDL, rhss) # or x = LBL \ rhss
There is a convenience interface to solve rectangular systems that complements the sparse QR factorization in Julia.
When A is m-by-n with m < n and has full row rank,
(x, y) = ma57_solve(A, b)
solves for the minimum-norm solution, i.e., x such that Ax = b and x + Aᵀ y = 0. The call
(x, y) = ma57_min_norm(A, b)
is also defined, and is equivalent to the above.
When m > n and has full column rank,
(r, x) = ma57_solve(A, b)
solves for the least-squares solution, i.e., x such that r = b - Ax satisfies Aᵀ r = 0. The call
(r, x) = ma57_least_squares(A, b)
is also defined, and is equivalent to the above. Example:
using MatrixMarket
using HSL
K = MatrixMarket.mmread("examples/K_0.mtx") # only the lower triangle
rhs = readdlm("examples/rhs_0.rhs")
## solve min norm
K_mn = K[1:200,:]
x_mn, y_mn = ma57_min_norm(K_mn, rhs[1:200]) # == ma57_solve(K_mn, rhs[1:200])
## solve least squares
K_ls = K[:,1:200]
r_ls, x_ls = ma57_least_squares(K_ls, rhs) # == ma57_solve(K_ls, rhs)