2011-07-15 82 views
8

是否有任何支持數組和線性代數操作的Lisp或模式方言?通過良好的支持,我不是指BLAS/LAPACk的接口,而是語言本身中有效的數組原語。比如,如果它能夠對抗Numpy,我會認爲它是有效的。我聽說斯大林速度非常快,但我很new舌,不熟悉句法方便的操作和多維數組在這些語言中的高效表示。指針(無雙關語)將深受讚賞,特別是如果支持個人經驗。具有良好多維數組編程支持的Lispy方言

回答

12

Arrays標準Common Lisp可以是​​多維的。

Array Dictionary描述了可用的操作。

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) 

使用數組時,使用Common Lisp的另一個特性:類型聲明和編譯器優化可能會很有用。 Common Lisp允許在不聲明類型的情況下編寫通用代碼。但是在關鍵部分,可以聲明變量,參數,返回值等類型。然後可以指示編譯器擺脫一些檢查或使用類型特定的操作。支持的數量取決於編譯器。還有更復雜的編譯器,如SBCL,LispWorks和Allegro CL,它們支持各種優化。一些編譯器也提供了大量的編譯信息。

最後的手段是使用外部函數接口(FFI)來調用C代碼或使用內聯彙編程序(它由一些編譯器支持)。

Common Lisp在默認情況下具有標準中的LOOP宏。它允許表達典型的命令循環結構。還有一個替代方案,即ITERATE宏 - 它對於多維數組可能有一些優勢。

另請注意,Lisp陣列具有一些不尋常的功能,如位移陣列。這些使用一些其他陣列的存儲,但可以有不同的尺寸佈局。

編寫特殊的宏有時也很有用,它隱藏了使用數組的樣板。沒有類型聲明的Lisp代碼,多維數組和LOOP可能有點大。不使用特殊語言抽象的典型代碼示例如下:fft.lisp

SIMD指令或其他形式的數據並行性的特殊用途通常不由Common Lisp編譯器開箱即用。例外情況可能存在。

4

您是否考慮過使用Incanter庫的Clojure?它對矩陣有很好的支持,並且具有用於繪圖,數學函數,統計等其他內容的高質量代碼。它也很好地支持內置的並行機制。

3

球拍(以前稱爲PLT計劃)最近有不錯的multi-dimensional arrays (math/array)。它們似乎受Python NumPy和Data Parallel Haskell的啓發。您可能喜歡的一些主要特點:

  • 真N維hyperrectangular形狀
  • 廣播(在一個或多個陣列逐點操作,如在NumPy的UFuncs,但更靈活)
  • 切片,轉化和重塑(與NumPy的票面)
  • 陣列推導
  • 部分和完全降低(倍)
  • 可選的可變性(可變陣列允許明確array-set!
  • 可選懶惰(數組是通過默認嚴格)
  • 可選分型(用於快速代碼所需)

這對陣列原語。他們也碰巧和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似乎是一個很好的理由重新考慮 方案 球拍實際任務。