{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "116af785-a9b7-4eaf-8a86-b1eeb235da18",
      "metadata": {},
      "source": [
        "---\n",
        "title: Fractional gates\n",
        "description: Use fractional gates to execute single- and two-qubit rotations\n",
        "---\n",
        "\n",
        "# Fractional gates\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5d679872",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "{/*\n",
        "  DO NOT EDIT THIS CELL!!!\n",
        "  This cell's content is generated automatically by a script. Anything you add\n",
        "  here will be removed next time the notebook is run. To add new content, create\n",
        "  a new cell before or after this one.\n",
        "  */}\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"Package versions\">\n",
        "    The code on this page was developed using the following requirements.\n",
        "    We recommend using these versions or newer.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.3.1\n",
        "    qiskit-ibm-runtime~=0.45.1\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f0d7fa16",
      "metadata": {},
      "source": [
        "This page introduces two newly supported gate types on the IBM Quantum® fleet of QPUs. These *fractional* gates are supported on [Heron QPUs](/docs/guides/processor-types#heron) in the form of:\n",
        "\n",
        "* $R_{ZZ}(\\theta)$ for $0 \\lt \\theta \\leq \\pi/2$\n",
        "* $R_X(\\theta)$ for any $\\theta$\n",
        "\n",
        "This page discusses the use cases where implementing fractional gates can improve the efficiency of your workflows, as well as how to use these gates on IBM Quantum QPUs.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ee241e99-d095-4cb5-9506-da3d92c32e1c",
      "metadata": {},
      "source": [
        "## How to use fractional gates\n",
        "\n",
        "Internally, these fractional gates work by directly executing an $R_{ZZ}(\\theta)$ and $R_X(\\theta)$ rotation for an arbitrary angle. Use of the $R_X(\\theta)$ gate can reduce the duration and error for single-qubit rotations of arbitrary angle by up to a factor of two. The direct execution of the $R_{ZZ}(\\theta)$ gate rotation avoids decomposition into multiple `CZGate` objects, similarly reducing a circuit's duration and error. This is especially useful for circuits that contain many single- and two-qubit rotations, such as when simulating the dynamics of a quantum system or when using a variational ansatz with many parameters.\n",
        "\n",
        "While these types of gates are in the [library of standard gates](/docs/guides/circuit-library) which a `QuantumCircuit` can possess, they can only be used on specific IBM Quantum QPUs, and which must be loaded with the flag `use_fractional_gates` set to `True` (shown below). This flag will ensure that fractional gates are included in the backend's `Target` for the transpiler.\n",
        "\n",
        "```python\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.backend('ibm_torino', use_fractional_gates=True)\n",
        "```\n",
        "\n",
        "This code example demonstrates how to use fractional gates in the context of a workflow that simulates the dynamics of an Ising chain using fractional gates. The circuit duration is then compared against a backend that does not use fractional gates.\n",
        "\n",
        "<Admonition title=\"Note about reported error rates\" type=\"note\">\n",
        "  The error value reported in the `Target` of a backend with fractional gates enabled is just a copy of the non-fractional gate's counterpart (which may not be the same). This is because the reporting of error rates on the fractional gates is not yet supported.\n",
        "\n",
        "  However, since the gate time of fractional versus non-fractional gates are the same, it is a reasonable assumption that their error rates are comparable -- especially when the dominant source of error in a circuit is due to relaxation.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "9cb7f696-dec0-4393-9320-fe945326c893",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/9cb7f696-dec0-4393-9320-fe945326c893-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "from qiskit.circuit import Parameter\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.visualization.timeline import draw as draw_timeline, IQXSimple\n",
        "\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "\n",
        "num_qubits = 5\n",
        "num_time_steps = 3\n",
        "rx_angle = 0.1\n",
        "rzz_angle = 0.1\n",
        "\n",
        "ising_circuit = QuantumCircuit(num_qubits)\n",
        "for i in range(num_time_steps):\n",
        "    # rx layer\n",
        "    for q in range(num_qubits):\n",
        "        ising_circuit.rx(rx_angle, q)\n",
        "    for q in range(1, num_qubits - 1, 2):\n",
        "        ising_circuit.rzz(rzz_angle, q, q + 1)\n",
        "    # 2nd rzz layer\n",
        "    for q in range(0, num_qubits - 1, 2):\n",
        "        ising_circuit.rzz(rzz_angle, q, q + 1)\n",
        "    ising_circuit.barrier()\n",
        "ising_circuit.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "983bbe11-fa20-4043-a146-66af18cae054",
      "metadata": {},
      "source": [
        "Specify two backend objects: one with fractional gates enabled, and the other with them disabled, then transpile them both.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "09ef3ed0-7126-45a2-a876-35a4f540c949",
      "metadata": {},
      "outputs": [],
      "source": [
        "service = QiskitRuntimeService()\n",
        "backend_fractional = service.backend(\"ibm_torino\", use_fractional_gates=True)\n",
        "backend_conventional = service.backend(\n",
        "    \"ibm_torino\", use_fractional_gates=False\n",
        ")\n",
        "\n",
        "pm_fractional = generate_preset_pass_manager(\n",
        "    optimization_level=3, backend=backend_fractional, scheduling_method=\"alap\"\n",
        ")\n",
        "pm_conventional = generate_preset_pass_manager(\n",
        "    optimization_level=3,\n",
        "    backend=backend_conventional,\n",
        "    scheduling_method=\"alap\",\n",
        ")\n",
        "\n",
        "ising_circuit_fractional = pm_fractional.run(ising_circuit)\n",
        "ising_circuit_conventional = pm_conventional.run(ising_circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cf108858-b8ee-44a8-b252-3e7748b691f8",
      "metadata": {},
      "source": [
        "Display the timeline of the circuit using the two types of gates.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "0013f5fa-4072-4aa4-94fe-7e195435f828",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/0013f5fa-4072-4aa4-94fe-7e195435f828-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Draw timeline of circuit with conventional gates\n",
        "draw_timeline(\n",
        "    ising_circuit_conventional,\n",
        "    idle_wires=False,\n",
        "    target=backend_conventional.target,\n",
        "    time_range=(0, 500),\n",
        "    style=IQXSimple(),\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "08dd1cdf-8b34-47c2-8324-f3538c9d1ab6",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/08dd1cdf-8b34-47c2-8324-f3538c9d1ab6-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Draw timeline of circuit with fractional gates\n",
        "draw_timeline(\n",
        "    ising_circuit_fractional,\n",
        "    idle_wires=False,\n",
        "    target=backend_fractional.target,\n",
        "    time_range=(0, 500),\n",
        "    style=IQXSimple(),\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "76f9f94e-f402-4519-b991-708b74a4f88c",
      "metadata": {},
      "source": [
        "### Angle constraints\n",
        "\n",
        "For the two-qubit $R_{ZZ}(\\theta)$ gate, only angles between $0$ and $\\pi/2$ can be executed on IBM Quantum hardware. If a circuit contains any $R_{ZZ}(\\theta)$ gates with an angle outside of this range, then the standard transpilation pipeline will generally correct this with an appropriate circuit transformation (through the [`FoldRzzAngle`](../api/qiskit-ibm-runtime/transpiler-passes-fold-rzz-angle) pass).  However, for any $R_{ZZ}(\\theta)$ gate containing one or more [`Parameter`](/docs/api/qiskit/qiskit.circuit.Parameter)s, the transpiler will assume these parameters will be assigned angles within this range at runtime. The job will fail if any of the parameter values specified in the PUB submitted to IBM Quantum Compute Service are outside of this range.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "48bad5e6-3c7a-4bd0-b050-e440c3257be2",
      "metadata": {},
      "source": [
        "## Where to use fractional gates\n",
        "\n",
        "Historically, the basis gates available on IBM Quantum QPUs have been **`CZ`**, **`X`**, **`RZ`**, **`SX`**, and **`ID`**, which can not efficiently represent circuits with single- and two-qubit rotations that are not multiples of $\\pi / 2$. For example, an $R_X(\\theta)$ gate, when transpiled, must decompose into a series of $RZ$ and $\\sqrt{X}$ gates, which creates a circuit with two gates of finite duration instead of one.\n",
        "\n",
        "Similarly, when two-qubit rotations such as an $R_{ZZ}(\\theta)$ gate are transpiled, the decomposition requires two **`CZ`** gates and several single-qubit gates, which increases the circuit depth. These decompositions are shown in the following code.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "11b003ee-aa8e-4794-a84a-b6870d15fa11",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/11b003ee-aa8e-4794-a84a-b6870d15fa11-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "qc = QuantumCircuit(1)\n",
        "param = Parameter(\"θ\")\n",
        "qc.rx(param, 0)\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "5da9bba4-9a3b-4569-9997-c5b9ccf87b6a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/5da9bba4-9a3b-4569-9997-c5b9ccf87b6a-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Decomposition of an RX(θ) gate using the IBM Quantum QPU basis\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.backend(\"ibm_torino\")\n",
        "optimization_level = 3\n",
        "pm = generate_preset_pass_manager(optimization_level, backend=backend)\n",
        "transpiled_circuit = pm.run(qc)\n",
        "transpiled_circuit.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "6b256201-0237-4f63-91ff-fde1bb884804",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/6b256201-0237-4f63-91ff-fde1bb884804-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "from qiskit.circuit import Parameter\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "qc = QuantumCircuit(2)\n",
        "param = Parameter(\"θ\")\n",
        "qc.rzz(param, 0, 1)\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "f07217b9-a6f0-4adf-b341-6da447535c33",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/fractional-gates/extracted-outputs/f07217b9-a6f0-4adf-b341-6da447535c33-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Decomposition of an RZZ(θ) gate using the IBM Quantum QPU basis\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.backend(\"ibm_torino\")\n",
        "optimization_level = 3\n",
        "pm = generate_preset_pass_manager(optimization_level, backend=backend)\n",
        "transpiled_circuit = pm.run(qc)\n",
        "transpiled_circuit.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5bc4f276-80e4-49af-bd5c-d9dceedc9aa3",
      "metadata": {},
      "source": [
        "For workflows that require many single-qubit $R_X(\\theta)$ or two-qubit rotations (such as in a variational ansatz or when simulating the time evolution of quantum systems), this constraint causes the circuit depth to grow rapidly. However, fractional gates remove this requirement, because the single- and two-qubit rotations are executed directly, and create a more efficient (and thus error-suppressed) quantum circuit.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c601cc20-be04-45b6-9917-e8fe2925d36b",
      "metadata": {},
      "source": [
        "<span id=\"when-not-to-use\" />\n",
        "\n",
        "<span id=\"when-not-to-use-fractional-gates\" />\n",
        "\n",
        "## When *not* to use fractional gates\n",
        "\n",
        "It is important to note that fractional gates are an *experimental* feature and the behavior of the `use_fractional_gates` flag may change in the future. Look to the [release notes](/docs/api/qiskit-ibm-runtime/release-notes) for new versions of `qiskit-ibm-runtime` for more information. See also the API reference documentation for [QiskitRuntimeService.backend](/docs/api/qiskit-ibm-runtime/qiskit-runtime-service#backend), which describes `use_fractional_gates`.\n",
        "\n",
        "Additionally, the Qiskit transpiler has limited capability to use $R_{ZZ}(\\theta)$ in its optimization passes. This requires you to take more care in crafting and optimizing circuits that contain these instructions.\n",
        "\n",
        "Lastly, using fractional gates is not supported for:\n",
        "\n",
        "* [Pauli twirling](/docs/guides/error-mitigation-and-suppression-techniques#pauli-twirling) - however, [measurement twirling with TREX](/docs/guides/error-mitigation-and-suppression-techniques#twirled-readout-error-extinction-trex) *is* supported.\n",
        "* [Probabilistic error cancellation](/docs/guides/error-mitigation-and-suppression-techniques#probabilistic-error-cancellation-pec)\n",
        "* [Zero-noise extrapolation (using probabilistic error amplification)](/docs/guides/error-mitigation-and-suppression-techniques#probabilistic-error-amplification-pea)\n",
        "\n",
        "Read the guide on [primitive options](/docs/guides/runtime-options-overview) to learn more about customizing the error mitigation and suppression techniques for a given quantum workload.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "58fba520-5d6e-4647-8cb7-2c8790eb8127",
      "metadata": {},
      "source": [
        "## Which backends support fractional gates?\n",
        "\n",
        "Not all backends support fractional gates. Run `service.backends(use_fractional_gates=True)` to find those that do. A fake backend supports fractional gates only if the related \"real\" backend supports them.\n",
        "\n",
        "Note that fake backends don't support fractional gates by default, since fractional gates are disabled by default. To enable fractional gates on a fake backend that supports them, refresh its configuration.\n",
        "\n",
        "Example:\n",
        "\n",
        "```python\n",
        "service = QiskitRuntimeService()\n",
        "fake_backend = FakeBoston()\n",
        "fake_backend.refresh(service=service, use_fractional_gates=True)\n",
        "```\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bf0a38a6-60d1-4848-bbde-df19bb496510",
      "metadata": {},
      "source": [
        "## Next steps\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recommendations\">\n",
        "  * To learn more about transpilation, see the [introduction to transpilation](/docs/guides/transpile) page.\n",
        "  * Read about [writing a custom transpiler pass](/docs/guides/custom-transpiler-pass).\n",
        "  * Understand how to [configure error mitigation](/docs/guides/configure-error-mitigation).\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 2
}