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.embedFunction
embed(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.
source

The unembed function allows to unembed a quantum operator from a larger Hilbert space.

QuantumCollocation.EmbeddedOperators.unembedFunction
unembed(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.
source

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.EmbeddedOperatorType
EmbeddedOperator

Embedded operator type to represent an operator embedded in a subspace of a larger quantum system.

Fields

  • operator::Matrix{ComplexF64}: Embedded operator of size prod(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.
source

And can be constructed using the following method:

QuantumCollocation.EmbeddedOperators.EmbeddedOperatorMethod
EmbeddedOperator(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.
source

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_indicesMethod
get_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.
source
# 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_indicesMethod
get_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.
source
# 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_indicesMethod
get_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.
source
# 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.