Decompose to Xmon gates and simulate xmon devices

Cirqprojectq decomposes arbitrary circuits to xmon gates such that proejctq can be used to simulate xmon devices.

Important modules are

cirqprojectq.xmon_gates This module provides Xmon gates for projectq.
cirqprojectq.xmon_decompositions Provides decompositon rules to decompose common gates into Xmon gates.
cirqprojectq.xmon_setup Provides proejctq engines for simulation of xmon devices.

In this example we show how to use projectq to decompose a circuit into Xmon native gates.

import cirqprojectq
from cirqprojectq.xmon_decompositions import all_defined_decomposition_rules as xmondec

def is_supported(eng, cmd):
    if isinstance(cmd.gate, projectq.ops.ClassicalInstructionGate):
        # This is required to allow Measure, Allocate, Deallocate, Flush
        return True
    elif isinstance(cmd.gate, cirqprojectq.xmon_gates.XmonGate):
        return True
    else:
        return False

supported_gate_set_filter = InstructionFilter(is_supported)
ruleset = projectq.cengines.DecompositionRuleSet(xmondec)
replacer = projectq.cengines.AutoReplacer(ruleset)
engine_list = [replacer, supported_gate_set_filter]

eng = projectq.MainEngine(backend=projectq.backends.CommandPrinter(), engine_list=engine_list)
qureg = eng.allocate_qureg(2)
projectq.ops.H | qureg[0]
projectq.ops.H | qureg[1]
projectq.ops.C(projectq.ops.X) | (qureg[0], qureg[1])
eng.flush()
W(0.5, 0.5) | Qureg[0]
ExpZ(1.0) | Qureg[0]
W(0.5, 0.5) | Qureg[1]
ExpZ(1.0) | Qureg[1]
W(0.5, 0.5) | Qureg[1]
ExpZ(1.0) | Qureg[1]
Exp11(1.0) | ( Qureg[0], Qureg[1] )
W(0.5, 0.5) | Qureg[1]
ExpZ(1.0) | Qureg[1]

Decomposition rules

Provides decompositon rules to decompose common gates into Xmon gates.

The module cirqprojectq.xmon_decompositions provides decomposition rules for rotation gates (Rx, Ry, Rz), Pauli gates (X, Y, Z), the Hadamard gate and for CNOT gates into native Xmon gates. All defined rules can be imported as cirqprojectq.xmon_decompositions.all_defined_decomposition_rules().

Note

The decompositions into xmon gates are correct up to global phases. If the module constant CORRECT_PHASES is set to True, ProjectQ global phase gates are applied to the affected qubits in order to keep track of the correct phase of thq qubit register. With projectq.setups.decompositions.ph2r these global phase gates can be translated to 1-qubit phase gates (R-gate) on control qubits if applicable. See example below

────  C ──────       ────  C ──── R(a) ──
      |         -->       |
  ---------            ---------
──|       | ──       ──|       | ────────
──| Ph(a) | ──       ──|       | ────────
──|       | ──       ──|       | ────────
  ---------            ---------

A full engine list can be generated with cirqproejctq.xmon_setup.xmon_engines()

cirqprojectq.xmon_decompositions._check_phase(angle)[source]
cirqprojectq.xmon_decompositions._decompose_CNOT(cmd)[source]

Decompose a CNOT gate into two Hadamards and an Exp11Gate.

Uses the following decomposition

── C ──         ───────    @     ───────
   |     -->               |
── X ──         ── H ── Exp11(1) ── H ──

This corresponds to the following map:

\[\mathrm{CNOT} \to \mathrm{CNOT}\]
Warning:
The Hadamard gates are correct Hamard gates! They have no wrong phases. However, in a second decomposition step these gates will each yield a phase of \(\exp(-i\pi/4)\) if CORRECT_PHASES is False! In this case, the final map will be \(\mathrm{CNOT}\to\exp(-i\pi/4)\mathrm{CNOT}\)
cirqprojectq.xmon_decompositions._decompose_H(cmd)[source]

Decompose a Hadamard gate into xmon gates.

If CORRECT_PHASES() is False the following decompositions will be used:

── H ──  -->  ── ExpW(1/2, 1/2) ── ExpZ(1) ──

This corresponds to the following map:

\[H \to e^{-i\pi/4}H\]

If CORRECT_PHASES() is True, the phases are countered by a projectq phase gate ops.Ph.

cirqprojectq.xmon_decompositions._decompose_SWAP(cmd)[source]

TODO

cirqprojectq.xmon_decompositions._decompose_paulis(cmd)[source]

Decompose a Pauli gate into xmon gates.

If CORRECT_PHASES() is False the following decompositions will be used:

Z  -->  ── ExpZ(1.0) ──

This corresponds to the following map:

\[Z \to \mathrm{ExpZ}(1) = e^{-i\pi/2}Z\]
── X ──  -->  ── ExpWGate(1, 0) ──

This corresponds to the following map:

\[X \to \mathrm{ExpW}(1, 0) = X\]
── Y ──  -->  ── ExpWGate(1, 1/2) ──

