Skip to content

apply_right! and apply_inv_right! #555

@sagnikpal2004

Description

@sagnikpal2004

QuantumClifford.jl has the apply! function that allows one to apply a quantum operator to a stabilizer state, including other operators. The functionality to apply an operator to another is crucial for a circuit simulator.

The typical way to apply a quantum operation to a quantum state is to multiply the operator to the left.
$\left| \psi \right>$ apply sHadmard(1) $\rightarrow$ $H\left| \psi \right>$
$\rho$ apply sHadmard(1) $\rightarrow$ $H \rho H^\dagger$

We are focused only on multiplying two operators for now:
$T$ apply $C$ $\rightarrow$ $CTC^\dagger$
The result is stored in T (This operation shall be denoted by T $\leftarrow$ C * T)

However, there is no way to easy and fast way to apply an operator to the right of another operator and stored in the former. This operation is:
$T$ apply_right $C$ $\rightarrow$ $TC$
The result is stored in T (This operation shall be denoted by T $\leftarrow$ T * C

Why this is required

This functionality is useful for #551 - Circuit simulation using backtracking, which requires building the inverse of a circuit.

Given a circuit: $C_1$ apply $C_2$ apply $C_3$ $\rightarrow$ $C_3 * C_2 * C_1$
The inverse of this is $C_1^{-1} * C_2^{-1} * C_1^{-1}$

This inverse cannot be built by simply using the original apply! function to the inverses:
$C_1^{-1}$ apply $C_2^{-1}$ apply $C_3^{-1}$ $\rightarrow$ $C_3^{-1} * C_2^{-1} * C_1^{-1}$
This does not give the correct inverse

Therefore, we actually need to run apply_right! to the inverses to build the correct circuit inverse
$C_1^{-1}$ apply_inv $C_2^{-1}$ apply_inv $C_3^{-1}$ $\rightarrow$ $C_1^{-1} * C_2^{-1} * C_1^{-1}$
This gives the correct circuit inverse

Current alternative

function apply_right!(l::CliffordOperator, r::AbstractCliffordOperator; phases=false)
    apply!(CliffordOperator(r, nqubits(l)), l; phases=phases)
end
T = apply_right!(T, C)

However, this method is especially slow (can be sped up using kernels that apply operations directly instead of converting to a dense clifford first. Also, C is destroyed in the process.

Second alternative
For circuit: $C_1, C_2, C_3, sMZ, C_4$

circuit = one(CliffordOperator, n)
apply!(circuit, C_1)
apply!(circuit, C_2)
apply!(circuit, C_3)
circuit_inv = inv(circuit)
measure!(circuit_inv, sMZ)
circuit = inv(circuit)
apply!(circuit, C_4)

How to build this
The Stim library has functions that are able to multiply right many symbolic operators fast.
I have been building this functionality into QuantumClifford.jl, and plan to submit a draft PR soon.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions