2011-07-15 13 views
8

配列と線形代数操作をうまくサポートしているLispやスキームの方言がありますか?良いサポートでは、BLAS/LAPACkへのインターフェースを意味するのではなく、言語自体の効率的な配列プリミティブを意味します。 Numpyに対して自分自身を支えることができれば効率的だと私は考えている。私はStalinが非常に高速であると聞いてきましたが、私は非常に新しく、構文的に便利な操作とそのような言語でのマルチd配列の効率的な表現に精通していません。特に個人的な経験に裏付けられている場合、ポインタ(意図しない言い方)は深く感謝されます。多次元配列プログラミングのサポートをしている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ような1つ以上のアレイ上の点別の操作、が、より柔軟な)
  • スライスは、(変換と整形します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実用的なタスクのために スキーム ラケットを再考する良い理由のように思えます。