This corresponds to the following map:

\[Y \to \mathrm{ExpW}(1, 1/2) = Y\]

If CORRECT_PHASES() is True, the phases are countered by a projectq phase gate ops.Ph.

cirqprojectq.xmon_decompositions._decompose_rotations(cmd)[source]

Decompose a rotation gate into xmon gates.

We define a rotation gate as

\[R_i(\alpha) = \exp(-i \frac{\alpha}{2}\sigma_i)\]

If CORRECT_PHASES() is False the following decompositions will be used:

── Rz(a) ──  -->  ── ExpZ(a / pi) ──

This corresponds to the following map:

\[\begin{split}R_z(\alpha) \to \mathrm{ExpZ}(\alpha/\pi) = \begin{cases} -R_z(\alpha),&\pi<\alpha\leq3\pi\\ R_z(\alpha),&\text{else} \end{cases}\end{split}\]
── Rx(a) ──  -->  ── ExpWGate(a/pi, 1) ──

This corresponds to the following map:

\[R_x(\alpha) \to \mathrm{ExpW}(\alpha/\pi, 0) = e^{i\alpha/2}R_x(\alpha)\]
── Ry(a) ──  -->  ── ExpWGate(a/pi, 1/2) ──

This corresponds to the following map:

\[R_y(\alpha) \to \mathrm{ExpW}(\alpha/\pi, 1/2) = e^{i\alpha/2}R_y(\alpha)\]

If CORRECT_PHASES() is True, the phases are countered by a projectq phase gate ops.Ph such that the obtained pahse is correct.

cirqprojectq.xmon_decompositions._recognize_CNOT(cmd)[source]
cirqprojectq.xmon_decompositions._recognize_H(cmd)[source]
cirqprojectq.xmon_decompositions._recognize_SWAP(cmd)[source]
cirqprojectq.xmon_decompositions._recognize_paulis(cmd)[source]
cirqprojectq.xmon_decompositions._recognize_rotations(cmd)[source]

Xmon gates

This module provides Xmon gates for projectq.

Xmon qubits are a specific type of transmon qubit developed by Google. In the cirq framework xmon specific gates are defined. This file ports these gates to projectq and allows imulation of algorithms with xmon qubits.

class cirqprojectq.xmon_gates.Exp11Gate(half_turns)[source]

Bases: cirqprojectq.xmon_gates.XmonGate

A two-qubit interaction that phases the amplitude of the 11 state.

This gate implements \(\exp(i \pi \varphi |11\rangle\langle 11|)\) where \(\varphi\) is half turns.

As a matrix it reads

\[\begin{split}\begin{pmatrix} 1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & \exp(i\varphi \pi) \end{pmatrix}\end{split}\]

Warning

There is no (-) sign in the definition of the gate.

Note

The half_turn parameter is such that a full turn is the identity matrix, in contrast to the single qubit gates, where a full turn is minus identity. The single qubit half-turn gates are defined so that a full turn corresponds to a rotation on the Bloch sphere of a 360 degree rotation. For two qubit gates, there isn’t a Bloch sphere, so the half_turn corresponds to half of a full rotation in U(4).

Parameters:half_turns (float) – angle of rotation in units of \(\pi\).
angle

Rotation angle in rad, \(\in(-\pi, \pi]\)

half_turns

Rotation angle in half turns, \(\in(-1, 1]\)

matrix

Gate matrix.

With \(\varphi=\mathrm{half\_turns}\) the matrix implemented by the Exp11Gate reads as

\[\begin{split}\begin{pmatrix} 1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & \exp(i\varphi \pi) \end{pmatrix}\end{split}\]
tex_str()[source]

Returns the class name and the angle as a subscript, i.e.

[CLASSNAME]$_[ANGLE]$
class cirqprojectq.xmon_gates.ExpWGate(half_turns, axis_half_turns=0)[source]

Bases: cirqprojectq.xmon_gates.XmonGate

A rotation around an axis in the XY plane of the Bloch sphere.

This gate is a “phased X rotation”. Specifically

───W(axis)^t─── = ───Z^-axis───X^t───Z^axis───

This gate is

\[\exp(-i * \pi * W(\mathrm{axis\_half\_turn}) * \mathrm{half\_turn} / 2)\]

where

\[W(\theta) = \cos(\pi \theta) X + \sin(\pi \theta) Y\]

Note the half_turn nomenclature here comes from viewing this as a rotation on the Bloch sphere. Two half_turns correspond to a rotation in the bloch sphere of 360 degrees. Note that this is minus identity, not just identity. Similarly the axis_half_turns refers thinking of rotating the Bloch operator, starting with the operator pointing along the X direction. An axis_half_turn of 1 corresponds to the operator pointing along the -X direction while an axis_half_turn of 0.5 correspond to an operator pointing along the Y direction.’

Contrary to the docstring, cirq implements the gate (\(\varphi = \mathrm{half\_turns}\) and \(\theta=\mathrm{axis\_half\_turns}\)):

