Skip to content

Commit

Permalink
merge luxor-upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
GiggleLiu committed Jul 2, 2024
2 parents 8e90cc1 + 51fe39d commit f82c974
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 27 deletions.
5 changes: 5 additions & 0 deletions lib/YaoBlocks/test/primitive/time_evolution.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,17 @@ end
mpb = mat(pb)
allpass = true
for i=basis(pb), j=basis(pb)
allpass &= isapprox(pb[i, j], mpb[Int(i)+1, Int(j)+1]; atol=1e-6)
allpass &= isapprox(pb[i, j], mpb[Int(i)+1, Int(j)+1]; atol=1e-6, rtol=1e-6)
end
@test allpass

allpass = true
for j=basis(pb)
allpass &= isapprox(vec(pb[:, j]), mpb[:, Int(j)+1]; atol=1e-6)
allpass &= isapprox(vec(pb[j,:]), mpb[Int(j)+1,:]; atol=1e-6)
allpass &= isapprox(vec(pb[:, EntryTable([j], [1.0+0im])]), mpb[:, Int(j)+1]; atol=1e-6)
allpass &= isapprox(vec(pb[EntryTable([j], [1.0+0im]),:]), mpb[Int(j)+1,:]; atol=1e-6)
allpass &= isapprox(vec(pb[:, j]), mpb[:, Int(j)+1]; atol=1e-6, rtol=1e-6)
allpass &= isapprox(vec(pb[j,:]), mpb[Int(j)+1,:]; atol=1e-6, rtol=1e-6)
allpass &= isapprox(vec(pb[:, EntryTable([j], [1.0+0im])]), mpb[:, Int(j)+1]; atol=1e-6, rtol=1e-6)
Expand Down
4 changes: 1 addition & 3 deletions lib/YaoPlots/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ version = "0.9.2"
[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Luxor = "ae8d54c2-7ccd-5906-9d76-62fc9837b5bc"
Thebes = "8b424ff8-82f5-59a4-86a6-de3761897198"
YaoArrayRegister = "e600142f-9330-5003-8abb-0ebd767abc51"
YaoBlocks = "418bc28f-b43b-5e0b-a6e7-61bbc1a2c1df"

[compat]
LinearAlgebra = "1"
Luxor = "3"
Thebes = "1"
Luxor = "4"
YaoArrayRegister = "0.9"
YaoBlocks = "0.13"
julia = "1"
Expand Down
2 changes: 1 addition & 1 deletion lib/YaoPlots/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ using YaoPlots, Yao
reg = zero_state(1) |> Rx/8) |> Rx/8)
rho = density_matrix(ghz_state(2), 1)

