The Hoff
The Hoff

Reputation: 974

How to create matrices with the Linear library in Haskell

The documentation for Linear shows how you can create vectors and matrices using the V1,V2,V3,V4 functions to create vectors of dimensions 1,2,3,4. But I would like to work with matrices that have more elements.

The matrix multiplication example shows and example using a function fromList.

V2 (fromList [(1,2)]) (fromList [(2,3)]) !*! fromList [(1,V3 0 0 1), (2, V3 0 0 5)]

But I can't seem to find that function in the Linear library. How would I go about creating a matrix of double values with arbitrary dimensions (e.g. 5x6)?

Upvotes: 2

Views: 491

Answers (1)

HTNW
HTNW

Reputation: 29193

Look at (!*!)'s type

(!*!) :: (Functor m, Foldable t, Additive t, Additive n, Num a)
      => m (t a) -> t (n a) -> m (n a)

The important constraint here is Additive, so look at its instances

instance Additive []
instance Additive Vector -- ordinary, unsized vectors from the vectors package
instance Additive V0
instance Additive V1
instance Additive V2
instance Additive V3
instance Additive V4 -- Sized vectors from linear up to n = 4
instance Dim n => Additive (V n) -- Vectors of arbitrary dimension where the size is given by a type level number n
-- plus other instances

So you can just use nested lists:

m :: [[Int]]
m = [ [ 0,1,2,3,4 ],
      [ 1,2,3,4,0 ],
      [ 2,3,4,0,1 ],
      [ 3,4,0,1,2 ],
      [ 4,0,1,2,3 ] ]

msq :: [[Int]]
msq = m !*! m

Or nested Vectors

import Data.Vector(Vector)
import qualified Data.Vector as V

mv :: Vector (Vector Int)
mv = V.fromList $ V.fromList <$> m

mvsq :: Vector (Vector Int)
mvsq = mv !*! mv

Or mix and match:

mvl :: Vector [Int]
mvl = V.fromList m
mlv :: [Vector Int]
mlv = V.fromList <$> m

mvlmlv :: Vector (Vector Int)
mvlmlv = mvl !*! mlv

And you can use V to keep track of the sizes:

{-# LANGUAGE DataKinds #-}
import Linear.V

mV :: V 5 (V 5 Int) -- GHC.TypeLits.Nat literals
mV = fromJust $ fromVector $ fromJust <$> fromVector <$> mv
mVsq :: V 5 (V 5 Int)
mVsq = mV !*! mV -- does not compile in case of dimension mismatch

Upvotes: 3

Related Questions