{-# LANGUAGE OverloadedLists #-}
module Lib.Internal.Core where
import Data.Bit ( Bit )
import Lib.QM ( QState(QState), Ix, QBit (Ptr), stateSize )
import Data.Bits ( Bits((.&.)) )
import Numeric.LinearAlgebra
( Complex,
magnitude,
flatten,
outer,
normalize,
size,
toList,
fromList,
C,
Vector )
import qualified Control.Monad.Random as Rand ( fromList, evalRandIO )
appendState :: QState -> QState -> QState
appendState :: QState -> QState -> QState
appendState (QState new :: Vector C
new) (QState []) = Vector C -> QState
QState Vector C
new
appendState (QState new :: Vector C
new) (QState state :: Vector C
state) = Vector C -> QState
QState (Vector C -> QState) -> Vector C -> QState
forall a b. (a -> b) -> a -> b
$ Vector C -> Vector C -> Vector C
tensorVector Vector C
new Vector C
state
tensorVector :: Vector C -> Vector C -> Vector C
tensorVector :: Vector C -> Vector C -> Vector C
tensorVector newVector :: Vector C
newVector oldVector :: Vector C
oldVector = Matrix C -> Vector C
forall t. Element t => Matrix t -> Vector t
flatten (Matrix C -> Vector C) -> Matrix C -> Vector C
forall a b. (a -> b) -> a -> b
$ Vector C -> Vector C -> Matrix C
forall t. Product t => Vector t -> Vector t -> Matrix t
outer Vector C
oldVector Vector C
newVector
newVector :: Bit -> QState
newVector :: Bit -> QState
newVector 0 = Vector C -> QState
QState [1, 0]
newVector 1 = Vector C -> QState
QState [0, 1]
type Prob = Rational
findQbitProb1 :: QBit -> QState -> Prob
findQbitProb1 :: QBit -> QState -> Prob
findQbitProb1 qbit :: QBit
qbit qstate :: QState
qstate = [Prob] -> Prob
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Prob] -> Prob) -> [Prob] -> Prob
forall a b. (a -> b) -> a -> b
$ (C -> Prob) -> [C] -> [Prob]
forall a b. (a -> b) -> [a] -> [b]
map C -> Prob
ampToProb (QBit -> QState -> [C]
findMarginAmps1 QBit
qbit QState
qstate)
type Amplitude = Complex Double
findMarginAmps1 :: QBit -> QState -> [Amplitude]
findMarginAmps1 :: QBit -> QState -> [C]
findMarginAmps1 qbit :: QBit
qbit qstate :: QState
qstate = ((Ix, C) -> C) -> [(Ix, C)] -> [C]
forall a b. (a -> b) -> [a] -> [b]
map (Ix, C) -> C
forall a b. (a, b) -> b
snd ([(Ix, C)] -> [C]) -> [(Ix, C)] -> [C]
forall a b. (a -> b) -> a -> b
$ ((Ix, C) -> Bool) -> [(Ix, C)] -> [(Ix, C)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Ix, C) -> Bool
isMargin [(Ix, C)]
allAmps
where
allAmps :: [(Ix, Amplitude)]
allAmps :: [(Ix, C)]
allAmps = QState -> [(Ix, C)]
qstateAmps QState
qstate
isMargin :: (Ix, Amplitude) -> Bool
isMargin :: (Ix, C) -> Bool
isMargin (ix :: Ix
ix, _) = Ix -> Ix -> Bool
maskMatch Ix
ix Ix
ixMask
ixMask :: Ix
ixMask = QBit -> QState -> Ix
qbitMask QBit
qbit QState
qstate
maskMatch :: Int -> Int -> Bool
maskMatch :: Ix -> Ix -> Bool
maskMatch a :: Ix
a b :: Ix
b = Ix
a Ix -> Ix -> Ix
forall a. Bits a => a -> a -> a
.&. Ix
b Ix -> Ix -> Bool
forall a. Eq a => a -> a -> Bool
== Ix
b
qbitMask :: QBit -> QState -> Int
qbitMask :: QBit -> QState -> Ix
qbitMask (Ptr qbitIx :: Ix
qbitIx) qstate :: QState
qstate = 2Ix -> Ix -> Ix
forall a b. (Num a, Integral b) => a -> b -> a
^(Ix
numQbits Ix -> Ix -> Ix
forall a. Num a => a -> a -> a
- 1 Ix -> Ix -> Ix
forall a. Num a => a -> a -> a
- Ix
qbitIx)
where
numQbits :: Ix
numQbits = QState -> Ix
stateSize QState
qstate
ampToProb :: Amplitude -> Prob
ampToProb :: C -> Prob
ampToProb = Double -> Prob
forall a. Real a => a -> Prob
toRational (Double -> Prob) -> (C -> Double) -> C -> Prob
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> Integer -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^2) (Double -> Double) -> (C -> Double) -> C -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. C -> Double
forall a. RealFloat a => Complex a -> a
magnitude
remImpossibleStates :: QState -> QBit -> Bit -> QState
remImpossibleStates :: QState -> QBit -> Bit -> QState
remImpossibleStates qstate :: QState
qstate qbit :: QBit
qbit bit :: Bit
bit = (Vector C -> QState
QState (Vector C -> QState)
-> ([(Ix, C)] -> Vector C) -> [(Ix, C)] -> QState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector C -> Vector C
forall t.
(Normed (Vector t), Num (Vector t), Field t) =>
Vector t -> Vector t
normalize (Vector C -> Vector C)
-> ([(Ix, C)] -> Vector C) -> [(Ix, C)] -> Vector C
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [C] -> Vector C
forall a. Storable a => [a] -> Vector a
fromList ([C] -> Vector C) -> ([(Ix, C)] -> [C]) -> [(Ix, C)] -> Vector C
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Ix, C) -> C) -> [(Ix, C)] -> [C]
forall a b. (a -> b) -> [a] -> [b]
map (Ix, C) -> C
transformAmp) [(Ix, C)]
amps
where
amps :: [(Ix, C)]
amps = QState -> [(Ix, C)]
qstateAmps QState
qstate
ixMask :: Ix
ixMask = QBit -> QState -> Ix
qbitMask QBit
qbit QState
qstate
transformAmp :: (Ix, Amplitude) -> Amplitude
transformAmp :: (Ix, C) -> C
transformAmp (ix :: Ix
ix, amp :: C
amp) | Ix -> Bool
impossibleState Ix
ix = 0
| Bool
otherwise = C
amp
impossibleState :: Ix -> Bool
impossibleState :: Ix -> Bool
impossibleState ix :: Ix
ix | Ix -> Ix -> Bool
maskMatch Ix
ix Ix
ixMask = Bit
bit Bit -> Bit -> Bool
forall a. Eq a => a -> a -> Bool
== 0
| Bool
otherwise = Bit
bit Bit -> Bit -> Bool
forall a. Eq a => a -> a -> Bool
== 1
qstateAmps :: QState -> [(Ix, Amplitude)]
qstateAmps :: QState -> [(Ix, C)]
qstateAmps (QState stateVector :: Vector C
stateVector) = [Ix] -> [C] -> [(Ix, C)]
forall a b. [a] -> [b] -> [(a, b)]
zip [0..] (Vector C -> [C]
forall a. Storable a => Vector a -> [a]
toList Vector C
stateVector)
rngQbit :: Prob -> IO Bit
rngQbit :: Prob -> IO Bit
rngQbit p1 :: Prob
p1 = Rand StdGen Bit -> IO Bit
forall a. Rand StdGen a -> IO a
Rand.evalRandIO (Rand StdGen Bit -> IO Bit) -> Rand StdGen Bit -> IO Bit
forall a b. (a -> b) -> a -> b
$ [(Bit, Prob)] -> Rand StdGen Bit
forall (m :: * -> *) a. MonadRandom m => [(a, Prob)] -> m a
Rand.fromList [(0, 1Prob -> Prob -> Prob
forall a. Num a => a -> a -> a
-Prob
p1), (1, Prob
p1)]