Registers

Registers

Quantum circuits process quantum states. A quantum state being processing by a quantum circuit will be stored on a quantum register. In Yao we provide several types for registers. The default type for registers is the Yao.Registers.DefaultRegister.

You can directly use factory method register

Storage

LDT format

Concepturely, a wave function $|\psi\rangle$ can be represented in a low dimentional tensor (LDT) format of order-3, L(f, r, b).

For simplicity, let's ignore batch dimension for the momentum, we have

\[|\psi\rangle = \sum\limits_{x,y} L(x, y, .) |j\rangle|i\rangle\]

Given a configuration x (in operational space), we want get the i-th bit using (x<<i) & 0x1, which means putting the small end the qubit with smaller index. In this representation L(x) will get return $\langle x|\psi\rangle$.

Note

Why not the other convension: Using the convention of putting 1st bit on the big end will need to know the total number of qubits n in order to know such positional information.

HDT format

Julia storage is column major, if we reshape the wave function to a shape of $2\times2\times ... \times2$ and get the HDT (high dimensional tensor) format representation H, we can use H($x_1, x_2, ..., x_3$) to get $\langle x|\psi\rangle$.

Operations

Kronecker product of operators

In order to put small bits on little end, the Kronecker product is $O = o_n \otimes \ldots \otimes o_2 \otimes o_1$ where the subscripts are qubit indices.

Measurements

Measure means sample and projection.

Sample

Suppose we want to measure operational subspace, we can first get

\[p(x) = \|\langle x|\psi\rangle\|^2 = \sum\limits_{y} \|L(x, y, .)\|^2.\]

Then we sample an $a\sim p(x)$. If we just sample and don't really measure (change wave function), its over.

Projection
\[|\psi\rangle' = \sum_y L(a, y, .)/\sqrt{p(a)} |a\rangle |y\rangle\]

Good! then we can just remove the operational qubit space since x and y spaces are totally decoupled and x is known as in state a, then we get

\[|\psi\rangle'_r = \sum_y l(0, y, .) |y\rangle\]

where l = L(a:a, :, :)/sqrt(p(a)).

Registers

AbstractRegister{B, T}

abstract type that registers will subtype from. B is the batch size, T is the data type.

Required Properties

PropertyDescriptiondefault
nqubits(reg)get the total number of qubits.
nactive(reg)get the number of active qubits.
nremain(reg)get the number of remained qubits.nqubits - nactive
nbatch(reg)get the number of batch.B
state(reg)get the state of this register. It always return the matrix stored inside.
statevec(reg)get the raveled state of this register. .
hypercubic(reg)get the hypercubic form of this register. .
eltype(reg)get the element type stored by this register on classical memory. (the type Julia should use to represent amplitude)T
copy(reg)copy this register.
similar(reg)construct a new register with similar configuration.

Required Methods

Multiply

*(op, reg)

define how operator op act on this register. This is quite useful when there is a special approach to apply an operator on this register. (e.g a register with no batch, or a register with a MPS state, etc.)

Note

be careful, generally, operators can only be applied to a register, thus we should only overload this operation and do not overload *(reg, op).

Pack Address

pack addrs together to the first k-dimensions.

Example

Given a register with dimension [2, 3, 1, 5, 4], we pack [5, 4] to the first 2 dimensions. We will get [5, 4, 2, 3, 1].

Focus Address

focus!(reg, range)

merge address in range together as one dimension (the active space).

Example

Given a register with dimension (2^4)x3 and address [1, 2, 3, 4], we focus address [3, 4], will pack [3, 4] together and merge them as the active space. Then we will have a register with size 2^2x(2^2x3), and address [3, 4, 1, 2].

Initializers

Initializers are functions that provide specific quantum states, e.g zero states, random states, GHZ states and etc.

register(::Type{RT}, raw, nbatch)

an general initializer for input raw state array.

register(::Val{InitMethod}, ::Type{RT}, ::Type{T}, n, nbatch)

init register type RT with InitMethod type (e.g Val{:zero}) with element type T and total number qubits n with nbatch. This will be auto-binded to some shortcuts like zero_state, rand_state, randn_state.

source
DefaultRegister{B, T} <: AbstractRegister{B, T}

Default type for a quantum register. It contains a dense array that represents a batched quantum state with batch size B of type T.

source
@bit_str -> QuBitStr

Construct a bit string. such as bit"0000". The bit strings also supports string concat. Just use it like normal strings.

source
hypercubic(r::AbstractRegister) -> AbstractArray

Return the hypercubic form (high dimensional tensor) of this register, only active qubits are considered.

source
density_matrix(register)

Returns the density matrix of this register.

source
extend!(r::DefaultRegister, n::Int) -> DefaultRegister
extend!(n::Int) -> Function

extend the register by n bits in state |0>. i.e. |psi> -> |000> ⊗ |psi>, extended bits have higher indices. If only an integer is provided, then perform lazy evaluation.

source
fidelity(reg1::DefaultRegister, reg2::DefaultRegister) -> Vector
source
Yao.Registers.focus!Function.
focus!(reg::DefaultRegister, bits::Ints) -> DefaultRegister
focus!(locs::Int...) -> Function

Focus register on specified active bits.

source
focuspair(locs::Int...) -> NTuple{2, Function}

Return focus! and relax! function for specific lines.

source
isnormalized(reg::DefaultRegister) -> Bool

Return true if a register is normalized else false.

source
Yao.Registers.measureFunction.
measure(register, [n=1]) -> Vector

measure active qubits for n times.

source
measure_remove!(register)

measure the active qubits of this register and remove them.

source
register([type], bit_str, [nbatch=1]) -> DefaultRegister

Returns a DefaultRegister by inputing a bit string, e.g

using Yao
register(bit"0000")
source
register(raw) -> DefaultRegister

Returns a DefaultRegister from a raw dense array (Vector or Matrix).

source
Yao.Registers.relax!Function.
relax!(reg::DefaultRegister; nbit::Int=nqubits(reg)) -> DefaultRegister
relax!(reg::DefaultRegister, bits::Ints; nbit::Int=nqubits(reg)) -> DefaultRegister
relax!(bits::Ints...; nbit::Int=-1) -> Function

Inverse transformation of focus, with nbit is the number of active bits of target register.

source
stack(regs::DefaultRegister...) -> DefaultRegister

stack multiple registers into a batch.

source
statevec(r::AbstractRegister) -> AbstractArray

Return the raveled state (vector) form of this register.

source
tracedist(reg1::DefaultRegister, reg2::DefaultRegister) -> Vector
tracedist(reg1::DensityMatrix, reg2::DensityMatrix) -> Vector

trace distance.

source
Yao.Registers.ρFunction.
ρ(register)

Returns the density matrix of this register.

source
QuBitStr

String literal for qubits.

source
normalize!(r::AbstractRegister) -> AbstractRegister

Return the register with normalized state.

source
Base.kronMethod.
kron(lhs, rhs)

Merge two registers together with kronecker tensor product.

source

Get the compact shape and order for permutedims.

source