\[\exp(i \pi \varphi / 2) \exp(-i \pi W(\theta) \varphi / 2)\]

which differs by a global phase \(\exp(i \varphi/2)\).

This class mimics the cir implementation, i.e., the matrix represented by this gate reads as

\[\begin{split}\exp(i \varphi \pi / 2)\begin{pmatrix} \cos(\varphi\pi / 2) & -i \sin(\varphi \pi / 2) exp(-i \theta \pi)\\ -i \sin(\varphi \pi / 2) \exp(i \theta \pi) & \cos(\varphi \pi / 2) \end{pmatrix}\end{split}\]

whih is a rotation around the W-axis and an additional global phase.

Note

This gate corresponds to a phase gate in the basis defined by the W-axis, not to a rotation gate.

Note

Restricting half_turns to the rage (-1, 1] corresponds to the full range (0, 2pi] for a phase gate, which the ExpW gate in the cirq implementation actually is.

Note

Another convention is to change a positive rotation around a negative axis to a negative rotation around a postive axis, i.e., half_turns -> - half_turns and axis_half_turns -> axis_half_turns + 1 if axis_half_turns < 0.

Parameters:
  • half_turns (float) – angle of rotation in units of \(\pi\).
  • axis_half_turns (float) – axis between X and Y in units of \(\pi\).
angle

Rotation angle in rad, \(\in(-\pi, \pi]\)

axis_angle

Axis angle in rad, \(\in(-\pi, \pi]\)

axis_half_turns

Axis angle in half turns, \(\in(-1, 1]\)

half_turns

Rotation angle in half turns, \(\in(-1, 1]\)

matrix

Rotation matrix.

With \(\varphi = \mathrm{half\_turns}\) and \(\theta=\mathrm{axis\_half\_turns}\) this gate implements the matrix

\[\begin{split}\exp(i \varphi \pi / 2)\begin{pmatrix} \cos(\varphi\pi / 2) & -i \sin(\varphi \pi / 2) exp(-i \theta \pi)\\ -i \sin(\varphi \pi / 2) \exp(i \theta \pi) & \cos(\varphi \pi / 2) \end{pmatrix}\end{split}\]
tex_str()[source]
class cirqprojectq.xmon_gates.ExpZGate(half_turns)[source]

Bases: cirqprojectq.xmon_gates.XmonGate

A rotation around the Z axis of the Bloch sphere.

This gate implements \(\exp(-i \pi Z \varphi / 2)\) where Z is the Z matrix

Z = [[1, 0], [0, -1]]

and \(\varphi\) are half turns.

The full matrix reads:

\[\begin{split}\begin{pmatrix} exp(-i \pi \varphi / 2) & 0\\ 0 & exp(i \pi \varphi / 2) \end{pmatrix}\end{split}\]

Note the half_turn nomenclature here comes from viewing this as a rotation on the Bloch sphere. Two half_turns correspond to a rotation in the bloch sphere of 360 degrees.

Half_turns are mapped to the range (-1, 1], i.e. to rotation angles in the range (-pi, pi].

Note

Restricting half_turns to the rage (-1, 1] corresponds to the full range (0, 2pi] for the phase difference between the Z eigenstates. However, we loose the global phase that comes with a full rotation gate in the range (0, 4pi]. Thus, the ExpZ gate is more like a phase then a rotation gate.

Parameters:half_turns (float) – number of half turns on the Bloch sphere.
angle

Rotation angle in rad, \(\in(-\pi, \pi]\)

get_merged(other)[source]

Return self merged with another gate. Default implementation handles rotation gate of the same type, where angles are simply added. :param other: Rotation gate of same type.

Raises:NotMergeable – For non-rotation gates or rotation gates of different type.
Returns:New object representing the merged gates.
half_turns

Rotation angle in half turns, \(\in(-1, 1]\)

matrix

Rotation matrix.

With \(\varphi = \mathrm{half\_turns}\) this gate implements the matrix

\[\begin{split}\begin{pmatrix} \cos(\varphi\pi / 2) - i \sin(\varphi \pi / 2) & 0\\ 0 & \cos(\varphi\pi / 2) + i \sin(\varphi \pi / 2) \end{pmatrix}\end{split}\]
tex_str()[source]

Latex representation of the gate.

class cirqprojectq.xmon_gates.XmonGate[source]

Bases: projectq.ops._basics.BasicGate

cirqprojectq.xmon_gates.drawer_settings()[source]

Xmon setup

Provides proejctq engines for simulation of xmon devices.

A full engine list can be generated with cirqproejctq.xmon_setup.xmon_engines()

cirqprojectq.xmon_setup.replacer_xmon()[source]

Autoreplacer for decomposition into xmon gates.

cirqprojectq.xmon_setup.xmon_engines()[source]

Full engine list for simulation with xmon gates.

cirqprojectq.xmon_setup.xmon_rules()[source]

DecompositionRuleSet for decomposition into xmon gates.

cirqprojectq.xmon_setup.xmon_supported_filter()[source]

InstructionFilter for xmon gates.