Skip to content

Commit 5774c06

Browse files
committed
fix typos and format files
1 parent e766aff commit 5774c06

File tree

3 files changed

+63
-78
lines changed

3 files changed

+63
-78
lines changed

ext/QuantumToolboxMakieExt.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,11 @@ Plot a pure quantum state on the Bloch sphere using the `Makie` backend.
736736
!!! note "Internal function"
737737
This is the `Makie`-specific implementation called by the main `plot_bloch` function.
738738
"""
739-
function QuantumToolbox.plot_bloch(::Val{:Makie}, state::QuantumObject{OpType}; kwargs...) where {OpType<:Union{Ket,Bra,Operator}}
739+
function QuantumToolbox.plot_bloch(
740+
::Val{:Makie},
741+
state::QuantumObject{OpType};
742+
kwargs...,
743+
) where {OpType<:Union{Ket,Bra,Operator}}
740744
bloch_vec = _state_to_bloch(state)
741745
return _render_bloch_makie(bloch_vec; kwargs...)
742746
end

src/visualization.jl

Lines changed: 35 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
export plot_wigner
22
export plot_fock_distribution
3-
export plot_bloch,
4-
Bloch,
5-
render,
6-
add_points!,
7-
add_vectors!,
8-
add_line!,
9-
add_arc!,
10-
clear!,
11-
add_states!
3+
export plot_bloch, Bloch, render, add_points!, add_vectors!, add_line!, add_arc!, clear!, add_states!
124

135
@doc raw"""
146
plot_wigner(
@@ -160,7 +152,7 @@ function Base.show(io::IO, b::Bloch)
160152
println(io, "Bloch Sphere\n")
161153
println(io, "data:")
162154
println(io, "-----")
163-
map(n -> println(io, "$n =\t", getfield(b, n)), data_fields)
155+
map(n -> println(io, "Number of $n =\t", length(getfield(b, n))), data_fields)
164156
println(io, "")
165157
println(io, "properties:")
166158
println(io, "-----------")
@@ -241,20 +233,13 @@ function add_points!(
241233
color::Union{Nothing,String} = nothing,
242234
alpha::Float64 = 1.0,
243235
)
244-
if size(pnts, 1) != 3
245-
error("Points must be a 3×N matrix where each column is [x; y; z]")
246-
end
247-
if !(meth in (:s, :m, :l))
248-
error("`meth` must be :s, :m, or :l")
249-
end
236+
(size(pnts, 1) == 3) || throw(ArgumentError("Points must be a 3×N matrix where each column is [x; y; z]"))
237+
(meth in (:s, :m, :l)) || throw(ArgumentError("`meth` must be :s, :m, or :l"))
238+
250239
push!(b.points, convert(Matrix{Float64}, pnts))
251240
push!(b.point_style, meth)
252241
push!(b.point_alpha, alpha)
253-
if color === nothing
254-
push!(b.point_color, nothing)
255-
else
256-
push!(b.point_color, color)
257-
end
242+
push!(b.point_color, color)
258243
return nothing
259244
end
260245

@@ -270,9 +255,7 @@ Add a line between two points on the Bloch sphere.
270255
- `fmt="k"`: Line format string (matplotlib style)
271256
"""
272257
function add_line!(b::Bloch, p1::Vector{<:Real}, p2::Vector{<:Real}; fmt = "k")
273-
if length(p1) != 3 || length(p2) != 3
274-
error("Points must be 3D vectors")
275-
end
258+
(length(p1) != 3 || length(p2) != 3) && throw(ArgumentError("Points must be 3D vectors"))
276259
x = [p1[2], p2[2]]
277260
y = [-p1[1], -p2[1]]
278261
z = [p1[3], p2[3]]
@@ -283,7 +266,7 @@ end
283266
@doc raw"""
284267
add_line!(
285268
b::Bloch,
286-
start_point_point::QuantumObject,
269+
start_point::QuantumObject,
287270
end_point::QuantumObject;
288271
fmt = "k"
289272
)
@@ -293,8 +276,8 @@ Add a line between two quantum states on the Bloch sphere visualization.
293276
# Arguments
294277
295278
- `b::Bloch`: The Bloch sphere object to modify.
296-
- `start_point_point::QuantumObject`: The start_point_pointing quantum state or operator. Can be a [`Ket`](@ref), [`Bra`](@ref), or [`Operator`](@ref).
297-
- `end_point::QuantumObject`: The ending quantum state or operator. Can be a [`Ket`](@ref), [`Bra`](@ref), or [`Operator`](@ref).
279+
- `start_point::QuantumObject`: The starting quantum state. Can be a [`Ket`](@ref), [`Bra`](@ref), or [`Operator`](@ref).
280+
- `end_point::QuantumObject`: The ending quantum state. Can be a [`Ket`](@ref), [`Bra`](@ref), or [`Operator`](@ref).
298281
- `fmt::String="k"`: (optional) A format string specifying the line style and color (default is black `"k"`).
299282
300283
# Description
@@ -310,14 +293,14 @@ b = Bloch()
310293
add_line!(b, ψ₁, ψ₂; fmt = "r--")
311294
```
312295
"""
313-
function QuantumToolbox.add_line!(
296+
function add_line!(
314297
b::Bloch,
315-
p1::QuantumObject{OpType1},
316-
p2::QuantumObject{OpType2};
298+
start_point::QuantumObject{OpType1},
299+
end_point::QuantumObject{OpType2};
317300
fmt = "k",
318301
) where {OpType1<:Union{Ket,Bra,Operator},OpType2<:Union{Ket,Bra,Operator}}
319-
coords1 = _state_to_bloch(p1)
320-
coords2 = _state_to_bloch(p2)
302+
coords1 = _state_to_bloch(start_point)
303+
coords2 = _state_to_bloch(end_point)
321304
return add_line!(b, coords1, coords2; fmt = fmt)
322305
end
323306

@@ -344,9 +327,11 @@ julia> add_arc!(b, [1, 0, 0], [0, 1, 0], [0, 0, 1])
344327
```
345328
"""
346329
function add_arc!(b::Bloch, p1::Vector{<:Real}, p2::Vector{<:Real})
330+
(length(p1) != 3 || length(p2) != 3) && throw(ArgumentError("Points must be 3D vectors"))
347331
return push!(b.arcs, [convert(Vector{Float64}, p1), convert(Vector{Float64}, p2)])
348332
end
349333
function add_arc!(b::Bloch, p1::Vector{<:Real}, p2::Vector{<:Real}, p3::Vector{<:Real})
334+
(length(p1) != 3 || length(p2) != 3 || length(p3) != 3) && throw(ArgumentError("Points must be 3D vectors"))
350335
return push!(b.arcs, [convert(Vector{Float64}, p1), convert(Vector{Float64}, p2), convert(Vector{Float64}, p3)])
351336
end
352337

@@ -369,7 +354,7 @@ b = Bloch();
369354
add_states!(b, [x, y, z])
370355
```
371356
"""
372-
function add_states!(b::Bloch, states::Vector{QuantumObject})
357+
function add_states!(b::Bloch, states::Vector{<:QuantumObject})
373358
vecs = map(state -> _state_to_bloch(state), states)
374359
append!(b.vectors, vecs)
375360
return b.vectors
@@ -401,16 +386,17 @@ A 3-element `Vector{Float64}` representing the Bloch vector `[x, y, z]`.
401386
- `ArgumentError` if the state dimension is not 2.
402387
"""
403388
function _ket_to_bloch(state::QuantumObject{Ket})
389+
(size(state) == (2,)) ||
390+
throw(ArgumentError("Bloch sphere visualization is only supported for qubit states (2-level systems)"))
391+
404392
state_norm = norm(state)
405393
if !isapprox(state_norm, 1.0, atol = 1e-6)
406394
@warn "State is not normalized. Normalizing before Bloch vector conversion."
407395
ψ = state.data / state_norm
408396
else
409397
ψ = state.data
410398
end
411-
if length(ψ) != 2
412-
error("Bloch sphere visualization is only supported for qubit states (2-level systems)")
413-
end
399+
414400
x = 2 * real(ψ[1] * conj(ψ[2]))
415401
y = 2 * imag(ψ[1] * conj(ψ[2]))
416402
z = abs2(ψ[1]) - abs2(ψ[2])
@@ -434,17 +420,15 @@ A 3-element `Vector{Float64}` representing the Bloch vector `[x, y, z]`.
434420
- `ArgumentError` if the matrix dimension is not 2.
435421
"""
436422
function _dm_to_bloch::QuantumObject{Operator})
437-
if !ishermitian(ρ)
438-
@warn "Density matrix is not Hermitian. Results may not be meaningful."
439-
end
440-
if size(ρ, 1) != 2
441-
error("Bloch sphere visualization is only supported for qubit states (2-level systems)")
442-
end
423+
(size(ρ) == (2, 2)) ||
424+
throw(ArgumentError("Bloch sphere visualization is only supported for qubit states (2-level systems)"))
443425

