2011-07-15 9 views
8

Czy są jakieś dialekty Lispa lub schematu, które mają dobre wsparcie dla Array i liniowych algebraicznych manipulacji. Przez dobre wsparcie nie mam na myśli interfejsów do BLAS/LAPACk, ale wydajnych prymitywów tablicowych w samym języku. Uznałbym, że jest to skuteczne, jeśli może utrzymywać własne na Numpy. Słyszałem, że Stalin jest bardzo szybki, ale jestem bardzo nowy w seplenieniu i nieznajomym w syntaktycznie wygodnej manipulacji i wydajnej reprezentacji tablic wielodrożnych w takich językach. Wskaźniki (gra słów nie przeznaczonych) będą głęboko docenione, szczególnie jeśli będą wspierane z osobistymi doświadczeniami.Dialekty Lispy z dobrym wielowymiarowym wsparciem programowania tablic

Odpowiedz

12

w standardowym Common Lisp może być wielowymiarowy.

The Array Dictionary opisuje dostępne operacje.

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) 

Podczas pracy z tablicami, może być przydatna do korzystania z innego cechę Common Lisp: deklaracje typ i optymalizacje kompilatora. Common Lisp pozwala pisać ogólny kod bez deklarowania typów. Ale w sekcjach krytycznych można zadeklarować typy dla zmiennych, parametrów, wartości zwracanych i tak dalej. Następnie można poinstruować kompilator, aby pozbył się niektórych sprawdzeń lub użył operacji specyficznych dla typu. Ilość wsparcia zależy od kompilatora. Są bardziej wyrafinowane kompilatory, takie jak SBCL, LispWorks i Allegro CL, które obsługują szeroki zakres optymalizacji. Niektóre kompilatory dostarczają również dużej ilości informacji kompilacji.

W ostateczności należy użyć interfejsu funkcji zagranicznych (FFI), aby wywołać kod C lub użyć wbudowanego asemblera (który jest obsługiwany przez niektóre kompilatory).

Common Lisp ma domyślnie makro LOOP w standardzie. Pozwala to wyrazić typowe imperatywne konstrukcje pętli. Istnieje również alternatywa, makro ITERATE - może to mieć pewne zalety dla wielowymiarowych macierzy.

Należy również zauważyć, że tablice Lisp mają kilka niezwykłych funkcji, takich jak przesunięte tablice. Te wykorzystują pamięć innej tablicy, ale mogą mieć inny układ wymiarowy.

Czasami przydatne jest pisanie specjalnych makr, które ukrywają skróconą tabelę użycia tablic. Bez tego kodu Lisp z deklaracjami typu, wielowymiarowe tablice i LOOP mogą być nieco duże. Przykład typowego kodu, który nie używa specjalnych abstrakcji językowych, znajduje się tutaj: fft.lisp.

Specjalne użycie instrukcji SIMD lub innych form paralelizmu danych zwykle nie jest dostarczane po wyjęciu z pudełka przez kompilatory Common Lisp. Mogą istnieć wyjątki.

4

Czy brałeś pod uwagę Clojure z biblioteką Incanter? Ma dobre wsparcie dla macierzy i ma bardzo wysoką jakość kodu dla innych rzeczy, takich jak wykresy, funkcje matematyczne, statystyki i więcej. Ma również dobre wsparcie dla wbudowanego równoległościanu.

3

Rakieta (dawniej PLT Scheme) niedawno uzyskała ładne multi-dimensional arrays (math/array). Wydaje się, że inspirują ich Python NumPy i Data Parallel Haskell.Niektóre z kluczowych cech może chcesz:

  • prawda N-wymiarowej hyperrectangular kształt
  • Broadcasting (działanie punktowo na jedną lub więcej tablic, jak UFuncs w NumPy, ale bardziej elastyczny)
  • krojenie, przetwarzania i przekształcania (na równi z NumPy)
  • tablicy listowe
  • częściowe i całkowite zmniejszenia (fałdy)
  • opcjonalnie zmienności (Zmienne tablice umożliwienia wyraźnej array-set!)
  • opcjonalnie lenistwo (tablice są surowe domyślnie)
  • opcja typowania (wymagany do szybkiego kodu)

To dla prymitywów tablicy. Zdarza się, że grają też dobrze z 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 Wygląda na to dobry powód do ponownego rozważenia Schemat rakieta do zadań praktycznych.

Powiązane problemy