Skip to content

Commit

Permalink
examples and specific operator properties
Browse files Browse the repository at this point in the history
  • Loading branch information
apkille committed Jun 13, 2024
1 parent a269b60 commit 9fbd799
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/QSymbolicsBase/QSymbolicsBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export SymQObj,QObj,
apply!,
express,
tensor,,
dagger,projector,commutator, anticommutator,
dagger,projector,commutator, anticommutator, expand,
I,X,Y,Z,σˣ,σʸ,σᶻ,Pm,Pp,σ₋,σ₊,
H,CNOT,CPHASE,XCX,XCY,XCZ,YCX,YCY,YCZ,ZCX,ZCY,ZCZ,
X1,X2,Y1,Y2,Z1,Z2,X₁,X₂,Y₁,Y₂,Z₁,Z₂,L0,L1,Lp,Lm,Lpi,Lmi,L₀,L₁,L₊,L₋,L₊ᵢ,L₋ᵢ,
Expand Down
87 changes: 81 additions & 6 deletions src/QSymbolicsBase/basic_ops_homogeneous.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
"""This file defines the symbolic operations for quantum objects (kets, operators, and bras) that are homogeneous in their arguments."""

"""Scaling of a quantum object (ket, operator, or bra) by a number."""
"""Scaling of a quantum object (ket, operator, or bra) by a number
```jldoctest
julia> k = SKet(:k, SpinBasis(1//2))
|k⟩
julia> 2*k
2|k⟩
julia> A = SOperator(:A, SpinBasis(1//2))
A
julia> 2*A
2A
````
"""
@withmetadata struct SScaled{T<:QObj} <: Symbolic{T}
coeff
obj
Expand Down Expand Up @@ -42,7 +57,15 @@ function Base.show(io::IO, x::SScaledBra)
end
end

