{ "cells": [ { "cell_type": "markdown", "id": "be0b2384", "metadata": {}, "source": [ "# CompilerV0" ] }, { "cell_type": "markdown", "id": "bc284b12", "metadata": {}, "source": [ "![image](../images/compilerv0.png)" ] }, { "cell_type": "markdown", "id": "16bb1d2b", "metadata": {}, "source": [ "## Description\n", "\n", "The **CompilerV0** environment is designed to simulate the task of **quantum gate compilation** for a single-qubit system.\n", "It is based on the `QuantumEnv` base class. The agent's goal is to sequentially apply quantum gates to approximate a randomly chosen target **unitary operation**\n", "from the special unitary group SU(2). This mimics a quantum compilation problem where one attempts to rewrite a quantum operation in terms of a limited gate set.\n", "\n", "At each step, the agent applies one of several predefined single-qubit gates, evolving the current circuit unitary.\n", "The agent receives a reward proportional to the **fidelity** between the evolved unitary and the target unitary, and the episode terminates when the agent either reaches a sufficiently high fidelity or exhausts the maximum step limit.\n", "\n", "The environment includes a rendering mode that visualizes the **difference matrix** between the target and the current unitary as a heatmap evolving over time." ] }, { "cell_type": "markdown", "id": "cfa13645", "metadata": {}, "source": [ "## Action Space\n", "\n", "The action space is **discrete**, where each action corresponds to applying a quantum gate\n", "from a fixed set of single-qubit operations:\n", "\n", "| Num | Action | Description |\n", "|-----|-----------|------------------------------------|\n", "| 0 | `H` | Hadamard gate |\n", "| 1 | `X` | Pauli-X gate |\n", "| 2 | `Y` | Pauli-Y gate |\n", "| 3 | `Z` | Pauli-Z gate |\n", "| 4 | `S` | Phase gate |\n", "| 5 | `SDG` | Conjugate transpose of Phase gate |\n", "| 6 | `T` | π/8 gate |\n", "| 7 | `TDG` | Conjugate transpose of π/8 gate |\n", "| 8 | `RX_pi_2` | X-axis rotation by π/2 |\n", "| 9 | `RX_pi_4` | X-axis rotation by π/4 |\n", "| 10 | `RY_pi_2` | Y-axis rotation by π/2 |\n", "| 11 | `RY_pi_4` | Y-axis rotation by π/4 |\n", "| 12 | `RZ_pi_2` | Z-axis rotation by π/2 |\n", "| 13 | `RZ_pi_4` | Z-axis rotation by π/4 |" ] }, { "cell_type": "markdown", "id": "2e416c51", "metadata": {}, "source": [ "## Observation Space\n", "\n", "The observation is a flattened representation of the current unitary matrix, expressed in terms\n", "of its **real and imaginary parts**. This results in an 8-dimensional vector:\n", "\n", "| Num | Observation Component | Range |\n", "|-----|------------------------|---------|\n", "| 0-3 | Real part of unitary | [-1, 1] |\n", "| 4-7 | Imag part of unitary | [-1, 1] |\n", "\n", "This encodes the full \\(2 \\times 2\\) complex unitary matrix." ] }, { "cell_type": "markdown", "id": "ba377f3a", "metadata": {}, "source": [ "## Rewards\n", "\n", "The reward is based on the **average gate fidelity** between the target unitary U_{target}\n", "and the current unitary U. Specifically:\n", "\n", "$reward = \\frac{1}{2} \\left| \\mathrm{Tr}(U_{target}^\\dagger U) \\right|$\n", "\n", "- A higher reward indicates closer alignment with the target unitary.\n", "- The episode terminates early if the reward exceeds `reward_tolerance` (default: 0.98)." ] }, { "cell_type": "markdown", "id": "27800516", "metadata": {}, "source": [ "## Starting State\n", "\n", "At the start of each episode:\n", "- The circuit unitary is initialized as the **identity matrix** \\( I \\).\n", "- The target unitary is specified by the user at initialization. \n", "(By default, this can be drawn from a random **U3(θ, φ, λ)** decomposition in SU(2).)\n", "\n", "The initial observation corresponds to the identity matrix.\n" ] }, { "cell_type": "markdown", "id": "8480ec50", "metadata": {}, "source": [ "## Episode End\n", "\n", "The episode ends if one of the following occurs:\n", "\n", "1. **Termination**: \n", "The fidelity between the current and target unitary exceeds the reward tolerance (`reward > 0.98` by default).\n", "2. **Truncation**: \n", "The number of steps exceeds the maximum episode length (`max_steps`, default: 30).\n" ] }, { "cell_type": "markdown", "id": "b460badd", "metadata": {}, "source": [ "## Rendering\n", "\n", "The environment supports visualization of the compilation process:\n", "\n", "- A heatmap is drawn showing the **magnitude of the difference matrix**:\n", "$|U_{target} - U|$\n", "at each step.\n", "- The heatmap updates dynamically, and the plot title displays the **step number, last applied gate, and reward**.\n", "\n", "The animation can be saved as an MP4 file or displayed interactively.\n" ] }, { "cell_type": "markdown", "id": "f4f5cfed", "metadata": {}, "source": [ "## Arguments\n", "\n", "- **`target`** (`np.ndarray`): The target \\(2 \\times 2\\) unitary matrix to compile towards. \n", "- **`max_steps`** (`int`, default=30): Maximum number of steps per episode. \n", "- **`reward_tolerance`** (`float`, default=0.98): Fidelity threshold for early termination.\n", "- **`ffmpeg`** (`bool`, default=False): If `True`, uses FFmpeg for saving animations; otherwise uses Pillow (GIF).\n" ] }, { "cell_type": "code", "execution_count": 1, "id": "10928b94", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Initial Circuit State: [1. 0. 0. 1. 0. 0. 0. 0.]\n", "After 12 action -> Observation: [ 6.123234e-17 0.000000e+00 0.000000e+00 6.123234e-17 -1.000000e+00\n", " 0.000000e+00 0.000000e+00 1.000000e+00]\n", "Reward: 0.7632554085856338 Done: False\n", "After 0 action -> Observation: [ 4.3297803e-17 4.3297803e-17 4.3297803e-17 -4.3297803e-17\n", " -7.0710677e-01 7.0710677e-01 -7.0710677e-01 -7.0710677e-01]\n", "Reward: 0.026880376541707558 Done: False\n", "After 13 action -> Observation: [-7.0710677e-01 7.0710677e-01 7.0710677e-01 7.0710677e-01\n", " -8.6595606e-17 0.0000000e+00 0.0000000e+00 -8.6595606e-17]\n", "Reward: 0.9003790168046004 Done: False\n", "After 1 action -> Observation: [ 7.0710677e-01 7.0710677e-01 -7.0710677e-01 7.0710677e-01\n", " 0.0000000e+00 -8.6595606e-17 -8.6595606e-17 0.0000000e+00]\n", "Reward: 0.3956568676265005 Done: False\n", "After 9 action -> Observation: [-4.3297803e-17 4.3297803e-17 -4.3297803e-17 -4.3297803e-17\n", " 7.0710677e-01 -7.0710677e-01 -7.0710677e-01 -7.0710677e-01]\n", "Reward: 0.9003790168046004 Done: False\n", "After 10 action -> Observation: [ 4.3297803e-17 4.3297803e-17 -4.3297803e-17 4.3297803e-17\n", " 7.0710677e-01 7.0710677e-01 7.0710677e-01 -7.0710677e-01]\n", "Reward: 0.17902713357182076 Done: False\n", "After 7 action -> Observation: [ 4.3297803e-17 4.3297803e-17 5.0000000e-01 -5.0000000e-01\n", " 7.0710677e-01 7.0710677e-01 5.0000000e-01 -5.0000000e-01]\n", "Reward: 0.013988176329040307 Done: False\n", "After 10 action -> Observation: [-5.00000000e-01 5.00000000e-01 7.39139743e-17 1.26816325e-17\n", " -5.00000000e-01 5.00000000e-01 7.07106769e-01 7.07106769e-01]\n", "Reward: 0.8421284198866531 Done: False\n", "After 13 action -> Observation: [-5.0000000e-01 5.0000000e-01 -7.0710677e-01 -7.0710677e-01\n", " 5.0000000e-01 -5.0000000e-01 1.1721177e-16 5.5979435e-17]\n", "Reward: 0.3197259028672091 Done: False\n", "After 9 action -> Observation: [ 8.6595606e-17 8.6595606e-17 5.0000000e-01 -5.0000000e-01\n", " 7.0710677e-01 7.0710677e-01 5.0000000e-01 -5.0000000e-01]\n", "Reward: 0.013988176329040366 Done: False\n", "After 8 action -> Observation: [ 5.0000000e-01 -5.0000000e-01 7.0710677e-01 7.0710677e-01\n", " -5.0000000e-01 5.0000000e-01 -5.5979435e-17 -1.1721177e-16]\n", "Reward: 0.31972590286720903 Done: False\n", "After 5 action -> Observation: [ 5.0000000e-01 -5.0000000e-01 -5.5979435e-17 -1.1721177e-16\n", " -5.0000000e-01 5.0000000e-01 -7.0710677e-01 -7.0710677e-01]\n", "Reward: 0.3693943622933696 Done: False\n", "After 4 action -> Observation: [ 5.0000000e-01 -5.0000000e-01 7.0710677e-01 7.0710677e-01\n", " -5.0000000e-01 5.0000000e-01 -5.5979435e-17 -1.1721177e-16]\n", "Reward: 0.31972590286720903 Done: False\n", "After 2 action -> Observation: [-5.5979435e-17 -1.1721177e-16 5.0000000e-01 -5.0000000e-01\n", " -7.0710677e-01 -7.0710677e-01 5.0000000e-01 -5.0000000e-01]\n", "Reward: 0.43404999985939907 Done: False\n", "After 10 action -> Observation: [-5.0000000e-01 5.0000000e-01 -2.5363265e-17 -1.4782795e-16\n", " -5.0000000e-01 5.0000000e-01 -7.0710677e-01 -7.0710677e-01]\n", "Reward: 0.3197259028672091 Done: False\n", "After 13 action -> Observation: [-5.0000000e-01 5.0000000e-01 7.0710677e-01 7.0710677e-01\n", " 5.0000000e-01 -5.0000000e-01 -6.8661066e-17 -1.9112575e-16]\n", "Reward: 0.8421284198866528 Done: False\n", "After 3 action -> Observation: [-5.0000000e-01 5.0000000e-01 -7.0710677e-01 -7.0710677e-01\n", " 5.0000000e-01 -5.0000000e-01 6.8661066e-17 1.9112575e-16]\n", "Reward: 0.3197259028672089 Done: False\n", "After 6 action -> Observation: [-0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5]\n", "Reward: 0.61765681188712 Done: False\n", "After 12 action -> Observation: [ 0.5 -0.5 0.5 0.5 0.5 -0.5 -0.5 -0.5]\n", "Reward: 0.6556714049540987 Done: False\n", "After 7 action -> Observation: [ 5.0000000e-01 -5.0000000e-01 -1.1102230e-16 -2.2204460e-16\n", " 5.0000000e-01 -5.0000000e-01 -7.0710677e-01 -7.0710677e-01]\n", "Reward: 0.8421284198866528 Done: False\n", "After 10 action -> Observation: [ 1.4163847e-16 1.9142844e-16 5.0000000e-01 -5.0000000e-01\n", " 7.0710677e-01 7.0710677e-01 5.0000000e-01 -5.0000000e-01]\n", "Reward: 0.013988176329040477 Done: False\n", "After 6 action -> Observation: [ 1.4163847e-16 1.9142844e-16 -2.2204460e-16 1.1102230e-16\n", " 7.0710677e-01 7.0710677e-01 7.0710677e-01 -7.0710677e-01]\n", "Reward: 0.1790271335718209 Done: False\n", "After 7 action -> Observation: [ 1.4163847e-16 1.9142844e-16 5.0000000e-01 -5.0000000e-01\n", " 7.0710677e-01 7.0710677e-01 5.0000000e-01 -5.0000000e-01]\n", "Reward: 0.013988176329040461 Done: False\n", "After 13 action -> Observation: [ 7.0710677e-01 7.0710677e-01 -5.0000000e-01 5.0000000e-01\n", " -9.8340671e-17 -1.4813063e-16 5.0000000e-01 -5.0000000e-01]\n", "Reward: 0.434049999859399 Done: False\n", "After 0 action -> Observation: [ 0.14644662 0.85355341 0.85355341 0.14644662 0.35355338 -0.35355338\n", " -0.35355338 0.35355338]\n", "Reward: 0.5855835819930668 Done: False\n", "After 7 action -> Observation: [ 0.14644662 0.85355341 0.35355338 0.35355338 0.35355338 -0.35355338\n", " -0.85355341 0.14644662]\n", "Reward: 0.744978975447949 Done: False\n", "After 6 action -> Observation: [ 0.14644662 0.85355341 0.85355341 0.14644662 0.35355338 -0.35355338\n", " -0.35355338 0.35355338]\n", "Reward: 0.5855835819930667 Done: False\n", "After 7 action -> Observation: [ 0.14644662 0.85355341 0.35355338 0.35355338 0.35355338 -0.35355338\n", " -0.85355341 0.14644662]\n", "Reward: 0.744978975447949 Done: False\n", "After 2 action -> Observation: [-0.85355341 0.14644662 -0.35355338 0.35355338 -0.35355338 -0.35355338\n", " 0.14644662 0.85355341]\n", "Reward: 0.5902209968381783 Done: False\n", "After 1 action -> Observation: [-0.35355338 0.35355338 -0.85355341 0.14644662 0.14644662 0.85355341\n", " -0.35355338 -0.35355338]\n", "Reward: 0.26833470406567134 Done: True\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "## Example:\n", "\n", "\n", "import numpy as np\n", "from qrl.env.core.utils import RY, RZ\n", "from qrl.env import CompilerV0\n", "\n", "theta, phi, lam = np.random.uniform(0, 2*np.pi, 3)\n", "target = (RZ(phi) @ RY(theta) @ RZ(lam)) # general SU(2)\n", "\n", "# Initialize environment with 1 qubit\n", "# set ffmpeg=True if you have ffmpeg installed to save as mp4, or ffmpeg=False to save as gif\n", "env = CompilerV0(target_unitary=target, max_steps=30, reward_tolerance=0.98, ffmpeg=False)\n", "\n", "# Reset\n", "obs, _ = env.reset()\n", "print(\"Initial Circuit State:\", obs)\n", "\n", "for _ in range(env.max_steps):\n", " action = env.action_space.sample()\n", " obs, reward, done, _ = env.step(action)\n", " print(f\"After {action} action -> Observation:\", obs)\n", " print(\"Reward:\", reward, \"Done:\", done)\n", "\n", " if done:\n", " break\n", "\n", "# Render Bloch sphere\n", "env.render(save_path_without_extension=\"compilerV0\")" ] } ], "metadata": { "kernelspec": { "display_name": "qrl_env (3.12.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.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }