lapack: Numerical Linear Algebra using LAPACK

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

This is a high-level interface to LAPACK. It provides solvers for simultaneous linear equations, linear least-squares problems, eigenvalue and singular value problems for matrices with certain kinds of structures.

Features:

See also: hmatrix.

For examples see the Example modules and the packages sum-pyramid, wuerfelschlange, magico, linear-circuit, resistor-cube.


[Skip to Readme]

Properties

Versions 0.0, 0.1, 0.2, 0.2.1, 0.2.2, 0.2.3, 0.2.3.1, 0.2.4, 0.3, 0.3.0.1, 0.3.1, 0.3.2, 0.4, 0.4.1, 0.5, 0.5.0.1, 0.5.0.2, 0.5.0.3, 0.5.1, 0.5.1.1, 0.5.2
Change log Changes.md
Dependencies base (>=4.5 && <5), blas-ffi (>=0.0 && <0.2), blaze-html (>=0.7 && <0.10), boxes (>=0.1.5 && <0.2), combinatorial (>=0.1 && <0.2), comfort-array (>=0.5.2 && <0.6), comfort-array-shape (>=0.0 && <0.1), comfort-blas (>=0.0 && <0.1), containers (>=0.4 && <0.8), deepseq (>=1.3 && <1.6), guarded-allocation (>=0.0 && <0.1), hyper (>=0.1 && <0.3), lapack, lapack-ffi (>=0.0.3 && <0.1), lazyio (>=0.1 && <0.2), netlib-ffi (>=0.1.1 && <0.2), non-empty (>=0.3 && <0.4), semigroups (>=0.18.3 && <1.0), Stream (>=0.4.7 && <0.5), tagged (>=0.7 && <0.9), text (>=1.2 && <2.2), tfp (>=1.0.2 && <1.1), transformers (>=0.4 && <0.7), utility-ht (>=0.0.13 && <0.1) [details]
License BSD-3-Clause
Author Henning Thielemann <haskell@henning-thielemann.de>
Maintainer Henning Thielemann <haskell@henning-thielemann.de>
Category Math
Home page https://hub.darcs.net/thielema/lapack/
Source repo this: darcs get https://hub.darcs.net/thielema/lapack/ --tag 0.5.2
head: darcs get https://hub.darcs.net/thielema/lapack/
Uploaded by HenningThielemann at 2024-01-14T09:43:41Z

Modules

Flags

Automatic Flags
NameDescriptionDefault
debug

Compile programs for demonstrating bugs in the LAPACK implementation.

Disabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Readme for lapack-0.5.2

[back to package description]

Installation

Before installing the Haskell bindings you need to install the BLAS and LAPACK packages. Please note, that additionally to the reference implementation in FORTRAN 77 there are alternative optimized implementations like OpenBLAS, ATLAS, Intel MKL.

Debian, Ubuntu

sudo apt-get install libblas-dev liblapack-dev

MacOS

You may install pkgconfig and LAPACK via MacPorts:

sudo port install pkgconfig lapack

However, the pkg-config files for LAPACK seem to be installed in a non-standard location. You must make them visible to pkg-config by

export PKG_CONFIG_PATH=/opt/local/lib/lapack/pkgconfig:$PKG_CONFIG_PATH

You may set the search PATH permanently by adding the above command line to your $HOME/.profile file.

Alternatively, a solution for all users of your machine would be to set symbolic links:

sudo ln -s /opt/local/lib/lapack/pkgconfig/blas.pc /opt/local/lib/pkgconfig/blas.pc
sudo ln -s /opt/local/lib/lapack/pkgconfig/lapack.pc /opt/local/lib/pkgconfig/lapack.pc

Introduction

Here is a small example for constructing and formatting matrices:

