diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f5b30c..7b4082b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # News +## v0.4.6 - dev + +- Operators now print with a hat + ## v0.4.5 - 2024-11-14 - Updated compat lower bounds for Symbolics to v6 (and for SymbolicUtils and TermInterface) diff --git a/docs/src/introduction.md b/docs/src/introduction.md index 759598e..64ed351 100644 --- a/docs/src/introduction.md +++ b/docs/src/introduction.md @@ -31,7 +31,7 @@ julia> @ket k # object of type SKet |k⟩ julia> @op A # object of type SOperator -A + julia> @superop S # object of type SSuperOperator S @@ -41,13 +41,13 @@ By default, each of the above macros defines a symbolic quantum object in the sp ```jldoctest julia> @op B FockBasis(Inf, 0.0) -B +B̂ julia> basis(B) Fock(cutoff=Inf) julia> @op C SpinBasis(1//2)⊗SpinBasis(5//2) -C +Ĉ julia> basis(C) [Spin(1/2) ⊗ Spin(5/2)] @@ -69,7 +69,7 @@ julia> 2*k 2|k⟩ julia> A*k -A|k⟩ +Â|k⟩ ``` Similar scaling procedures can be performed on bras and operators. Addition between symbolic objects is also available, for instance: @@ -78,7 +78,7 @@ Similar scaling procedures can be performed on bras and operators. Addition betw julia> @op A₁; @op A₂; julia> A₁+A₂ -(A₁+A₂) +(Â₁+Â₂) julia> @bra b; @@ -117,10 +117,10 @@ More involved combinations of operations can be explored. Here are few other str julia> @bra b; @ket k; @op A; @op B; julia> 3*A*B*k -3AB|k⟩ +3ÂB̂|k⟩ julia> A⊗(k*b + B) -(A⊗(B+|k⟩⟨b|)) +(Â⊗(B̂+|k⟩⟨b|)) julia> A-A 𝟎 @@ -135,10 +135,10 @@ QuantumSymbolics supports a wide variety of linear algebra on symbolic bras, ket julia> @op A; @op B; julia> commutator(A, B) -[A,B] +[Â,B̂] julia> anticommutator(A, B) -{A,B} +{Â,B̂} julia> commutator(A, A) 𝟎 @@ -149,13 +149,13 @@ Or, one can take the dagger of a quantum object with the [`dagger`](@ref) functi julia> @ket k; @op A; @op B; julia> dagger(A) -A† +† julia> dagger(A*k) -|k⟩†A† +|k⟩†Â† julia> dagger(A*B) -B†A† +B̂†Â† ``` Below, we state all of the supported linear algebra operations on quantum objects: @@ -259,10 +259,10 @@ Symbolic expressions containing quantum objects can be expanded with the [`qexpa julia> @op A; @op B; @op C; julia> qexpand(A⊗(B+C)) -((A⊗B)+(A⊗C)) +((Â⊗B̂)+(Â⊗Ĉ)) julia> qexpand((B+C)*A) -(BA+CA) +(B̂Â+ĈÂ) julia> @ket k₁; @ket k₂; @ket k₃; @@ -270,7 +270,7 @@ julia> qexpand(k₁⊗(k₂+k₃)) (|k₁⟩|k₂⟩+|k₁⟩|k₃⟩) julia> qexpand((A*B)*(k₁+k₂)) -(AB|k₁⟩+AB|k₂⟩) +(ÂB̂|k₁⟩+ÂB̂|k₂⟩) ``` ## Numerical Translation of Symbolic Objects diff --git a/src/QSymbolicsBase/basic_ops_homogeneous.jl b/src/QSymbolicsBase/basic_ops_homogeneous.jl index ed41ff8..711cc35 100644 --- a/src/QSymbolicsBase/basic_ops_homogeneous.jl +++ b/src/QSymbolicsBase/basic_ops_homogeneous.jl @@ -13,10 +13,10 @@ julia> 2*k 2|k⟩ julia> @op A -A + julia> 2*A -2A +2 ``` """ @withmetadata struct SScaled{T<:QObj} <: Symbolic{T} @@ -125,7 +125,7 @@ end julia> @op A; @op B; julia> A*B -AB +ÂB̂ ``` """ @withmetadata struct SMulOperator <: Symbolic{AbstractOperator} @@ -165,7 +165,7 @@ julia> k₁ ⊗ k₂ julia> @op A; @op B; julia> A ⊗ B -(A⊗B) +(Â⊗B̂) ``` """ @withmetadata struct STensor{T<:QObj} <: Symbolic{T} diff --git a/src/QSymbolicsBase/basic_ops_inhomogeneous.jl b/src/QSymbolicsBase/basic_ops_inhomogeneous.jl index 4b5989d..03c638e 100644 --- a/src/QSymbolicsBase/basic_ops_inhomogeneous.jl +++ b/src/QSymbolicsBase/basic_ops_inhomogeneous.jl @@ -8,7 +8,7 @@ julia> @ket k; @op A; julia> A*k -A|k⟩ +Â|k⟩ ``` """ @withmetadata struct SApplyKet <: Symbolic{AbstractKet} @@ -41,7 +41,7 @@ basis(x::SApplyKet) = basis(x.ket) julia> @bra b; @op A; julia> b*A -⟨b|A +⟨b| ``` """ @withmetadata struct SApplyBra <: Symbolic{AbstractBra} diff --git a/src/QSymbolicsBase/basic_superops.jl b/src/QSymbolicsBase/basic_superops.jl index b52792c..880c928 100644 --- a/src/QSymbolicsBase/basic_superops.jl +++ b/src/QSymbolicsBase/basic_superops.jl @@ -13,7 +13,7 @@ julia> K = kraus(A₁, A₂, A₃) julia> @op ρ; julia> K*ρ -(A₁ρA₁†+A₂ρA₂†+A₃ρA₃†) +(Â₁ρ̂Â₁†+Â₂ρ̂Â₂†+Â₃ρ̂Â₃†) ``` """ @withmetadata struct KrausRepr <: Symbolic{AbstractSuperOperator} @@ -41,7 +41,7 @@ Base.show(io::IO, x::KrausRepr) = print(io, "𝒦("*join([symbollabel(i) for i i julia> @op A; @superop S; julia> S*A -S[A] +S[Â] ``` """ @withmetadata struct SSuperOpApply <: Symbolic{AbstractOperator} diff --git a/src/QSymbolicsBase/linalg.jl b/src/QSymbolicsBase/linalg.jl index 0fd7362..231ba45 100644 --- a/src/QSymbolicsBase/linalg.jl +++ b/src/QSymbolicsBase/linalg.jl @@ -14,7 +14,7 @@ function anticommutator end julia> @op A; @op B; julia> commutator(A, B) -[A,B] +[Â,B̂] julia> commutator(A, A) 𝟎 @@ -51,7 +51,7 @@ basis(x::SCommutator) = basis(x.op1) julia> @op A; @op B; julia> anticommutator(A, B) -{A,B} +{Â,B̂} ``` """ @withmetadata struct SAnticommutator <: Symbolic{AbstractOperator} @@ -85,7 +85,7 @@ basis(x::SAnticommutator) = basis(x.op1) julia> @op A; @ket k; julia> conj(A) -Aˣ +Âˣ julia> conj(k) |k⟩ˣ @@ -161,10 +161,10 @@ end julia> @op A; @op B; @ket k; julia> transpose(A) -Aᵀ +Âᵀ julia> transpose(A+B) -(Aᵀ+Bᵀ) +(Âᵀ+B̂ᵀ) julia> transpose(k) |k⟩ᵀ @@ -206,20 +206,20 @@ end julia> @ket a; @op A; julia> dagger(2*im*A*a) -(0 - 2im)|a⟩†A† +(0 - 2im)|a⟩†Â† julia> @op B; julia> dagger(A*B) -B†A† +B̂†Â† julia> ℋ = SHermitianOperator(:ℋ); U = SUnitaryOperator(:U); julia> dagger(ℋ) -ℋ +ℋ̂ julia> dagger(U) -U⁻¹ +Û⁻¹ ``` """ @withmetadata struct SDagger{T<:QObj} <: Symbolic{T} @@ -275,7 +275,7 @@ end julia> @op A; @op B; julia> tr(A) -tr(A) +tr(Â) julia> tr(commutator(A, B)) 0 @@ -318,7 +318,7 @@ Base.isequal(x::STrace, y::STrace) = isequal(x.op, y.op) julia> @op 𝒪 SpinBasis(1//2)⊗SpinBasis(1//2); julia> op = ptrace(𝒪, 1) -tr1(𝒪) +tr1(𝒪̂) julia> QuantumSymbolics.basis(op) Spin(1/2) @@ -326,27 +326,27 @@ Spin(1/2) julia> @op A; @op B; julia> ptrace(A⊗B, 1) -(tr(A))B +(tr(Â))B̂ julia> @ket k; @bra b; julia> factorizable = A ⊗ (k*b) -(A⊗|k⟩⟨b|) +(Â⊗|k⟩⟨b|) julia> ptrace(factorizable, 1) -(tr(A))|k⟩⟨b| +(tr(Â))|k⟩⟨b| julia> ptrace(factorizable, 2) -(⟨b||k⟩)A +(⟨b||k⟩) julia> mixed_state = (A⊗(k*b)) + ((k*b)⊗B) -((A⊗|k⟩⟨b|)+(|k⟩⟨b|⊗B)) +((Â⊗|k⟩⟨b|)+(|k⟩⟨b|⊗B̂)) julia> ptrace(mixed_state, 1) -((0 + ⟨b||k⟩)B+(tr(A))|k⟩⟨b|) +((0 + ⟨b||k⟩)B̂+(tr(Â))|k⟩⟨b|) julia> ptrace(mixed_state, 2) -((0 + ⟨b||k⟩)A+(tr(B))|k⟩⟨b|) +((0 + ⟨b||k⟩)Â+(tr(B̂))|k⟩⟨b|) ``` """ @withmetadata struct SPartialTrace <: Symbolic{AbstractOperator} @@ -441,7 +441,7 @@ end julia> @op A; julia> inv(A) -A⁻¹ +Â⁻¹ julia> inv(A)*A 𝕀 @@ -474,7 +474,7 @@ inv(x::Symbolic{AbstractOperator}) = SInvOperator(x) julia> @op A; @op B; julia> exp(A) -exp(A) +exp(Â) ``` """ @withmetadata struct SExpOperator <: Symbolic{AbstractOperator} @@ -502,10 +502,10 @@ exp(x::Symbolic{AbstractOperator}) = SExpOperator(x) julia> @op A; @op B; julia> vec(A) -|A⟩⟩ +|Â⟩⟩ julia> vec(A+B) -(|A⟩⟩+|B⟩⟩) +(|Â⟩⟩+|B̂⟩⟩) ``` """ @withmetadata struct SVec <: Symbolic{AbstractKet} diff --git a/src/QSymbolicsBase/literal_objects.jl b/src/QSymbolicsBase/literal_objects.jl index a2a4161..ed9369e 100644 --- a/src/QSymbolicsBase/literal_objects.jl +++ b/src/QSymbolicsBase/literal_objects.jl @@ -70,10 +70,10 @@ Define a symbolic ket of type `SOperator`. By default, the defined basis is the ```jldoctest julia> @op A -A + julia> @op B FockBasis(2) -B +B̂ ``` """ macro op(name, basis) @@ -138,7 +138,10 @@ basis(x::SymQ) = x.basis Base.show(io::IO, x::SKet) = print(io, "|$(symbollabel(x))⟩") Base.show(io::IO, x::SBra) = print(io, "⟨$(symbollabel(x))|") -Base.show(io::IO, x::Union{SOperator,SHermitianOperator,SUnitaryOperator,SHermitianUnitaryOperator,SSuperOperator}) = print(io, "$(symbollabel(x))") +Base.show(io::IO, x::Union{SOperator,SHermitianOperator,SUnitaryOperator,SHermitianUnitaryOperator}) = begin + symbol_name = String(symbollabel(x)) + print(io, symbol_name[1:1] * "\u0302" * symbol_name[2:end]) # add hat to the first character +end Base.show(io::IO, x::SymQObj) = print(io, symbollabel(x)) # fallback that probably is not great struct SZero{T<:QObj} <: Symbolic{T} end diff --git a/src/QSymbolicsBase/rules.jl b/src/QSymbolicsBase/rules.jl index a0a9402..40a1970 100644 --- a/src/QSymbolicsBase/rules.jl +++ b/src/QSymbolicsBase/rules.jl @@ -182,15 +182,15 @@ Manually expand a symbolic expression of quantum objects. julia> @op A; @op B; @op C; julia> qexpand(commutator(A, B)) -(-1BA+AB) +(-1B̂Â+ÂB̂) julia> qexpand(A⊗(B+C)) -((A⊗B)+(A⊗C)) +((Â⊗B̂)+(Â⊗Ĉ)) julia> @ket k₁; @ket k₂; julia> qexpand(A*(k₁+k₂)) -(A|k₁⟩+A|k₂⟩) +(Â|k₁⟩+Â|k₂⟩) ``` """ function qexpand(s)