444-
state_norm = norm(state)
426+
ishermitian(ρ) || (@warn "Density matrix is not Hermitian. Results may not be meaningful.")
427+
428+
state_norm = norm(ρ)
445429
if !isapprox(state_norm, 1.0, atol = 1e-6)
446430
@warn "State is not normalized. Normalizing before Bloch vector conversion."
447-
ρ2 = ρ2 / state_norm
431+
ρ2 = ρ / state_norm
448432
else
449433
ρ2 = ρ
450434
end
@@ -519,27 +503,10 @@ The `library` keyword argument specifies the plotting backend to use. The defaul
519503
!!! warning "Beware of type-stability!"
520504
For improved performance and type-stability, prefer passing `Val(:Makie)` instead of `:Makie`. See [Performance Tips](https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-value-type) for details.
521505
"""
522-
plot_bloch(state::QuantumObject{OpType}; library::Union{Symbol,Val} = Val(:Makie), kwargs...) where {OpType<:Union{Ket,Bra,Operator}} = plot_bloch(makeVal(lib_val), state; kwargs...)
523-
524-
@doc raw"""
525-
plot_bloch(::Val{T}, state::QuantumObject; kwargs...) where {T}
526-
527-
Fallback implementation for unsupported plotting backends.
528-
529-
# Arguments
530-
- `::Val{T}`: The unsupported backend specification.
531-
- `state::QuantumObject`: The quantum state that was attempted to be plotted.
532-
- `kwargs...`: Ignored keyword arguments.
533-
534-
# Throws
535-
- `ErrorException`: Always throws an error indicating the backend `T` is unsupported.
536-
537-
# Note
538-
This function serves as a fallback when an unsupported backend is requested. Currently supported backends include:
539-
- `:Makie` (using `Makie.jl`)
540-
541-
See the main `plot_bloch` documentation for supported backends.
542-
"""
543-
function plot_bloch(::Val{T}, state::QuantumObject{OpType}; kwargs...) where {T,OpType<:Union{Ket,Bra,Operator}}
544-
return error("Unsupported backend: $T. Try :Makie or another supported library.")
545-
end
506+
plot_bloch(
507+
state::QuantumObject{OpType};
508+
library::Union{Symbol,Val} = Val(:Makie),
509+
kwargs...,
510+
) where {OpType<:Union{Ket,Bra,Operator}} = plot_bloch(makeVal(library), state; kwargs...)
511+
plot_bloch(::Val{T}, state::QuantumObject{OpType}; kwargs...) where {T,OpType<:Union{Ket,Bra,Operator}} =
512+
throw(ArgumentError("The specified plotting library $T is not available. Try running `using $T` first."))

test/ext-test/cpu/makie/makie_ext.jl

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
xvec = yvec = -15.0:0.1:15.0
44
wig = transpose(wigner(ψ, xvec, yvec))
55

6+
# Makie unload errors
67
@test_throws ArgumentError plot_wigner(ψ; library = :Makie, xvec = xvec, yvec = yvec)
7-
88
@test_throws ArgumentError plot_fock_distribution(ψ; library = :Makie)
9+
@test_throws ArgumentError plot_bloch(ψ; library = :Makie)
910

1011
using Makie
1112

@@ -63,12 +64,12 @@
6364
end
6465

6566
@testset "Makie Bloch sphere" begin
66-
ρ = 0.7*ket2dm(basis(2, 0)) + 0.3*ket2dm(basis(2, 1))
67+
ρ = 0.7 * ket2dm(basis(2, 0)) + 0.3 * ket2dm(basis(2, 1))
6768
fig, ax = plot_bloch(ρ)
6869
@test fig isa Figure
6970
@test ax isa Axis3
7071

71-
ψ = (basis(2, 0) + basis(2, 1))/2
72+
ψ = (basis(2, 0) + basis(2, 1)) / 2
7273
fig, ax = plot_bloch(ψ)
7374
@test fig isa Figure
7475
@test ax isa Axis3
@@ -92,25 +93,37 @@ end
9293
add_points!(b, hcat(pts...))
9394
@test length(b.points) == 2
9495
@test b.points[2] hcat(pts...)
96+
@test_throws ArgumentError add_points!(b, [1 2 3 4])
97+
@test_throws ArgumentError add_points!(b, pts; meth = :wrong)
9598

9699
b = Bloch()
97100
add_vectors!(b, [1.0, 1.0, 0.0])
98101
@test length(b.vectors) == 1
99-
@test isapprox(norm(b.vectors[1]), 1.0)
102+
@test isapprox(norm(b.vectors[1]), 2)
100103

101104
vecs = [[0.0, 0.0, 1.0], [1.0, 0.0, 0.0]]
102105
add_vectors!(b, vecs)
103106
@test length(b.vectors) == 3
104-
@test all(norm(v) 1.0 for v in b.vectors)
107+
@test isapprox(norm(b.vectors[2]), 1.0)
108+
@test isapprox(norm(b.vectors[3]), 1.0)
105109

110+
vec_correct = [1, 0, 0]
111+
vec_wrong = [1, 0]
106112
b = Bloch()
107113
add_line!(b, [0, 0, 0], [1, 0, 0])
108114
@test length(b.lines) == 1
109115
@test b.lines[1][1][3] [0.0, 0.0]
116+
@test_throws ArgumentError add_line!(b, vec_wrong, vec_correct)
117+
@test_throws ArgumentError add_line!(b, vec_correct, vec_wrong)
110118

111119
add_arc!(b, [0, 0, 1], [0, 1, 0], [1, 0, 0])
112120
@test length(b.arcs) == 1
113121
@test b.arcs[1][3] == [1.0, 0.0, 0.0]
122+
@test_throws ArgumentError add_arc!(b, vec_wrong, vec_correct)
123+
@test_throws ArgumentError add_arc!(b, vec_correct, vec_wrong)
124+
@test_throws ArgumentError add_arc!(b, vec_wrong, vec_correct, vec_correct)
125+
@test_throws ArgumentError add_arc!(b, vec_correct, vec_wrong, vec_correct)
126+
@test_throws ArgumentError add_arc!(b, vec_correct, vec_correct, vec_wrong)
114127

115128
b = Bloch()
116129
add_points!(b, [0.0, 0.0, 1.0])
@@ -148,10 +161,11 @@ end
148161
@info "Render threw unexpected error" exception=e
149162
end
150163
b = Bloch()
151-
x = basis(2, 0) + basis(2, 1)
152-
y = basis(2, 0) - im * basis(2, 1)
153-
z = basis(2, 0)
154-
add_states!(b, [x, y, z])
164+
x = normalize!(basis(2, 0) + basis(2, 1)) # normalized
165+
y = basis(2, 0) - im * basis(2, 1) # unnormalized Ket
166+
ρ1 = 0.3 * rand_dm(2) + 0.4 * rand_dm(2) # unnormalized density operator
167+
ρ2 = Qobj(rand(ComplexF64, 2, 2)) # unnormalized and non-Hermitian Operator
168+
@test_logs (:warn,) (:warn,) (:warn,) (:warn,) add_states!(b, [x, y, ρ1, ρ2])
155169
th = range(0, 2π; length = 20);
156170
xp = cos.(th);
157171
yp = sin.(th);

0 commit comments

Comments
 (0)