Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ TermInterface = "8ea1fca8-c5ef-4a55-8b96-4e9afe9c9a3c"
Gabs = "0eb812ee-a11f-4f5e-b8d4-bb8a44f06f50"
QuantumClifford = "0525e862-1e90-11e9-3e4d-1b39d7109de1"
QuantumOpticsBase = "4f57444f-1401-5e15-980d-4471b28d5678"
QuantumToolbox = "6c2fb7c5-b903-41d2-bc5e-5a7c320b9fab"

[extensions]
GabsExt = "Gabs"
MixedCliffordOpticsExt = ["QuantumClifford", "QuantumOpticsBase"]
QuantumCliffordExt = "QuantumClifford"
QuantumOpticsExt = "QuantumOpticsBase"
QuantumToolboxExt = "QuantumToolbox"

[compat]
Gabs = "1.3.1"
Expand All @@ -33,6 +35,7 @@ PrecompileTools = "1.2"
QuantumClifford = "0.8.19, 0.9, 0.10"
QuantumInterface = "0.3.7, 0.4.1"
QuantumOpticsBase = "0.4.22, 0.5"
QuantumToolbox = "0.32.0"
SymbolicUtils = "3.7"
Symbolics = "6"
TermInterface = "2"
Expand Down
85 changes: 85 additions & 0 deletions ext/QuantumToolboxExt/QuantumToolboxExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
module QuantumToolboxExt

using QuantumToolbox
using QuantumSymbolics
using QuantumSymbolics:
HGate, XGate, YGate, ZGate, CPHASEGate, CNOTGate, PauliP, PauliM,
XCXGate, XCYGate, XCZGate, YCXGate, YCYGate, YCZGate, ZCXGate, ZCYGate, ZCZGate,
XBasisState, YBasisState, ZBasisState,
NumberOp, CreateOp, DestroyOp,
FockState,
MixedState, IdentityOp, STensor,
qubit_basis
import QuantumSymbolics: express, express_nolookup
using TermInterface
using TermInterface: isexpr, head, operation, arguments, metadata

const _l0 = QuantumToolbox.basis(2,0)
const _l1 = QuantumToolbox.basis(2,1)
const _s₊ = (_l0+_l1)/√2
const _s₋ = (_l0-_l1)/√2
const _i₊ = (_l0+im*_l1)/√2
const _i₋ = (_l0-im*_l1)/√2
const _σ₊ = QuantumToolbox.sigmap()
const _σ₋ = QuantumToolbox.sigmam()
const _l00 = QuantumToolbox.proj(_l0)
const _l11 = QuantumToolbox.proj(_l1)
const _id = QuantumToolbox.qeye(2)
const _z = QuantumToolbox.sigmaz()
const _x = QuantumToolbox.sigmax()
const _y = QuantumToolbox.sigmay()
const _hadamard = (_z+_x)/√2
const _cnot = QuantumToolbox.tensor(_l00,_id) + QuantumToolbox.tensor(_l11,_x)
const _cphase = QuantumToolbox.tensor(_l00,_id) + QuantumToolbox.tensor(_l11,_z)
const _phase = _l00 + im*_l11
const _iphase = _l00 - im*_l11

const _f0₂ = QuantumToolbox.basis(2, 0)
const _f1₂ = QuantumToolbox.basis(2, 1)
const _ad₂ = QuantumToolbox.create(2)
const _a₂ = QuantumToolbox.destroy(2)
const _n₂ = QuantumToolbox.num(2)

express_nolookup(::HGate, ::QuantumToolboxRepr) = _hadamard
express_nolookup(::XGate, ::QuantumToolboxRepr) = _x
express_nolookup(::YGate, ::QuantumToolboxRepr) = _y
express_nolookup(::ZGate, ::QuantumToolboxRepr) = _z
express_nolookup(::CPHASEGate, ::QuantumToolboxRepr) = _cphase
express_nolookup(::CNOTGate, ::QuantumToolboxRepr) = _cnot