Prelude> import qualified Numeric.LAPACK.Matrix as Matrix
Prelude Matrix> import Numeric.LAPACK.Format as Fmt ((##))
Prelude Matrix Fmt> let a = Matrix.fromList (Matrix.shapeInt 3) (Matrix.shapeInt 4) [(0::Float)..]
Prelude Matrix Fmt> a ## "%.4f"
 0.0000 1.0000  2.0000  3.0000
 4.0000 5.0000  6.0000  7.0000
 8.0000 9.0000 10.0000 11.0000
Prelude Matrix Fmt> import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape
Prelude Matrix Fmt MatrixShape> import qualified Numeric.LAPACK.Matrix.Triangular as Triangular
Prelude Matrix Fmt MatrixShape Triangular> let u = Triangular.upperFromList MatrixShape.RowMajor (Matrix.shapeInt 4) [(0::Float)..]
Prelude Matrix Fmt MatrixShape Triangular> (u, Triangular.transpose u) ## "%.4f"
 0.0000 1.0000 2.0000 3.0000
        4.0000 5.0000 6.0000
               7.0000 8.0000
                      9.0000

 0.0000
 1.0000 4.0000
 2.0000 5.0000 7.0000
 3.0000 6.0000 8.0000 9.0000

You may find a more complex introductory example at: http://code.henning-thielemann.de/bob2019/main.pdf

Formatting

We do not try to do fancy formatting for the Show instance. The Show instances of matrices emit plain valid Haskell code in one line where all numbers are printed in full precision. If matrices are part of larger Haskell data structures this kind of formatting works best. For human-friendly formatting in GHCi you need to add something like ## "%.4f" after a matrix or vector expression. It means: Print all numbers in fixed point representation using four digits for the fractional part. You can use the formatting placeholders provided by printf. The matrices have Hyper instances for easy usage in HyperHaskell.

Formatting is based on the Output type class that currently supports output as Text boxes for GHCi and HTML for HyperHaskell.

You may tell GHCi to use Format class instead of Show:

Fmt> let lapackPrint = Fmt.print "%.3f"
Fmt> :set -interactive-print lapackPrint

You may permanently configure this one in your local .ghci file. If you want to display values via Show class, you can always fall back by:

Fmt> print "Hello"

Matrix vs. Vector

Vectors are Storable.Arrays from the comfort-array package. An array can have a fancy shape like a shape defined by an enumeration type, the shape of two appended arrays, a shape that is compatible to a Haskell container type, a rectangular or triangular shape.

All operations check dynamically whether corresponding shapes match structurally. E.g. a|||b === c|||d composes a matrix from four quadrants a, b, c, d. It is not enough that a|||b and c|||d have the same width, but the widths of a and c as well as b and d must match. The type variables for shapes show which dimensions must be compatible. We recommend to use type variables for the shapes as long as possible because this increases type safety even if you eventually use only ShapeInt. If you use statically sized shapes you get static size checks.

A matrix can have any of these shapes as height and as width. E.g. it is no problem to define a matrix that maps a triangular shaped array to a rectangular shaped one. There are actually practical applications to such matrices. A matrix can be treated as vector, but there are limitations. E.g. if you scale a Hermitian matrix by a complex factor it will in general be no longer Hermitian. Another problem: Two equally sized rectangular matrices may differ in the element order (row major vs. column major). You cannot simply add them by adding the flattened arrays element-wise. Thus if you want to perform vector operations on a matrix the package requires you to "unpack" a matrix to a vector using Matrix.Array.toVector. This conversion is almost a no-op and preserves most of the shape information. The reverse operation is Matrix.Array.fromVector.

There are more matrix types that are not based on a single array. E.g. we provide a symbolic inverse, a scaling matrix, a permutation matrix. We also support arrays that represent factors of a matrix factorization. You obtain these by LU and QR decompositions. You can extract the matrix factors of it, but you can also multiply the factors to other matrices or use the decompositions for solving simultaneous linear equations.

Matrix type parameters

LAPACK supports a variety of special matrix types, e.g. dense, banded, triangular, symmetric, Hermitian matrices and our Haskell interface supports them, too. There are two layers: The low level layer addresses how matrices are stored for LAPACK. Matrices and vectors are stored in the Array type from comfort-array:Data.Array.Comfort.Storable using shape types from Numeric.LAPACK.Matrix.Layout. The high level layer provides a matrix type in Numeric.LAPACK.Matrix.Array with mathematically relevant type parameters. The matrix type is:

ArrayMatrix pack property lower upper meas vert horiz height width a

The type parameters are from right to left:

Let us examine some examples:

The type tags have a mathematical meaning and this pays off for operations on matrices. E.g. matrix multiplication adds off-diagonals. Matrix inversion fills non-zero triangular matrix parts. The five supported relations for matrix dimensions are transitive, and thus matrix multiplication maintains a dimension relation, e.g. tall times tall is tall.

Please note, that not all type parameter combinations are supported. Some restrictions are dictated by mathematics, e.g. Hermitian matrices must always be square, matrices with unit diagonal must always be triangular and so on. Some combinations are simply not supported, because they do not add value. E.g. a (square) diagonal matrix is always symmetric but we allow Symmetric only together with Filled. Forbidden combinations are often not prevented at the type level, but you will not be able to construct a matrix of a forbidden type.

Infix operators

The package provides fancy infix operators like #*| and \*#. They symbolize both operands and operations. E.g. in #*| the hash means Matrix, the star means Multiplication and the bar means Column Vector.

Possible operations are:

Possible operands are:

For multiplication of equally shaped matrices we also provide instances of Semigroup.<>.

Precedence of the operators is chosen analogously to plain * and /. Associativity is chosen such that the same operator can be applied multiple times without parentheses. But sometimes this may mean that you have to mix left and right associative operators, and thus you may still need parentheses.

Type errors

You might encounter cryptic type errors that refer to the encoding of particular matrix types via matrix type parameters.

E.g. the error

Couldn't match type `Numeric.LAPACK.Matrix.Extent.Big`
               with `Numeric.LAPACK.Matrix.Extent.Small`

may mean that you passed Square where General or Tall was expected. You may solve the problem with a function like Square.toFull or Square.fromFull.

The error

Couldn't match type `Type.Data.Bool.False`
               with `Type.Data.Bool.True`

most likely refers to non-matching definiteness warranties in a Hermitian matrix. You may try a function like Hermitian.assureFullRank or Hermitian.relaxIndefinite to fix the issue.