haskellmatrixlinear-algebrahmatrix

how to add two matrices in haskell


I am trying to use Haskell's Linear Algebra library to compute some eigenvalues, but first I need to try to add matrices first.

import Numeric.LinearAlgebra.Data
matrix 3 [1,2,3,4,5,6,7,8,9 ]  + matrix 3 [1,2,3,4,5,6,7,8,9 ] 

(3><3)
 [  2.0,  4.0,  6.0
 ,  8.0, 10.0, 12.0
 , 14.0, 16.0, 18.0 ]

However, if I try to represent another way I get error message

( 3 >< 3 ) [1,2,3,4,5,6,7,8,9 ]  + ( 3 >< 3 ) [1,2,3,4,5,6,7,8,9 ] 

No instance for (Element a0) arising from a use of ‘print’
The type variable ‘a0’ is ambiguous

I am not even sure about matrix 3 [1,2,3,4,5,6,7,8,9 ] since I would like to specify that I want a 3 × 3 matrix. Where did the other 3 go?


Solution

  • The problem arises from the difference in type signatures.

     matrix :: Int -> [ℝ] -> Matrix ℝ
     (><) :: Storable a => Int -> Int -> [a] -> Matrix a
    

    So actually matrix 3 [1,2,3,4,5,6,7,8,9 ] has type Matrix ℝ while ( 3 >< 3 ) [1,2,3,4,5,6,7,8,9 ] has type (Num a, Foreign.Storable.Storable a) => Matrix a. Then, the problem is suddenly tractable. Until you specify what a is, you don't know what (+) is, so you can't actually evaluate the sum of the matrix (only produce thunks), hence you can't print it.

    A quick fix is to specify the type of your matrix

    (3 >< 3) ([1..9] :: [ℝ])  + (3 >< 3) ([1..9] :: [ℝ])
    

    which outputs (given the right imports):

    (3><3)
     [  2.0,  4.0,  6.0
     ,  8.0, 10.0, 12.0
     , 14.0, 16.0, 18.0 ]
    

    Some bonus info

    I wanted to do (3 >< 3) ([1..9] :: [Integer]) + (3 >< 3) ([1..9] :: [Integer]), but note that the Num instance of Matrix has (Container Matrix a, Num (Vector a)) => Num (Matrix a) so we need Vector a to also have a Num instance. However, you can check that Vector Integer does not have a num declaration. Alternatives that work:

    Num (Vector Double)  
    Num (Vector Float)   
    Num (Vector (Complex Double))    
    Num (Vector (Complex Float))