const xyzopdict = Dict(:X=>_x, :Y=>_y, :Z=>_z)
const xyzstatedict = Dict(:X=>(_s₊,_s₋),:Y=>(_i₊,_i₋),:Z=>(_l0,_l1))
for control in (:X, :Y, :Z)
for target in (:X, :Y, :Z)
k1, k2 = xyzstatedict[control]
o = xyzopdict[target]
gate = QuantumToolbox.tensor(proj(k1),_id) + QuantumToolbox.tensor(proj(k2),o)
structname = Symbol(control,"C",target,"Gate")
let gate=copy(gate)
@eval express_nolookup(::$(structname), ::QuantumToolboxRepr) = $gate
end
end
end

express_nolookup(::PauliM, ::QuantumToolboxRepr) = _σ₋
express_nolookup(::PauliP, ::QuantumToolboxRepr) = _σ₊

express_nolookup(s::XBasisState, ::QuantumToolboxRepr) = (_s₊,_s₋)[s.idx]
express_nolookup(s::YBasisState, ::QuantumToolboxRepr) = (_i₊,_i₋)[s.idx]
express_nolookup(s::ZBasisState, ::QuantumToolboxRepr) = (_l0,_l1)[s.idx]

express_nolookup(s::FockState, r::QuantumToolboxRepr) = fock(r.cutoff, s.idx)
express_nolookup(s::CoherentState, r::QuantumToolboxRepr) = coherent(r.cutoff,s.alpha)
express_nolookup(s::SqueezedState, r::QuantumToolboxRepr) = (c = r.cutoff; squeeze(c, s.z)*fock(c, 0))
express_nolookup(o::NumberOp, r::QuantumToolboxRepr) = num(r.cutoff)
express_nolookup(o::CreateOp, r::QuantumToolboxRepr) = create(r.cutoff)
express_nolookup(o::DestroyOp, r::QuantumToolboxRepr) = destroy(r.cutoff)
express_nolookup(o::DisplaceOp, r::QuantumToolboxRepr) = displace(r.cutoff, o.alpha)
express_nolookup(o::SqueezeOp, r::QuantumToolboxRepr) = squeeze(r.cutoff, o.z)
express_nolookup(x::MixedState, r::QuantumToolboxRepr) = (l = length(x.basis); return qeye(l)/l)
express_nolookup(x::IdentityOp, r::QuantumToolboxRepr) = qeye(length(x.basis))

express_nolookup(s::SOuterKetBra, r::QuantumToolboxRepr) = proj(express(s.ket, r), express(s.bra, r))
express_nolookup(s::STensor, r::QuantumToolboxRepr) = QuantumToolbox.tensor((express(i, r) for i in s.terms)...)

end
11 changes: 10 additions & 1 deletion src/QSymbolicsBase/QSymbolicsBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import QuantumInterface:

export SymQObj,QObj,
AbstractRepresentation,AbstractUse,
QuantumOpticsRepr,QuantumMCRepr,CliffordRepr,GabsRepr,
QuantumOpticsRepr,QuantumMCRepr,CliffordRepr,GabsRepr,QuantumToolboxRepr,
UseAsState,UseAsObservable,UseAsOperation,
apply!,
express,
Expand Down Expand Up @@ -52,6 +52,15 @@ export SymQObj,QObj,
isunitary,
KrausRepr,kraus




# TODO: move this to QuantumInterface
"""Representation using kets, bras, density matrices, and superoperators governed by `QuantumToolbox.jl`."""
Base.@kwdef struct QuantumToolboxRepr <: AbstractRepresentation
cutoff::Int = 2
end

##
# Metadata cache helpers
##
Expand Down
1 change: 1 addition & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ QuantumClifford = "0525e862-1e90-11e9-3e4d-1b39d7109de1"
QuantumInterface = "5717a53b-5d69-4fa3-b976-0bf2f97ca1e5"
QuantumOptics = "6e0679c1-51ea-5a7c-ac74-d61b76210b0c"
QuantumOpticsBase = "4f57444f-1401-5e15-980d-4471b28d5678"
QuantumToolbox = "6c2fb7c5-b903-41d2-bc5e-5a7c320b9fab"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
Expand Down
9 changes: 8 additions & 1 deletion test/test_conditional_cliffords.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
@testitem "Conditional Cliffords" begin
using QuantumClifford
using QuantumOpticsBase
using QuantumToolbox
using LinearAlgebra

