Current state of numericals | dense-numericals

Included

core

There are two main asdf systems:

  • numericals is designed to work with cl:array so that interfacing with the rest of the lisp ecosystem is trivial.
  • dense-numericals is designed to work with dense-arrays:array

Currently, (asdf:load-system "numericals") provides 3(+1) packages:

  • numericals provides basic math functionality
  • numericals.random provides array generators of random numbers sampled from various distributions
  • numericals.linalg contains some common linear algebra operations

Equivalent packages are provided by the (asdf:load-system "dense-numericals") asdf system:

  • dense-numericals
  • dense-numericals.random
  • dense-numericals.linalg

tests

Tests for various functions are littered through all the files in the form of (5am:def-test ...) forms. Once the system is loaded, run (asdf:test-system "numericals") or (asdf:test-system "dense-numericals") to run the tests.

magicl

The following two systems provide packages for using magicl functions:

  • numericals/magicl,
  • and dense-numericals/magicl

Functions in the numericals.magicl and the dense-numericals.magicl package are essentially wrappers around magicl.

Comparison with other libraries

Native CL arrays

As of this writing,

  • The only libraries that offer broadcasted operations on arrays are this and numcl
  • numcl does not yet have a focus on high performance - though, it should be possible to implement the current einsum based backend using BLAS and BMAS; instead the focus there is on functionality; by contrast, the focus here is on performance first, and functionality second. Users do not have to choose. :mix option of uiop:define-package can be useful for mixing the two libraries as per user preferences
  • Other minor differences wrt numcl include:
  • Both (ones 2 3 :type 'single-float) and (ones '(2 3) :type 'single-float) are legal in numericals; while only the latter is legal in numcl/numpy
  • numericals provides a *array-element-type-alist* equivalent to swank:*readtable-alist* to provide a package local way of specifying the default element-type for arrays. This can be further overriden by binding *array-element-type*. This does impose performance penalties however.
  • numcl relies on JIT backed by specialized-function, while numericals relies on AOT backed by polymorphic-functions and cl-form-types. Again, these are not either-or, high level user functions can (in theory) utilize specialized-function, while the innards can use static-dispatch either by polymorphic-functions or static-dispatch or fast-generic-functions.
  • In addition to these two, another performant library operating on CL arrays includes lla. Again, uiop:define-package with :mix can be used suitably.

The author of numericals did not find other libraries operating on native CL arrays.

Non-native CL arrays

There are quite a few libraries in Common Lisp in this domain. I have only managed to take a peak at femlisp-matlisp.

That said, the goal of numericals is not to replace python ecosystems, at least not in the short run, but instead to overcome the limitations of libraries like py4cl/2 of sub-10,000 instructions per second. However, now there's also py4cl2-cffi which is about a 10 times faster than py4cl/2 without using compiler macros yet.

Foreign function interfaces

gsll

A number of functions in gsl and gsll operate on double precision floats, while some applications appreciate operators working on single precision floats without a conversion overhead. Thus, while extremely featureful, gsll is insufficient for everyone's needs.

eigen

eigen has wonderful documentation. I have only ever done a basic course in linear algebra, and often feel as if I am missing out on something when people work on linear algebra, but I found eigen's documentation to be superb! For instance, see

So, if eigen and C++ suit your needs, you might as well use it! That said, it isn't the fastest in everything - SLEEF can often be faster in areas where it is specifically designed for.

History

Curiosity got the better of me one day, and I set out to explore the limits of numerical computing with Common Lisp. I mean - what does speed require? Just memory-locality and SIMD? SBCL has memory-locality. What about SIMD? Well, the functionality hasn't been "standardized" yet, and there are several attempts. Indeed, SBCL needs more documentation - think Emacs! But knowledge exists in people's heads. People are willing to share it. So, this was possible.

PS: This library began as a reddit post, that, in turn, was triggered by this reddit post.

You should probably use the latest SBCL (get from git), at least SBCL-2.0.9. The build is fairly easy: sh make.sh && sh run-sbcl.sh # or install.sh or pick a binary from here.

Project Predecessors

The project renaming reflects an attempt to separate the portable parts of the codebase from the SBCL-specific part, so that a portability attempt may be made in the future.