diff --git a/src/QSymbolicsBase/QSymbolicsBase.jl b/src/QSymbolicsBase/QSymbolicsBase.jl index a712623..ac50922 100644 --- a/src/QSymbolicsBase/QSymbolicsBase.jl +++ b/src/QSymbolicsBase/QSymbolicsBase.jl @@ -29,7 +29,8 @@ export SymQObj,QObj, X1,X2,Y1,Y2,Z1,Z2,X₁,X₂,Y₁,Y₂,Z₁,Z₂,L0,L1,Lp,Lm,Lpi,Lmi,L₀,L₁,L₊,L₋,L₊ᵢ,L₋ᵢ, vac,F₀,F0,F₁,F1, N,n̂,Create,âꜛ,Destroy,â,SpinBasis,FockBasis, - SBra,SKet,SOperator, + SBra,SKet,SOperator,SHermitianOperator,SUnitaryOperator,SHermitianUnitaryOperator, + @ket,@bra,@op, SAdd,SAddBra,SAddKet,SAddOperator, SScaled,SScaledBra,SScaledOperator,SScaledKet, STensorBra,STensorKet,STensorOperator, diff --git a/src/QSymbolicsBase/basic_ops_homogeneous.jl b/src/QSymbolicsBase/basic_ops_homogeneous.jl index db89a41..176feeb 100644 --- a/src/QSymbolicsBase/basic_ops_homogeneous.jl +++ b/src/QSymbolicsBase/basic_ops_homogeneous.jl @@ -6,13 +6,13 @@ """Scaling of a quantum object (ket, operator, or bra) by a number ```jldoctest -julia> k = SKet(:k, SpinBasis(1//2)) +julia> @ket k |k⟩ julia> 2*k 2|k⟩ -julia> A = SOperator(:A, SpinBasis(1//2)) +julia> @op A A julia> 2*A @@ -63,7 +63,7 @@ end """Addition of quantum objects (kets, operators, or bras) ```jldoctest -julia> k₁ = SKet(:k₁, SpinBasis(1//2)); k₂ = SKet(:k₂, SpinBasis(1//2)); +julia> @ket k₁; @ket k₂; julia> k₁ + k₂ (|k₁⟩+|k₂⟩) @@ -112,7 +112,7 @@ end """Symbolic application of operator on operator ```jldoctest -julia> A = SOperator(:A, SpinBasis(1//2)); B = SOperator(:B, SpinBasis(1//2)); +julia> @op A; @op B; julia> A*B AB @@ -141,12 +141,12 @@ basis(x::SMulOperator) = basis(x.terms) """Tensor product of quantum objects (kets, operators, or bras) ```jldoctest -julia> k₁ = SKet(:k₁, SpinBasis(1//2)); k₂ = SKet(:k₂, SpinBasis(1//2)); +julia> @ket k₁; @ket k₂; julia> k₁ ⊗ k₂ |k₁⟩|k₂⟩ -julia> A = SOperator(:A, SpinBasis(1//2)); B = SOperator(:B, SpinBasis(1//2)); +julia> @op A; @op B; julia> A ⊗ B A⊗B @@ -183,7 +183,7 @@ Base.show(io::IO, x::STensorBra) = print(io, join(map(string, arguments(x)),"")) """Symbolic commutator of two operators ```jldoctest -julia> A = SOperator(:A, SpinBasis(1//2)); B = SOperator(:B, SpinBasis(1//2)); +julia> @op A; @op B; julia> commutator(A, B) [A,B] @@ -217,7 +217,7 @@ expand(x::SCommutator) = x == 0 ? x : x.op1*x.op2 - x.op2*x.op1 """Symbolic anticommutator of two operators ```jldoctest -julia> A = SOperator(:A, SpinBasis(1//2)); B = SOperator(:B, SpinBasis(1//2)); +julia> @op A; @op B; julia> anticommutator(A, B) {A,B} diff --git a/src/QSymbolicsBase/basic_ops_inhomogeneous.jl b/src/QSymbolicsBase/basic_ops_inhomogeneous.jl index 3dd6d63..49c48ae 100644 --- a/src/QSymbolicsBase/basic_ops_inhomogeneous.jl +++ b/src/QSymbolicsBase/basic_ops_inhomogeneous.jl @@ -5,7 +5,7 @@ """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> @ket k; @op A; julia> A*k A|k⟩ @@ -35,7 +35,7 @@ basis(x::SApplyKet) = basis(x.ket) """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> @bra b; @op A; julia> b*A ⟨b|A @@ -65,7 +65,7 @@ basis(x::SApplyBra) = basis(x.bra) """Symbolic inner product of a bra and a ket ```jldoctest -julia> b = SBra(:b, SpinBasis(1//2)); k = SKet(:k, SpinBasis(1//2)); +julia> @bra b; @ket k; julia> b*k ⟨b||k⟩ @@ -108,7 +108,7 @@ basis(x::SSuperOpApply) = basis(x.op) """Symbolic outer product of a ket and a bra ```jldoctest -julia> b = SBra(:b, SpinBasis(1//2)); k = SKet(:k, SpinBasis(1//2)); +julia> @bra b; @ket k; julia> k*b |k⟩⟨b| diff --git a/src/QSymbolicsBase/literal_objects.jl b/src/QSymbolicsBase/literal_objects.jl index e032f28..d6ebfbc 100644 --- a/src/QSymbolicsBase/literal_objects.jl +++ b/src/QSymbolicsBase/literal_objects.jl @@ -2,20 +2,41 @@ # This file defines quantum objects (kets, bras, and operators) with various properties ## -struct SKet <: Symbolic{AbstractKet} +struct SBra <: Symbolic{AbstractBra} name::Symbol basis::Basis end +SBra(name) = SBra(name, qubit_basis) +macro bra(name, basis) + :($(esc(name)) = SBra($(Expr(:quote, name)), $(basis))) +end +macro bra(name) + :($(esc(name)) = SBra($(Expr(:quote, name)))) +end -struct SBra <: Symbolic{AbstractBra} +struct SKet <: Symbolic{AbstractKet} name::Symbol basis::Basis end +SKet(name) = SKet(name, qubit_basis) +macro ket(name, basis) + :($(esc(name)) = SKet($(Expr(:quote, name)), $(basis))) +end +macro ket(name) + :($(esc(name)) = SKet($(Expr(:quote, name)))) +end struct SOperator <: Symbolic{AbstractOperator} name::Symbol basis::Basis end +SOperator(name) = SOperator(name, qubit_basis) +macro op(name, basis) + :($(esc(name)) = SOperator($(Expr(:quote, name)), $(basis))) +end +macro op(name) + :($(esc(name)) = SOperator($(Expr(:quote, name)))) +end ishermitian(x::SOperator) = false isunitary(x::SOperator) = false @@ -23,6 +44,8 @@ struct SHermitianOperator <: Symbolic{AbstractOperator} name::Symbol basis::Basis end +SHermitianOperator(name) = SHermitianOperator(name, qubit_basis) + ishermitian(::SHermitianOperator) = true isunitary(::SHermitianOperator) = false @@ -30,6 +53,8 @@ struct SUnitaryOperator <: Symbolic{AbstractOperator} name::Symbol basis::Basis end +SUnitaryOperator(name) = SUnitaryOperator(name, qubit_basis) + ishermitian(::SUnitaryOperator) = false isunitary(::SUnitaryOperator) = true @@ -37,6 +62,8 @@ struct SHermitianUnitaryOperator <: Symbolic{AbstractOperator} name::Symbol basis::Basis end +SHermitianUnitaryOperator(name) = SHermitianUnitaryOperator(name, qubit_basis) + ishermitian(::SHermitianUnitaryOperator) = true isunitary(::SHermitianUnitaryOperator) = true diff --git a/src/QSymbolicsBase/predefined.jl b/src/QSymbolicsBase/predefined.jl index b1d89af..182e8bc 100644 --- a/src/QSymbolicsBase/predefined.jl +++ b/src/QSymbolicsBase/predefined.jl @@ -233,17 +233,17 @@ end """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> @ket a; @op A; julia> dagger(2*im*A*a) 0 - 2im|a⟩†A† -julia> B = SOperator(:B, SpinBasis(1//2)); +julia> @op B; julia> dagger(A*B) B†A† -julia> ℋ = SHermitianOperator(:ℋ, SpinBasis(1//2)); U = SUnitaryOperator(:U, SpinBasis(1//2)); +julia> ℋ = SHermitianOperator(:ℋ); U = SUnitaryOperator(:U); julia> dagger(ℋ) ℋ @@ -291,7 +291,7 @@ symbollabel(x::SDagger) = symbollabel(x.obj) """Inverse Operator ```jldoctest -julia> A = SOperator(:A, SpinBasis(1//2)); +julia> @op A; julia> inv(A) A⁻¹ diff --git a/test/test_anticommutator.jl b/test/test_anticommutator.jl index 52f9753..98100b8 100644 --- a/test/test_anticommutator.jl +++ b/test/test_anticommutator.jl @@ -1,8 +1,7 @@ using QuantumSymbolics using Test -A = SOperator(:A, SpinBasis(1//2)) -B = SOperator(:B, SpinBasis(1//2)) +@op A; @op B; @testset "symbolic anticommutator tests" begin @test isequal(anticommutator(2*A, B), anticommutator(A, 2*B)) && isequal(2*anticommutator(A, B), anticommutator(2*A, B)) && isequal(2*anticommutator(A, B), anticommutator(2*A, B)) diff --git a/test/test_commutator.jl b/test/test_commutator.jl index 2cbbd71..23d7520 100644 --- a/test/test_commutator.jl +++ b/test/test_commutator.jl @@ -1,8 +1,7 @@ using QuantumSymbolics using Test -A = SOperator(:A, SpinBasis(1//2)) -B = SOperator(:B, SpinBasis(1//2)) +@op A; @op B; @testset "symbolic commutator tests" begin @test isequal(commutator(2*A, B), commutator(A, 2*B)) && isequal(2*commutator(A, B), commutator(2*A, B)) && isequal(commutator(A, 2*B), 2*commutator(A, B)) diff --git a/test/test_dagger.jl b/test/test_dagger.jl index ce740b9..dbabafc 100644 --- a/test/test_dagger.jl +++ b/test/test_dagger.jl @@ -2,17 +2,11 @@ using QuantumSymbolics using QuantumInterface: AbstractOperator using Test -b₁ = SBra(:b₁, SpinBasis(1//2)) -b₂ = SBra(:b₂, SpinBasis(1//2)) -k₁ = SKet(:k₁, SpinBasis(1//2)) -k₂ = SKet(:k₂, SpinBasis(1//2)) +@bra b₁; @bra b₂; +@ket k₁; @ket k₂; -A = SOperator(:A, SpinBasis(1//2)) -B = SOperator(:B, SpinBasis(1//2)) -C = SOperator(:C, SpinBasis(1//2)) - -U = SUnitaryOperator(:U, SpinBasis(1//2)) -ℋ = SHermitianOperator(:ℋ, SpinBasis(1//2)) +@op A; @op B; @op C; +U = SUnitaryOperator(:U); ℋ = SHermitianOperator(:ℋ); @testset "symbolic dagger tests" begin @test isequal(dagger(im*k₁), -im*dagger(k₁))