]> gitweb.michael.orlitzky.com - numerical-analysis.git/commitdiff
Add Linear.Matrix.ifoldr2.
authorMichael Orlitzky <michael@orlitzky.com>
Wed, 12 Feb 2014 00:21:53 +0000 (19:21 -0500)
committerMichael Orlitzky <michael@orlitzky.com>
Wed, 12 Feb 2014 00:21:53 +0000 (19:21 -0500)
src/Linear/Matrix.hs

index 4d1dceb417c07e63992ec7afefd981a23d484c39..119d77089461dfae968320c79bd1375c31d46b41 100644 (file)
@@ -37,6 +37,7 @@ import qualified Data.Vector.Fixed as V (
   fromList,
   head,
   ifoldl,
+  ifoldr,
   imap,
   map,
   maximum,
@@ -911,7 +912,8 @@ map2 f (Mat rows) =
 
 
 -- | Fold over the entire matrix passing the coordinates @i@ and @j@
---   (of the row/column) to the accumulation function.
+--   (of the row/column) to the accumulation function. The fold occurs
+--   from top-left to bottom-right.
 --
 --   Examples:
 --
@@ -938,6 +940,36 @@ ifoldl2 f initial (Mat rows) =
     row_function rowinit idx r = V.ifoldl (g idx) rowinit r
 
 
+-- | Fold over the entire matrix passing the coordinates @i@ and @j@
+--   (of the row/column) to the accumulation function. The fold occurs
+--   from bottom-right to top-left.
+--
+--   The order of the arguments in the supplied function are different
+--   from those in V.ifoldr; we keep them similar to ifoldl2.
+--
+--   Examples:
+--
+--   >>> let m = fromList [[1,2,3],[4,5,6],[7,8,9]] :: Mat3 Int
+--   >>> ifoldr2 (\i j cur _ -> cur + i + j) 0 m
+--   18
+--
+ifoldr2 :: forall a b m n.
+           (Int -> Int -> b -> a -> b)
+        -> b
+        -> Mat m n a
+        -> b
+ifoldr2 f initial (Mat rows) =
+  V.ifoldr row_function initial rows
+  where
+    -- | Swap the order of arguments in @f@ so that it agrees with the
+    --   @f@ passed to ifoldl2.
+    g :: Int -> Int -> a -> b -> b
+    g w x y z = f w x z y
+
+    row_function :: Int -> Vec n a -> b -> b
+    row_function idx r rowinit = V.ifoldr (g idx) rowinit r
+
+
 -- | Map a function over a matrix of any dimensions, passing the
 --   coordinates @i@ and @j@ to the function @f@.
 --