Lisp dialects with good multidimensional array support

Are there Lisp or dialect dialects that have good support for arrays and linear algebraic manipulations. Thanks to the good support, I do not mean interfaces with BLAS / LAPACk, but efficient array primitives in the language itself. I would find him effective if he can hold his own against Numpy, say. I heard that Stalin was very fast, but I am very new to Lisp and not familiar with the syntactically convenient manipulation and efficient representation of multi-d arrays in such languages. Pointers (not intended for puns) will be deeply appreciated, especially if they are supported by personal experience.

+8
arrays numpy lisp scheme common-lisp
source share
3 answers

Arrays in the Common Lisp standard can be multidimensional.

Array Dictionary describes the available operations.

CL-USER 12 > (defparameter *a* (make-array '(3 2 4) :initial-element 'foo)) *A* CL-USER 13 > *a* #3A(((FOO FOO FOO FOO) (FOO FOO FOO FOO)) ((FOO FOO FOO FOO) (FOO FOO FOO FOO)) ((FOO FOO FOO FOO) (FOO FOO FOO FOO))) CL-USER 14 > (setf (aref *a* 1 1 2) 'bar) BAR CL-USER 15 > *a* #3A(((FOO FOO FOO FOO) (FOO FOO FOO FOO)) ((FOO FOO FOO FOO) (FOO FOO BAR FOO)) ((FOO FOO FOO FOO) (FOO FOO FOO FOO))) CL-USER 16 > (array-dimensions *a*) (3 2 4) 

When working with arrays, it may be useful to use another Common Lisp function: type declarations and compiler optimization. Generic Lisp allows you to write generic code without declaring types. But in critical sections you can declare types of variables, parameters, return values, etc. Then you can instruct the compiler to get rid of some checks or use type operations. The amount of support depends on the compiler. There are more complex compilers, such as SBCL, LispWorks, and Allegro CL, which support a wide range of optimizations. Some compilers also provide great compilation information.

The last resort is to use an external function interface (FFI) to invoke C code or use the built-in assembler (which is supported by some compilers).

Generic Lisp has a default LOOP macro in the standard. This allows us to express typical designs of planing cycles. There is also an alternative, the ITERATE macro - it may have some advantages for multidimensional arrays.

Also note that Lisp arrays have some unusual functions, such as relocated arrays. They use storage of some other array, but can have a different format.

Sometimes it is also useful to write special macros that hide the pattern of using arrays. Without this, Lisp code with declarations like multidimensional arrays and LOOPs can be a little big. An example of typical code that does not use special linguistic abstractions is given here: fft.lisp .

The special use of SIMD instructions or other forms of parallelism data is usually not provided by Common Lisp compilers out of the box. Exceptions may exist.

+12
source share

Have you considered the Incanter Clojure library? It has good matrix support and has very high-quality code for other things, such as graphical display, mathematical functions, statistics, and much more. It also has good support for parallelism built into.

+4
source share

Racket (formerly PLT Scheme) recently got good multidimensional arrays ( math/array ) . They seem to be inspired by Python NumPy and Data Parallel Haskell. Some key features you might like:

  • true N-dimensional hyperregular form
  • broadcasting (streaming control on one or several arrays, for example, UFuncs in NumPy, but more flexible)
  • slicing, transforming and reshaping (in order with NumPy)
  • understanding array
  • partial and complete reduction (folds)
  • optional mutability (mutable arrays allow explicit array-set! )
  • optional laziness (strict lines by default)
  • optional entry (required for quick code)

This is for array primitives. They also play well with math/matrix .

 > (require math/array math/matrix) > (define arr3d (array-reshape (list->array (range 1 19)) #[2 3 3])) > arr3d (array #[#[#[1 2 3] #[4 5 6] #[7 8 9]] #[#[10 11 12] #[13 14 15] #[16 17 18]]]) > (array-map * arr3d arr3d) (array #[#[#[1 4 9] #[16 25 36] #[49 64 81]] #[#[100 121 144] #[169 196 225] #[256 289 324]]]) > (define m (array-slice-ref arr3d (list 1 ::...))) > m (array #[#[10 11 12] #[13 14 15] #[16 17 18]]) > (array-shape m) '#(3 3) > (matrix-trace m) 42 

math/array seems to be a good reason to revise the Scheme Racket for practical tasks.

+3
source share

All Articles