Are there any Lisp or scheme dialects that have good support for Array and linear algebraic manipulations. By good support I do not mean interfaces to BLAS/LAPACk, but efficient array primitives in the language itself. I would consider it efficient if it can hold its own against Numpy, say. I have heard Stalin to be very fast but I am very new to lisp and not familiar with syntactically convenient manipulation and efficient representation of multi-d arrays in such languages. Pointers (no pun intended) will be deeply appreciated especially if supported with personal experiences.
Languages. The canonical examples of array programming languages are Fortran, APL, and J.
Data in multidimensional arrays are stored in row-major order. The general form of declaring N-dimensional arrays is: data_type array_name[size1][size2]....[sizeN]; data_type: Type of data to be stored in the array.
Arrays in standard Common Lisp can be multi-dimensional.
The 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 feature of Common Lisp: type declarations and compiler optimizations. Common Lisp allows to write generic code without declaring types. But in critical sections one can declare types for variables, parameters, return values and so on. One then can instruct the compiler to get rid of some checks or to use type specific operations. The amount of support depends on the compiler. There are more sophisticated compilers like SBCL, LispWorks and Allegro CL which support a wide variety of optimizations. Some compilers also give large amounts of compilation information.
A last resort is to use a Foreign Function Interface (FFI) to call C code or to use inline assembler (which is supported by some compilers).
Common Lisp has by default the LOOP macro in the standard. It allows to express the typical imperative looping constructs. There is also an alternative, the ITERATE macro - it may have some advantages for multi-dimensional arrays.
Also note that Lisp arrays have some unusual features like displaced arrays. These use the storage of some other array, but can have a different dimensional layout.
It is also sometimes useful to write special macros, which hide the boilerplate of using arrays. Without that Lisp code with type declarations, multi-dimensional arrays and LOOP can be a bit large. An example for a typical code not using special linguistic abstractions is here: fft.lisp.
Special use of SIMD instructions or other forms of data parallelism are usually not provided out of the box by Common Lisp compilers. Exceptions may exist.
Have you considered Clojure with the Incanter library? It has good support for matrices and has very high quality code for other things like graphing, mathematical functions, statistics and more. It also has good support for parallelism built right in.
Racket (formerly PLT Scheme) has recently got nice multi-dimensional arrays (math/array
). They seem to be inspired by Python NumPy and Data Parallel Haskell. Some key features you may like:
array-set!
)That's for array primitives. They happen to play well with math/matrix
too.
> (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 like a good reason to reconsider Scheme Racket for practical tasks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With