7

GNU Octave では、このコード -

[e, ix] = min(X);

最小要素とその場所を返します。任意のバイナリ関数の repa でこれをどのように行いますか?

これは私が思いついたものです:

min x = z $ foldl' f (e,0,0) es
  where
    (e:es) = toList x
    f (a,ix,r) b = let ix' = ix+1 in if a < b then (a,ix',r) else (b,ix',ix')
    z (a,ix,r) = (a,r)

上記の例では、repa 1D マトリックスをリストに変換し、foldl' (Data.List から) を 2 つのアキュムレータで使用します。しかし、repa を使用するポイントは、リストではなく配列を使用することです。

repa には、配列型 (foldS と foldP) の 2 つのフォールドがありますが、それらは (a -> a -> a) 型の関数しか使用できません。つまり、アキュムレータを含むタプルをそれに渡すことはできません。traverse もあります。これは、原則として、1D 配列をスカラー配列に縮小できます。

min x = traverse x to0D min
  where
    to0D (Z:.i) = Z
    min f (Z) = ??? -- how to get elements for comparison?

最初に頭に浮かぶのは

[f (Z:.i) | i <- [1..n]], where n = (\(Z:.i) -> i) $ extent x

ただし、これにより、配列で計算を行う代わりに、配列もリストに変換されます。

4

2 に答える 2

3

私は Repa の専門家ではありませんが、これは 1 次元配列で機能するようです。おそらく、他の次元に適応することができます。

import Data.Array.Repa

indexed arr = traverse arr id (\src idx@(Z :. i) -> (src idx, i))

minimize arr = foldP f h t
  where
    (Z :. n) = extent arr
    arr' = indexed arr
    h = arr' ! (Z :. 0)
    t = extract (Z :. 1) (Z :. (n-1)) arr'
    f min@(valMin, iMin) x@(val, i) | val < valMin = x
                                    | otherwise = min
于 2012-11-29T20:04:15.977 に答える