bloch_sphere(""=>reg, "ρ"=>rho; show_projection_lines=true)
bloch_sphere(">"=>reg, "ρ"=>rho; show_projection_lines=true)
```

Similarly, you will see
Expand Down
100 changes: 100 additions & 0 deletions lib/YaoPlots/src/3d.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# The following code is copied from Thebes.jl, which is a package for 3D plotting in Julia.
# Since Thebes.jl is not updated for a while, we need to update the code to make it work with the latest version of Luxor.jl.

module Thebes
using Luxor
struct Point3D
x::Float64
y::Float64
z::Float64
end

mutable struct Projection
U::Point3D #
V::Point3D #
W::Point3D #
ue::Float64 #
ve::Float64 #
we::Float64 #
eyepoint::Point3D
centerpoint::Point3D
uppoint::Point3D
perspective::Float64 #
end

function newprojection(ipos::Point3D, center::Point3D, up::Point3D, perspective=0.0)
if iszero(ipos.x)
ipos = Point3D(10e-9, ipos.y, ipos.z)
end
if iszero(ipos.y)
ipos = Point3D(ipos.x, 10e-9, ipos.z)
end
if iszero(ipos.z)
ipos = Point3D(ipos.x, ipos.y, 10e-9)
end

# w is the line of sight
W = Point3D(center.x - ipos.x, center.y - ipos.y, center.z - ipos.z)
r = (W.x * W.x) + (W.y * W.y) + (W.z * W.z)
if r < eps()
@info("eye position and center are the same")

W = Point3D(0.0, 0.0, 0.0)
else
# distancealise w to unit length
rinv = 1 / sqrt(r)
W = Point3D(W.x * rinv, W.y * rinv, W.z * rinv)
end
we = W.x * ipos.x + W.y * ipos.y + W.z * ipos.z # project e on to w
U = Point3D(W.y * (up.z - ipos.z) - W.z * (up.y - ipos.y), # u is at right angles to t - e
W.z * (up.x - ipos.x) - W.x * (up.z - ipos.z), # and w ., its' the pictures x axis
W.x * (up.y - ipos.y) - W.y * (up.x - ipos.x))
r = (U.x * U.x) + (U.y * U.y) + (U.z * U.z)

if r < eps()
@info("struggling to make a valid projection with these parameters")
U = Point3D(0.0, 0.0, 0.0)
else
rinv = 1 / sqrt(r) # distancealise u
U = Point3D(U.x * rinv, U.y * rinv, U.z * rinv)
end

ue = U.x * ipos.x + U.y * ipos.y + U.z * ipos.z # project e onto u

V = Point3D(U.y * W.z - U.z * W.y, # v is at right angles to u and w
U.z * W.x - U.x * W.z, # it's the world's y axis
U.x * W.y - U.y * W.x)

ve = V.x * ipos.x + V.y * ipos.y + V.z * ipos.z # project e onto v

Projection(U, V, W, ue, ve, we, ipos, center, up, perspective)
end

function project(proj::Projection, P::Point3D)
# use default value for perspectiveness if not specified
r = proj.W.x * P.x + proj.W.y * P.y + proj.W.z * P.z - proj.we
if r < eps()
# "point $P is behind eye"
result = nothing
else
if proj.perspective == 0.0
depth = 1
else
depth = proj.perspective * (1 / r)
end
uq = depth * (proj.U.x * P.x + proj.U.y * P.y + proj.U.z * P.z - proj.ue)
vq = depth * (proj.V.x * P.x + proj.V.y * P.y + proj.V.z * P.z - proj.ve)
result = Point(uq, -vq) # because Y is down the page in Luxor (?!)
end
return result
end

function eyepoint(pt::Point3D)
return newprojection(pt, Point3D(0, 0, 0), Point3D(0, 0, 1))
end

function Luxor.distance(p1::Point3D, p2::Point3D)
sqrt((p2.x - p1.x)^2 + (p2.y - p1.y)^2 + (p2.z - p1.z)^2)
end

end
4 changes: 2 additions & 2 deletions lib/YaoPlots/src/YaoPlots.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ using YaoBlocks
using YaoBlocks.DocStringExtensions
using YaoArrayRegister
import Luxor
import Thebes
using Luxor: @layer, Point
using Thebes: Point3D, project
using LinearAlgebra: tr
using YaoBlocks

Expand All @@ -21,6 +19,8 @@ plot(blk::AbstractBlock; kwargs...) = vizcircuit(blk; kwargs...)

include("helperblock.jl")
include("vizcircuit.jl")
include("3d.jl")
using .Thebes: Point3D, project
include("bloch.jl")

end
35 changes: 18 additions & 17 deletions lib/YaoPlots/src/bloch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module BlochStyles
# generic config
const lw = Ref(1.0)
const textsize = Ref(16.0)
const fontfamily = Ref("monospace")
const fontfamily = Ref("JuliaMono")
const background_color = Ref("transparent")
const color = Ref("#000000")

Expand Down Expand Up @@ -132,8 +132,6 @@ function bloch_sphere(states...;
Luxor.fontsize(textsize)
fontfamily !== nothing && Luxor.fontface(fontfamily)
Luxor.setline(lw)
Thebes.eyepoint(eye_point...)

draw_bloch_sphere(states...; eye_point, extra_kwargs...)

# Save the drawing to a file
Expand All @@ -153,21 +151,23 @@ function draw_bloch_sphere(states::Pair{<:AbstractString}...;
colors = fill(BlochStyles.color[], length(states)),
extra_kwargs...
)
proj = Thebes.eyepoint(Point3D(eye_point...))

# get coordinate of a state
getcoo(x) = Point3D(ball_size .* state_to_cartesian(x))
getcoo(x) = Point3D((ball_size .* state_to_cartesian(x))...)

# ball
Luxor.circle(Point(0, 0), ball_size, :stroke)

# equator
nstep = 100
equator_points = map(LinRange(0, 2π*(1-1/nstep), nstep)) do ϕ
project(Point3D(ball_size .* polar_to_cartesian(1.0, π/2, ϕ)))
project(proj, Point3D((ball_size .* polar_to_cartesian(1.0, π/2, ϕ))...))
end
Luxor.line.(equator_points[1:2:end], equator_points[2:2:end], :stroke)

# show axes
axes3D(ball_size*3 ÷ 2; extra_kwargs...)
axes3D(ball_size*3 ÷ 2; proj, extra_kwargs...)

# show 01 states
if show01
Expand All @@ -178,7 +178,7 @@ function draw_bloch_sphere(states::Pair{<:AbstractString}...;
if Thebes.distance(Point3D(0, 0, 0), Point3D(eye_point...)) < Thebes.distance(p, Point3D(eye_point...))
Luxor.setopacity(0.3)
end
show_point(txt, project(p); dot_size, text_offset=Point(10, 0), show_line=false)
show_point(txt, project(proj, p); dot_size, text_offset=Point(10, 0), show_line=false)
end
end
end
Expand All @@ -191,32 +191,32 @@ function draw_bloch_sphere(states::Pair{<:AbstractString}...;
if Thebes.distance(Point3D(0, 0, 0), Point3D(eye_point...)) < Thebes.distance(p, Point3D(eye_point...))
Luxor.setopacity(0.3)
end
show_point(txt, project(p); dot_size, text_offset=Point(10, 0), show_line=show_line)
show_point(txt, project(proj, p); dot_size, text_offset=Point(10, 0), show_line=show_line)
end
if show_projection_lines
# show θ
ratio = 0.2
sz = project(Point3D(0, 0, ball_size*ratio))
sz = project(proj, Point3D(0, 0, ball_size*ratio))
if show_angle_texts
Luxor.move(sz)
Luxor.arc2r(Point(0, 0), sz, project(p) * ratio, :stroke)
Luxor.arc2r(Point(0, 0), sz, project(proj, p) * ratio, :stroke)
Luxor.text("θ", sz - Point(0, ball_size*0.07))
end
# show equator projection and ϕ
equatorp = Point3D(p[1], p[2], 0)
sx = project(Point3D(ball_size*ratio, 0, 0))
equatorp = Point3D(p.x, p.y, 0)
sx = project(proj, Point3D(ball_size*ratio, 0, 0))

if show_angle_texts
Luxor.move(sx)
Luxor.carc2r(Point(0, 0), sx, project(equatorp) * ratio, :stroke)
Luxor.carc2r(Point(0, 0), sx, project(proj, equatorp) * ratio, :stroke)
Luxor.text("ϕ", sx - Point(ball_size*0.12, 0))
end

@layer begin
Luxor.setdash("dot")
Luxor.setline(1)
Luxor.line(project(p), project(equatorp), :stroke)
Luxor.line(Point(0, 0), project(equatorp), :stroke)
Luxor.line(project(proj, p), project(proj, equatorp), :stroke)
Luxor.line(Point(0, 0), project(proj, equatorp), :stroke)
end
end
end
Expand Down Expand Up @@ -253,6 +253,7 @@ state_to_cartesian(state) = polar_to_cartesian(state_to_polar(state)...)

# Draw labelled 3D axes with length `n`.
function axes3D(n::Int;
proj,
axes_lw = BlochStyles.axes_lw[],
axes_textsize = BlochStyles.textsize[],
axes_colors = BlochStyles.axes_colors,
Expand All @@ -262,10 +263,10 @@ function axes3D(n::Int;
Luxor.fontsize(axes_textsize)
Luxor.setline(axes_lw)
for i = 1:3
axis1 = project(Point3D(0.1, 0.1, 0.1))
axis1 = project(proj, Point3D(0.1, 0.1, 0.1))
axis2 = [0.1, 0.1, 0.1]
axis2[i] = n
axis2 = project(Point3D(axis2...))
axis2 = project(proj, Point3D(axis2...))
Luxor.sethue(axes_colors[i])
if (axis1 !== nothing) && (axis2 !== nothing) && !isapprox(axis1, axis2)
Luxor.arrow(axis1, axis2)
Expand Down
6 changes: 3 additions & 3 deletions lib/YaoPlots/src/vizcircuit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ module CircuitStyles
const lw = Ref(1.0)
const textsize = Ref(16.0)
const paramtextsize = Ref(10.0)
const fontfamily = Ref("monospace")
const fontfamily = Ref("JuliaMono")
#const fontfamily = Ref("Dejavu Sans")
const linecolor = Ref("#000000")
const gate_bgcolor = Ref("transparent")
Expand Down Expand Up @@ -439,7 +439,7 @@ get_brush_texts(c, ::ConstGate.P0Gate) = (c.gatestyles.g, "P₀")
get_brush_texts(c, ::ConstGate.P1Gate) = (c.gatestyles.g, "P₁")
get_brush_texts(c, b::PrimitiveBlock) = (c.gatestyles.g, string(b))
get_brush_texts(c, b::TimeEvolution) = (c.gatestyles.g, string(b))
get_brush_texts(c, b::ShiftGate) = (c.gatestyles.g, "ϕ($(pretty_angle(b.theta)))")
get_brush_texts(c, b::ShiftGate) = (c.gatestyles.g, "φ($(pretty_angle(b.theta)))")
get_brush_texts(c, b::PhaseGate) = (CircuitStyles.Phase("$(pretty_angle(b.theta))"), "")
function get_brush_texts(c, b::T) where T<:ConstantGate
namestr = string(T.name.name)
Expand Down Expand Up @@ -480,7 +480,7 @@ They are defined as:
* CircuitStyles.lw = Ref(1.0) # line width
* CircuitStyles.textsize = Ref(16.0) # text size
* CircuitStyles.paramtextsize = Ref(10.0) # text size (longer texts)
* CircuitStyles.fontfamily = Ref("monospace") # font family
* CircuitStyles.fontfamily = Ref("JuliaMono") # font family
* CircuitStyles.linecolor = Ref("#000000") # line color
* CircuitStyles.gate_bgcolor = Ref("transparent") # gate background color
* CircuitStyles.textcolor = Ref("#000000") # text color
Expand Down
2 changes: 1 addition & 1 deletion lib/YaoPlots/test/vizcircuit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ using Luxor
c = YaoPlots.CircuitGrid(1)
@test YaoPlots.get_brush_texts(c, X)[2] == "X"
@test YaoPlots.get_brush_texts(c, Rx(0.5))[2] == "Rx(0.5)"
@test YaoPlots.get_brush_texts(c, shift(0.5))[2] == "ϕ(0.5)"
@test YaoPlots.get_brush_texts(c, shift(0.5))[2] == "φ(0.5)"
@test YaoPlots.get_brush_texts(c, YaoBlocks.phase(0.5))[2] == ""
end

Expand Down

0 comments on commit f82c974

Please sign in to comment.