{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE Trustworthy #-}
module Physics.Learn.Schrodinger1D
(
freeV
, harmonicV
, squareWell
, doubleWell
, stepV
, wall
, coherent
, gaussian
, movingGaussian
, stateVectorFromWavefunction
, hamiltonianMatrix
, expectX
, picture
, xRange
, listForm
)
where
import Data.Complex
( Complex(..)
, magnitude
)
import Graphics.Gloss
( Picture(..)
, yellow
, black
, Display(..)
, display
)
import Numeric.LinearAlgebra
( R
, C
, Vector
, Matrix
, (|>)
, (<.>)
, fromLists
, toList
, size
)
import Physics.Learn.QuantumMat
( probVector
, timeEv
)
freeV
:: Double
-> Double
freeV :: R -> R
freeV R
_x = R
0
harmonicV
:: Double
-> Double
-> Double
harmonicV :: R -> R -> R
harmonicV R
k R
x = R
k forall a. Num a => a -> a -> a
* R
xforall a. Floating a => a -> a -> a
**R
2 forall a. Fractional a => a -> a -> a
/ R
2
doubleWell
:: Double
-> Double
-> Double
-> Double
doubleWell :: R -> R -> R -> R
doubleWell R
a R
v0 R
x = R
v0 forall a. Num a => a -> a -> a
* ((R
xforall a. Floating a => a -> a -> a
**R
2 forall a. Num a => a -> a -> a
- R
aforall a. Floating a => a -> a -> a
**R
2)forall a. Fractional a => a -> a -> a
/R
aforall a. Floating a => a -> a -> a
**R
2)forall a. Floating a => a -> a -> a
**R
2
squareWell
:: Double
-> Double
-> Double
-> Double
squareWell :: R -> R -> R -> R
squareWell R
l R
v0 R
x
| forall a. Num a => a -> a
abs R
x forall a. Ord a => a -> a -> Bool
< R
lforall a. Fractional a => a -> a -> a
/R
2 = R
0
| Bool
otherwise = R
v0
stepV
:: Double
-> Double
-> Double
stepV :: R -> R -> R
stepV R
v0 R
x
| R
x forall a. Ord a => a -> a -> Bool
< R
0 = R
0
| Bool
otherwise = R
v0
wall
:: Double
-> Double
-> Double
-> Double
-> Double
wall :: R -> R -> R -> R -> R
wall R
w R
v0 R
x0 R
x
| forall a. Num a => a -> a
abs (R
xforall a. Num a => a -> a -> a
-R
x0) forall a. Ord a => a -> a -> Bool
< R
wforall a. Fractional a => a -> a -> a
/R
2 = R
v0
| Bool
otherwise = R
0
coherent
:: R
-> C
-> R -> C
coherent :: R -> Complex R -> R -> Complex R
coherent R
l Complex R
z R
x
= ((R
1forall a. Fractional a => a -> a -> a
/(forall a. Floating a => a
piforall a. Num a => a -> a -> a
*R
lforall a. Floating a => a -> a -> a
**R
2))forall a. Floating a => a -> a -> a
**R
0.25 forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
exp(-R
xforall a. Floating a => a -> a -> a
**R
2forall a. Fractional a => a -> a -> a
/(R
2forall a. Num a => a -> a -> a
*R
lforall a. Floating a => a -> a -> a
**R
2)) forall a. a -> a -> Complex a
:+ R
0)
forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
exp(-Complex R
zforall a. Floating a => a -> a -> a
**Complex R
2forall a. Fractional a => a -> a -> a
/Complex R
2 forall a. Num a => a -> a -> a
+ (forall a. Floating a => a -> a
sqrt(R
2forall a. Fractional a => a -> a -> a
/R
lforall a. Floating a => a -> a -> a
**R
2) forall a. Num a => a -> a -> a
* R
x forall a. a -> a -> Complex a
:+ R
0) forall a. Num a => a -> a -> a
* Complex R
z)
gaussian
:: R
-> R
-> R -> C
gaussian :: R -> R -> R -> Complex R
gaussian R
a R
x0 R
x = forall a. Floating a => a -> a
exp(-(R
xforall a. Num a => a -> a -> a
-R
x0)forall a. Floating a => a -> a -> a
**R
2forall a. Fractional a => a -> a -> a
/(R
2forall a. Num a => a -> a -> a
*R
aforall a. Floating a => a -> a -> a
**R
2)) forall a. Fractional a => a -> a -> a
/ forall a. Floating a => a -> a
sqrt(R
a forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
sqrt forall a. Floating a => a
pi) forall a. a -> a -> Complex a
:+ R
0
movingGaussian
:: R
-> R
-> R
-> R -> C
movingGaussian :: R -> R -> R -> R -> Complex R
movingGaussian R
a R
x0 R
l0 R
x = forall a. Floating a => a -> a
exp((R
0 forall a. a -> a -> Complex a
:+ R
xforall a. Fractional a => a -> a -> a
/R
l0) forall a. Num a => a -> a -> a
- ((R
xforall a. Num a => a -> a -> a
-R
x0)forall a. Floating a => a -> a -> a
**R
2forall a. Fractional a => a -> a -> a
/(R
2forall a. Num a => a -> a -> a
*R
aforall a. Floating a => a -> a -> a
**R
2) forall a. a -> a -> Complex a
:+ R
0)) forall a. Fractional a => a -> a -> a
/ (forall a. Floating a => a -> a
sqrt(R
a forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
sqrt forall a. Floating a => a
pi) forall a. a -> a -> Complex a
:+ R
0)
fact :: Int -> Double
fact :: Int -> R
fact Int
0 = R
1
fact Int
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n forall a. Num a => a -> a -> a
* Int -> R
fact (Int
nforall a. Num a => a -> a -> a
-Int
1)
linspace :: Double -> Double -> Int -> [Double]
linspace :: R -> R -> Int -> [R]
linspace R
left R
right Int
num
= let dx :: R
dx = (R
right forall a. Num a => a -> a -> a
- R
left) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
num forall a. Num a => a -> a -> a
- Int
1)
in [ R
left forall a. Num a => a -> a -> a
+ R
dx forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n | Int
n <- [Int
0..Int
numforall a. Num a => a -> a -> a
-Int
1]]
stateVectorFromWavefunction :: R
-> R
-> Int
-> (R -> C)
-> Vector C
stateVectorFromWavefunction :: R -> R -> Int -> (R -> Complex R) -> Vector (Complex R)
stateVectorFromWavefunction R
left R
right Int
num R -> Complex R
psi
= (Int
num forall a. Storable a => Int -> [a] -> Vector a
|>) [R -> Complex R
psi R
x | R
x <- R -> R -> Int -> [R]
linspace R
left R
right Int
num]
hamiltonianMatrix :: R
-> R
-> Int
-> R
-> R
-> (R -> R)
-> Matrix C
hamiltonianMatrix :: R -> R -> Int -> R -> R -> (R -> R) -> Matrix (Complex R)
hamiltonianMatrix R
xmin R
xmax Int
num R
hbar R
m R -> R
pe
= let coeff :: R
coeff = -R
hbarforall a. Floating a => a -> a -> a
**R
2forall a. Fractional a => a -> a -> a
/(R
2forall a. Num a => a -> a -> a
*R
m)
dx :: R
dx = (R
xmax forall a. Num a => a -> a -> a
- R
xmin) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
num forall a. Num a => a -> a -> a
- Int
1)
diagKEterm :: R
diagKEterm = -R
2 forall a. Num a => a -> a -> a
* R
coeff forall a. Fractional a => a -> a -> a
/ R
dxforall a. Floating a => a -> a -> a
**R
2
offdiagKEterm :: R
offdiagKEterm = R
coeff forall a. Fractional a => a -> a -> a
/ R
dxforall a. Floating a => a -> a -> a
**R
2
xs :: [R]
xs = R -> R -> Int -> [R]
linspace R
xmin R
xmax Int
num
in forall t. Element t => [[t]] -> Matrix t
fromLists [[case forall a. Num a => a -> a
abs(Int
iforall a. Num a => a -> a -> a
-Int
j) of
Int
0 -> (R
diagKEterm forall a. Num a => a -> a -> a
+ R -> R
pe R
x) forall a. a -> a -> Complex a
:+ R
0
Int
1 -> R
offdiagKEterm forall a. a -> a -> Complex a
:+ R
0
Int
_ -> Complex R
0
| Int
j <- [Int
1..Int
num] ] | (Int
i,R
x) <- forall a b. [a] -> [b] -> [(a, b)]
zip [Int
1..Int
num] [R]
xs]
expectX :: Vector C
-> Vector R
-> R
expectX :: Vector (Complex R) -> Vector R -> R
expectX Vector (Complex R)
psi Vector R
xs = Vector (Complex R) -> Vector R
probVector Vector (Complex R)
psi forall t. Numeric t => Vector t -> Vector t -> t
<.> Vector R
xs
glossScaleX :: Int -> (Double,Double) -> Double -> Float
glossScaleX :: Int -> (R, R) -> R -> Float
glossScaleX Int
screenWidth (R
xmin,R
xmax) R
x
= let w :: R
w = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
screenWidth :: Double
in forall a b. (Real a, Fractional b) => a -> b
realToFrac forall a b. (a -> b) -> a -> b
$ (R
x forall a. Num a => a -> a -> a
- R
xmin) forall a. Fractional a => a -> a -> a
/ (R
xmax forall a. Num a => a -> a -> a
- R
xmin) forall a. Num a => a -> a -> a
* R
w forall a. Num a => a -> a -> a
- R
w forall a. Fractional a => a -> a -> a
/ R
2
glossScaleY :: Int -> (Double,Double) -> Double -> Float
glossScaleY :: Int -> (R, R) -> R -> Float
glossScaleY Int
screenHeight (R
ymin,R
ymax) R
y
= let h :: R
h = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
screenHeight :: Double
in forall a b. (Real a, Fractional b) => a -> b
realToFrac forall a b. (a -> b) -> a -> b
$ (R
y forall a. Num a => a -> a -> a
- R
ymin) forall a. Fractional a => a -> a -> a
/ (R
ymax forall a. Num a => a -> a -> a
- R
ymin) forall a. Num a => a -> a -> a
* R
h forall a. Num a => a -> a -> a
- R
h forall a. Fractional a => a -> a -> a
/ R
2
glossScalePoint :: (Int,Int)
-> (Double,Double)
-> (Double,Double)
-> (Double,Double)
-> (Float,Float)
glossScalePoint :: (Int, Int) -> (R, R) -> (R, R) -> (R, R) -> (Float, Float)
glossScalePoint (Int
screenWidth,Int
screenHeight) (R, R)
xMinMax (R, R)
yMinMax (R
x,R
y)
= (Int -> (R, R) -> R -> Float
glossScaleX Int
screenWidth (R, R)
xMinMax R
x
,Int -> (R, R) -> R -> Float
glossScaleY Int
screenHeight (R, R)
yMinMax R
y)
picture :: (Double, Double)
-> [Double]
-> Vector C
-> Picture
picture :: (R, R) -> [R] -> Vector (Complex R) -> Picture
picture (R
ymin,R
ymax) [R]
xs Vector (Complex R)
psi
= Color -> Picture -> Picture
Color
Color
yellow
(Path -> Picture
Line
[(Int, Int) -> (R, R) -> (R, R) -> (R, R) -> (Float, Float)
glossScalePoint
(Int
screenWidth,Int
screenHeight)
(forall a. [a] -> a
head [R]
xs, forall a. [a] -> a
last [R]
xs)
(R
ymin,R
ymax)
(R, R)
p | (R, R)
p <- forall a b. [a] -> [b] -> [(a, b)]
zip [R]
xs (forall a b. (a -> b) -> [a] -> [b]
map Complex R -> R
magSq forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Vector a -> [a]
toList Vector (Complex R)
psi)])
where
magSq :: Complex R -> R
magSq = \Complex R
z -> forall a. RealFloat a => Complex a -> a
magnitude Complex R
z forall a. Floating a => a -> a -> a
** R
2
screenWidth :: Int
screenWidth = Int
1000
screenHeight :: Int
screenHeight = Int
750
listForm :: (R,R,Vector C) -> ([R],Vector C)
listForm :: (R, R, Vector (Complex R)) -> ([R], Vector (Complex R))
listForm (R
xmin,R
xmax,Vector (Complex R)
v)
= let dt :: R
dt = (R
xmax forall a. Num a => a -> a -> a
- R
xmin) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (c :: * -> *) t. Container c t => c t -> IndexOf c
size Vector (Complex R)
v forall a. Num a => a -> a -> a
- Int
1)
in ([R
xmin, R
xmin forall a. Num a => a -> a -> a
+ R
dt .. R
xmax],Vector (Complex R)
v)
xRange :: R -> R -> Int -> [R]
xRange :: R -> R -> Int -> [R]
xRange R
xmin R
xmax Int
n
= let dt :: R
dt = (R
xmax forall a. Num a => a -> a -> a
- R
xmin) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
n forall a. Num a => a -> a -> a
- Int
1)
in [R
xmin, R
xmin forall a. Num a => a -> a -> a
+ R
dt .. R
xmax]