2011-07-15 10 views
8

¿Hay dialectos Lisp o esquema que tengan un buen soporte para Array y manipulaciones algebraicas lineales. Con un buen soporte, no me refiero a las interfaces con BLAS/LAPACk, sino a las primitivas de matriz eficiente en el lenguaje en sí. Lo consideraría eficiente si puede defenderse contra Numpy, por ejemplo. He escuchado que Stalin es muy rápido, pero soy muy nuevo en el ceceo y no estoy familiarizado con la manipulación sintácticamente conveniente y la representación eficiente de matrices multi-d en dichos idiomas. Los punteros (sin juego de palabras) serán muy apreciados, especialmente si se respaldan con experiencias personales.Dialectos Lispy con buena compatibilidad de programación de matriz multidimensional

Respuesta

12

Arrays en estándar Common Lisp puede ser multidimensional.

El Array Dictionary describe las operaciones disponibles.

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) 

Cuando se trabaja con matrices, puede ser útil el uso de otra de las características de Common Lisp: declaraciones de tipo y optimizaciones del compilador. Common Lisp permite escribir código genérico sin declarar tipos. Pero en las secciones críticas, uno puede declarar tipos para variables, parámetros, valores de retorno, etc. Entonces uno puede instruir al compilador para que se deshaga de algunos controles o para que use operaciones específicas del tipo. La cantidad de soporte depende del compilador. Existen compiladores más sofisticados como SBCL, LispWorks y Allegro CL que admiten una amplia variedad de optimizaciones. Algunos compiladores también brindan grandes cantidades de información de compilación.

Un último recurso consiste en utilizar una Interfaz de función en el extranjero (FFI) para llamar al código C o utilizar el ensamblador en línea (que es compatible con algunos compiladores).

Common Lisp tiene por defecto la macro LOOP en el estándar. Permite expresar las típicas construcciones de bucle imperativo. También existe una alternativa, la macro ITERATE, que puede tener algunas ventajas para las matrices multidimensionales.

También tenga en cuenta que las matrices Lisp tienen algunas características inusuales, como las matrices desplazadas. Estos usan el almacenamiento de alguna otra matriz, pero pueden tener un diseño dimensional diferente.

También es a veces útil escribir macros especiales, que ocultan la repetición de las matrices. Sin ese código Lisp con declaraciones de tipo, las matrices multidimensionales y LOOP pueden ser un poco grandes. Un ejemplo para un código típico que no utiliza abstracciones lingüísticas especiales es aquí: fft.lisp.

El uso especial de las instrucciones SIMD u otras formas de paralelismo de datos generalmente no son proporcionados por los compiladores de Common Lisp. Excepciones pueden existir.

4

¿Ha considerado Clojure con la biblioteca Incanter? Tiene un buen soporte para matrices y tiene un código de muy alta calidad para otras funciones como gráficos, funciones matemáticas, estadísticas y más. También tiene un buen soporte para el paralelismo integrado.

3

Raqueta (anteriormente PLT Scheme) ha recibido recientemente multi-dimensional arrays (math/array). Parecen inspirados por Python NumPy y Data Parallel Haskell.Algunas de las características clave que pueden como: forma hyperrectangular

  • cierto N-dimensional
  • radiodifusión (operación puntual en una o más matrices, como UFuncs en NumPy, pero más flexible)
  • corte en rodajas, la transformación y la remodelación (a la par con NumPy)
  • por comprensión de matriz
  • reducciones parciales y completas (pliegues)
  • mutabilidad opcional (arrays mutables permiten explícita array-set!)
  • pereza opcional (matrices son estrictos por defecto)
  • mecanografía opcional (requerido sobre el código rápido)

Eso es para los primitivos de matriz. Suelen jugar bien con math/matrix también.

> (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 parece una buena razón para reconsiderar Esquema Raqueta de tareas prácticas.

Cuestiones relacionadas