From 8a0a7f9aea40204212a89139bdbb1bca24c2e391 Mon Sep 17 00:00:00 2001 From: Rohan Bali Date: Tue, 13 Aug 2024 10:42:21 -0400 Subject: [PATCH 1/4] Updated operators to print with hat --- CHANGELOG.md | 4 ++++ src/QSymbolicsBase/literal_objects.jl | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0086a7b..195b1cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # News +## v0.4.3 - 2024-08-13 + +- Operators now print with hat + ## v0.4.2 - 2024-08-11 - `@withmetadata` now supports inline docstrings for struct fields diff --git a/src/QSymbolicsBase/literal_objects.jl b/src/QSymbolicsBase/literal_objects.jl index a2a4161..dd3e7bc 100644 --- a/src/QSymbolicsBase/literal_objects.jl +++ b/src/QSymbolicsBase/literal_objects.jl @@ -138,7 +138,7 @@ 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,SSuperOperator}) = print(io, "$(symbollabel(x))̂") Base.show(io::IO, x::SymQObj) = print(io, symbollabel(x)) # fallback that probably is not great struct SZero{T<:QObj} <: Symbolic{T} end From 3e00446504c6bbae7bfd02534bff8a783c8b9d06 Mon Sep 17 00:00:00 2001 From: Rohan Bali Date: Tue, 13 Aug 2024 20:31:54 -0400 Subject: [PATCH 2/4] updated hat to print at the center character of an operator --- Project.toml | 1 + docs/src/introduction.md | 30 ++++++------- src/QSymbolicsBase/basic_ops_homogeneous.jl | 8 ++-- src/QSymbolicsBase/basic_ops_inhomogeneous.jl | 4 +- src/QSymbolicsBase/basic_superops.jl | 4 +- src/QSymbolicsBase/linalg.jl | 44 +++++++++---------- src/QSymbolicsBase/literal_objects.jl | 10 +++-- src/QSymbolicsBase/rules.jl | 6 +-- 8 files changed, 56 insertions(+), 51 deletions(-) diff --git a/Project.toml b/Project.toml index b5021c0..da60d48 100644 --- a/Project.toml +++ b/Project.toml @@ -9,6 +9,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" QuantumInterface = "5717a53b-5d69-4fa3-b976-0bf2f97ca1e5" +QuantumOptics = "6e0679c1-51ea-5a7c-ac74-d61b76210b0c" SymbolicUtils = "d1185830-fcd6-423d-90d6-eec64667417b" Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" TermInterface = "8ea1fca8-c5ef-4a55-8b96-4e9afe9c9a3c" diff --git a/docs/src/introduction.md b/docs/src/introduction.md index c85298a..688fdbc 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: @@ -209,10 +209,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₃; @@ -220,7 +220,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 7cc77f9..83c6ac5 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 dd3e7bc..a01cfd4 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,11 @@ 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)) + middle_index = (length(symbol_name) + 1) ÷ 2 + print(io, symbol_name[1:middle_index-1] * symbol_name[middle_index] * "\u0302" * symbol_name[middle_index+1:end]) # add hat to the middle 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 ac31f95..38e3c9b 100644 --- a/src/QSymbolicsBase/rules.jl +++ b/src/QSymbolicsBase/rules.jl @@ -181,15 +181,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) From 953e3ebc56c6c58aadc5fbfc182e7317ef15e9b2 Mon Sep 17 00:00:00 2001 From: Rohan Bali Date: Tue, 13 Aug 2024 20:35:00 -0400 Subject: [PATCH 3/4] removed accidentally added dependency --- Project.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Project.toml b/Project.toml index da60d48..b5021c0 100644 --- a/Project.toml +++ b/Project.toml @@ -9,7 +9,6 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" QuantumInterface = "5717a53b-5d69-4fa3-b976-0bf2f97ca1e5" -QuantumOptics = "6e0679c1-51ea-5a7c-ac74-d61b76210b0c" SymbolicUtils = "d1185830-fcd6-423d-90d6-eec64667417b" Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" TermInterface = "8ea1fca8-c5ef-4a55-8b96-4e9afe9c9a3c" From 955a95f701a8b62bb77e23a6a7270943b82277f0 Mon Sep 17 00:00:00 2001 From: Stefan Krastanov Date: Thu, 14 Nov 2024 16:15:19 -0500 Subject: [PATCH 4/4] add hat only to the first character --- src/QSymbolicsBase/literal_objects.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/QSymbolicsBase/literal_objects.jl b/src/QSymbolicsBase/literal_objects.jl index a01cfd4..ed9369e 100644 --- a/src/QSymbolicsBase/literal_objects.jl +++ b/src/QSymbolicsBase/literal_objects.jl @@ -140,8 +140,7 @@ 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}) = begin symbol_name = String(symbollabel(x)) - middle_index = (length(symbol_name) + 1) ÷ 2 - print(io, symbol_name[1:middle_index-1] * symbol_name[middle_index] * "\u0302" * symbol_name[middle_index+1:end]) # add hat to the middle character + 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