P = [1. 0. 0. 0.; # Maps QuantumOptics to QuantumToolbox basis
0. 0. 1. 0.;
0. 1. 0. 0.;
0. 0. 0. 1.]
for control in (:X, :Y, :Z)
for target in (:X, :Y, :Z)
structname = Symbol(control,"C",target,"Gate")
gate = eval(structname)()
gate_qo = express(gate, QuantumOpticsRepr())
gate_qc = Operator(CliffordOperator(express(gate, CliffordRepr(), UseAsOperation())(1,2),2))
gate_qc = QuantumOpticsBase.Operator(CliffordOperator(express(gate, CliffordRepr(), UseAsOperation())(1,2),2))
gate_qt = express(gate, QuantumToolboxRepr())
@test gate_qo ≈ gate_qc
@test P * gate_qo.data * P' ≈ gate_qt.data atol = 1e-10
end
end
end
49 changes: 49 additions & 0 deletions test/test_quantumtoolbox.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@testitem "QuantumToolbox objects" begin
using QuantumSymbolics
using QuantumToolbox

α = rand(ComplexF64)
n = rand(1:9)

@testset "Fock states and operators" begin
repr = QuantumToolboxRepr(cutoff = 10)
@test express(vac, repr) ≈ fock(10, 0)
@test express(FockState(n), repr) ≈ fock(10, n)
@test express(CoherentState(α), repr) ≈ coherent(10, α)
@test express(SqueezedState(α), repr) ≈ squeeze(10, α) * fock(10, 0)
@test express(NumberOp(), repr) ≈ num(10)
@test express(CreateOp(), repr) ≈ create(10)
@test express(DestroyOp(), repr) ≈ destroy(10)
@test express(DisplaceOp(α), repr) ≈ displace(10, α)
end

@testset "Quantum gates" begin
repr = QuantumToolboxRepr()
@test express(H, repr) ≈ to_sparse(Qobj([1.0+0.0im 1.; 1. -1.]/√2))
@test express(X, repr) ≈ sigmax()
@test express(Y, repr) ≈ sigmay()
@test express(Z, repr) ≈ sigmaz()
@test express(CPHASE, repr) ≈ Qobj([1.0+0.0im 0. 0. 0.; 0. 1. 0. 0.; 0. 0. 1. 0.; 0. 0. 0. -1.], dims = (2,2))
@test express(CNOT, repr) ≈ Qobj([1.0+0.0im 0. 0. 0.; 0. 1. 0. 0.; 0. 0. 0. 1.; 0. 0. 1. 0.], dims = (2,2))
@test express(QuantumSymbolics.PauliM(), repr) ≈ sigmam()
@test express(QuantumSymbolics.PauliP(), repr) ≈ sigmap()
end

@testset "Pure states" begin
repr = QuantumToolboxRepr()
@test express(XBasisState(1, SpinBasis(1//2)), repr) ≈ Qobj([1.0+0.0im, 1.0]/√2)
@test express(XBasisState(2, SpinBasis(1//2)), repr) ≈ Qobj([1.0+0.0im, -1.0]/√2)
@test express(YBasisState(1, SpinBasis(1//2)), repr) ≈ Qobj([1.0+0.0im, 1.0im]/√2)
@test express(YBasisState(2, SpinBasis(1//2)), repr) ≈ Qobj([1.0+0.0im, -1.0im]/√2)
@test express(ZBasisState(1, SpinBasis(1//2)), repr) ≈ Qobj([1.0+0.0im, 0.0])
@test express(ZBasisState(2, SpinBasis(1//2)), repr) ≈ Qobj([0.0+0.0im, 1.0])
end

@testset "Linear algebra" begin
repr = QuantumToolboxRepr()
@test express(QuantumSymbolics.tensor(X, Y) + QuantumSymbolics.tensor(Z, X), repr) ≈ QuantumToolbox.tensor(express(X, repr), express(Y, repr)) + QuantumToolbox.tensor(express(Z, repr), express(X, repr))
@test express(CreateOp() * (FockState(1) + CoherentState(α)), repr) ≈ express(CreateOp(), repr) * (express(FockState(1), repr) + express(CoherentState(α), repr))
@test express(IdentityOp(QuantumSymbolics.tensor(X, Y)), repr) ≈ qeye(4)
@test express(MixedState(QuantumSymbolics.tensor(X, Y)), repr) ≈ qeye(4) / 4
end
end
Loading