Embedded Operators
In this manual, we will discuss embedding operators in subspaces of larger quantum systems.
The embed
and unembed
functions
A frequent situation in quantum optimal control is the need to embed a quantum operator in a larger Hilbert space. This is often necessary when the control Hamiltonian acts on a subspace of the full Hilbert space.
The embed
function allows to embed a quantum operator in a larger Hilbert space.
QuantumCollocation.EmbeddedOperators.embed
— Functionembed(matrix::Matrix{ComplexF64}, subspace_indices::AbstractVector{Int}, levels::Int)
Embed an operator $U$ in the subspace of a larger system $\mathcal{X} = \mathcal{X}_{\text{subspace}} \oplus \mathcal{X}_{\text{leakage}}$ which is composed of matrices of size $\text{levels} \times \text{levels}$.
Arguments
matrix::Matrix{ComplexF64}
: Operator to embed.subspace_indices::AbstractVector{Int}
: Indices of the subspace to embed the operator in.levels::Int
: Total number of levels in the system.
The unembed
function allows to unembed a quantum operator from a larger Hilbert space.
QuantumCollocation.EmbeddedOperators.unembed
— Functionunembed(matrix::AbstractMatrix, subspace_indices::AbstractVector{Int})
Unembed an operator $U$ from a subspace of a larger system $\mathcal{X} = \mathcal{X}_{\text{subspace}} \oplus \mathcal{X}_{\text{leakage}}$ which is composed of matrices of size $\text{levels} \times \text{levels}$.
This is equivalent to calling matrix[subspace_indices, subspace_indices]
.
Arguments
matrix::AbstractMatrix
: Operator to unembed.subspace_indices::AbstractVector{Int}
: Indices of the subspace to unembed the operator from.
For example, for a single qubit X gate embedded in a multilevel system:
using QuantumCollocation
using SparseArrays # for visualization
# define levels of full system
levels = 3
# get a 2-level X gate
X = GATES[:X]
# define subspace indices as lowest two levels
subspace_indices = 1:2
# embed the X gate in the full system
X_embedded = embed(X, subspace_indices, levels)
3×3 Matrix{ComplexF64}:
0.0+0.0im 1.0+0.0im 0.0+0.0im
1.0+0.0im 0.0+0.0im 0.0+0.0im
0.0+0.0im 0.0+0.0im 0.0+0.0im
We can retrieve the original operator:
X_unembedded = unembed(X_embedded, subspace_indices)
2×2 Matrix{ComplexF64}:
0.0+0.0im 1.0+0.0im
1.0+0.0im 0.0+0.0im
The EmbeddedOperator
type
The EmbeddedOperator
type is a convenient way to define an operator embedded in a subspace of a larger quantum system.
The EmbeddedOperator
type is defined as follows:
QuantumCollocation.EmbeddedOperators.EmbeddedOperator
— TypeEmbeddedOperator
Embedded operator type to represent an operator embedded in a subspace of a larger quantum system.
Fields
operator::Matrix{ComplexF64}
: Embedded operator of sizeprod(subsystem_levels) x prod(subsystem_levels)
.subspace_indices::Vector{Int}
: Indices of the subspace the operator is embedded in.subsystem_levels::Vector{Int}
: Levels of the subsystems in the composite system.
And can be constructed using the following method:
QuantumCollocation.EmbeddedOperators.EmbeddedOperator
— MethodEmbeddedOperator(op::Matrix{<:Number}, subspace_indices::AbstractVector{Int}, subsystem_levels::AbstractVector{Int})
Create an embedded operator. The operator op
is embedded in the subspace defined by subspace_indices
in subsystem_levels
.
Arguments
op::Matrix{<:Number}
: Operator to embed.subspace_indices::AbstractVector{Int}
: Indices of the subspace to embed the operator in. e.g.get_subspace_indices([1:2, 1:2], [3, 3])
.subsystem_levels::AbstractVector{Int}
: Levels of the subsystems in the composite system. e.g.[3, 3]
for two 3-level systems.
For example, for an X gate on the first qubit of two qubit, 3-level system:
# define the target operator X ⊗ I
gate = GATES[:X] ⊗ GATES[:I]
# define the subsystem levels
subsystem_levels = [3, 3]
# define the subspace indices
subspace_indices = get_subspace_indices([1:2, 1:2], subsystem_levels)
# create the embedded operator
op = EmbeddedOperator(gate, subspace_indices, subsystem_levels)
# show the full operator
op.operator .|> abs |> sparse
9×9 SparseArrays.SparseMatrixCSC{Float64, Int64} with 4 stored entries:
⋅ ⋅ ⋅ 1.0 ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ 1.0 ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
1.0 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ 1.0 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
We can get the original operator back:
gate_unembeded = unembed(op)
gate_unembeded .|> abs |> sparse
4×4 SparseArrays.SparseMatrixCSC{Float64, Int64} with 4 stored entries:
⋅ ⋅ 1.0 ⋅
⋅ ⋅ ⋅ 1.0
1.0 ⋅ ⋅ ⋅
⋅ 1.0 ⋅ ⋅
The get_subspace_indices
function
The get_subspace_indices
function is a convenient way to get the indices of a subspace in a larger quantum system.
Simple quantum systems
For simple (non-composite) quantum systems, such as a single multilevel qubit, we provode the following method:
QuantumCollocation.EmbeddedOperators.get_subspace_indices
— Methodget_subspace_indices(subspace::AbstractVector{Int}, levels::Int)
Get the indices for the subspace of simple, non-composite, quantum system. For example:
get_subspace_indices([1, 2], 3) == [1, 2]
Arguments
subspace::AbstractVector{Int}
: Subspace to get indices for. e.g.[1, 2]
.levels::Int
: Levels of the subsystem. e.g.3
.
# get the indices of the lowest two levels of a 3-level system
subspace_indices = get_subspace_indices(1:2, 3)
2-element Vector{Int64}:
1
2
Comosite quantum systems
For composite quantum systems, such as a two qubit system, we provide the following methods.
Targeting subspaces in a composite quantum system, with general subsystem levels:
QuantumCollocation.EmbeddedOperators.get_subspace_indices
— Methodget_subspace_indices(subspaces::Vector{<:AbstractVector{Int}}, subsystem_levels::AbstractVector{Int})
Get the indices for the subspace of composite quantum system.
Example: for the two-qubit subspace of two 3-level systems:
subspaces = [1:2, 1:2]
subsystem_levels = [3, 3]
get_subspace_indices(subspaces, subsystem_levels) == [1, 2, 4, 5]
Arguments
subspaces::Vector{<:AbstractVector{Int}}
: Subspaces to get indices for. e.g.[1:2, 1:2]
.subsystem_levels::AbstractVector{Int}
: Levels of the subsystems in the composite system. e.g.[3, 3]
. Each element corresponds to a subsystem.
# get the subspace indices for a three level qubit coupled to a 9-level cavity
get_subspace_indices([1:2, 1:2], [3, 9])
4-element Vector{Int64}:
1
2
10
11
Targeting subspaces in a composite quantum system, with all subsystems having the same number of levels:
QuantumCollocation.EmbeddedOperators.get_subspace_indices
— Methodget_subspace_indices(levels::AbstractVector{Int}; subspace=1:2, kwargs...)
Get the indices for the subspace of composite quantum system. This is a convenience function that allows to specify the subspace as a range that is constant for every subsystem, which defaults to 1:2
, that is qubit systems.
Arguments
levels::AbstractVector{Int}
: Levels of the subsystems in the composite system. e.g.[3, 3]
.
Keyword Arguments
subspace::AbstractVector{Int}
: Subspace to get indices for. e.g.1:2
.
# get the subspace indices for a two qubit system with 3 levels each
get_subspace_indices([3, 3])
4-element Vector{Int64}:
1
2
4
5
This page was generated using Literate.jl.