diff --git a/docs/source/tutorial.rst b/docs/source/tutorial.rst index 2de28001..ed616f2d 100644 --- a/docs/source/tutorial.rst +++ b/docs/source/tutorial.rst @@ -5,6 +5,7 @@ Jupyter Tutorials .. toctree:: tutorials/circuit_basics.ipynb + tutorials/circuit_qudit_basics.ipynb tutorials/qaoa.ipynb tutorials/qaoa_bo.ipynb tutorials/qaoa_nae3sat.ipynb diff --git a/docs/source/tutorial_cn.rst b/docs/source/tutorial_cn.rst index 956d03b6..7a373045 100644 --- a/docs/source/tutorial_cn.rst +++ b/docs/source/tutorial_cn.rst @@ -5,6 +5,7 @@ .. toctree:: tutorials/circuit_basics_cn.ipynb + tutorials/circuit_qudit_basics_cn.ipynb tutorials/qaoa_cn.ipynb tutorials/tfim_vqe_cn.ipynb tutorials/mnist_qml_cn.ipynb diff --git a/docs/source/tutorials/circuit_qudit_basics.ipynb b/docs/source/tutorials/circuit_qudit_basics.ipynb new file mode 100644 index 00000000..44f22e75 --- /dev/null +++ b/docs/source/tutorials/circuit_qudit_basics.ipynb @@ -0,0 +1,450 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "fb9014d4", + "metadata": {}, + "source": [ + "# Qudit Circuit Basics\n", + "\n", + "*A gentle intro to `tensorcircuit.quditcircuit.QuditCircuit`*" + ] + }, + { + "cell_type": "markdown", + "id": "78755298", + "metadata": {}, + "source": [ + "\n", + "## Overview\n", + "\n", + "This tutorial shows how to build and simulate **qudit** circuits (d‑level systems, where `d ≥ 3`) using `tensorcircuit`'s `QuditCircuit` API.\n", + "**Highlights**\n", + "- Create a `QuditCircuit(nqudits, dim)` with dimension `dim ∈ [3, 36]`.\n", + "- Single-qudit gates: `X`, `Z`, `H`, rotations `RX/RY/RZ` on selected levels `(j, k)`.\n", + "- Two‑qudit gates: `RXX`, `RZZ`, and the generalized controlled‑sum `CSUM` and controlled-phase `CPHASE`.\n", + "- Obtain wavefunctions, probabilities, samples, expectations, and sub‑system projections.\n", + "- Samples and bitstrings use base‑36 digits (`0–9A–Z`) where `A = 10, ..., Z = 35`.\n" + ] + }, + { + "cell_type": "markdown", + "id": "639c47d1", + "metadata": {}, + "source": [ + "\n", + "## Setup" + ] + }, + { + "cell_type": "code", + "id": "8f2d9565", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:32:59.941117Z", + "start_time": "2025-09-10T10:32:58.690552Z" + } + }, + "source": [ + "import tensorcircuit as tc\n", + "from tensorcircuit.quditcircuit import QuditCircuit\n", + "\n", + "tc.set_backend(\"numpy\") # or \"jax\", \"tensorflow\", \"pytorch\"\n", + "print(\"tensorcircuit version:\", tc.__version__)" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensorcircuit version: 1.3.0\n" + ] + } + ], + "execution_count": 1 + }, + { + "cell_type": "markdown", + "id": "e19b9c5d", + "metadata": {}, + "source": [ + "\n", + "## Hello, Qutrit! (dim = 13)\n", + "\n", + "We'll prepare a **single qudit** (`nqudits=1`, `dim=13`), apply a generalized Hadamard `H` to put it into an equal superposition, and inspect the resulting state and probabilities.\n" + ] + }, + { + "cell_type": "code", + "id": "3fa13efe", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:33:00.001551Z", + "start_time": "2025-09-10T10:32:59.998454Z" + } + }, + "source": [ + "c = QuditCircuit(nqudits=1, dim=13)\n", + "c.h(0) # generalized Hadamard on the only qudit\n", + "psi = c.wavefunction() # state vector of length 13^1 = 13\n", + "probs = c.probability() # probability vector (length 3)\n", + "print(r\"\\psi:\", psi)\n", + "print(\"P:\", probs)" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\\psi: [0.2773501+0.j 0.2773501+0.j 0.2773501+0.j 0.2773501+0.j 0.2773501+0.j\n", + " 0.2773501+0.j 0.2773501+0.j 0.2773501+0.j 0.2773501+0.j 0.2773501+0.j\n", + " 0.2773501+0.j 0.2773501+0.j 0.2773501+0.j]\n", + "P: [0.07692308 0.07692308 0.07692308 0.07692308 0.07692308 0.07692308\n", + " 0.07692308 0.07692308 0.07692308 0.07692308 0.07692308 0.07692308\n", + " 0.07692308]\n" + ] + } + ], + "execution_count": 2 + }, + { + "cell_type": "markdown", + "id": "3d4bd27e", + "metadata": {}, + "source": [ + "\n", + "## Multi‑Qudit Basics\n", + "\n", + "Let's move to **two qutrits** and create a maximally entangled state using `H` and the qudit controlled‑sum `CSUM`.\n", + "\n", + "The operator `CSUM(control, target, cv=None)` adds the control's value to the target modulo `dim`. It's a natural generalization of CNOT. If you pass `cv`, the gate activates only when the control equals that value (default is `None`).\n" + ] + }, + { + "cell_type": "code", + "id": "c53a755e", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:33:00.018234Z", + "start_time": "2025-09-10T10:33:00.014110Z" + } + }, + "source": [ + "cq = QuditCircuit(nqudits=2, dim=3) # two qutrits\n", + "cq.h(0) # superpose control\n", + "cq.csum(0, 1) # qudit CNOT analog (control=0, target=1)\n", + "psi = cq.wavefunction()\n", + "probs = cq.probability()\n", + "print(r\"|\\psi|^2 (length 3^2=9):\", probs)" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "|\\psi|^2 (length 3^2=9): [0.3333333 0. 0. 0. 0.3333333 0. 0.\n", + " 0. 0.3333333]\n" + ] + } + ], + "execution_count": 3 + }, + { + "cell_type": "markdown", + "id": "10f5f60a", + "metadata": {}, + "source": [ + "\n", + "### Sampling and Base‑36 Readout\n", + "\n", + "Sampling returns strings in base‑`dim` using **`0-9A-Z`**. For `dim=3`, the alphabet is `0,1,2`:\n" + ] + }, + { + "cell_type": "code", + "id": "6542deab", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:33:00.335589Z", + "start_time": "2025-09-10T10:33:00.031885Z" + } + }, + "source": [ + "samples = cq.sample(batch=512, format=\"count_dict_bin\") # e.g., '00', '11', '22'\n", + "samples" + ], + "outputs": [ + { + "data": { + "text/plain": [ + "{'00': 160, '11': 171, '22': 181}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 4 + }, + { + "cell_type": "markdown", + "id": "d2bd578c", + "metadata": {}, + "source": [ + "\n", + "## Single‑Qudit Rotations on Selected Levels\n", + "\n", + "For a qudit, rotations target a **two‑level subspace** inside the `d` levels.\n", + "\n", + "- `rx(index, theta, j=0, k=1)` rotates between levels `j` and `k` about the X‑axis of that embedded SU(2).\n", + "- `ry(index, theta, j=0, k=1)` similarly for Y.\n", + "- `rz(index, theta, j=0)` applies a Z‑phase to a single level `j`.\n", + "\n", + "> Tip: `(j, k)` must be distinct integers in `[0, dim-1]`.\n" + ] + }, + { + "cell_type": "code", + "id": "e4e2b769", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:33:00.350793Z", + "start_time": "2025-09-10T10:33:00.346566Z" + } + }, + "source": [ + "import numpy as np\n", + "\n", + "c = QuditCircuit(nqudits=1, dim=5) # a ququint\n", + "c.h(0) # start in equal superposition\n", + "c.rx(0, theta=np.pi / 3, j=1, k=3) # rotate levels 1 and 3\n", + "c.rz(0, theta=np.pi / 5, j=4) # add a phase to level 4\n", + "psi = c.wavefunction()\n", + "probs = c.probability()\n", + "psi, probs" + ], + "outputs": [ + { + "data": { + "text/plain": [ + "(array([0.4472136 +0.j , 0.38729832-0.2236068j ,\n", + " 0.4472136 +0.j , 0.38729832-0.2236068j ,\n", + " 0.3618034 +0.26286554j], dtype=complex64),\n", + " array([0.19999999, 0.19999997, 0.19999999, 0.19999997, 0.20000002],\n", + " dtype=float32))" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 5 + }, + { + "cell_type": "markdown", + "id": "9d98e918", + "metadata": {}, + "source": [ + "\n", + "## Two‑Qudit Interactions: `RXX`, `RZZ`\n", + "\n", + "You can couple two qudits by acting on chosen **subspaces** of each:\n", + "\n", + "- `rxx(q1, q2, theta, j1=0, k1=1, j2=0, k2=1)`\n", + "- `rzz(q1, q2, theta, j1=0, k1=1, j2=0, k2=1)`\n", + "\n", + "Both gates are the natural generalizations of qubit XX/ZZ rotations but restricted to the `(j, k)` subspaces.\n" + ] + }, + { + "cell_type": "code", + "id": "a56be75e", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:33:00.361091Z", + "start_time": "2025-09-10T10:33:00.357370Z" + } + }, + "source": [ + "c2 = QuditCircuit(nqudits=2, dim=4) # two ququarts\n", + "c2.h(0)\n", + "c2.h(1)\n", + "c2.rxx(0, 1, theta=np.pi / 4, j1=0, k1=2, j2=1, k2=3)\n", + "c2.rzz(0, 1, theta=np.pi / 7, j1=0, k1=1, j2=0, k2=1)\n", + "c2.probability()" + ], + "outputs": [ + { + "data": { + "text/plain": [ + "array([0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625,\n", + " 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625],\n", + " dtype=float32)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 6 + }, + { + "cell_type": "markdown", + "id": "c5a56af8", + "metadata": {}, + "source": [ + "\n", + "## Expectation Values of Local Operators\n", + "\n", + "`expectation(*ops)` computes the expectation for one or more local observables. Each observable is a pair `(op, [site_indices])` where `op` is a tensor (matrix) with appropriate dimension.\n" + ] + }, + { + "cell_type": "code", + "id": "fe4ed499", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:33:00.372256Z", + "start_time": "2025-09-10T10:33:00.367671Z" + } + }, + "source": [ + "# Example: build a diagonal operator on a single qutrit (dim=3)\n", + "import numpy as np\n", + "\n", + "c = QuditCircuit(1, dim=3)\n", + "c.h(0)\n", + "op = np.diag([0.0, 0.5, 1.0]) # acts on subspace levels 0,1,2\n", + "expval = c.expectation((op, [0]))\n", + "expval" + ], + "outputs": [ + { + "data": { + "text/plain": [ + "array(0.49999997+0.j, dtype=complex64)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 7 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "### Apply Arbitrary Gate\n", + "\n", + "Just directly using ``any`` API by feeding the corresponding unitary" + ], + "id": "648ee02776427b3c" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:33:14.972605Z", + "start_time": "2025-09-10T10:33:00.385060Z" + } + }, + "cell_type": "code", + "source": [ + "d = 36\n", + "c = tc.QuditCircuit(2, dim=d)\n", + "h_matrix = tc.quditgates.h_matrix_func(d)\n", + "c.any(0, unitary=h_matrix)\n", + "csum_matrix = tc.quditgates.csum_matrix_func(d)\n", + "c.any(0, 1, unitary=csum_matrix)\n", + "c.sample(1024, format=\"count_dict_bin\")" + ], + "id": "4d73e00b952f2ac4", + "outputs": [ + { + "data": { + "text/plain": [ + "{'00': 29,\n", + " '11': 35,\n", + " '22': 29,\n", + " '33': 41,\n", + " '44': 25,\n", + " '55': 28,\n", + " '66': 28,\n", + " '77': 35,\n", + " '88': 32,\n", + " '99': 27,\n", + " 'AA': 38,\n", + " 'BB': 35,\n", + " 'CC': 29,\n", + " 'DD': 31,\n", + " 'EE': 30,\n", + " 'FF': 22,\n", + " 'GG': 26,\n", + " 'HH': 19,\n", + " 'II': 26,\n", + " 'JJ': 24,\n", + " 'KK': 37,\n", + " 'LL': 27,\n", + " 'MM': 34,\n", + " 'NN': 27,\n", + " 'OO': 31,\n", + " 'PP': 31,\n", + " 'QQ': 28,\n", + " 'RR': 26,\n", + " 'SS': 23,\n", + " 'TT': 27,\n", + " 'UU': 32,\n", + " 'VV': 27,\n", + " 'WW': 19,\n", + " 'XX': 27,\n", + " 'YY': 22,\n", + " 'ZZ': 17}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 8 + }, + { + "cell_type": "markdown", + "id": "7aa6de25", + "metadata": {}, + "source": [ + "\n", + "## Notes & Tips\n", + "\n", + "- **Dimensions**: `QuditCircuit` validates `dim` and keeps it consistent across the circuit.\n", + "- **Wavefunction & Probability**: `wavefunction()` returns the state; `probability()` returns a length‑`dim^n` vector.\n", + "- **Sampling**: `sample(batch, format=\"str\")` returns base‑36 strings for readability; use `format=None` for raw integers.\n", + "- **Controlled Operations**: `csum(control, target, cv=None)` generalizes CNOT; `cv` picks the active control value.\n", + "- **Backend**: Switch via `tc.set_backend(\"numpy\" | \"jax\" | \"tensorflow\" | \"pytorch\")` as needed.\n", + "- **Interoperability**: You can still obtain `matrix()` for the full unitary or `quoperator()` MPO‑like forms for advanced workflows.\n", + "\n", + "All the functions are similar to the `tc.Circuit`\n" + ] + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:33:14.985131Z", + "start_time": "2025-09-10T10:33:14.983579Z" + } + }, + "cell_type": "code", + "source": "", + "id": "9a33f318814fa510", + "outputs": [], + "execution_count": null + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/source/tutorials/circuit_qudit_basics_cn.ipynb b/docs/source/tutorials/circuit_qudit_basics_cn.ipynb new file mode 100644 index 00000000..c2d986bc --- /dev/null +++ b/docs/source/tutorials/circuit_qudit_basics_cn.ipynb @@ -0,0 +1,444 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "fb9014d4", + "metadata": {}, + "source": [ + "# Qudit(多能级量子比特) 电路基础\n", + "\n", + "*`tensorcircuit.quditcircuit.QuditCircuit` 的轻量入门*" + ] + }, + { + "cell_type": "markdown", + "id": "78755298", + "metadata": {}, + "source": [ + "\n", + "## 概述\n", + "\n", + "这个教程展示了如何使用 `tensorcircuit` 的 `QuditCircuit` API 来构建和模拟 **qudit(多能级量子比特)** 电路(d 级系统,其中 `d ≥ 3`)。\n", + "\n", + "**要点**\n", + "- 创建一个 `QuditCircuit(nqudits, dim)` with dimension `dim ∈ [3, 36]`;\n", + "- 单比特门: `X`, `Z`, `H`, rotations `RX/RY/RZ` on selected levels `(j, k)`;\n", + "- 两比特门: `RXX`, `RZZ`, and the 广义受控求和 `CSUM` and 受控相位 `CPHASE`;\n", + "- 可得到波函数、概率、采样、期望值以及子系统投影;\n", + "- 样本和比特串使用36进制数字(`0–9A–Z`),其中`A = 10, ..., Z = 35`。\n" + ] + }, + { + "cell_type": "markdown", + "id": "639c47d1", + "metadata": {}, + "source": [ + "\n", + "## 配置" + ] + }, + { + "cell_type": "code", + "id": "8f2d9565", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:32:55.146319Z", + "start_time": "2025-09-10T10:32:54.084837Z" + } + }, + "source": [ + "import tensorcircuit as tc\n", + "from tensorcircuit.quditcircuit import QuditCircuit\n", + "\n", + "tc.set_backend(\"numpy\") # or \"jax\", \"tensorflow\", \"pytorch\"\n", + "print(\"tensorcircuit version:\", tc.__version__)" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensorcircuit version: 1.3.0\n" + ] + } + ], + "execution_count": 1 + }, + { + "cell_type": "markdown", + "id": "e19b9c5d", + "metadata": {}, + "source": [ + "## 嗨,Qutrit!(维度为 13)\n", + "\n", + "我们来准备一个**单独的 qudit* (`nqudits=1`, `dim=13`), 对它应用一个广义的 Hadamard 门 `H`,让它进入一个等概率叠加态,然后观察最终的状态和概率。" + ] + }, + { + "cell_type": "code", + "id": "3fa13efe", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:32:55.208690Z", + "start_time": "2025-09-10T10:32:55.205644Z" + } + }, + "source": [ + "c = QuditCircuit(nqudits=1, dim=13)\n", + "c.h(0) # generalized Hadamard on the only qudit\n", + "psi = c.wavefunction() # state vector of length 13^1 = 13\n", + "probs = c.probability() # probability vector (length 3)\n", + "print(r\"\\psi:\", psi)\n", + "print(\"P:\", probs)" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\\psi: [0.2773501+0.j 0.2773501+0.j 0.2773501+0.j 0.2773501+0.j 0.2773501+0.j\n", + " 0.2773501+0.j 0.2773501+0.j 0.2773501+0.j 0.2773501+0.j 0.2773501+0.j\n", + " 0.2773501+0.j 0.2773501+0.j 0.2773501+0.j]\n", + "P: [0.07692308 0.07692308 0.07692308 0.07692308 0.07692308 0.07692308\n", + " 0.07692308 0.07692308 0.07692308 0.07692308 0.07692308 0.07692308\n", + " 0.07692308]\n" + ] + } + ], + "execution_count": 2 + }, + { + "cell_type": "markdown", + "id": "3d4bd27e", + "metadata": {}, + "source": [ + "## 多量子比特基础\n", + "\n", + "让我们来研究一下**两个三态量子比特**,使用 `H` 门和量子比特受控和门 `CSUM` 来创建一个最大纠缠态。\n", + "\n", + "算符 `CSUM(control, target, cv=None)` 将控制位的数值加到目标位上,结果对 `dim` 取模。这是 CNOT 门的自然推广。如果传入 `cv`,则该门仅在控制位等于该值时激活(默认为 `None`)。" + ] + }, + { + "cell_type": "code", + "id": "c53a755e", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:32:55.224139Z", + "start_time": "2025-09-10T10:32:55.221295Z" + } + }, + "source": [ + "cq = QuditCircuit(nqudits=2, dim=3) # two qutrits\n", + "cq.h(0) # superpose control\n", + "cq.csum(0, 1) # qudit CNOT analog (control=0, target=1)\n", + "psi = cq.wavefunction()\n", + "probs = cq.probability()\n", + "print(r\"|\\psi|^2 (length 3^2=9):\", probs)" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "|\\psi|^2 (length 3^2=9): [0.3333333 0. 0. 0. 0.3333333 0. 0.\n", + " 0. 0.3333333]\n" + ] + } + ], + "execution_count": 3 + }, + { + "cell_type": "markdown", + "id": "10f5f60a", + "metadata": {}, + "source": [ + "### 采样和 36 进制读数\n", + "\n", + "采样会返回用 `0-9A-Z` 表示的、基于 `dim` 进制的字符串。例如,当 `dim=3` 时,字母表是 `0,1,2`:" + ] + }, + { + "cell_type": "code", + "id": "6542deab", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:32:55.513434Z", + "start_time": "2025-09-10T10:32:55.230298Z" + } + }, + "source": [ + "samples = cq.sample(batch=512, format=\"count_dict_bin\") # e.g., '00', '11', '22'\n", + "samples" + ], + "outputs": [ + { + "data": { + "text/plain": [ + "{'00': 175, '11': 165, '22': 172}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 4 + }, + { + "cell_type": "markdown", + "id": "d2bd578c", + "metadata": {}, + "source": [ + "## 在选定能级上的单量子比特旋转\n", + "\n", + "对于一个 qudit(多态量子位),旋转的目标是 `d` 个能级中的一个**双能级子空间**。\n", + "\n", + "- `rx(index, theta, j=0, k=1)` 在能级 `j` 和 `k` 之间绕该嵌入的 SU(2) 的 X 轴旋转。\n", + "- `ry(index, theta, j=0, k=1)` 类似地,绕 Y 轴旋转。\n", + "- `rz(index, theta, j=0)` 对单个能级 `j` 应用 Z 相位。\n", + "\n", + "> 提示:`(j, k)` 必须是 `[0, dim-1]` 中的不同整数。" + ] + }, + { + "cell_type": "code", + "id": "e4e2b769", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:32:55.529822Z", + "start_time": "2025-09-10T10:32:55.526134Z" + } + }, + "source": [ + "import numpy as np\n", + "\n", + "c = QuditCircuit(nqudits=1, dim=5) # a ququint\n", + "c.h(0) # start in equal superposition\n", + "c.rx(0, theta=np.pi / 3, j=1, k=3) # rotate levels 1 and 3\n", + "c.rz(0, theta=np.pi / 5, j=4) # add a phase to level 4\n", + "psi = c.wavefunction()\n", + "probs = c.probability()\n", + "psi, probs" + ], + "outputs": [ + { + "data": { + "text/plain": [ + "(array([0.4472136 +0.j , 0.38729832-0.2236068j ,\n", + " 0.4472136 +0.j , 0.38729832-0.2236068j ,\n", + " 0.3618034 +0.26286554j], dtype=complex64),\n", + " array([0.19999999, 0.19999997, 0.19999999, 0.19999997, 0.20000002],\n", + " dtype=float32))" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 5 + }, + { + "cell_type": "markdown", + "id": "9d98e918", + "metadata": {}, + "source": [ + "## 两个多能级量子比特的相互作用:`RXX`,`RZZ`\n", + "\n", + "你可以对每个多能级量子比特的选定**子空间**进行操作来进行耦合:\n", + "\n", + "- `rxx(q1, q2, theta, j1=0, k1=1, j2=0, k2=1)`\n", + "- `rzz(q1, q2, theta, j1=0, k1=1, j2=0, k2=1)`\n", + "\n", + "这两个门都是量子比特 XX/ZZ 旋转的自然推广,但仅限于 `(j, k)` 子空间。" + ] + }, + { + "cell_type": "code", + "id": "a56be75e", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:32:55.542966Z", + "start_time": "2025-09-10T10:32:55.539802Z" + } + }, + "source": [ + "c2 = QuditCircuit(nqudits=2, dim=4) # two ququarts\n", + "c2.h(0)\n", + "c2.h(1)\n", + "c2.rxx(0, 1, theta=np.pi / 4, j1=0, k1=2, j2=1, k2=3)\n", + "c2.rzz(0, 1, theta=np.pi / 7, j1=0, k1=1, j2=0, k2=1)\n", + "c2.probability()" + ], + "outputs": [ + { + "data": { + "text/plain": [ + "array([0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625,\n", + " 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625],\n", + " dtype=float32)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 6 + }, + { + "cell_type": "markdown", + "id": "c5a56af8", + "metadata": {}, + "source": [ + "## 局部算符的期望值\n", + "\n", + "`expectation(*ops)` 计算一个或多个局部可观测量(算符)的期望值。每个可观测量是一个对 `(op, [site_indices])`,其中 `op` 是一个具有适当维度的张量(矩阵)。" + ] + }, + { + "cell_type": "code", + "id": "fe4ed499", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:32:55.554767Z", + "start_time": "2025-09-10T10:32:55.551801Z" + } + }, + "source": [ + "# Example: build a diagonal operator on a single qutrit(三能级量子比特)(三能级量子比特) (dim=3)\n", + "import numpy as np\n", + "\n", + "c = QuditCircuit(1, dim=3)\n", + "c.h(0)\n", + "op = np.diag([0.0, 0.5, 1.0]) # acts on subspace levels 0,1,2\n", + "expval = c.expectation((op, [0]))\n", + "expval" + ], + "outputs": [ + { + "data": { + "text/plain": [ + "array(0.49999997+0.j, dtype=complex64)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 7 + }, + { + "cell_type": "markdown", + "id": "648ee02776427b3c", + "metadata": {}, + "source": [ + "### 应用任意门\n", + "\n", + "直接使用 ``any`` API,输入对应的幺正矩阵即可。" + ] + }, + { + "cell_type": "code", + "id": "4d73e00b952f2ac4", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:33:10.278158Z", + "start_time": "2025-09-10T10:32:55.563904Z" + } + }, + "source": [ + "d = 36\n", + "c = tc.QuditCircuit(2, dim=d)\n", + "h_matrix = tc.quditgates.h_matrix_func(d)\n", + "c.any(0, unitary=h_matrix)\n", + "csum_matrix = tc.quditgates.csum_matrix_func(d)\n", + "c.any(0, 1, unitary=csum_matrix)\n", + "c.sample(1024, format=\"count_dict_bin\")" + ], + "outputs": [ + { + "data": { + "text/plain": [ + "{'00': 35,\n", + " '11': 28,\n", + " '22': 28,\n", + " '33': 25,\n", + " '44': 33,\n", + " '55': 30,\n", + " '66': 34,\n", + " '77': 25,\n", + " '88': 22,\n", + " '99': 22,\n", + " 'AA': 40,\n", + " 'BB': 38,\n", + " 'CC': 35,\n", + " 'DD': 17,\n", + " 'EE': 21,\n", + " 'FF': 27,\n", + " 'GG': 24,\n", + " 'HH': 26,\n", + " 'II': 27,\n", + " 'JJ': 24,\n", + " 'KK': 18,\n", + " 'LL': 27,\n", + " 'MM': 23,\n", + " 'NN': 38,\n", + " 'OO': 26,\n", + " 'PP': 31,\n", + " 'QQ': 27,\n", + " 'RR': 37,\n", + " 'SS': 28,\n", + " 'TT': 20,\n", + " 'UU': 34,\n", + " 'VV': 34,\n", + " 'WW': 32,\n", + " 'XX': 25,\n", + " 'YY': 29,\n", + " 'ZZ': 34}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 8 + }, + { + "cell_type": "markdown", + "id": "7aa6de25", + "metadata": {}, + "source": [ + "## 注意事项和提示\n", + "\n", + "- **维度**: `QuditCircuit` 会验证 `dim` 并且保持它在整个电路中的一致性。\n", + "- **波函数和概率**: `wavefunction()` 返回状态;`probability()` 返回一个长度为 `dim^n` 的向量。\n", + "- **采样**: `sample(batch, format=\"str\")` 返回易于阅读的 36 进制字符串;使用 `format=None` 获取原始整数。\n", + "- **受控操作**: `csum(control, target, cv=None)` 泛化了 CNOT 门;`cv` 选择激活的控制值。\n", + "- **后端**: 根据需要通过 `tc.set_backend(\"numpy\" | \"jax\" | \"tensorflow\" | \"pytorch\")` 切换后端。\n", + "- **互操作性**: 你仍然可以获取完整幺正矩阵的 `matrix()` 或类似 MPO 的 `quoperator()` 形式,用于高级工作流程。\n", + "\n", + "所有这些函数都类似于 `tc.Circuit`。" + ] + }, + { + "cell_type": "code", + "id": "9a33f318814fa510", + "metadata": { + "ExecuteTime": { + "end_time": "2025-09-10T10:33:10.287714Z", + "start_time": "2025-09-10T10:33:10.286396Z" + } + }, + "source": [], + "outputs": [], + "execution_count": null + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +}