Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/MPSKit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ include("operators/projection.jl")
include("operators/timedependence.jl")
include("operators/multipliedoperator.jl")
include("operators/lazysum.jl")
include("operators/show.jl")

include("transfermatrix/transfermatrix.jl")
include("transfermatrix/transfer.jl")
Expand Down
74 changes: 0 additions & 74 deletions src/operators/abstractmpo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -82,80 +82,6 @@ function remove_orphans!(mpo::SparseMPO; tol=eps(real(scalartype(mpo)))^(3 / 4))
return mpo
end

# Show
# ----
function Base.show(io::IO, ::MIME"text/plain", W::AbstractMPO)
L = length(W)
println(io, L == 1 ? "single site " : "$L-site ", typeof(W), ":")
context = IOContext(io, :typeinfo => eltype(W), :compact => true)
return show(context, W)
end

Base.show(io::IO, mpo::AbstractMPO) = show(convert(IOContext, io), mpo)
function Base.show(io::IOContext, mpo::AbstractMPO)
charset = (; top="┬", bot="┴", mid="┼", ver="│", dash="──")
limit = get(io, :limit, false)::Bool
half_screen_rows = limit ? div(displaysize(io)[1] - 8, 2) : typemax(Int)
L = length(mpo)

# used to align all mposite infos regardless of the length of the mpo (100 takes up more space than 5)
npad = floor(Int, log10(L))
mpoletter = mpo isa MPOHamiltonian ? "W" : "O"
isfinite = (mpo isa FiniteMPO) || (mpo isa FiniteMPOHamiltonian)

!isfinite && println(io, "╷ ⋮")
for site in reverse(1:L)
if site < half_screen_rows || site > L - half_screen_rows
if site == L && isfinite
println(io, charset.top, " $mpoletter[$site]: ",
repeat(" ", npad - floor(Int, log10(site))), mpo[site])
elseif (site == 1) && isfinite
println(io, charset.bot, " $mpoletter[$site]: ",
repeat(" ", npad - floor(Int, log10(site))), mpo[site])
else
println(io, charset.mid, " $mpoletter[$site]: ",
repeat(" ", npad - floor(Int, log10(site))), mpo[site])
end
elseif site == half_screen_rows
println(io, " ", "⋮")
end
end
!isfinite && println(io, "╵ ⋮")
return nothing
end

function braille(H::SparseMPO)
isfinite = (H isa FiniteMPO) || (H isa FiniteMPOHamiltonian)
dash = "🭻"
stride = 2 #amount of dashes between braille
L = length(H)

brailles = Vector{Vector{String}}(undef, L)
buffer = IOBuffer()
for (i, W) in enumerate(H)
BlockTensorKit.show_braille(buffer, W)
brailles[i] = split(String(take!(buffer)))
end

maxheight = maximum(length.(brailles))

for i in 1:maxheight
line = ""
line *= ((i == 1 && !isfinite) ? ("... " * dash) : " ")
line *= (i > 1 && !isfinite) ? " " : ""
for (j, braille) in enumerate(brailles)
line *= (checkbounds(Bool, braille, i) ? braille[i] :
repeat(" ", length(braille[1])))
if j < L
line *= repeat(((i == 1) ? dash : " "), stride)
end
end
line *= ((i == 1 && !isfinite) ? (dash * " ...") : " ")
println(line)
end
return nothing
end

# Linear Algebra
# --------------
Base.:+(mpo::AbstractMPO) = scale(mpo, One())
Expand Down
90 changes: 90 additions & 0 deletions src/operators/show.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# AbstractMPO
# -----------
function Base.show(io::IO, ::MIME"text/plain", W::AbstractMPO)
L = length(W)
println(io, L == 1 ? "single site " : "$L-site ", typeof(W), ":")
context = IOContext(io, :typeinfo => eltype(W), :compact => true)
return show(context, W)

Check warning on line 7 in src/operators/show.jl

View check run for this annotation

Codecov / codecov/patch

src/operators/show.jl#L3-L7

Added lines #L3 - L7 were not covered by tests
end

Base.show(io::IO, mpo::AbstractMPO) = show(convert(IOContext, io), mpo)
function Base.show(io::IOContext, mpo::AbstractMPO)
charset = (; top="┬", bot="┴", mid="┼", ver="│", dash="──")
limit = get(io, :limit, false)::Bool
half_screen_rows = limit ? div(displaysize(io)[1] - 8, 2) : typemax(Int)
L = length(mpo)

Check warning on line 15 in src/operators/show.jl

View check run for this annotation

Codecov / codecov/patch

src/operators/show.jl#L10-L15

Added lines #L10 - L15 were not covered by tests

# used to align all mposite infos regardless of the length of the mpo (100 takes up more space than 5)
npad = floor(Int, log10(L))
mpoletter = mpo isa MPOHamiltonian ? "W" : "O"
isfinite = (mpo isa FiniteMPO) || (mpo isa FiniteMPOHamiltonian)

Check warning on line 20 in src/operators/show.jl

View check run for this annotation

Codecov / codecov/patch

src/operators/show.jl#L18-L20

Added lines #L18 - L20 were not covered by tests

!isfinite && println(io, "╷ ⋮")
for site in reverse(1:L)
if site < half_screen_rows || site > L - half_screen_rows
if site == L && isfinite
println(io, charset.top, " $mpoletter[$site]: ",

Check warning on line 26 in src/operators/show.jl

View check run for this annotation

Codecov / codecov/patch

src/operators/show.jl#L22-L26

Added lines #L22 - L26 were not covered by tests
repeat(" ", npad - floor(Int, log10(site))), mpo[site])
elseif (site == 1) && isfinite
println(io, charset.bot, " $mpoletter[$site]: ",

Check warning on line 29 in src/operators/show.jl

View check run for this annotation

Codecov / codecov/patch

src/operators/show.jl#L28-L29

Added lines #L28 - L29 were not covered by tests
repeat(" ", npad - floor(Int, log10(site))), mpo[site])
else
println(io, charset.mid, " $mpoletter[$site]: ",

Check warning on line 32 in src/operators/show.jl

View check run for this annotation

Codecov / codecov/patch

src/operators/show.jl#L32

Added line #L32 was not covered by tests
repeat(" ", npad - floor(Int, log10(site))), mpo[site])
end
elseif site == half_screen_rows
println(io, " ", "⋮")

Check warning on line 36 in src/operators/show.jl

View check run for this annotation

Codecov / codecov/patch

src/operators/show.jl#L35-L36

Added lines #L35 - L36 were not covered by tests
end
end
!isfinite && println(io, "╵ ⋮")
return nothing

Check warning on line 40 in src/operators/show.jl

View check run for this annotation

Codecov / codecov/patch

src/operators/show.jl#L38-L40

Added lines #L38 - L40 were not covered by tests
end

# braille
# -------
"""
braille(io::IO, H::Union{SparseMPO, MPOHamiltonian})
braille(H::Union{SparseMPO, MPOHamiltonian})

Prints a compact, human-readable "braille" visualization of a sparseMPO or MPOHamiltonian.
Each site of the MPO is represented as a block of Unicode braille characters, with sites separated by dashes.
This visualization is useful for quickly inspecting the structure and sparsity pattern of MPOs.

# Arguments
- `io::IO`: The output stream to print to (e.g., `stdout`).
- `H::Union{SparseMPO, MPOHamiltonian}`: The `SparseMPO` or `MPOHamiltonian` to visualize.

If called without an `io` argument, output is printed to `stdout`.
"""
function braille(io::IO, H::Union{SparseMPO,MPOHamiltonian})
dash = "🭻"
stride = 2 #amount of dashes between braille
L = length(H)

brailles = Vector{Vector{String}}(undef, L)
buffer = IOBuffer()
for (i, W) in enumerate(H)
BlockTensorKit.show_braille(buffer, W)
brailles[i] = split(String(take!(buffer)))
end

maxheight = maximum(length.(brailles))

for i in 1:maxheight
line = ""
line *= ((i == 1 && !isfinite(H)) ? ("... " * dash) : " ")
line *= (i > 1 && !isfinite(H)) ? " " : ""
for (j, braille) in enumerate(brailles)
line *= (checkbounds(Bool, braille, i) ? braille[i] :
repeat(" ", length(braille[1])))
if j < L
line *= repeat(((i == 1) ? dash : " "), stride)
end
end
line *= ((i == 1 && !isfinite(H)) ? (dash * " ...") : " ")
println(io, line)
end
return nothing
end

braille(H::Union{SparseMPO,MPOHamiltonian}) = braille(stdout, H)

Check warning on line 90 in src/operators/show.jl

View check run for this annotation

Codecov / codecov/patch

src/operators/show.jl#L90

Added line #L90 was not covered by tests
30 changes: 30 additions & 0 deletions test/other.jl
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,34 @@ end
end
end

@testset "braille" begin
# Infinite Hamiltonians and MPOs
# -------------------------------
H = transverse_field_ising()
buffer = IOBuffer()
braille(buffer, H)
output = String(take!(buffer))
check = "... 🭻⎡⠉⢀⎤🭻 ...\n ⎣⠀⢀⎦ \n"
@test output == check

O = make_time_mpo(H, 1.0, TaylorCluster(3, false, false))
braille(buffer, O)
output = String(take!(buffer))
check = "... 🭻⎡⡏⠉⠒⠔⎤🭻 ...\n ⎣⡇⠀⠀⡂⎦ \n"
@test output == check

# Finite Hamiltonians and MPOs
# ----------------------------
H = transverse_field_ising(; L=4)
braille(buffer, H)
output = String(take!(buffer))
check = " ⎡⠉⠀⎤🭻🭻⎡⠉⢀⎤🭻🭻⎡⠉⢀⎤🭻🭻⎡⡀⠀⎤ \n ⎣⠀⠀⎦ ⎣⠀⢀⎦ ⎣⠀⢀⎦ ⎣⡀⠀⎦ \n"
@test output == check

O = make_time_mpo(H, 1.0, TaylorCluster(3, false, false))
braille(buffer, O)
output = String(take!(buffer))
check = " ⎡⠉⠉⎤🭻🭻⎡⠍⠉⠤⠠⎤🭻🭻⎡⡏⠉⠒⠔⎤🭻🭻⎡⡇⠀⎤ \n ⎣⠀⠀⎦ ⎣⡂⠀⠀⠂⎦ ⎣⡇⠀⠀⡂⎦ ⎣⡇⠀⎦ \n"
@test output == check
end
end
Loading