@@ -9,17 +9,20 @@ export BellState,
99 BellSinglePermutation, BellDoublePermutation, BellPauliPermutation,
1010 BellMeasure, bellmeasure!,
1111 BellGate, CNOTPerm, GoodSingleQubitPerm,
12- PauliNoiseOp, PauliNoiseBellGate, NoisyBellMeasure, NoisyBellMeasureNoisyReset
12+ PauliNoiseOp, PauliNoiseBellGate, NoisyBellMeasure, NoisyBellMeasureNoisyReset,
13+ BellSwap, NoisyBellSwap
1314
14- function int_to_bit (int,digits)
15+ const IT = Union{Int8,Int16,Int32,Int64,UInt8,UInt16,UInt32,UInt64}
16+
17+ function int_to_bit (int:: IT ,digits)
1518 int = int - 1 # -1 so that we use julia indexing conventions
1619 Bool[int>> shift& 0x1 for shift in 0 : digits- 1 ]
1720end
18- @inline function int_to_bit (int,:: Val{2} ) # faster if we know we need only two bits
21+ @inline function int_to_bit (int:: IT ,:: Val{2} ) # faster if we know we need only two bits
1922 int = int - 1 # -1 so that we use julia indexing conventions
2023 int & 0x1 , int>> 1 & 0x1
2124end
22- @inline function int_to_bit (int,:: Val{4} ) # faster if we know we need only two bits
25+ @inline function int_to_bit (int:: IT ,:: Val{4} ) # faster if we know we need only two bits
2326 int = int - 1 # -1 so that we use julia indexing conventions
2427 int & 0x1 , int>> 1 & 0x1 , int>> 2 & 0x1 , int>> 3 & 0x1
2528end
@@ -367,6 +370,27 @@ function QuantumClifford.apply!(state::BellState, g::BellGate)
367370 return state
368371end
369372
373+ # #############################
374+ # SWAP gate
375+ # #############################
376+
377+ """ SWAP gate"""
378+ struct BellSwap <: BellOp
379+ idx1:: Int
380+ idx2:: Int
381+ end
382+
383+ function QuantumClifford. apply! (state:: BellState , op:: BellSwap )
384+ phase = state. phases
385+ @inbounds temp1 = phase[op. idx1* 2 - 1 ]
386+ @inbounds temp2 = phase[op. idx1* 2 ]
387+ @inbounds phase[op. idx1* 2 - 1 ] = phase[op. idx2* 2 - 1 ]
388+ @inbounds phase[op. idx1* 2 ] = phase[op. idx2* 2 ]
389+ @inbounds phase[op. idx2* 2 - 1 ] = temp1
390+ @inbounds phase[op. idx2* 2 ] = temp2
391+ return state
392+ end
393+
370394# #############################
371395# Typically good operations
372396# #############################
@@ -518,6 +542,112 @@ function QuantumClifford.apply!(state::BellState, g::PauliNoiseOp)
518542 return state
519543end
520544
545+ """ Simulates bilateral twirled T1 noise with per-qubit Kraus ops `|0⟩⟨0| + √(1-λ) |1⟩⟨1|` and `√λ |0⟩⟨1|`"""
546+ struct T1NoiseOp <: BellOp
547+ idx:: Int
548+ λ₁:: Float64
549+ end
550+
551+ function QuantumClifford. apply! (state:: BellState , g:: T1NoiseOp )
552+ phase = state. phases
553+ input_state = bit_to_int (phase[g. idx* 2 - 1 ],phase[g. idx* 2 ]) # this is my initial state
554+
555+ r = rand ()
556+ λ₁ = g. λ₁
557+
558+ output_state = if input_state== 1
559+ if r < 0.5 * λ₁^ 2 - λ₁ + 1
560+ 1
561+ elseif r < 0.5 * λ₁^ 2 - λ₁ + 1 + 0.5 * λ₁^ 2
562+ 2 # XXX
563+ elseif r < 0.5 * λ₁^ 2 - λ₁ + 1 + 0.5 * λ₁^ 2 + 0.5 * λ₁* (1 - λ₁)
564+ 3 # XXX
565+ else # r < 1 = 0.5*λ₁^2 - λ₁ + 1 + 0.5*λ₁*(1-λ₁) + 0.5*λ₁^2 + 0.5*λ₁*(1-λ₁)
566+ 4
567+ end
568+ elseif input_state== 2
569+ if r < 0.5 * λ₁^ 2
570+ 1
571+ elseif r < 0.5 * λ₁^ 2 + 0.5 * λ₁^ 2 - λ₁ + 1
572+ 2 # XXX
573+ elseif r < 0.5 * λ₁^ 2 + 0.5 * λ₁^ 2 - λ₁ + 1 + 0.5 * λ₁* (1 - λ₁)
574+ 3 # XXX
575+ else # r < 1 = 0.5*λ₁^2 + 0.5*λ₁^2 -λ₁ + 1 + 0.5*λ₁*(1-λ₁) + 0.5*λ₁*(1-λ₁)
576+ 4
577+ end
578+ elseif input_state== 3
579+ if r < 0.5 * λ₁
580+ 1
581+ elseif r < 0.5 * λ₁ + 0.5 * λ₁
582+ 2 # XXX
583+ elseif r < 0.5 * λ₁ + 0.5 * λ₁ + (1 - λ₁)
584+ 3 # XXX
585+ else # r < 1 = 0.5*λ₁ + 0.5*λ₁ + (1-λ₁) + 0
586+ 4
587+ end
588+ else # input_state==4
589+ if r < 0.5 * λ₁
590+ 1
591+ elseif r < 0.5 * λ₁ + 0.5 * λ₁
592+ 2 # XXX
593+ # elseif r < 0.5*λ₁ + 0.5*λ₁ + 0 # output_state 3 is never reached
594+ # 3 # XXX
595+ else # r < 1 = 0.5*λ₁ + 0.5*λ₁ + 0 + 1-λ₁
596+ 4
597+ end
598+ end
599+
600+ bit1, bit2 = int_to_bit (output_state, Val (2 ))
601+ @inbounds phase[g. idx* 2 - 1 ] = bit1
602+ @inbounds phase[g. idx* 2 ] = bit2
603+ return state
604+ end
605+
606+ """ Simulates bilateral T2 noise with per-qubit Kraus ops `√(1-λ/2) I` and `√(λ/2) Z`"""
607+ struct T2NoiseOp <: BellOp
608+ idx:: Int
609+ λ₂:: Float64
610+ end
611+
612+ function QuantumClifford. apply! (state:: BellState , g:: T2NoiseOp )
613+ phase = state. phases
614+ input_state = bit_to_int (phase[g. idx* 2 - 1 ],phase[g. idx* 2 ]) # this is my initial state
615+
616+ r = rand ()
617+ λ₂ = g. λ₂
618+
619+ output_state = if input_state== 1
620+ if r < 0.5 * λ₂^ 2 - λ₂ + 1
621+ 1
622+ else # r < 1 = 0.5*λ₂^2 - λ₂ + 1 + 0.5*λ₂*(2-λ₂)
623+ 2
624+ end
625+ elseif input_state== 2
626+ if r < 0.5 * λ₂^ 2 - λ₂ + 1
627+ 2
628+ else # r < 1 = 0.5*λ₂^2 - λ₂ + 1 + 0.5*λ₂*(2-λ₂)
629+ 1
630+ end
631+ elseif input_state== 3
632+ if r < 0.5 * λ₂^ 2 - λ₂ + 1
633+ 3
634+ else # r < 1 = 0.5*λ₂^2 - λ₂ + 1 + 0.5*λ₂*(2-λ₂)
635+ 4
636+ end
637+ else # input_state==4
638+ if r < 0.5 * λ₂^ 2 - λ₂ + 1
639+ 4
640+ else # r < 1 = 0.5*λ₂^2 - λ₂ + 1 + 0.5*λ₂*(2-λ₂)
641+ 3
642+ end
643+ end
644+
645+ bit1, bit2 = int_to_bit (output_state, Val (2 ))
646+ @inbounds phase[g. idx* 2 - 1 ] = bit1
647+ @inbounds phase[g. idx* 2 ] = bit2
648+ return state
649+ end
650+
521651""" A wrapper for [`BellMeasure`](@ref) that implements measurement noise."""
522652struct NoisyBellMeasure <: BellOp # TODO make it work with the QuantumClifford noise ops
523653 m:: BellMeasure
@@ -545,6 +675,11 @@ function QuantumClifford.applywstatus!(state::BellState, op::NoisyBellMeasureNoi
545675 state, cont ? continue_stat : failure_stat
546676end
547677
678+ function NoisyBellSwap (idx1,idx2,px,py,pz)
679+ return PauliNoiseBellGate (BellSwap (idx1,idx2), px,py,pz)
680+ end
681+
682+
548683# #############################
549684# Random
550685# #############################
@@ -703,12 +838,12 @@ function toBPpermutation1(circ) # this one works only on single pair mappings th
703838end
704839
705840function BellState (s:: Stabilizer )
706- r, c = size (s)
841+ r, c = size (s):: Tuple{Int, Int}
707842 r== c || throw (ArgumentError (" Conversion to `BellState` failed. The stabilizer state has to be square in order to be convertible to a `BellState`." ))
708- s = canonicalize_rref! (copy (s))[1 ][end : - 1 : 1 ]
843+ s = canonicalize_rref! (copy (s))[1 ][end : - 1 : 1 ]:: Stabilizer
709844 bits = Bool[]
710845 for i in 1 : r÷ 2
711- j = 2 i- 1
846+ j = ( 2 i- 1 )
712847 s[j ,j] == s[j ,j+ 1 ] == (true , false ) && all (== ((false ,false )), (s[j ,k] for k in 1 : c if k!= j && k!= j+ 1 )) || throw (ArgumentError (lazy " Conversion to `BellState` failed. Row $(j ) of the stabilizer state has to be of the form `..._XX_...` for it to be a valid `BellState`" ))
713848 s[j+ 1 ,j] == s[j+ 1 ,j+ 1 ] == (false , true ) && all (== ((false ,false )), (s[j+ 1 ,k] for k in 1 : c if k!= j && k!= j+ 1 )) || throw (ArgumentError (lazy " Conversion to `BellState` failed. Row $(j+1) row of the stabilizer state has to be of the form `..._ZZ_...` for it to be a valid `BellState`" ))
714849 push! (bits, s. tab. phases[j]÷ 2 )
0 commit comments