Skip to content

Invert

The invert statement applies the adjoint (conjugate transpose) of the unitary operation specified as a nested statement block. If the nested block specifies the unitary operation \(U\), invert applies \(U^{\dagger}\).

Syntax

invert { statements }

def invert(stmt_block: QCallable) -> None:
    pass

Semantics

  • The invert statement applies the adjoint of the operations specified in the nested block, equivalent to the adjoint of each nested statement in reverse order.
  • Quantum variables declared outside the invert statement and used inside its nested block must be initialized prior to it and remain initialized subsequently.

Example

The following example demonstrates the use of invert applied to a single gate-level function call, and to a statement block in which a user-defined function foo is called twice.

qfunc foo(target: qbit) {
  H(target);
  X(target);
}

qfunc main() {
  qba: qbit[];
  allocate(2, qba);
  invert {
    RX(pi / 2, qba[0]);
  }
  invert {
    foo(qba[0]);
    foo(qba[1]);
  }
}
from sympy import pi
from classiq import QBit, QArray, allocate, invert, qfunc, X, RX, H


@qfunc
def foo(target: QBit) -> None:
    H(target)
    X(target)


@qfunc
def main() -> None:
    qba = QArray("qba")
    allocate(2, qba)
    invert(lambda: RX(pi / 2, qba[0]))
    invert(lambda: [foo(qba[0]), foo(qba[1])])

Synthesizing this model creates the quantum program shown below. The inversion of RX is simply negating the rotation angle. In the second invert statement each call to foo is inverted, applying the gate-level functions in reverse but unchanged (as they are hermitian).

invert.png