Skip to content

Commit 371f36c

Browse files
committed
Work on operator bases
1 parent be523ec commit 371f36c

File tree

2 files changed

+82
-61
lines changed

2 files changed

+82
-61
lines changed

src/bases.jl

Lines changed: 82 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ See also [`nsubsystems`](@ref) and [`CompositeBasis`](@ref).
5858
"""
5959
Base.size(b::Basis) = [length(b)]
6060

61+
"""
62+
getindex(b::Basis)
63+
64+
Get the i'th factor in the tensor product decomposition of the basis into
65+
subsystems.
66+
67+
See also [`nsubsystems`](@ref) and [`CompositeBasis`](@ref).
68+
"""
69+
Base.getindex(b::Basis, i) = i==1 ? b : throw(BoundsError("attempted to access a nonexistent subsystem basis"))
6170

6271
##
6372
# GenericBasis, CompositeBasis, SumBasis
@@ -98,7 +107,7 @@ CompositeBasis(bases::Tuple) = CompositeBasis([bases...])
98107
Base.:(==)(b1::CompositeBasis, b2::CompositeBasis) = all(((i, j),) -> i == j, zip(b1.bases, b2.bases))
99108
Base.length(b::CompositeBasis) = prod(b.shape)
100109
Base.size(b::CompositeBasis) = b.shape
101-
Base.getindex(b::CompositeBasis, i) = getindex(b.bases, i)
110+
Base.getindex(b::CompositeBasis, i) = b.bases[i]
102111

103112
"""
104113
tensor(x::Basis, y::Basis, z::Basis...)
@@ -377,6 +386,72 @@ See [`SpinBasis`](@ref).
377386
spinnumber(b::SpinBasis) = b.spinnumber
378387

379388

389+
##
390+
# Operator Bases
391+
##
392+
393+
"""
394+
KetBraBasis(BL,BR)
395+
396+
The "Ket-Bra" operator basis is the standard representation for the left and
397+
right bases of superoperators. This basis is formed by "vec'ing" the
398+
outer-product "Ket-Bra" basis for an operator with a left Bra basis and right
399+
Ket basis which practically means flipping the Bra to a Ket. The operator itself
400+
is then represented as a "Super-Bra" in this basis and corresponds to
401+
column-stacking its matrix.
402+
"""
403+
struct KetBraBasis{BL<:Basis, BR<:Basis} <: Basis
404+
left::BL
405+
right::BR
406+
end
407+
KetBraBasis(b::Basis) = KetBraBasis(b,b)
408+
basis_l(b::KetBraBasis) = b.left
409+
basis_r(b::KetBraBasis) = b.right
410+
Base.:(==)(b1::KetBraBasis, b2::KetBraBasis) = (b1.left == b2.left && b1.right == b2.right)
411+
Base.length(b::KetBraBasis) = length(b.left)*length(b.right)
412+
413+
struct ChoiBasis{BL<:Basis, BR<:Basis} <: Basis
414+
ref::BL
415+
out::BR
416+
end
417+
basis_l(b::ChoiBasis) = b.ref
418+
basis_r(b::ChoiBasis) = b.out
419+
Base.:(==)(b1::ChoiBasis, b2::ChoiBasis) = (b1.ref == b2.ref && b1.out == b2.out)
420+
Base.length(b::ChoiBasis) = length(b.ref)*length(b.out)
421+
422+
"""
423+
PauliBasis(N)
424+
425+
The standard Pauli operator basis for an `N` qubit space. This consists of
426+
tensor products of the Pauli matrices I, X, Y, Z, in that order for each qubit.
427+
The dimension of the basis is 2²ᴺ.
428+
"""
429+
struct PauliBasis{T<:Integer} <: Basis
430+
N::T
431+
end
432+
Base.:(==)(b1::PauliBasis, b2::PauliBasis) = b1.N == b2.N
433+
Base.length(b::PauliBasis) = 4^b.N
434+
435+
"""
436+
HWPauliBasis(N)
437+
438+
The Hesienberg-Weyl Pauli operator basis consisting of the
439+
N represents the underlying Hilbert
440+
space dimension, not the operator basis dimension. For N>2, this representes the
441+
operator basis formed by the generalized Pauli matrices, also called the clock
442+
and shift matrices. The ordering is the usual one: when the index is written in
443+
base-N and thus has only two digits, the least significant bit gives powers of Z
444+
(the clock matrix), and most significant bit gives powers of X (the shfit matrix).
445+
"""
446+
struct HWPauliBasis{T<:Integer} <: Basis
447+
shape::Vector{T}
448+
end
449+
HWPauliBasis(N::Integer) = HWPauliBasis([N])
450+
Base.:(==)(b1::HWPauliBasis, b2::HWPauliBasis) = b1.shape == b2.shape
451+
Base.length(b::HWPauliBasis) = prod(b.shape)
452+
Base.getindex(b::HWPauliBasis, i) = HWPauliBasis([b.shape[i]])
453+
454+
380455
##
381456
# show methods
382457
##
@@ -429,54 +504,14 @@ function show(stream::IO, x::SumBasis)
429504
write(stream, "]")
430505
end
431506