"""Addition of quantum objects (kets, operators, or bras)."""
"""Addition of quantum objects (kets, operators, or bras)
```jldoctest
julia> k₁ = SKet(:k₁, SpinBasis(1//2)); k₂ = SKet(:k₂, SpinBasis(1//2));
julia> k₁ + k₂
(|k₁⟩+|k₂⟩)
```
"""
@withmetadata struct SAdd{T<:QObj} <: Symbolic{T}
dict
SAdd{S}(d) where S = length(d)==1 ? SScaled{S}(reverse(first(d))...) : new{S}(d)
Expand All @@ -64,7 +87,15 @@ Base.show(io::IO, x::SAddOperator) = print(io, "("*join(map(string, arguments(x)
const SAddBra = SAdd{AbstractBra}
Base.show(io::IO, x::SAddBra) = print(io, "("*join(map(string, arguments(x)),"+")::String*")") # type assert to help inference

"""Symbolic application of operator on operator"""
"""Symbolic application of operator on operator
```jldoctest
julia> A = SOperator(:A, SpinBasis(1//2)); B = SOperator(:B, SpinBasis(1//2));
julia> A*B
AB
```
"""
@withmetadata struct SApplyOp <: Symbolic{AbstractOperator}
terms
function SApplyOp(terms)
Expand All @@ -80,7 +111,20 @@ Base.:(*)(xs::Symbolic{AbstractOperator}...) = SApplyOp(collect(xs))
Base.show(io::IO, x::SApplyOp) = print(io, join(map(string, arguments(x)),""))
basis(x::SApplyOp) = basis(x.terms)

"""Tensor product of quantum objects (kets, operators, or bras)."""
"""Tensor product of quantum objects (kets, operators, or bras)
```jldoctest
julia> k₁ = SKet(:k₁, SpinBasis(1//2)); k₂ = SKet(:k₂, SpinBasis(1//2));
julia> k₁ ⊗ k₂
|k₁⟩|k₂⟩
julia> A = SOperator(:A, SpinBasis(1//2)); B = SOperator(:B, SpinBasis(1//2));
julia> A ⊗ B
A⊗B
```
"""
@withmetadata struct STensor{T<:QObj} <: Symbolic{T}
terms
function STensor{S}(terms) where S
Expand All @@ -106,7 +150,24 @@ Base.show(io::IO, x::STensorSuperOperator) = print(io, join(map(string, argument
const STensorBra = STensor{AbstractBra}
Base.show(io::IO, x::STensorBra) = print(io, join(map(string, arguments(x)),""))

"""Symbolic commutator of two operators"""
"""Symbolic commutator of two operators
```jldoctest
julia> A = SOperator(:A, SpinBasis(1//2)); B = SOperator(:B, SpinBasis(1//2));
julia> commutator(A, B)
[A,B]
julia> expand(commutator(A, B))
(AB+-1BA)

Check warning on line 162 in src/QSymbolicsBase/basic_ops_homogeneous.jl

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"BA" should be "BY" or "BE".
julia> commutator(A, A)
0
julia> commutator(commutative(A), B)
0
```
"""
@withmetadata struct SCommutator <: Symbolic{AbstractOperator}
op1
op2
Expand All @@ -127,7 +188,21 @@ Base.show(io::IO, x::SCommutator) = print(io, "[$(x.op1),$(x.op2)]")
basis(x::SCommutator) = basis(x.op1)
expand(x::SCommutator) = x == 0 ? x : (x.op1)*(x.op2) - (x.op2)*(x.op1) # expands commutator into [A,B] = AB - BA

Check warning on line 189 in src/QSymbolicsBase/basic_ops_homogeneous.jl

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"BA" should be "BY" or "BE".

"""Symbolic anticommutator of two operators"""
"""Symbolic anticommutator of two operators
```jldoctest
julia> A = SOperator(:A, SpinBasis(1//2)); B = SOperator(:B, SpinBasis(1//2));
julia> anticommutator(A, B)
{A,B}
julia> expand(anticommutator(A, B))
(AB+BA)

Check warning on line 200 in src/QSymbolicsBase/basic_ops_homogeneous.jl

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"BA" should be "BY" or "BE".
julia> anticommutator(commutative(A), B)
2AB
```
"""
@withmetadata struct SAnticommutator <: Symbolic{AbstractOperator}
op1
op2
Expand Down
37 changes: 33 additions & 4 deletions src/QSymbolicsBase/basic_ops_inhomogeneous.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
"""This file defines the symbolic operations for quantum objects (kets, operators, and bras) that are inhomogeneous in their arguments."""

"""Symbolic application of an operator on a ket (from the left)"""
"""Symbolic application of an operator on a ket (from the left)
```jldoctest
julia> k = SKet(:k, SpinBasis(1//2)); A = SOperator(:A, SpinBasis(1//2));
julia> A*k
A|k⟩
```
"""
@withmetadata struct SApplyKet <: Symbolic{AbstractKet}
op
ket
Expand All @@ -19,7 +27,14 @@ Base.:(*)(op::Symbolic{AbstractOperator}, k::Symbolic{AbstractKet}) = SApplyKet(
Base.show(io::IO, x::SApplyKet) = begin print(io, x.op); print(io, x.ket) end
basis(x::SApplyKet) = basis(x.ket)

"""Symbolic application of an operator on a bra (from the right)"""
"""Symbolic application of an operator on a bra (from the right)
```jldoctest
julia> b = SBra(:b, SpinBasis(1//2)); A = SOperator(:A, SpinBasis(1//2));
julia> b*A
⟨b|A
"""
@withmetadata struct SApplyBra <: Symbolic{AbstractBra}
bra
op
Expand All @@ -38,7 +53,15 @@ Base.:(*)(b::Symbolic{AbstractBra}, op::Symbolic{AbstractOperator}) = SApplyBra(
Base.show(io::IO, x::SApplyBra) = begin print(io, x.bra); print(io, x.op) end
basis(x::SApplyBra) = basis(x.bra)

"""Symbolic inner product of a bra and a ket."""
"""Symbolic inner product of a bra and a ket
```jldoctest
julia> b = SBra(:b, SpinBasis(1//2)); k = SKet(:k, SpinBasis(1//2));
julia> b*k
⟨b||k⟩
```
"""
@withmetadata struct SBraKet <: Symbolic{Complex}
bra
ket
Expand Down Expand Up @@ -72,7 +95,13 @@ Base.:(*)(sop::Symbolic{AbstractSuperOperator}, k::Symbolic{AbstractKet}) = SApp
Base.show(io::IO, x::SApplyOpSuper) = begin print(io, x.sop); print(io, x.op) end
basis(x::SApplyOpSuper) = basis(x.op)

"""Symbolic outer product of a ket and a bra"""
"""Symbolic outer product of a ket and a bra
```jldoctest
julia> b = SBra(:b, SpinBasis(1//2)); k = SKet(:k, SpinBasis(1//2));
julia> k*b
|k⟩⟨b|
"""
@withmetadata struct SOuterKetBra <: Symbolic{AbstractOperator}
ket
bra
Expand Down
6 changes: 3 additions & 3 deletions src/QSymbolicsBase/objects.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ isexpr(::SHermitianOperator) = false
basis(x::SHermitianOperator) = basis(x.op)
Base.show(io::IO, x::SHermitianOperator) = print(io, "$(x.op)")
hermitian(x::Symbolic{AbstractOperator}) = SHermitianOperator(x)
ishermitian(x::SHermitianOperator) = true
ishermitian(::SHermitianOperator) = true

"""Unitary Operator"""
@withmetadata struct SUnitaryOperator <: Symbolic{AbstractOperator}
Expand All @@ -58,7 +58,7 @@ isexpr(::SUnitaryOperator) = false
basis(x::SUnitaryOperator) = basis(x.op)
Base.show(io::IO, x::SUnitaryOperator) = print(io, "$(x.op)")
unitary(x::Symbolic{AbstractOperator}) = SUnitaryOperator(x)
isunitary(x::SUnitaryOperator) = true
isunitary(::SUnitaryOperator) = true

"""Commutative Operator"""
@withmetadata struct SCommutativeOperator <: Symbolic{AbstractOperator}
Expand All @@ -68,4 +68,4 @@ isexpr(::SCommutativeOperator) = false
basis(x::SCommutativeOperator) = basis(x.op)
Base.show(io::IO, x::SCommutativeOperator) = print(io, "$(x.op)")
commutative(x::Symbolic{AbstractOperator}) = SCommutativeOperator(x)
iscommutative(x::SCommutativeOperator) = true
iscommutative(::SCommutativeOperator) = true
55 changes: 54 additions & 1 deletion src/QSymbolicsBase/predefined.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,22 +105,53 @@ isexpr(::OperatorEmbedding) = true
@withmetadata struct XGate <: AbstractSingleQubitGate end
eigvecs(g::XGate) = [X1,X2]
symbollabel(::XGate) = "X"
ishermitian(::XGate) = true
isunitary(::XGate) = true
iscommutative(::XGate) = false

@withmetadata struct YGate <: AbstractSingleQubitGate end
eigvecs(g::YGate) = [Y1,Y2]
symbollabel(::YGate) = "Y"
ishermitian(::YGate) = true
isunitary(::YGate) = true
iscommutative(::YGate) = false

@withmetadata struct ZGate <: AbstractSingleQubitGate end
eigvecs(g::ZGate) = [Z1,Z2]
symbollabel(::ZGate) = "Z"
ishermitian(::ZGate) = true
isunitary(::ZGate) = true
iscommutative(::ZGate) = false

@withmetadata struct PauliM <: AbstractSingleQubitGate end
symbollabel(::PauliM) = "σ₋"
ishermitian(::PauliM) = true
isunitary(::PauliM) = true
iscommutative(::PauliM) = false

@withmetadata struct PauliP <: AbstractSingleQubitGate end
symbollabel(::PauliP) = "σ₊"
ishermitian(::PauliP) = true
isunitary(::PauliP) = true
iscommutative(::PauliP) = false

@withmetadata struct HGate <: AbstractSingleQubitGate end
symbollabel(::HGate) = "H"
ishermitian(::HGate) = true
isunitary(::HGate) = true
iscommutative(::HGate) = false

@withmetadata struct CNOTGate <: AbstractTwoQubitGate end
symbollabel(::CNOTGate) = "CNOT"
ishermitian(::CNOTGate) = true
isunitary(::CNOTGate) = true
iscommutative(::CNOTGate) = false

@withmetadata struct CPHASEGate <: AbstractTwoQubitGate end
symbollabel(::CPHASEGate) = "CPHASE"
ishermitian(::CPHASEGate) = true
isunitary(::CPHASEGate) = true
iscommutative(::CPHASEGate) = false

const xyzsuplabeldict = Dict(:X=>"ˣ",:Y=>"ʸ",:Z=>"")
for control in (:X, :Y, :Z)
Expand Down Expand Up @@ -210,7 +241,26 @@ function Base.show(io::IO, x::SProjector)
print(io,"]")
end

"""Dagger, i.e., adjoint of quantum objects (kets, bras, operators)"""
"""Dagger, i.e., adjoint of quantum objects (kets, bras, operators)
```jldoctest
julia> a = SKet(:a, SpinBasis(1//2)); A = SOperator(:A, SpinBasis(1//2));
julia> dagger(2*im*A*a)
0 - 2im⟨a|A†
julia> B = SOperator(:B, SpinBasis(1//2));
julia> dagger(A*B)
B†A†
julia> dagger(hermitian(A))
A
julia> dagger(unitary(A))
A⁻¹
```
"""
@withmetadata struct SDagger{T<:QObj} <: Symbolic{T}
obj
end
Expand Down Expand Up @@ -296,6 +346,9 @@ IdentityOp(x::Symbolic{AbstractOperator}) = IdentityOp(basis(x))
isexpr(::IdentityOp) = false
basis(x::IdentityOp) = x.basis
symbollabel(x::IdentityOp) = "𝕀"
ishermitian(::IdentityOp) = true
isunitary(::IdentityOp) = true
iscommutative(::IdentityOp) = true

"""Identity operator in qubit basis"""
const I = IdentityOp(qubit_basis)
1 change: 1 addition & 0 deletions test/test_doctests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ using Documenter
using QuantumSymbolics
using QuantumOptics
using QuantumClifford
using Test

function doctests()
@testset "Doctests" begin
Expand Down

0 comments on commit 9fbd799

Please sign in to comment.