using GLMakie using ClassicalOrthogonalPolynomials set_theme!(theme_black()) """ phi_N = hermite_mode(x,N) Physicists Hermite mode with Gaussian weight at `x`. Normalisation ∫|ψ|²dx = 1. Uses stable recursion. """ function hermite_mode(x,N) Z₀ = exp(-x^2/2)/π^(0.25) Z₁ = √2*x*Z₀ if N == 0 return Z₀ elseif N == 1 return Z₁ else Zₙ₊₁,Zₙ,Zₙ₋₁ = zero(x),Z₁,Z₀ for n in 1:N-1 Zₙ₊₁ = sqrt(2/(n+1))*x*Zₙ-sqrt(n/(n+1))*Zₙ₋₁ Zₙ,Zₙ₋₁ = Zₙ₊₁,Zₙ end return Zₙ₊₁ end end W(x,p,n) = (-1)^n/π * exp(-(x^2+p^2)) * laguerrel(n, 2*(x^2 + p^2)) ψ(x,n) = hermite_mode(x,n) P(x,n) = abs2(ψ(x,n)) ## combined plot function wignerax(n,j,f;mlabels=false,Nx = 500,cmap=:diverging_tritanopic_cwr_75_98_c20_n256,reverse=false,ttl=false) xmax = sqrt(2n+2)+2 x = range(-xmax,xmax,Nx) p = x cmap = reverse ? Reverse(cmap) : cmap s = [W(x,p,n) for x in x, p in p] ax = Axis3(f[j,1]; aspect =(1,1,1), perspectiveness = .4f0, azimuth = -1.275π * 1.81, elevation = pi/10, protrusions=0, xlabel=L"x", ylabel=L"p", xlabelalign=(:right,:center), ylabelalign=(:left,:center), xlabelrotation=0,ylabelrotation=0, zlabel="", xticks=LinearTicks(3),yticks=LinearTicks(3),zticks=LinearTicks(3), title = ttl ? L"W(x,p)" : "",titlegap =-30 ) hidedecorations!(ax, ticks=false, ticklabels=false, label=false) surface!(ax,x,p,s, colormap=cmap, ) # marginals pm = p[end]; xm = x[1] yend(z,n) = P(z,n) xend(z,n) = P(z,n) zx = [yend(x,n) for x in x, p in pm] zp = [xend(p,n) for x in xm, p in p] xupper = Point3f.(x, pm, zx) xlower = Point3f.(x, pm, zero.(x)) pupper = Point3f.(xm, p, zp) plower = Point3f.(xm, p, zero.(p)) band!(ax,xlower,xupper;color = :white, alpha = 0.3) band!(ax,plower,pupper;color = :white, alpha = 0.3) if mlabels text!(ax, L"|\phi(p)|^2", position = Point3f(x[1],p[1],maximum(zx)),align=(:left,:top),fontsize=19) text!(ax, L"|\psi(x)|^2", position = Point3f(x[end],p[end],maximum(zp)),align=(:right,:top),fontsize=19) end return ax end ## combined plot fall = Figure(size=(400,1200), fonts= (; regular = "CMU Serif",bold="CMU Serif"), fontsize=22, linewidth=2, figure_padding = 30) ax1 = wignerax(0,1,fall,mlabels=true,reverse=true,ttl=true) ax2 = wignerax(1,2,fall) ax3 = wignerax(19,3,fall) labs = ["a)","b)","c)"] pad = (0, -15, -80, 0) for i in 1:3 Label(fall.layout[i, 1, TopLeft()], labs[i], padding = pad) end rowgap!(fall.layout,1) rowgap!(fall.layout,1,0) fall ## save("fock_wigner_function.png", fall)