Abstract Registers

Abstract 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 ArrayReg which is defined in YaoArrayRegister.jl.

The registers can be extended by subtyping AbstractRegister and define correspinding register interfaces defined in YaoBase.jl, which includes:

Minimal Required Interfaces

The following interfaces are the minial required interfaces to make a register's printing work and be able to accept certain gates/blocks.

But if you don't want to work with our default printing, you could define your custom printing with Base.show.

YaoBase.nqubitsFunction.
nqubits(register) -> Int

Returns the (total) number of qubits. See nactive, nremain for more details.

source
YaoBase.nactiveFunction.
nactive(register) -> Int

Returns the number of active qubits.

Note

Operators always apply on active qubits.

source

you can define instruct!, to provide specialized instructions for the registers from plain storage types.

Qubit Management Interfaces

YaoBase.addbits!Function.
addbits!(register, n::Int) -> register
addbits!(n::Int) -> λ(register)

Add n qubits to given register in state |0>. i.e. |psi> -> |000> ⊗ |psi>, increased bits have higher indices.

If only an integer is provided, then returns a lambda function.

source
YaoBase.reorder!Function.
reorder!(reigster, orders)

Reorder the locations of register by input orders.

source

Qubit Scope Management Interfaces

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 now, 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$.

YaoBase.focus!Function.
focus!(register, locs) -> register

Focus the wires on specified location.

Example

julia> focus!(r, (1, 2, 4))
source
focus!(locs...) -> f(register) -> register

Lazy version of focus!, this returns a lambda which requires a register.

focus(f, register, locs...)

Call a callable f under the context of focus. See also focus!.

Example

print the focused register

julia> r = ArrayReg(bit"101100")
ArrayReg{1,Complex{Float64},Array...}
    active qubits: 6/6

julia> focus(x->(println(x);x), r, 1, 2);
ArrayReg{1,Complex{Float64},Array...}
    active qubits: 2/6
source
YaoBase.relax!Function.
relax!(register[, locs]; to_nactive=nqubits(register)) -> register

Inverse transformation of focus!, where to_nactive is the number of active bits for target register.

source
relax!(locs::Int...; to_nactive=nqubits(register)) -> f(register) -> register

Lazy version of relax!, it will be evaluated once you feed a register to its output lambda.

Measurement Interfaces

YaoBase.measureFunction.
measure(register[, operator][, locs]; nshots=1) -> Vector{Int}

Return measurement results of current active qubits (regarding to active qubits, see focus! and relax!).

YaoBase.measure!Function.
measure!([operator, ]register[, locs])

Measure current active qubits or qubits at locs and collapse to result state.

measure_remove!([operator, ]reg::AbstractRegister[, locs])

Measure current active qubits or qubits at locs and remove them.

measure_collapseto!([operator, ]reg::AbstractRegister[, locs]; config) -> Int

Measure current active qubits or qubits at locs and set the register to specific value.

YaoBase.select!Function.
select!(dest::AbstractRegister, src::AbstractRegister, bits::Integer...) -> AbstractRegister
select!(register::AbstractRegister, bits::Integer...) -> register

select a subspace of given quantum state based on input eigen state bits. See also select.

Example

select!(reg, 0b110) will select the subspace with (focused) configuration 110. After selection, the focused qubit space is 0, so you may want call relax! manually.

Tip

Developers should overload select!(r::RegisterType, bits::NTuple{N, <:Integer}) and do not assume bits has specific number of bits (e.g Int64), or it will restrict the its maximum available number of qubits.

source
select!(b::Integer) -> f(register)

Lazy version of select!. See also select.

Others

YaoBase.fidelityFunction.
fidelity(register1, register2)

Return the fidelity between two states.

Definition

The fidelity of two quantum state for qubits is defined as:

\[F(ρ, σ) = tr(\sqrt{\sqrt{ρ}σ\sqrt{ρ}})\]

Or its equivalent form (which we use in numerical calculation):

\[F(ρ, σ) = sqrt(tr(ρσ) + 2 \sqrt{det(ρ)det(σ)})\]

Reference

  • Jozsa R. Fidelity for mixed quantum states[J]. Journal of modern optics, 1994, 41(12): 2315-2323.
  • Nielsen M A, Chuang I. Quantum computation and quantum information[J]. 2002.
Note

The original definition of fidelity $F$ was from "transition probability", defined by Jozsa in 1994, it is the square of what we use here.

source
fidelity(r1::ArrayReg, r2::ArrayReg)

Calcuate the fidelity between r1 and r2, if r1 or r2 is not pure state (nactive(r) != nqubits(r)), the fidelity is calcuated by purification. See also pure_state_fidelity, purification_fidelity.

YaoBase.tracedistFunction.
tracedist(register1, register2)

Return the trace distance of register1 and register2.

Definition

Trace distance is defined as following:

\[\frac{1}{2} || A - B ||_{tr}\]

Reference

  • https://en.wikipedia.org/wiki/Trace_distance
source
density_matrix(register)

Returns the density matrix of current active qubits.

source
YaoBase.viewbatchFunction.
viewbatch(register, i::Int) -> AbstractRegister{1}

Returns a view of the i-th slice on batch dimension.

source