summaryrefslogtreecommitdiff
path: root/lib/LinearAlgebra/Linear.hs
blob: 2f1bc6f18cd838d3c37717f07a4fa0a8793efee8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
{-# OPTIONS_GHC -fglasgow-exts #-}
-----------------------------------------------------------------------------
{- |
Module      :  LinearAlgebra.Linear
Copyright   :  (c) Alberto Ruiz 2006-7
License     :  GPL-style

Maintainer  :  Alberto Ruiz (aruiz at um dot es)
Stability   :  provisional
Portability :  uses ffi


-}
-----------------------------------------------------------------------------

module LinearAlgebra.Linear (
    Linear(..),
    multiply, dot, outer
) where


import Data.Packed.Internal
import Data.Packed.Matrix
import GSL.Vector
import Complex


class (Field e) => Linear c e where
    scale       :: e -> c e -> c e
    scaleRecip  :: e -> c e -> c e
    addConstant :: e -> c e -> c e
    add         :: c e -> c e -> c e
    sub         :: c e -> c e -> c e
    mul         :: c e -> c e -> c e
    divide      :: c e -> c e -> c e
    toComplex   :: RealFloat e => (c e, c e) -> c (Complex e)
    fromComplex :: RealFloat e => c (Complex e) -> (c e, c e)
    comp        :: RealFloat e => c e -> c (Complex e)
    conj        :: RealFloat e => c (Complex e) -> c (Complex e)
    real        :: c Double -> c e
    complex     :: c e -> c (Complex Double)

instance Linear Vector Double where
    scale = vectorMapValR Scale
    scaleRecip = vectorMapValR Recip
    addConstant = vectorMapValR AddConstant
    add = vectorZipR Add
    sub = vectorZipR Sub
    mul = vectorZipR Mul
    divide = vectorZipR Div
    toComplex = Data.Packed.Internal.toComplex
    fromComplex = Data.Packed.Internal.fromComplex
    comp = Data.Packed.Internal.comp
    conj = Data.Packed.Internal.conj
    real = id
    complex = LinearAlgebra.Linear.comp

instance Linear Vector (Complex Double) where
    scale = vectorMapValC Scale
    scaleRecip = vectorMapValC Recip
    addConstant = vectorMapValC AddConstant
    add = vectorZipC Add
    sub = vectorZipC Sub
    mul = vectorZipC Mul
    divide = vectorZipC Div
    toComplex = undefined -- can't match
    fromComplex = undefined
    comp = undefined
    conj = undefined
    real = LinearAlgebra.Linear.comp
    complex = id

instance Linear Matrix Double where
    scale x = liftMatrix (scale x)
    scaleRecip x = liftMatrix (scaleRecip x)
    addConstant x = liftMatrix (addConstant x)
    add = liftMatrix2 add
    sub = liftMatrix2 sub
    mul = liftMatrix2 mul
    divide = liftMatrix2 divide
    toComplex = uncurry $ liftMatrix2 $ curry LinearAlgebra.Linear.toComplex
    fromComplex z = (reshape c r, reshape c i)
        where (r,i) = LinearAlgebra.Linear.fromComplex (cdat z)
              c = cols z
    comp = liftMatrix Data.Packed.Internal.comp
    conj = liftMatrix Data.Packed.Internal.conj
    real = id
    complex = LinearAlgebra.Linear.comp

instance Linear Matrix (Complex Double) where
    scale x = liftMatrix (scale x)
    scaleRecip x = liftMatrix (scaleRecip x)
    addConstant x = liftMatrix (addConstant x)
    add = liftMatrix2 add
    sub = liftMatrix2 sub
    mul = liftMatrix2 mul
    divide = liftMatrix2 divide
    toComplex = undefined
    fromComplex = undefined
    comp = undefined
    conj = undefined
    real = LinearAlgebra.Linear.comp
    complex = id

--------------------------------------------------

-- | euclidean inner product
dot :: (Field t) => Vector t -> Vector t -> t
dot u v = dat (multiply r c) `at` 0
    where r = asRow u
          c = asColumn v


{- | Outer product of two vectors.

@\> 'fromList' [1,2,3] \`outer\` 'fromList' [5,2,3]
(3><3)
 [  5.0, 2.0, 3.0
 , 10.0, 4.0, 6.0
 , 15.0, 6.0, 9.0 ]@
-}
outer :: (Field t) => Vector t -> Vector t -> Matrix t
outer u v = asColumn u `multiply` asRow v