2012-06-27 4 views
6

Repa?の過去の値(すなわち、より小さなインデックス)に依存する配列を計算することは可能ですか?アレイの最初の部分(例えば、a[0])が与えられる。 (配列の要素を示すにはCのような表記法を使用していますが、混同しないでください)Repaで[i] = f(a [i-1])をどのように計算しますか?

私はtutorialを読んですぐにハックをチェックしましたが、それを行う機能が見つかりませんでした。

(私はあなたがそれを並列化できないため、1次元配列で計算のこの種をやってするのrepAでローミングサービスをしないと思います。しかし、私はあなたが2次元以上の場合には、それを並列化することができると思います。)

EDIT: おそらく私はどのような種類のfを使用したいのかについて具体的に述べるべきです。 a[i]がスカラーの場合に並列化する方法がないので、a[i]はN dimベクトルです。 a[i]はベクトルに「展開」することができるため、より高い次元(行列など)である必要はありません。したがって、fは、R^NをR^Nにマッピングする関数です。

例ほとんどが、それはこのようなものだ:bはN DIMベクトルで

b = M a[i-1] 
a[i][j] = g(b)[j] 

MはN Nの行列(スパースなし仮定)であり、そしてgは、いくつかの非線形関数です。そして、i=1,..N-1の値をa[0],gMと計算します。私の希望は、(1)このタイプの計算を並列化し、(2)bなどの中間変数を効率的に割り当てる(C言語のような言語で、再利用することができる、Repaまたは同様のライブラリは純粋さを壊さずに魔法のように行うことができます)。

+0

アソシエイティブfの場合、並列化することができ、「スキャン」と呼ばれます。 http://en.wikipedia.org/wiki/Prefix_sum私はRepaのドキュメントでスキャンを見つけることができませんでした。 – Heatsink

+0

repaステンシル、http://hackage.haskell.org/packages/archive/repa/2.0.2.1/doc/html/Data-Array-Repa-Stencil.htmlで行うことができます。 http://stackoverflow.com/questions/6170008/how-to-take-an-array-slice-with-repa-over-a-range –

+1

@Heatsinkスキャンではシリーズを入力として要求しないでしょうか?私にとって、これは[展開](http://en.wikipedia.org/wiki/Anamorphism)のようになります。 – phg

答えて

1

編集:実際には、私は質問を誤解したと思う。マルチためにそれを拡張

R.computeUnboxedS $       -- force the vector to be "real" 
    R.traverse x         -- traverse the vector 
    (\ (Z :. i) -> (Z :. (i - 1)))     -- function to get the shape of the result 
    (\f (Z :. i) -> f (Z :. (i + 1)) - f (Z :. i)) -- actual "stencil" 

Prelude Data.Array.Repa R> let x = fromListUnboxed (Z :. 10 :: DIM1) [1..10] 
Prelude Data.Array.Repa R> R.computeUnboxedS $ R.traverse x (\ (Z :. i) -> (Z :. (i - 1))) (\f (Z :. i) -> f (Z :. (i + 1)) - f (Z :. i)) 
AUnboxed (Z :. 9) (fromList [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]) 

それを解剖:私は

あなたはtraversehttp://hackage.haskell.org/packages/archive/repa/3.2.1.1/doc/html/Data-Array-Repa.html#v:traverseを使用することができます...それは他の誰かのために便利だ場合には、ここに私の答えを残しておきます2次元アレイは些細でなければならない。

+0

ソース配列のみに基づいて結果配列を計算しています。私が計算したいのは、その要素がその1ステップ前のものに依存する配列です。タイトルの 'i'は配列の大きさと考えるかもしれません。私は指数を意味した。 – tkf

+0

'Data.Vector.Unboxed.scanl1''と' Repa.toUnboxed'の組み合わせはどうでしょうか?たとえば、 'cumsum'は' R.fromUnboxed(R.extent y)$ U.scanl1 '(+)$(R.toUnboxed y) 'となります。 [地獄と醜い、おそらくより高次元に拡張できない] – lbolla

+0

cumsumは、ソース配列からターゲット配列への計算のままです。 *ソース*配列の初期の部分であり、ターゲットではありません。上記のコメントにヒートシンクとphgが記載されているので、私は必要なものを展開します。私はRepa(またはHaskellの他の配列指向ライブラリ)で展開する方法を知りたいと思います。 – tkf

3

私はこれを行うためのRepaの方法を見ることができません。しかし、ベクターがある:Data.Vector.iterateNは、あなたが望むベクトルを構築する。次にData.Array.Repa.fromUnboxedをVectorからRepaに変換します。

iterateN :: Int -> (a -> a) -> a -> Vector aSource 

O(n)の値に関数をn回適用します。ゼロ要素は元の値です。

+0

ありがとうございます。これは、1D計算を行うときに十分でなければなりません。おそらく私はRepaを気にする必要はないでしょう。私は、ハスケルのスピードの点で(最適化されていない)Cに匹敵するものを欲しいだけです。これは多次元的なことができますか? ( '' a''は別のベクトルになりますか?)もしそうなら、並列化できますか? – tkf

+0

それは、あなたが求めている多次元汎化の種類に依存します。 1Dの場合、関数自体はかなり本質的に連続しているので、並列化することは明らかに不可能です。あなたが求めている多次元の一般化がどのように見えるかについて、より具体的に説明できますか? –

+0

'a [i]'がベクトルであるので( 'a'は2次元配列です)、初期値' a [0] 'が与えられてa [i] = M a [i-1]行列「M」から「i = N-1」までの行列である。タイトルに使用した表記法を使って、 'f(x)= M x'ここで' f'はベクトル化されています。どんな種類の 'f'でも考えることができますが、基本的には前の1ステップの値だけを使用します。 – tkf

関連する問題