In GNU Octave, this code is
[e, ix] = min(X);
returns the minimum element and its location. How do you do this in repa for an arbitrary binary function?
Here is what I came up with:
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)
In the above example, we convert the repa 1D matrix to a list and use foldl '(from Data.List) with two accumulators - one to calculate iterations (ix) and the other to maintain the position of min element (r). But the whole point of using repa is to use arrays, not lists!
In repa, there are two folds for the Array type (foldS and foldP), but they can only accept functions of the type (a → a → a) - that is, I cannot pass a tuple with batteries to it. There is also a traverse, which can basically reduce a 1D array to a scalar array:
min x = traverse x to0D min where to0D (Z:.i) = Z min f (Z) = ??? -- how to get elements for comparison?
The first thing that comes to mind is
[f (Z:.i) | i <- [1..n]], where n = (\(Z:.i) -> i) $ extent x
But it also converts the array to a list, rather than doing the calculations in the array.
EvgenijM86
source share