
I'm working on simple matrix / matrix addition for a short project. Doing this with lists (not worrying about matrix sizes and such) is relatively easy and makes quite a bit of sense to me: basically: madd :: Num a => [[a]] -> [[a]] -> [[a]] I could read this as: - with a as a Numeric type, take two lists of lists of Numerics and return a list of lists of Numerics And then to do the job simple madd m n = zipWith (zipWith (+)) m n And I can read that easily enough: -- madd has two inputs, m and n and it will do the function "zipWith (+)" across its inputs of the inner lists from m and n (the rows, basically) Ok, so madd [[1,2,3], [4,5,6], [7,8,9]] [[10,11,12], [13,14,5], [16,17,18]] yields [[11,13,15],[17,19,11],[23,25,27]] Cool I can get a little nicer (possibly) if I use a Matrix type: data Matrix a = Matrix [[a]] deriving (Show, Eq) madd :: Num a => [[a]] -> [[a]] -> [[a]] madd m n = zipWith (zipWith (+)) m n madd2 :: (Num a) => Matrix a -> Matrix a -> Matrix a madd2 (Matrix m) (Matrix n) = Matrix $ zipWith (zipWith (+)) m n The only real change in terms of the code is in the madd2 definition where I have to construct a Matrix to return from the results of the zipWiths … and some better type safety of course. *Main> madd2 (Matrix [[1,2,3], [4,5,6], [7,8,9]]) (Matrix [[10,11,12], [13,14,5], [16,17,18]]) Matrix [[11,13,15],[17,19,11],[23,25,27]] Cool' Now, I really want to use Unboxed Vectors. As I look around the web and poke around through various resources, I believe that I need the rows to be unboxed but the columns can be boxed … the actual operations on the rows will give me the speed up I desire. So, here it is: import qualified Data.Vector as V import qualified Data.Vector.Unboxed as U data UMatrix a = UMatrix (V.Vector (U.Vector a)) deriving (Show, Eq) madd3 :: (U.Unbox a, Num a) => UMatrix a -> UMatrix a -> UMatrix a madd3 (UMatrix m) (UMatrix n) = UMatrix $ V.zipWith (U.zipWith (+)) m n And it works … (really, when I started writing this note, I was completely lost … welcome to the power of sitting and walking through Haskell) madd3 (UMatrix (Data.Vector.fromList [Data.Vector.Unboxed.fromList [1,2,3], Data.Vector.Unboxed.fromList [4,5,6], Data.Vector.Unboxed.fromList [7,8,9]])) (UMatrix (Data.Vector.fromList [Data.Vector.Unboxed.fromList [10,11,12], Data.Vector.Unboxed.fromList [13,14,5], Data.Vector.Unboxed.fromList [16,17,18]])) I have ONE thing that I can't really explain … Why does the declaration of madd3 REQUIRE the use of U.Unbox a as a data type? madd3 :: (U.Unbox a, Num a) => UMatrix a -> UMatrix a -> UMatrix a I would have thought that my declaration of UMatrix would have done this? Cheers. Paul Monday Parallel Scientific, LLC. paul.monday@parsci.com