diff --git a/src/instruct.jl b/src/instruct.jl index 314ef2b3f..9d9723ad5 100644 --- a/src/instruct.jl +++ b/src/instruct.jl @@ -398,3 +398,29 @@ function YaoBase.instruct!( end return state end + +function YaoBase.instruct!( + state::AbstractVecOrMat{T}, + ::Val{:PSWAP}, + locs::Tuple{Int, Int}, + theta::Real) where T + mask1 = bmask(locs[1]) + mask2 = bmask(locs[2]) + mask12 = mask1|mask2 + a = T(cos(theta/2)) + c = T(-im * sin(theta/2)) + e = T(exp(-im/2*theta)) + for b in basis(state) + if b&mask1==0 + i = b+1 + i_ = b ⊻ mask12 + 1 + if b&mask2==mask2 + u1rows!(state, i, i_, a, c, c, a) + else + mulrow!(state, i, e) + mulrow!(state, i_, e) + end + end + end + return state +end diff --git a/test/instruct.jl b/test/instruct.jl index 7eeaf4dc9..46b28e6fd 100644 --- a/test/instruct.jl +++ b/test/instruct.jl @@ -91,6 +91,12 @@ end @test instruct!(copy(ST), Val(:SWAP), (1, 2)) ≈ SWAP * ST end +@testset "pswap instruction" begin + ST = randn(ComplexF64, 1 << 2) + θ = π/3 + @test instruct!(copy(ST), Val(:PSWAP), (1, 2), θ) ≈ (cos(θ/2)*IMatrix{4}() - im*sin(θ/2)* SWAP) * ST +end + @testset "Yao.jl/#189" begin st = rand(1<<4) @test instruct!(st, IMatrix{2, Float64}(), 1) == st