Idiomatic Vector Algebra in Haskell -
as way practice vector library in haskell, i'm trying rewrite nelder-mead minimization algorithm had written in c. far i've been having bit of trouble translating vector operations idiomatically.
for instance, consider function finds centroid of n vectors out of list of n+1 (filtering away 1 index),
in c, can written as
static void get_centroid(double **s, int n, int iz, double *c) { (int = 0; < n+1; i++) { if (i != iz) { (int j = 0; j < n; j++) c[j] += s[i][j]; } } (int j = 0; j < n; j++) c[j] /= n; }
i tried translating haskell, , ended following
import data.vector import qualified data.vector v type node = vector double type simplex = vector node centroid :: simplex -> int -> node centroid s iz = v.map (/ (fromintegral $ v.length s)) $ v.zipwith (-) v (s ! iz) v = v.foldl go v.empty s go b = v.zipwith (+) b
i find code quite inelegant, doesn't capture essence of vector algebra that's happening (and more inefficient since i'm adding , subtracting s[iz]).
one solution implement kind of vector space typeclass or use more specific linear algebra library, since such common operations wondering if there's more idiomatic 'straight' solution.
i'd start +1 dfeuer; more specific library both cleaner , more efficient.
however, if looking more idiomatic implementation of centroid
function, one:
centroid' :: simplex -> int -> node centroid' s iz = let t = foldl1 (v.zipwith (+)) (v.drop iz s) n = fromintegral (v.length t - 1) in v.map (/ n) t
one general comment on version: it's easy create "write-only" haskell code. there going on in first line difficult parse. where
block step in right direction, i'd go further break out conceptual components.
also, hoogle. didn't know there existed function drop
, knew if existed, took int
, vector
onto new vector
. hoogle doesn't index vector
, api vector similar api lists. searched "[a] -> int -> [a]" , "int -> [a] -> [a]" , found drop
.
(stackage index vector
, search "int -> vector -> vector a" works there)
Comments
Post a Comment