diff --git a/docs/source/tutorial.rst b/docs/source/tutorial.rst index 54388c7f..2de28001 100644 --- a/docs/source/tutorial.rst +++ b/docs/source/tutorial.rst @@ -26,6 +26,7 @@ Jupyter Tutorials tutorials/dqas.ipynb tutorials/barren_plateaus.ipynb tutorials/qubo_problem.ipynb + tutorials/lattice.ipynb tutorials/portfolio_optimization.ipynb tutorials/imag_time_evo.ipynb tutorials/classical_shadows.ipynb diff --git a/docs/source/tutorials/lattice.ipynb b/docs/source/tutorials/lattice.ipynb new file mode 100644 index 00000000..30e99abb --- /dev/null +++ b/docs/source/tutorials/lattice.ipynb @@ -0,0 +1,650 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b3f40e81", + "metadata": {}, + "source": [ + "# Lattice Geometries in TensorCircuit\n", + "\n", + "## Quick Start Guide\n", + "\n", + "**šŸ“‹ Available Lattice Types:**\n", + "\n", + "| Class | Description | Use Cases |\n", + "|-------|-------------|-----------|\n", + "| `SquareLattice` | 2D square grid with optional PBC | Spin models, quantum dots |\n", + "| `ChainLattice` | 1D linear chain | Time evolution, MPS algorithms |\n", + "| `HoneycombLattice` | 2D hexagonal structure | Graphene, topological materials |\n", + "| `CustomizeLattice` | Arbitrary finite geometry | Molecular clusters, defects, irregular structures |\n", + "\n", + "**⚔ Key Methods:**\n", + "- `.get_site_info(index)` → Site details (index, identifier, coordinates)\n", + "- `.get_neighbors(site, k=1)` → k-th nearest neighbors of a site\n", + "- `.get_neighbor_pairs(k=1)` → All unique k-th nearest neighbor pairs\n", + "- `.show()` → Interactive visualization with matplotlib\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "id": "9a7ff355", + "metadata": {}, + "source": [ + "This tutorial introduces the unified and extensible **Lattice API** in TensorCircuit, a powerful framework for defining and working with quantum systems on various geometric structures.\n", + "\n", + "## Setup\n", + "\n", + "**Environment Requirements:**\n", + "- TensorCircuit >= 1.3.0\n", + "- Optional: JAX backend for automatic differentiation support\n", + "- Python packages: `numpy`, `matplotlib`, `optax` (for optimization demos)\n", + "\n", + "## What You'll Learn\n", + "\n", + "By the end of this tutorial, you'll be able to:\n", + "\n", + "šŸ”¹ **Build common lattices** (square, chain, honeycomb) and custom geometries \n", + "šŸ”¹ **Query sites and neighbors** with configurable interaction ranges \n", + "šŸ”¹ **Visualize lattices** with bonds and site indices \n", + "šŸ”¹ **Generate physics Hamiltonians** (Heisenberg, Rydberg) directly from geometry \n", + "šŸ”¹ **Create gate layers** for efficient parallel two-qubit operations \n", + "šŸ”¹ **Explore differentiable geometry** for variational optimization \n", + "\n", + "## Architecture Overview\n", + "\n", + "The API is centered around the **`AbstractLattice`** base class, with concrete implementations for:\n", + "- **Translationally invariant lattices**: `SquareLattice`, `HoneycombLattice`, `ChainLattice` \n", + "- **Arbitrary custom geometries**: `CustomizeLattice` for finite clusters and irregular structures\n", + "\n", + "This unified approach provides consistent interfaces while supporting both regular periodic structures and completely custom finite geometries." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "944ca9b5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "āœ… Using JAX backend (supports automatic differentiation)\n" + ] + }, + { + "data": { + "text/plain": [ + "jax_backend" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Essential imports for the lattice tutorial\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import tensorcircuit as tc\n", + "\n", + "# Import all lattice classes and utility functions\n", + "from tensorcircuit.templates.lattice import (\n", + " AbstractLattice,\n", + " SquareLattice,\n", + " HoneycombLattice,\n", + " ChainLattice,\n", + " CustomizeLattice,\n", + " get_compatible_layers,\n", + ")\n", + "from tensorcircuit.templates.hamiltonians import (\n", + " heisenberg_hamiltonian,\n", + " rydberg_hamiltonian,\n", + ")\n", + "\n", + "# JAX backend is preferred for differentiable geometry optimization,\n", + "# but the API works with all TensorCircuit backends (numpy, jax, tensorflow, torch)\n", + "K = tc.set_backend(\"jax\")\n", + "# Set precision to complex128 for better numerical accuracy\n", + "tc.set_dtype(\"complex128\")\n", + "print(\"āœ… Using JAX backend (supports automatic differentiation)\")\n", + "\n", + "K" + ] + }, + { + "cell_type": "markdown", + "id": "83f4e186", + "metadata": {}, + "source": [ + "## 1. Square Lattice: Basic Operations\n", + "\n", + "We'll start by exploring a 3Ɨ3 square lattice with periodic boundary conditions (PBC). This demonstrates the core functionality: site information access, neighbor queries, and connectivity analysis.\n", + "\n", + "**Key concepts:**\n", + "- **Site indexing**: Sites are numbered in row-major order (0-8 for a 3Ɨ3 grid)\n", + "- **Identifiers**: Each site has a tuple identifier (row, col, layer) for multi-dimensional lattices \n", + "- **Periodic boundaries**: With `pbc=True`, edge sites connect to opposite edges\n", + "- **Neighbor shells**: `k=1` means nearest neighbors, `k=2` next-nearest neighbors, etc." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "077c05f4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "num_sites: 9\n", + "dimensionality: 2\n", + "site 4 info -> 4 (1, 1, 0) [1. 1.]\n", + "nearest neighbors of site 4 -> [1, 3, 5, 7]\n", + "unique NN pairs (first 8) -> [(0, 1), (0, 2), (0, 3), (0, 6), (1, 2), (1, 4), (1, 7), (2, 5)] ...\n" + ] + } + ], + "source": [ + "# Create a 3x3 square lattice with periodic boundary conditions and lattice constant 1.0\n", + "sq = SquareLattice(size=(3, 3), pbc=True, lattice_constant=1.0)\n", + "\n", + "# Access basic lattice properties\n", + "print(f\"num_sites: {sq.num_sites}\")\n", + "print(f\"dimensionality: {sq.dimensionality}\")\n", + "\n", + "# Get information about site 4 (center site in row-major ordering for 3x3)\n", + "idx, ident, coords = sq.get_site_info(4)\n", + "print(\"site 4 info ->\", idx, ident, coords)\n", + "\n", + "# Find nearest neighbors of site 4\n", + "nn = sq.get_neighbors(4, k=1)\n", + "print(\"nearest neighbors of site 4 ->\", nn)\n", + "\n", + "# Get all unique nearest-neighbor pairs\n", + "pairs = sq.get_neighbor_pairs(k=1, unique=True)\n", + "print(\"unique NN pairs (first 8) ->\", pairs[:8], \"...\")" + ] + }, + { + "cell_type": "markdown", + "id": "2b54daaf", + "metadata": {}, + "source": [ + "### Visualize the square lattice and bonds\n", + "Use `.show()` to plot sites and optional bonds." + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "4e1327bf", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAdEAAAHWCAYAAAAoxrMjAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAATNdJREFUeJzt3Qe8FNXd//HfpYNKk44IKIJKVRQECxiplkA0SglSHsQERUWiBIhSjQUR0YgSlWZBEBE0FoooINJCs0sAQaQj0juy/9f3PM/sf++9e9u5ZffC5/16DdzdnZ09M3t2fnPqJIRCoZABAIAMy5PxtwAAACGIAgDgiSAKAIAngigAAJ4IogAAeCKIAgDgiSAKAIAngigAAJ4IogAAeCKIAqeJhIQEGzx4cI5/7qlTp6xWrVr2j3/8w+JJ+/bt7Y477sjUNrp27Wpnn322xaONGze673zEiBEWTxJilA9jhSCaS3377bd2++232wUXXGBFihSxUqVK2XXXXWf//ve/vbf5+OOP21VXXWWlS5e2QoUK2UUXXWS9e/e2Xbt2pev9Bw8etEGDBrkT6llnnWXnnnuu1atXzx544AHbunWrnc4mTJjgTh7Lly/P9LYOHz7sTkLz5s1L9tpHH30Udyeot956y37++Wfr1atXsuMRLMpP1atXd+vs2LEjvJ72MXI9LSVLlnT58M0334z6efv377chQ4ZY3bp1XYArXLiwy3N/+9vfEuUzPZ42bZp9+eWXFq9mz55t3bt3d+nPmzevValSJdZJQgbly+gbEB9++uknO3DggHXp0sUqVKjgTrw6Yfz+97+3f/3rX3b33XdneJsrVqxwQU9X8Oecc459//339sorr9iHH35oq1evdoExJSdOnHBB/IcffnBpuu+++1xQVbCfNGmS/eEPf3DpRNr0XSpISNOmTZMF0dGjR0cNpEeOHLF8+XL+J/3000+7PFOsWLFkrw0dOtSqVq1qR48etYULF9pLL73k9uGbb75xF3+B+++/36688kr39+7du23KlCnWqVMn27t3r917773h9X788Udr1qyZbdq0yV1EKp8XKFDAvvrqKxs7dqxNnz7d/vvf/7p1L7vsMrviiivsmWeesddee83ikX4b2tfLL7+c30dupQnocXo4efJkqG7duqEaNWpk2Tbfeecd3aAg9NZbb6W63ttvv+3We/PNN5O9duTIkdC+fftC8ergwYOZ3sb48ePd/v/nP//J9LZ27drltjVo0KBkr917773utXixcuVKl55PPvkkXcejT58+7vlJkya5x5999pl7PHXq1ETrHTt2LFSxYsVQ48aNw8+dOHHC5e8iRYqEPv/882RpUR4bMGBAoudGjBgROuuss0IHDhzw2r8uXbq492eXLVu2hI4fP+7+vummm0KVK1dO93s3bNjgjt3TTz8diieWQt49XVGdexpRdVClSpXc1Xvg008/tTx58tjAgQOTXQGr6kwlg9QE1UuR24xm/fr17v+rr7462WuqyitatGii52bMmOGqsPSa/lcJQu1PkdVZQVVf0mrNoC1IVYYBlUT0flVva5vlypWz//mf/3Glmkgqwem93333nXXs2NFKlChh11xzTfj1N954w+rXr++qCFWtqBKWqiqzwvHjx933oO2r1KaS/bXXXmufffZZon1TdbqoNBpUcSrd2j+VQiWy+jO1tqgtW7a46kKVcgoWLOhKhT179nRpCei7VbW98o7WqVatmj311FOurTMt+h5VElQtRHr87ne/c/9v2LAh1fW0TX03kSXroGr273//e6LvLKA8lrRdtnnz5nbo0CGbM2eOZRXVyug7Ui2BalsyQ99L/vz5M52mZ5991ipXruzybZMmTVxJPymdC5TflO+KFy9ubdq0cbVN0X4f69atc/lN6ymvduvWzdWQRDp27Jg9+OCD7lio5kq1YJs3b072uaoxU/7Sb1v5q0yZMu57WblypZ0OqM7N5XSCUDXevn377P3337ePP/7Y2rVrl+ikdc8999gTTzxhbdu2ddVG27Ztc9Wtqhb7y1/+kmh7upBU4Dl58qStXbvW+vXr54Jz0mrFpPQDFlWbPfLII4lO7tHagW677Ta79NJLXbr0efqRnnfeed7HQSdJVfVpOwqgqkZ++eWX3f9LlixJlh5VBarNV+3Awd0AdQJ+9NFHXWeUu+66y7UF//Of/3QBYtWqVe6Ekhlqy3v11VetQ4cO1qNHD3dyURVky5YtbdmyZa4qXSckXdgo0KkK/NZbb3XvrVOnjvuu1eanfX399dfT/Dyt26BBAxckVe158cUXu6D6zjvvuBOiApX+10lXz//5z3+2888/3xYtWmT9+/d3+WTUqFGpfobW1UVQegNBcLGl9vJIOha//PKL+/vXX391F3kK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lZvSm5vSKqT39EovHYsAAPBESRQAAE8EUQAAPBFEAQDwRBAFAMATQTQDRo8ebVWqVLFChQpZw4YNbdmyZamuP3XqVLv44ovd+rVr17aPPvoo0evq0zVw4EArX768FS5c2Jo1a2Zr166NSXpfeeUVu/baa61EiRJuUVqSrt+1a1c3g1Pk0qpVq5ikd8KECcnSovfl1PHNSFqbNm2aLK1abrrpphw5tgsWLLBbbrnFzb6i7c6YMSPN98ybN88uv/xy18OxWrVq7nhn9veQHWl99913rXnz5la6dGk3sL5Ro0Y2a9asROsMHjw42bHV7zIrZDS9Oq7R8sL27duz/dj6pDdavtRSs2bNbD++TzzxhF155ZVu5rgyZcpY27Ztbc2aNWm+L6fPuwTRdJoyZYr16dPHdZ1euXKl1a1b11q2bGk7d+6Muv6iRYusQ4cO1r17d1u1apXLAFq++eab8DrDhw+3559/3saMGWNLly61s846y23z6NGjOZ5e/biV3s8++8wWL17sps1q0aKFbdmyJdF6OrFv27YtvLz11luZTqtPekUnzci0/PTTT4lez67jm9G06kQfmU7lgbx589rtt9+eI8f20KFDLo06MafHhg0bXIC//vrrbfXq1da7d2+76667EgUnn+8rO9KqoKAgqhPlihUrXJoVJPSbi6STfuSxXbhwYabS6ZvegIJBZHoUJLL72Pqk97nnnkuUTk2lV7JkyWR5t2Y2HN/58+fbvffea0uWLLE5c+a4ieV1TtI+pCQm510NcUHaGjRoELr33nvDj3/77bdQhQoVQk888UTU9e+4447QTTfdlOi5hg0bhv785z+7v0+dOhUqV65c6Omnnw6/vnfv3lDBggVDb731Vo6nN6mTJ0+GzjnnnNDEiRPDz3Xp0iXUpk2bTKctK9I7fvz4ULFixVLcXnYe38we22effdYd24MHD+bIsY2kn/z06dNTXadv376hmjVrJnquXbt2oZYtW2bZMciqtEZz6aWXhoYMGRJ+PGjQoFDdunVD2S096f3ss8/cenv27ElxnZw4tulNb1JaPyEhIbRx48YcP747d+50aZ4/f36K68TivEtJNB2OHz/urnJV7I+cX1ePVWqLRs9Hri+62gnW19W+qnAi19Fcjaq6SWmb2ZnepHQrIV356aozaYlVV801atSwnj172u7duzOV1syk9+DB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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Draw square lattice on a provided Axes to avoid extra blank figures\n", + "fig, ax = plt.subplots(figsize=(5, 5))\n", + "sq.show(ax=ax, show_indices=True, show_bonds_k=1)\n", + "ax.set_title(\"3x3 Square Lattice (PBC), k=1 bonds\")\n", + "ax.set_aspect(\"equal\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "63118376", + "metadata": {}, + "source": [ + "## 2. Custom geometry: triangular fragment\n", + "For irregular or finite clusters, use `CustomizeLattice` with explicit coordinates and identifiers." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "7925359a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "neighbors of site 2 -> [0, 1, 4, 5]\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAdMAAAGlCAYAAAChhRxxAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAaI9JREFUeJztnQeYVOXVx89KX9ClswhSpXeQLr1LFQRFiUpQv6AmIagkmEhRPzEW1EQiakTQiEiVIr333hHpvZelL6zgfM//mHe+2d3Z3Zmdcu/M/f+e5z5zd+bOnbN33rnnfU+NcblcLiGEEEJIprkr828lhBBCCKAyJYQQQgKEypQQQggJECpTQgghJECoTAkhhJAAoTIlhBBCAoTKlBBCCAkQKlNCCCEkQKhMCSGEkAChMiVead68uW6RxrBhwyQmJiZsn/f1119LxYoVJVu2bJI3b96wfS4RKVWqlDz99NM+H9upUyeJNOwod6TeG0INlWmUAoXiy7Z06VKrRY1YfvrpJ72Zly1bVj7//HP57LPPrBbJFvz44486qTl8+HDUfK75vbz//vupXhs7dqy+tnHjxlSTuiJFisiNGzciQkmSwMga4PuJTcGKyZOvvvpKFixYkOr5SpUqeX3//PnzQypfNICJyC+//CIfffSR3H///VaLYxug1IYPH66rFyiNULFnzx656667wvq57777rvTv319iY2N9Ov7s2bPyySefyEsvvRQSeYh9oDKNUvr06ZPs77Vr16oyTfl8SjCLxo0ie/bs4nTQA+LmzZuSK1euNG+UICPzbkbnIZkjR44cYf28mjVrytatW2X06NEycOBAn98DBfz888/z+49yaOZ1MJjBV61aVTZt2iRNmzZVJfrqq6969YskJSXJkCFDpE6dOhIXFye5c+eWJk2ayJIlS5KdEyY2mLfee+89NXvCBIqbXt26dWXDhg2pZJg0aZJUrlxZcubMqbJMmzZNTaeeKwusAL2ZpM1nwcyWHl9++aW0bNlSChcurLLg87BaSMv0Nm/ePHnggQf05vfpp596PSeOHTp0qO4XKlRI5YBpL6Pz+CoLVrw437333qvfS4sWLXTlldJPaEyMK1eulD/84Q8qC5T7//zP/+h3dunSJXnyySclX758ug0aNEiVe8rP+vDDD6VKlSr6PcA0ifcnJCR4vT74rHr16umxZcqUUauH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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Define a small triangular fragment\n", + "tri_coords = [\n", + " [0.0, 0.0],\n", + " [1.0, 0.0],\n", + " [0.5, float(np.sqrt(3) / 2)], # triangle 1\n", + " [2.0, 0.0],\n", + " [1.5, float(np.sqrt(3) / 2)], # triangle 2\n", + " [1.0, float(np.sqrt(3))], # top site\n", + "]\n", + "tri_ids = list(range(len(tri_coords)))\n", + "tri = CustomizeLattice(dimensionality=2, identifiers=tri_ids, coordinates=tri_coords)\n", + "# Compute nearest neighbors on demand (k=1)\n", + "print(\"neighbors of site 2 ->\", tri.get_neighbors(2, k=1))\n", + "\n", + "# Draw triangular fragment on a provided Axes\n", + "fig, ax = plt.subplots(figsize=(5, 5))\n", + "tri.show(ax=ax, show_indices=True, show_bonds_k=1)\n", + "ax.set_title(\"Triangular fragment with NN bonds\")\n", + "ax.set_aspect(\"equal\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "6c276e82", + "metadata": {}, + "source": [ + "## 3. From geometry to Hamiltonians\n", + "We can build sparse physics Hamiltonians directly from lattice connectivity and coordinates." + ] + }, + { + "cell_type": "markdown", + "id": "978c629c", + "metadata": {}, + "source": [ + "### 3.1 Heisenberg model on a 2x2 square lattice\n", + "Nearest-neighbor Heisenberg: H = J Σ⟨i,j⟩ (X_i X_j + Y_i Y_j + Z_i Z_j)." + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "9147ff4b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Heisenberg(H) shape: (16, 16)\n", + "Hermitian check -> True\n" + ] + } + ], + "source": [ + "sq22 = SquareLattice(size=(2, 2), pbc=True)\n", + "Hh = heisenberg_hamiltonian(sq22, j_coupling=1.0, interaction_scope=\"neighbors\")\n", + "print(\"Heisenberg(H) shape:\", Hh.shape)\n", + "Hd = tc.backend.to_dense(Hh)\n", + "print(\"Hermitian check ->\", np.allclose(Hd, Hd.conj().T))" + ] + }, + { + "cell_type": "markdown", + "id": "f8c63286", + "metadata": {}, + "source": [ + "### 3.2 Rydberg atom array Hamiltonian\n", + "Includes on-site drive/detuning and distance-dependent interactions V_ij = C6/|r_i-r_j|^6." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "25fe2372", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Rydberg(H) shape: (4, 4)\n" + ] + }, + { + "data": { + "text/plain": [ + "Array([[-0.71947874+0.j, 0.5 +0.j, 0.5 +0.j,\n", + " 0. +0.j],\n", + " [ 0.5 +0.j, -0.21947874+0.j, 0. +0.j,\n", + " 0.5 +0.j],\n", + " [ 0.5 +0.j, 0. +0.j, -0.21947874+0.j,\n", + " 0.5 +0.j],\n", + " [ 0. +0.j, 0.5 +0.j, 0.5 +0.j,\n", + " 1.15843621+0.j]], dtype=complex128)" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "chain2 = ChainLattice(size=(2,), pbc=False, lattice_constant=1.5)\n", + "Hr = rydberg_hamiltonian(chain2, omega=1.0, delta=-0.5, c6=10.0)\n", + "print(\"Rydberg(H) shape:\", Hr.shape)\n", + "tc.backend.to_dense(Hr) # display" + ] + }, + { + "cell_type": "markdown", + "id": "c814e2af", + "metadata": {}, + "source": [ + "## 4. Gate layering for NN two-qubit gates\n", + "To schedule parallel two-qubit gates on neighbors, group edges into disjoint layers." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "a0553ad7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of layers: 5\n", + "Layer 0 : [(0, 1), (2, 5), (3, 4), (6, 7)] \n", + "Layer 1 : [(0, 2), (1, 4), (3, 5), (6, 8)] \n", + "Layer 2 : [(0, 3), (1, 2), (4, 5), (7, 8)] \n", + "Layer 3 : [(0, 6), (1, 7), (2, 8)] \n", + "Layer 4 : [(3, 6), (4, 7), (5, 8)] \n" + ] + } + ], + "source": [ + "pairs = sq.get_neighbor_pairs(k=1, unique=True)\n", + "layers = get_compatible_layers(pairs)\n", + "print(\"Number of layers:\", len(layers))\n", + "for li, layer in enumerate(layers):\n", + " head = layer[:6]\n", + " suffix = \" ...\" if len(layer) > 6 else \"\"\n", + " print(\"Layer\", li, \":\", head, suffix)" + ] + }, + { + "cell_type": "markdown", + "id": "19bafac9", + "metadata": {}, + "source": [ + "## 5. Differentiable geometry: optimize lattice constant (Lennard-Jones)\n", + "\n", + "Below we demonstrate optimizing a geometric parameter (the lattice constant) using automatic differentiation.\n", + "We use a Lennard-Jones potential over all pairs as a simple, geometry-driven objective." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "3c417cdb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "iter 20: E=-20.305588, a=1.116975\n", + "iter 40: E=-20.495401, a=1.104924\n", + "iter 60: E=-20.516659, a=1.099829\n", + "iter 80: E=-20.516122, a=1.100113\n", + "Final: E=-20.516308 a=1.100113\n" + ] + } + ], + "source": [ + "import optax\n", + "\n", + "\n", + "# Define a differentiable objective with log(a) parameterization to keep a>0\n", + "def lj_total_energy(log_a, epsilon=0.5, sigma=1.0, size=(4, 4)):\n", + " a = K.exp(log_a)\n", + " lat = SquareLattice(size=size, pbc=True, lattice_constant=a)\n", + " d = lat.distance_matrix\n", + " # More robust distance handling to avoid numerical issues\n", + " d_safe = K.where(\n", + " d > 1e-6, d, K.convert_to_tensor(1e6)\n", + " ) # Large value for self-interactions\n", + " term12 = K.power(sigma / d_safe, 12)\n", + " term6 = K.power(sigma / d_safe, 6)\n", + " e_mat = 4.0 * epsilon * (term12 - term6)\n", + " n = lat.num_sites\n", + " # Zero out diagonal (self-interactions) more explicitly\n", + " mask = 1.0 - K.eye(n, dtype=e_mat.dtype)\n", + " e_mat = e_mat * mask\n", + " total_energy = K.sum(e_mat) / 2.0 # each pair counted twice\n", + " return total_energy\n", + "\n", + "\n", + "val_and_grad = K.jit(K.value_and_grad(lj_total_energy))\n", + "opt = optax.adam(learning_rate=0.02)\n", + "log_a = K.convert_to_tensor(K.log(K.convert_to_tensor(1.2)))\n", + "state = opt.init(log_a)\n", + "\n", + "hist_a = []\n", + "hist_e = []\n", + "for it in range(80):\n", + " e, g = val_and_grad(log_a)\n", + " hist_a.append(K.exp(log_a))\n", + " hist_e.append(e)\n", + " upd, state = opt.update(g, state)\n", + " log_a = optax.apply_updates(log_a, upd)\n", + " if (it + 1) % 20 == 0:\n", + " print(f\"iter {it+1}: E={float(e):.6f}, a={float(K.exp(log_a)):.6f}\")\n", + "\n", + "final_a = K.exp(log_a)\n", + "final_e = lj_total_energy(log_a)\n", + "print(\"Final:\", f\"E={float(final_e):.6f}\", f\"a={float(final_a):.6f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "66d7b54a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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n/a0OnlafQDr5B6wTu4B62Qbetupt6U5QcEhIteuXVPzSpUqObsohBBCiNu2pWFhYTmu99HykiReQGZmppw/f16KFSumRvO0l+KDgDlz5oyEhoaKJ+BpdfK0+gDWyT1gndwD1sk2ICMgNsqXLy++GI8pB2jhUONV+UpFB3XnjAvqKTeqp9bJ0+oDWCf3gHVyD1invMnNsqHDoFFCCCGEOBwKDkIIIYQ4HAoOBxEYGCjjx49Xc0/B0+rkafUBrJN7wDq5B6yTfWHQKCGEEEIcDi0chBBCCHE4FByEEEIIcTgUHIQQQghxOBQchBBCCHE4FBw3wYwZM6RKlSoSFBQkLVu2lK1bt+a6/fTp06V27doSHBysenobPny4JCcni7vWCX3yT5w4UapXr662b9y4sSxbtkxchXXr1knPnj1V73foQfaXX37J8ztr1qyRW265RUVw16hRQ+bMmSOuRH7rdOHCBXn00UelVq1aqoO7YcOGiauR3zr9/PPP0qVLFyldurTquKh169by559/ijvXaf369dK2bVspWbKkej7UqVNHpk2bJu78W9LZsGGD+Pn5SZMmTcSVyG+d8GzAdpZTVFSUuPN1SklJkVdeeUUiIyPVcw/P/6+++soh5aPgKCALFiyQESNGqPSinTt3qsa2W7duEh0dbXX7efPmyUsvvaS2P3jwoMyaNUvt4+WXXxZ3rdO4cePks88+k48++kgOHDggzz77rPTu3Vt27dolrsD169dVHSCibOHEiRPSo0cPuf3222X37t2qcf7f//7nUo1ZfuuEhwkaZlwrfM8VyW+d8FCF4Fi6dKns2LFDXS88ZF3lvitInYoUKSJDhgxRdcPzAdcL0+effy7uWB+d2NhY6devn9xxxx3iahS0TocOHVJCXp/KlCkj7lynhx56SFauXKnaJNTt+++/Vy/GDgFpsST/tGjRQnvuueeMnzMyMrTy5ctrkydPtro9tu3UqZPZshEjRmht27bV3LVO5cqV0z7++GOzZffdd5/22GOPaa4GbvVFixblus3o0aO1+vXrmy3r06eP1q1bN80VsaVOpnTo0EF74YUXNFcmv3XSqVevnjZhwgTNk+rUu3dv7fHHH9fcuT74/YwbN04bP3681rhxY81VsaVOq1evVttdvXpVcwfEhjr98ccfWlhYmHb58uVCKRMtHAUgNTVVvVl17tzZ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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plot energy curve and optimization steps\n", + "# sample a-curve (NumPy for speed is fine)\n", + "a_grid = np.linspace(0.8, 1.6, 120)\n", + "\n", + "\n", + "def lj_energy_np(a, epsilon=0.5, sigma=1.0, size=(4, 4)):\n", + " lat = SquareLattice(size=size, pbc=True, lattice_constant=float(a))\n", + " d = lat.distance_matrix\n", + " d = np.asarray(d)\n", + " n = d.shape[0]\n", + " mask = ~np.eye(n, dtype=bool)\n", + " ds = d[mask]\n", + " ds = np.where(ds > 1e-9, ds, 1e-9)\n", + " e = 4 * epsilon * (np.sum((sigma / ds) ** 12 - (sigma / ds) ** 6)) / 2.0\n", + " return float(e)\n", + "\n", + "\n", + "e_grid = [lj_energy_np(a) for a in a_grid]\n", + "\n", + "# convert hist tensors to floats\n", + "hist_a_f = [float(x) for x in hist_a]\n", + "hist_e_f = [float(x) for x in hist_e]\n", + "fa = float(final_a)\n", + "fe = float(final_e)\n", + "\n", + "plt.figure(figsize=(6, 4))\n", + "plt.plot(a_grid, e_grid, label=\"LJ potential\")\n", + "plt.scatter(hist_a_f, hist_e_f, s=18, color=\"tab:red\", label=\"opt steps\")\n", + "plt.scatter([fa], [fe], s=80, color=\"tab:green\", marker=\"*\", label=\"final\")\n", + "plt.xlabel(\"lattice constant a\")\n", + "plt.ylabel(\"total energy\")\n", + "plt.title(\"Differentiable geometry optimization (4x4 square, PBC)\")\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "165c0bca", + "metadata": {}, + "source": [ + "### Summary of differentiable demo\n", + "- The lattice constant `a` was treated as a differentiable parameter via `log(a)` reparameterization.\n", + "- We computed the Lennard-Jones energy using lattice distances and optimized it with Adam.\n", + "- For a full script and more iterations, see `examples/lennard_jones_optimization.py`." + ] + }, + { + "cell_type": "markdown", + "id": "22d9f903", + "metadata": {}, + "source": [ + "# Further Reading and Resources\n", + "\n", + "## API Reference\n", + "- **Core lattice classes**: `tensorcircuit/templates/lattice.py` - All lattice geometry classes\n", + "- **Hamiltonian utilities**: `tensorcircuit/templates/hamiltonians.py` - Physics Hamiltonian builders\n", + "\n", + "## Complete Examples\n", + "Explore these examples in the `examples/` directory:\n", + "- **`lennard_jones_optimization.py`** - Full differentiable geometry optimization with JAX/Optax\n", + "- **`lattice_neighbor_benchmark.py`** - Performance comparison for different neighbor-finding algorithms\n", + "\n", + "## Test Suite and Validation\n", + "The test suites showcase rich usage patterns and provide validation:\n", + "- **`tests/test_lattice.py`** - Comprehensive lattice functionality tests\n", + "- **`tests/test_hamiltonians.py`** - Physics Hamiltonian validation against analytical results\n", + "\n", + "## Key Features Demonstrated\n", + "āœ… **Unified API** for both regular and custom geometries \n", + "āœ… **Efficient neighbor finding** with configurable interaction shells \n", + "āœ… **Interactive visualization** with bonds and site labeling \n", + "āœ… **Physics-ready Hamiltonians** from geometric connectivity \n", + "āœ… **Parallel gate scheduling** for quantum circuit optimization \n", + "āœ… **Differentiable parameters** for variational material design \n", + "\n", + "## Performance Tips & Best Practices\n", + "\n", + "### For Large Systems (N > 1000 sites):\n", + "- Use `CustomizeLattice` with KDTree neighbor building for better scalability\n", + "- Consider sparse representations for distance-dependent interactions\n", + "- Pre-compute neighbors with `_build_neighbors(max_k=...)` once\n", + "\n", + "### Backend Selection:\n", + "- **JAX**: Best for differentiable geometry and automatic differentiation\n", + "- **NumPy**: Simple and reliable for static lattice analysis\n", + "- **TensorFlow/PyTorch**: For integration with existing ML pipelines\n", + "\n", + "### Memory Efficiency:\n", + "- Distance matrices scale as O(N²) - use neighbor lists for very large systems\n", + "- For visualization: use `show_bonds_k=0` for large lattices to show only sites\n", + "\n", + "### Precision Considerations:\n", + "- Use `tc.set_dtype(\"complex128\")` for high-precision physics calculations\n", + "- Set `JAX_ENABLE_X64=True` to avoid precision warnings with complex numbers\n", + "\n", + "---\n", + "\n", + "**šŸŽÆ Next Steps**: Try building your own custom lattice geometry or implementing a new physics Hamiltonian using this framework!" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "id": "921ef23d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "OS info: Windows-10-10.0.26100-SP0\n", + "Python version: 3.10.5\n", + "Numpy version: 1.26.4\n", + "Scipy version: 1.15.3\n", + "Pandas version: 2.3.0\n", + "TensorNetwork version: 0.5.1\n", + "Cotengra version: 0.7.5\n", + "TensorFlow version: 2.15.1\n", + "TensorFlow GPU: []\n", + "TensorFlow CUDA infos: {'is_cuda_build': False, 'is_rocm_build': False, 'is_tensorrt_build': False, 'msvcp_dll_names': 'msvcp140.dll,msvcp140_1.dll'}\n", + "Jax version: 0.4.34\n", + "Jax installation doesn't support GPU\n", + "JaxLib version: 0.4.34\n", + "PyTorch version: 2.7.1+cpu\n", + "PyTorch GPU support: False\n", + "PyTorch GPUs: []\n", + "Cupy is not installed\n", + "Qiskit version: 2.1.1\n", + "Cirq version: 1.5.0\n", + "TensorCircuit version 1.3.0\n", + "None\n", + "\n", + "šŸŽ‰ Tutorial completed successfully! You're now ready to use the lattice API in your quantum simulations.\n" + ] + } + ], + "source": [ + "# Environment info for reproducibility\n", + "print(tc.about())\n", + "print(\n", + " \"\\nšŸŽ‰ Tutorial completed successfully! You're now ready to use the lattice API in your quantum simulations.\"\n", + ")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "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.10.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}