TBit-0.4.2.0: TBit/Hamiltonian/Builder/Matrification.hs
{-# LANGUAGE NoImplicitPrelude #-}
module TBit.Hamiltonian.Builder.Matrification (mixedSum, toMatrix) where
import Prelude.Listless
import Data.List.Stream
import Numeric.LinearAlgebra.HMatrix
import Data.Graph.Inductive
import Data.Maybe
mixedAdd :: Maybe (Matrix (Complex Double))
-> Maybe (Matrix (Complex Double))
-> Maybe (Matrix (Complex Double))
mixedAdd (Just a) (Just b) | dim a == dim b = Just $ a + b
| dim a == 2 * dim b = Just $ a + expand b
| dim b == 2 * dim a = Just $ expand a + b
| otherwise = Nothing
where dim = fst . size
expand m = m `kronecker` ident 2
mixedAdd _ _ = Nothing
{-|
Take a list of matrices, some of which may differ from the others in
dimensionality by a factor of two, and maybe return the sum of these
matrices with appropriate (right) kronecker products taken to make
the summation well-formed. Useful for combining matrices written in
forms with and without spin indices.
-}
mixedSum :: [Matrix (Complex Double)] -> Maybe (Matrix (Complex Double))
mixedSum = foldl1 mixedAdd . map Just
{-|
Send a tight-binding graph model to the corresponding Hamiltonian
matrix.
-}
toMatrix :: Gr (Matrix (Complex Double)) (Matrix (Complex Double))
-> Matrix (Complex Double)
toMatrix gr = fromJust $ mixedSum [offd, ond]
where es = map (\(i,j,k) -> ((i,j),k)) $ labEdges gr
n = noNodes gr
ns = labNodes gr
d i j = if i==j then 1 else 0
--offd = fromBlocks [[ fromMaybe 0 $ lookup (i,j) es | i <- [1..n]]
-- | j <- [1..n]]
offd = fromBlocks [[ sum $ map snd
$ filter ((==) (i,j) . fst) es | i <- [1..n]]
| j <- [1..n]]
ond = fromBlocks [[ (*) (d i j)
$ sum $ map snd $ filter ((==) j . fst) ns
| i <- [1..n]]
| j <- [1..n]]