432-
##
433-
# Operator Bases
434-
##
435-
436-
"""
437-
KetBraBasis(BL,BR)
438-
439-
The "Ket-Bra" operator basis is the standard representation for the left and
440-
right bases of superoperators. This basis is formed by "vec'ing" the
441-
outer-product "Ket-Bra" basis for an operator with a left Bra basis and right
442-
Ket basis which practically means flipping the Bra to a Ket. The operator itself
443-
is then represented as a "Super-Bra" in this basis and corresponds to
444-
column-stacking its matrix.
445-
"""
446-
struct KetBraBasis{BL<:Basis, BR<:Basis} <: Basis
447-
left::BL
448-
right::BR
507+
function show(stream::IO, x::KetBraBasis)
508+
write(stream, "KetBra(left=$(x.left), right=$(x.right))")
449509
end
450-
KetBraBasis(b::Basis) = KetBraBasis(b,b)
451-
basis_l(b::KetBraBasis) = b.left
452-
basis_r(b::KetBraBasis) = b.right
453-
Base.:(==)(b1::KetBraBasis, b2::KetBraBasis) = (b1.left == b2.left && b1.right == b2.right)
454-
Base.length(b::KetBraBasis) = length(b.left)*length(b.right)
455510

456-
struct ChoiBasis{BL<:Basis, BR<:Basis} <: Basis
457-
ref::BL
458-
out::BR
511+
function show(stream::IO, x::PauliBasis)
512+
write(stream, "Pauli(N=$(x.N)")
459513
end
460-
basis_l(b::ChoiBasis) = b.ref
461-
basis_r(b::ChoiBasis) = b.out
462-
Base.:(==)(b1::ChoiBasis, b2::ChoiBasis) = (b1.ref == b2.ref && b1.out == b2.out)
463-
Base.length(b::ChoiBasis) = length(b.ref)*length(b.out)
464514

465-
"""
466-
_PauliBasis()
467-
_PauliBasis(N)
468-
469-
By default N=2 and this represents the Pauli operator basis consisting of the
470-
Pauli matrices I, Z, X, Y, in that order. N represents the underlying Hilbert
471-
space dimension, not the operator basis dimension. For N>2, this representes the
472-
operator basis formed by the generalized Pauli matrices, also called the clock
473-
and shift matrices. The ordering is the usual one: when the index is written in
474-
base-N and thus has only two digits, the least significant bit gives powers of Z
475-
(the clock matrix), and most significant bit gives powers of X (the shfit matrix).
476-
"""
477-
struct _PauliBasis(T<:Integer) <: Basis
478-
dim::T
515+
function show(stream::IO, x::HWPauliBasis)
516+
write(stream, "Pauli($(x.shape)")
479517
end
480-
_PauliBasis() = _PauliBasis(2)
481-
Base.:(==)(pb1::_PauliBasis, pb2::_PauliBasis) = true
482-
Base.length(b::_PauliBasis) = b.dim^2

src/deprecated.jl

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,6 @@ function equal_bases(a, b)
1111
return true
1212
end
1313

14-
struct PauliBasis{S,B} <: Basis
15-
shape::S
16-
bases::B
17-
function PauliBasis(num_qubits::T) where {T<:Integer}
18-
Base.depwarn("`PauliBasis` is currently not the Pauli operator basis and its behavior will be changed in future versions.", :PauliBasis)
19-
shape = [2 for _ in 1:num_qubits]
20-
bases = Tuple(SpinBasis(1//2) for _ in 1:num_qubits)
21-
return new{typeof(shape),typeof(bases)}(shape, bases)
22-
end
23-
end
24-
25-
Base.:(==)(pb1::PauliBasis, pb2::PauliBasis) = length(pb1.bases) == length(pb2.bases)
26-
Base.length(b::PauliBasis) = prod(b.shape)
27-
2814
# TODO: figure out how to deprecate abstract type
2915
abstract type AbstractSuperOperator end
3016

0 commit comments

Comments
 (0)