File: Eigensystem.hs

package info (click to toggle)
haskell-numeric-quest 0.2-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 288 kB
  • sloc: haskell: 1,190; makefile: 5
file content (174 lines) | stat: -rw-r--r-- 6,725 bytes parent folder | download | duplicates (2)
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
------------------------------------------------------------------------------
-- Haskell module:      Eigensystem
-- Date:                initialized 2001-03-25, last modified 2001-03-25
-- Author:              Jan Skibinski, Numeric Quest Inc.
-- Location:            http://www.numeric-quest.com/haskell/Eigensystem.hs
-- See also:            http://www.numeric-quest.com/haskell/QuantumVector.html
-- See also:            http://www.numeric-quest.com/haskell/Orthogonals.html
--
-- Description:
--
-- This module extends the QuantumVector module by providing functions
-- to calculate eigenvalues and eigenvectors of Hermitian operators.
-- Such toolkit is of primary importance due to pervasiveness of
-- eigenproblems in Quantum Mechanics.
--
-- This module is organized in three layers:
--
-- 1. Interface to module QuantumVector, where all function signatures
--   are expressed in terms of linear operators, Dirac vectors and scalars.
--
--   Here the operators are defined directly via maps from input to
--   output vectors. In many cases it is much easier to define the operators
--   directly rather than to rely on their matrix representation.
--
-- 2.  Conversion layer between operators and their matrix representation.
--
--   Sometimes it is more convenient to start with an underlying matrix
--   representation of an operator. There are also cases where a direct
--   manipulation on operators is too difficult, while it is trivial
--   to obtain the corresponding results via matrices. One example is a
--   computation of a Hermitian conjugate of A:
--      < ei | A' | ej > = conjugate < ej | A | ej >
--     (Here ' stands for a dagger)
--   If however the operator A is made from a product or a sum of simpler
--   operators, whose Hermitian conjugates are known to us, then the
--   direct approach from the upper layer could be easier and perhaps more
--   efficient in some cases.
--
-- 3.  Implementation layer is stored in a separate module LinearAlgorithms,
--   where matrices are represented as lists of columns of scalars, and
--   vectors -- as lists of scalars.
--
--   This layer is completely independendent of the other two and can be
--   reused separately for applications other than those caring for the
--   QuantumVector module and its notation. It can also be reimplemented
--   via Haskell arrays, or perhaps by some other means, such as trees
--   of nodes relating square blocks of data to support paralleism.
--
-- See also bottom of the page for references and license.
-----------------------------------------------------------------------------

module Eigensystem (eigenvalues, adjoint) where
import Data.Complex
import QuantumVector
import LinearAlgorithms (triangular, tridiagonal, triangular2)
import Data.List (findIndex)

----------------------------------------------------------------------------
-- Category: Eigensystem for QuantumVector
----------------------------------------------------------------------------

eigenvalues :: Ord a => Bool -> Int -> [Ket a] -> (Ket a -> Ket a) -> [Scalar]
eigenvalues doTri n es a
    --  A list of eigenvalues of operator 'a'
    --  obtained after 'n' triangularizations
    --  of a matrix corresponding to operator 'a'
    --  where
    --      'es' is a list of base vectors
    --      'doTri' declares whether or not we
    --        want the initial tridiagonalization
    --        (applies to Hermitian operators only)
    | doTri == True     =  f b1
    | otherwise         =  f b
    where
        f c             = diagonals  $ operator es $ triangular n c
        diagonals us    = [toBra e <> us e | e <- es]
        b               = matrix es a
        b1              = tridiagonal b


eigenpairs :: Ord a => Int -> [Ket a] -> (Ket a -> Ket a) -> ([Scalar], [Ket a])
eigenpairs n es a
    --  A pair of lists (eigenvalues, eigenvectors) of hermitian
    --  operator 'a' obtained after 'n' triangularizations of 'a'
    --  where
    --      'es' is a list of base vectors
    --  Note: For a moment this applies only to Hermitian operators
    --  until we decide what would be the best way to compute eigenvectors
    --  of a triangular matrix: the method from module Orthogonal, power
    --  iteration, etc.
    = (ls, xs)
    where
        (t, q)  = triangular2 n b
        b       = matrix es a
        ls      = [ tk!!k | (tk, k) <- zip t [0..length t - 1] ]
        xs      = [compose qk es | qk <- q]

adjoint :: Ord a => [Ket a] -> (Ket a -> Ket a) -> (Ket a -> Ket a)
adjoint es a
    --  A Hermitian conjugate of operator a,
    --  (or a-dagger, or adjoint to a)
    --  where 'es' is a list of base vectors
    =   operator es ms
    where
        ms = [[ conjugate (toBra ei <> vj) | vj <- v] | ei <- es]
        v = [a ej | ej <- es]


----------------------------------------------------------------------------
-- Category: Conversion from operators to matrices and vice versa
----------------------------------------------------------------------------

operator :: Ord a => [Ket a] -> [[Scalar]] -> Ket a -> Ket a
operator bss ms x
    --  Definition of an operator corresponding
    --  to a matrix 'ms' given as a list of scalar
    --  columns
    --  where
    --      'bss' (basis) is a complete list of base vectors
    --      'x' is any ket vector from this space
    =   a >< x
    where
        a u = case (findIndex (u == ) bss) of
                Just k  -> compose (ms !! k) bss
                Nothing -> error "Out of bounds"


matrix :: Ord a => [Ket a] -> (Ket a -> Ket a) -> [[Scalar]]
matrix bss a
    --  List of scalar columns representing
    --  the operator 'a' in a given 'basis'
    = [[ei' <> vj | ei' <- e'] | vj <- v]
    where
        v = [a ej | ej <- bss]
        e' = [toBra ei | ei <- bss]

----------------------------------------------------------------------------
-- Category: Test data
--
----------------------------------------------------------------------------

matrixA :: [[Scalar]]
matrixA
    --  Test matrix A represented as list of scalar columns.
    =   [
                [1, 2, 4, 1, 5]
        ,       [2, 3, 2, 6, 4]
        ,       [4, 2, 5, 2, 3]
        ,       [1, 6, 2, 7, 2]
        ,       [5, 4, 3, 2, 9]
        ]

opA :: Ket Int -> Ket Int
opA     = operator basisA matrixA

basisA :: [Ket Int]
basisA  = map Ket [1..5::Int] -- or: map Ket "abcde", etc.

---------------------------------------------------------------------------
-- Copyright:
--
--      (C) 2001 Numeric Quest, All rights reserved
--
--      Email: jans@numeric-quest.com
--
--      http://www.numeric-quest.com
--
-- License:
--
--      GNU General Public License, GPL
--
---------------------------------------------------------------------------