Skip to content

Commit a4980ef

Browse files
authored
Fix Base.show methods and add corresponding test suite (#112)
* Fix printing of SScaled ops * Fix printing of Tensor product times bra * add Base.show test suite for symbolic expressions * update changelog * bump project.toml to v0.4.10
1 parent f03b07c commit a4980ef

File tree

5 files changed

+124
-8
lines changed

5 files changed

+124
-8
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# News
22

3+
## v0.4.10 - 2025-05-11
4+
5+
- Polish `Base.show` methods for application products and scaled quantum objects.
6+
- Add test suite for `Base.show` methods of quantum symbolic types.
7+
38
## v0.4.9 - 2025-04-23
49

510
- `Base.zero` implemented for quantum symbolic objects.

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "QuantumSymbolics"
22
uuid = "efa7fd63-0460-4890-beb7-be1bbdfbaeae"
33
authors = ["QuantumSymbolics.jl contributors"]
4-
version = "0.4.9"
4+
version = "0.4.10"
55

66
[deps]
77
Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"

src/QSymbolicsBase/basic_ops_homogeneous.jl

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,25 +49,49 @@ basis(x::SScaled) = basis(x.obj)
4949
const SScaledKet = SScaled{AbstractKet}
5050
function Base.show(io::IO, x::SScaledKet)
5151
if x.coeff isa Real
52-
print(io, "$(x.coeff)$(x.obj)")
52+
if x.obj isa SAddKet
53+
print(io, "$(x.coeff)($(x.obj))")
54+
else
55+
print(io, "$(x.coeff)$(x.obj)")
56+
end
5357
else
54-
print(io, "($(x.coeff))$(x.obj)")
58+
if x.obj isa SAddKet
59+
print(io, "($(x.coeff))($(x.obj))")
60+
else
61+
print(io, "($(x.coeff))$(x.obj)")
62+
end
5563
end
5664
end
5765
const SScaledOperator = SScaled{AbstractOperator}
5866
function Base.show(io::IO, x::SScaledOperator)
5967
if x.coeff isa Real
60-
print(io, "$(x.coeff)$(x.obj)")
68+
if x.obj isa SAddOperator
69+
print(io, "$(x.coeff)($(x.obj))")
70+
else
71+
print(io, "$(x.coeff)$(x.obj)")
72+
end
6173
else
62-
print(io, "($(x.coeff))$(x.obj)")
74+
if x.obj isa SAddOperator
75+
print(io, "($(x.coeff))($(x.obj))")
76+
else
77+
print(io, "($(x.coeff))$(x.obj)")
78+
end
6379
end
6480
end
6581
const SScaledBra = SScaled{AbstractBra}
6682
function Base.show(io::IO, x::SScaledBra)
6783
if x.coeff isa Real
68-
print(io, "$(x.coeff)$(x.obj)")
84+
if x.obj isa SAddBra
85+
print(io, "$(x.coeff)($(x.obj))")
86+
else
87+
print(io, "$(x.coeff)$(x.obj)")
88+
end
6989
else
70-
print(io, "($(x.coeff))$(x.obj)")
90+
if x.obj isa SAddBra
91+
print(io, "($(x.coeff))($(x.obj))")
92+
else
93+
print(io, "($(x.coeff))$(x.obj)")
94+
end
7195
end
7296
end
7397

src/QSymbolicsBase/basic_ops_inhomogeneous.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Base.:(*)(b::SZeroBra, op::Symbolic{AbstractOperator}) = SZeroBra()
6969
Base.:(*)(b::Symbolic{AbstractBra}, op::SZeroOperator) = SZeroBra()
7070
Base.:(*)(b::SZeroBra, op::SZeroOperator) = SZeroBra()
7171
function Base.show(io::IO, x::SApplyBra)
72-
str_func = x -> x isa SAdd || x isa STensor ? "("*string(x)*")" : string(x)
72+
str_func = x -> x isa SAdd || x isa STensorOperator ? "("*string(x)*")" : string(x)
7373
print(io, join(map(str_func, arguments(x)),""))
7474
end
7575
basis(x::SApplyBra) = basis(x.bra)

test/test_show.jl

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
@testitem "Base show methods" begin
2+
@op A; @op B;
3+
@superop S;
4+
@bra b₁; @bra b₂;
5+
@ket k₁; @ket k₂;
6+
7+
@testset "symbolic literal objects" begin
8+
@test repr(k₁) == "|k₁⟩"
9+
@test repr(b₁) == "⟨b₁|"
10+
@test repr(A) == "A"
11+
@test repr(S) == "S"
12+
@test repr(zero(k₁)) == repr(zero(b₁)) == repr(zero(A)) == repr(zero(S)) == "𝟎"
13+
end
14+
15+
@testset "symbolic addition" begin
16+
@test repr(k₁ + k₂) == "|k₁⟩+|k₂⟩"
17+
@test repr(b₁ + b₂) == "⟨b₁|+⟨b₂|"
18+
@test repr(A + B) == "A+B"
19+
end
20+
21+
@testset "symbolic application products" begin
22+
@test repr(A * k₁) == "A|k₁⟩"
23+
@test repr(b₁ * A) == "⟨b₁|A"
24+
@test repr((A + B) * k₁) == "(A+B)|k₁⟩"
25+
@test repr(b₁ * (A + B)) == "⟨b₁|(A+B)"
26+
@test repr((A + B) * (k₁ + k₂)) == "(A+B)(|k₁⟩+|k₂⟩)"
27+
@test repr((b₁ + b₂) * (A + B)) == "(⟨b₁|+⟨b₂|)(A+B)"
28+
@test repr((A B) * SKet(:k, SpinBasis(1//2)^2)) == "(A⊗B)|k⟩"
29+
@test repr(SBra(:b, SpinBasis(1//2)^2) * (A B)) == "⟨b|(A⊗B)"
30+
@test repr((A B) * (k₁ k₂)) == "(A⊗B)|k₁⟩|k₂⟩"
31+
@test repr((b₁ b₂) * (A B)) == "⟨b₁|⟨b₂|(A⊗B)"
32+
end
33+
34+
@testset "symbolic scaling" begin
35+
@test repr(2 * k₁) == "2|k₁⟩"
36+
@test repr(2 * b₁) == "2⟨b₁|"
37+
@test repr(2 * A) == "2A"
38+
@test repr(2 * (k₁ + k₂)) == "2(|k₁⟩+|k₂⟩)"
39+
@test repr(2 * (b₁ + b₂)) == "2(⟨b₁|+⟨b₂|)"
40+
@test repr(2 * (A + B)) == "2(A+B)"
41+
@test repr(2 * (k₁ k₂)) == "2|k₁⟩|k₂⟩"
42+
@test repr(2 * (b₁ b₂)) == "2⟨b₁|⟨b₂|"
43+
@test repr(2 * (A B)) == "2A⊗B"
44+
@test repr((1 + im) * k₁) == "(1 + 1im)|k₁⟩"
45+
@test repr((1 + im) * b₁) == "(1 + 1im)⟨b₁|"
46+
@test repr((1 + im) * A) == "(1 + 1im)A"
47+
@test repr((1 + im) * (k₁ + k₂)) == "(1 + 1im)(|k₁⟩+|k₂⟩)"
48+
@test repr((1 + im) * (b₁ + b₂)) == "(1 + 1im)(⟨b₁|+⟨b₂|)"
49+
@test repr((1 + im) * (A + B)) == "(1 + 1im)(A+B)"
50+
@test repr((1 + im) * (k₁ k₂)) == "(1 + 1im)|k₁⟩|k₂⟩"
51+
@test repr((1 + im) * (b₁ b₂)) == "(1 + 1im)⟨b₁|⟨b₂|"
52+
@test repr((1 + im) * (A B)) == "(1 + 1im)A⊗B"
53+
end
54+
55+
@testset "symbolic inner and outer products" begin
56+
@test repr(b₁ * k₁) == "⟨b₁||k₁⟩"
57+
@test repr(k₁ * b₁) == "|k₁⟩⟨b₁|"
58+
end
59+
60+
@testset "symbolic superoperators" begin
61+
@test repr(S * A) == "S[A]"
62+
end
63+
64+
@testset "symbolic commutator and anticommutator" begin
65+
@test repr(commutator(A, B)) == "[A,B]"
66+
@test repr(anticommutator(A, B)) == "{A,B}"
67+
end
68+
69+
@testset "symbolic linear algebra operations" begin
70+
@test repr(conj(k₁)) == "|k₁⟩ˣ"
71+
@test repr(conj(b₁)) == "⟨b₁|ˣ"
72+
@test repr(conj(A)) == ""
73+
@test repr(projector(k₁)) == "𝐏[|k₁⟩]"
74+
@test repr(transpose(k₁)) == "|k₁⟩ᵀ"
75+
@test repr(transpose(b₁)) == "⟨b₁|ᵀ"
76+
@test repr(transpose(A)) == "Aᵀ"
77+
@test repr(dagger(k₁)) == "|k₁⟩†"
78+
@test repr(dagger(b₁)) == "⟨b₁|†"
79+
@test repr(dagger(A)) == "A†"
80+
@test repr(tr(A)) == "tr(A)"
81+
@test repr(ptrace(A B, 1)) == "(tr(A))B"
82+
@test repr(ptrace(SOperator(:A, SpinBasis(1//2)^2), 1)) == "tr1(A)"
83+
@test repr(inv(A)) == "A⁻¹"
84+
@test repr(exp(A)) == "exp(A)"
85+
@test repr(vec(A)) == "|A⟩⟩"
86+
end
87+
end

0 commit comments

Comments
 (0)