@@ -743,8 +743,8 @@ function _mul_left_nonvec!(r::AbstractVector{T}, l::AbstractVector{T}; phases::B
743743 s
744744end
745745
746- function mul_left! (r:: AbstractVector{T} , l:: AbstractVector{T} ; phases:: Bool = true ):: UInt8 where T<: Unsigned
747- if ! phases
746+ function mul_left! (r:: AbstractVector{T} , l:: AbstractVector{T} ; phases:: Val{B} = Val ( true )) :: UInt8 where { T<: Unsigned , B}
747+ if ! B
748748 r .⊻= l
749749 return UInt8 (0x0 )
750750 end
@@ -789,16 +789,16 @@ function mul_left!(r::AbstractVector{T}, l::AbstractVector{T}; phases::Bool=true
789789 UInt8 ((rcnt1 ⊻ (rcnt2<< 1 ))& 0x3 )
790790end
791791
792- @inline function mul_left! (r:: PauliOperator , l:: PauliOperator ; phases:: Bool = true )
792+ @inline function mul_left! (r:: PauliOperator , l:: PauliOperator ; phases:: Val{B} = Val ( true )) where B
793793 nqubits (l)== nqubits (r) || throw (DimensionMismatch (" The two Pauli operators should have the same length!" )) # TODO skip this when @inbounds is set
794794 s = mul_left! (r. xz, l. xz, phases= phases)
795- phases && (r. phase[] = (s+ r. phase[]+ l. phase[])& 0x3 )
795+ B && (r. phase[] = (s+ r. phase[]+ l. phase[])& 0x3 )
796796 r
797797end
798798
799- @inline function mul_left! (r:: PauliOperator , l:: Stabilizer , i:: Int ; phases:: Bool = true )
799+ @inline function mul_left! (r:: PauliOperator , l:: Stabilizer , i:: Int ; phases:: Val{B} = Val ( true )) where B
800800 s = mul_left! (r. xz, (@view l. xzs[:,i]), phases= phases)
801- phases && (r. phase[] = (s+ r. phase[]+ l. phases[i])& 0x3 )
801+ B && (r. phase[] = (s+ r. phase[]+ l. phases[i])& 0x3 )
802802 r
803803end
804804
@@ -861,24 +861,24 @@ end
861861 rowswap! (s. tab, i+ n, j+ n; phases= phases)
862862end
863863
864- @inline function mul_left! (s:: Stabilizer , m, i; phases:: Bool = true )
864+ @inline function mul_left! (s:: Stabilizer , m, i; phases:: Val{B} = Val ( true )) where B
865865 extra_phase = mul_left! ((@view s. xzs[:,m]), (@view s. xzs[:,i]); phases= phases)
866- phases && (s. phases[m] = (extra_phase+ s. phases[m]+ s. phases[i])& 0x3 )
866+ B && (s. phases[m] = (extra_phase+ s. phases[m]+ s. phases[i])& 0x3 )
867867 s
868868end
869869
870- @inline function mul_left! (s:: Destabilizer , i, j; phases:: Bool = true )
871- mul_left! (s. tab, j, i; phases= false ) # Indices are flipped to preserve commutation constraints
870+ @inline function mul_left! (s:: Destabilizer , i, j; phases:: Val{B} = Val ( true )) where B
871+ mul_left! (s. tab, j, i; phases= Val ( false ) ) # Indices are flipped to preserve commutation constraints
872872 n = size (s. tab,1 )÷ 2
873873 mul_left! (s. tab, i+ n, j+ n; phases= phases)
874874end
875875
876- @inline function mul_left! (s:: MixedStabilizer , i, j; phases:: Bool = true )
876+ @inline function mul_left! (s:: MixedStabilizer , i, j; phases:: Val{B} = Val ( true )) where B
877877 mul_left! (s. tab, i, j; phases= phases)
878878end
879879
880- @inline function mul_left! (s:: MixedDestabilizer , i, j; phases:: Bool = true )
881- mul_left! (s. tab, j, i; phases= false ) # Indices are flipped to preserve commutation constraints
880+ @inline function mul_left! (s:: MixedDestabilizer , i, j; phases:: Val{B} = Val ( true )) where B
881+ mul_left! (s. tab, j, i; phases= Val ( false ) ) # Indices are flipped to preserve commutation constraints
882882 n = nqubits (s)
883883 mul_left! (s. tab, i+ n, j+ n; phases= phases)
884884end
@@ -1028,6 +1028,7 @@ Based on [garcia2012efficient](@cite).
10281028See also: [`canonicalize_rref!`](@ref), [`canonicalize_gott!`](@ref)
10291029"""
10301030function canonicalize! (state:: AbstractStabilizer ; phases:: Bool = true , ranks:: Bool = false )
1031+ _phases = Val (phases)
10311032 xzs = stabilizerview (state). xzs
10321033 xs = @view xzs[1 : end ÷ 2 ,:]
10331034 zs = @view xzs[end ÷ 2 + 1 : end ,:]
@@ -1047,7 +1048,7 @@ function canonicalize!(state::AbstractStabilizer; phases::Bool=true, ranks::Bool
10471048 rowswap! (state, k, i; phases= phases)
10481049 for m in 1 : rows
10491050 if xs[jbig,m]& jsmall!= zerobit && m!= i # if X or Y
1050- mul_left! (state, m, i; phases= phases )
1051+ mul_left! (state, m, i; phases= _phases )
10511052 end
10521053 end
10531054 i += 1
@@ -1065,7 +1066,7 @@ function canonicalize!(state::AbstractStabilizer; phases::Bool=true, ranks::Bool
10651066 rowswap! (state, k, i; phases= phases)
10661067 for m in 1 : rows
10671068 if zs[jbig,m]& jsmall!= zerobit && m!= i # if Z or Y
1068- mul_left! (state, m, i; phases= phases )
1069+ mul_left! (state, m, i; phases= _phases )
10691070 end
10701071 end
10711072 i += 1
@@ -1094,6 +1095,7 @@ Based on [audenaert2005entanglement](@cite).
10941095See also: [`canonicalize!`](@ref), [`canonicalize_gott!`](@ref)
10951096"""
10961097function canonicalize_rref! (state:: AbstractStabilizer , colindices; phases:: Bool = true )
1098+ _phases = Val (phases)
10971099 xzs = stabilizerview (state). xzs
10981100 xs = @view xzs[1 : end ÷ 2 ,:]
10991101 zs = @view xzs[end ÷ 2 + 1 : end ,:]
@@ -1111,7 +1113,7 @@ function canonicalize_rref!(state::AbstractStabilizer, colindices; phases::Bool=
11111113 rowswap! (state, k, i; phases= phases)
11121114 for m in 1 : rows
11131115 if xs[jbig,m]& jsmall!= zerobit && m!= i # if X or Y
1114- mul_left! (state, m, i; phases= phases )
1116+ mul_left! (state, m, i; phases= _phases )
11151117 end
11161118 end
11171119 i -= 1
@@ -1122,7 +1124,7 @@ function canonicalize_rref!(state::AbstractStabilizer, colindices; phases::Bool=
11221124 rowswap! (state, k, i; phases= phases)
11231125 for m in 1 : rows
11241126 if zs[jbig,m]& jsmall!= zerobit && m!= i # if Z or Y
1125- mul_left! (state, m, i; phases= phases )
1127+ mul_left! (state, m, i; phases= _phases )
11261128 end
11271129 end
11281130 i -= 1
@@ -1178,6 +1180,7 @@ Based on [gottesman1997stabilizer](@cite).
11781180See also: [`canonicalize!`](@ref), [`canonicalize_rref!`](@ref)
11791181"""
11801182function canonicalize_gott! (stabilizer:: Stabilizer{Tzv,Tm} ; phases:: Bool = true ) where {Tzv<: AbstractVector{UInt8} , Tme<: Unsigned , Tm<: AbstractMatrix{Tme} }
1183+ _phases = Val (phases)
11811184 xzs = stabilizer. xzs
11821185 xs = @view xzs[1 : end ÷ 2 ,:]
11831186 zs = @view xzs[end ÷ 2 + 1 : end ,:]
@@ -1196,7 +1199,7 @@ function canonicalize_gott!(stabilizer::Stabilizer{Tzv,Tm}; phases::Bool=true) w
11961199 rowswap! (stabilizer, k, i; phases= phases)
11971200 for m in 1 : rows
11981201 if xs[jbig,m]& jsmall!= zerobit && m!= i # if X or Y
1199- mul_left! (stabilizer, m, i; phases= phases )
1202+ mul_left! (stabilizer, m, i; phases= _phases )
12001203 end
12011204 end
12021205 i += 1
@@ -1216,7 +1219,7 @@ function canonicalize_gott!(stabilizer::Stabilizer{Tzv,Tm}; phases::Bool=true) w
12161219 rowswap! (stabilizer, k, i; phases= phases)
12171220 for m in 1 : rows
12181221 if zs[jbig,m]& jsmall!= zerobit && m!= i # if Z or Y
1219- mul_left! (stabilizer, m, i; phases= phases )
1222+ mul_left! (stabilizer, m, i; phases= _phases )
12201223 end
12211224 end
12221225 i += 1
@@ -1427,7 +1430,7 @@ function _apply_nonthread!(stab::AbstractStabilizer, c::CliffordOperator; phases
14271430 new_stabrow = zero (s_tab[1 ])
14281431 for row_stab in eachindex (s_tab)
14291432 zero! (new_stabrow)
1430- apply_row_kernel! (new_stabrow, row_stab, s_tab, c_tab, phases= phases)
1433+ apply_row_kernel! (new_stabrow, row_stab, s_tab, c_tab, phases= Val ( phases) )
14311434 end
14321435 stab
14331436end
@@ -1439,19 +1442,19 @@ function _apply!(stab::AbstractStabilizer, c::CliffordOperator; phases::Val{B}=V
14391442 c_tab = tab (c)
14401443 @batch minbatch= 25 threadlocal= zero (c_tab[1 ]) for row_stab in eachindex (s_tab)
14411444 zero! (threadlocal) # a new stabrow for temporary storage
1442- apply_row_kernel! (threadlocal, row_stab, s_tab, c_tab, phases= B )
1445+ apply_row_kernel! (threadlocal, row_stab, s_tab, c_tab, phases= phases )
14431446 end
14441447 stab
14451448end
14461449
14471450# TODO Added a lot of type assertions to help Julia infer types, but they are much too strict for cases where bitpacking varies (check tests)
14481451# @inline function apply_row_kernel!(new_stabrow::PauliOperator{Array{UInt8,0},Vector{Tme}}, row::Int, s_tab::Stabilizer{Tv,Tm}, c_tab::Stabilizer{Tv,Tm}; phases=true) where {Tme,Tv<:AbstractVector{UInt8},Tm<:AbstractMatrix{Tme}}
1449- @inline function apply_row_kernel! (new_stabrow, row, s_tab, c_tab; phases= true )
1450- phases && (new_stabrow. phase[] = s_tab. phases[row])
1452+ @inline function apply_row_kernel! (new_stabrow, row, s_tab, c_tab; phases:: Val{B} = Val ( true )) where B
1453+ B && (new_stabrow. phase[] = s_tab. phases[row])
14511454 n = nqubits (c_tab)
14521455 for qubit in 1 : n
14531456 x,z = s_tab[row,qubit]
1454- if phases && x&& z
1457+ if B && x&& z
14551458 new_stabrow. phase[] -= 0x1
14561459 end
14571460 if x
@@ -1472,7 +1475,7 @@ function _apply_nonthread!(stab::AbstractStabilizer, c::CliffordOperator, indice
14721475 new_stabrow = zero (PauliOperator,nqubits (c))
14731476 for row in eachindex (s_tab)
14741477 zero! (new_stabrow)
1475- apply_row_kernel! (new_stabrow, row, s_tab, c_tab, indices_of_application; phases= phases)
1478+ apply_row_kernel! (new_stabrow, row, s_tab, c_tab, indices_of_application; phases= Val ( phases) )
14761479 end
14771480 stab
14781481end
@@ -1484,17 +1487,17 @@ function _apply!(stab::AbstractStabilizer, c::CliffordOperator, indices_of_appli
14841487 c_tab = tab (c)
14851488 @batch minbatch= 25 threadlocal= zero (c_tab[1 ]) for row_stab in eachindex (s_tab)
14861489 zero! (threadlocal) # a new stabrow for temporary storage
1487- apply_row_kernel! (threadlocal, row_stab, s_tab, c_tab, indices_of_application, phases= B )
1490+ apply_row_kernel! (threadlocal, row_stab, s_tab, c_tab, indices_of_application, phases= phases )
14881491 end
14891492 stab
14901493end
14911494
1492- @inline function apply_row_kernel! (new_stabrow, row, s_tab, c_tab, indices_of_application; phases= true )
1493- phases && (new_stabrow. phase[] = s_tab. phases[row])
1495+ @inline function apply_row_kernel! (new_stabrow, row, s_tab, c_tab, indices_of_application; phases:: Val{B} = Val ( true )) where B
1496+ B && (new_stabrow. phase[] = s_tab. phases[row])
14941497 n = nqubits (c_tab)
14951498 for (qubit_i, qubit) in enumerate (indices_of_application)
14961499 x,z = s_tab[row,qubit]
1497- if phases && x&& z
1500+ if B && x&& z
14981501 new_stabrow. phase[] -= 0x1
14991502 end
15001503 if x
@@ -1507,7 +1510,7 @@ end
15071510 for (qubit_i, qubit) in enumerate (indices_of_application)
15081511 s_tab[row,qubit] = new_stabrow[qubit_i]
15091512 end
1510- phases && (s_tab. phases[row] = new_stabrow. phase[])
1513+ B && (s_tab. phases[row] = new_stabrow. phase[])
15111514 new_stabrow
15121515end
15131516
0 commit comments