{ "cells": [ { "cell_type": "markdown", "id": "66b4a2f2-46a1-44a1-8207-43c76389af74", "metadata": {}, "source": [ "# Basics of Tree Tensor Networks\n", "\n", "## Overview\n", "Tree tensor network state (TTNS) and tree tensor network operator (TTNO) are generalizations of MPS and MPO.\n", "In this notebook, we will show how to define tree tensor network states in Renormalizer. Overall the interfaces for tree tensor networks are very similar to that of the matrix product states.\n", "The biggest difference is how we define the model (tree structure), which we will describe in detail in the following." ] }, { "cell_type": "markdown", "id": "4891d395-b8f4-4e78-9df7-36317393b8c0", "metadata": {}, "source": [ "## Defining a Tree\n", "The tree structure in Renormalizer is specified through `BasisTree`, i.e., a tree of basis sets.\n", "This is similar to the list of basis sets for the definition of MPS.\n", "\n", "The tree node of `BasisTree` is `TreeNodeBasis`. In the following we'll construct a number of `TreeNodeBasis`s and connect them as a tree." ] }, { "cell_type": "code", "execution_count": 1, "id": "bca5f57b-713d-4d9f-a17e-5ed520d82912", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:38.568233Z", "iopub.status.busy": "2026-10-14T01:46:38.567954Z", "iopub.status.idle": "2026-10-14T01:46:39.716668Z", "shell.execute_reply": "2026-10-14T01:46:39.715762Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2026-10-14 01:46:38,865[INFO] Use numpy as backend\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026-10-14 01:46:38,867[INFO] numpy random seed is 9012\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026-10-14 01:46:38,867[INFO] backend random seed is 2019\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026-10-14 01:46:38,868[INFO] random seed is 1092\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026-10-14 01:46:38,875[INFO] Git Commit Hash: 3507afde83fd6f408c1c2198aad4dfe455d88312\n" ] } ], "source": [ "from renormalizer import BasisHalfSpin\n", "from renormalizer.tn import TreeNodeBasis, BasisTree" ] }, { "cell_type": "code", "execution_count": 2, "id": "304fd8da-2649-42c9-86d6-2e8ccc5c727b", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.718830Z", "iopub.status.busy": "2026-10-14T01:46:39.718556Z", "iopub.status.idle": "2026-10-14T01:46:39.725200Z", "shell.execute_reply": "2026-10-14T01:46:39.724435Z" } }, "outputs": [ { "data": { "text/plain": [ "[BasisHalfSpin(dof: 0, nbas: 2),\n", " BasisHalfSpin(dof: 1, nbas: 2),\n", " BasisHalfSpin(dof: 2, nbas: 2),\n", " BasisHalfSpin(dof: 3, nbas: 2),\n", " BasisHalfSpin(dof: 4, nbas: 2)]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# some spin DOF for future usage\n", "spins = [BasisHalfSpin(i) for i in range(5)]\n", "spins" ] }, { "cell_type": "code", "execution_count": 3, "id": "25278cba-0295-486d-a93f-5bbbdc619de2", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.727026Z", "iopub.status.busy": "2026-10-14T01:46:39.726844Z", "iopub.status.idle": "2026-10-14T01:46:39.729791Z", "shell.execute_reply": "2026-10-14T01:46:39.728848Z" } }, "outputs": [], "source": [ "# construct tree nodes. One node for one basis set\n", "nodes = [TreeNodeBasis(basis) for basis in spins]" ] }, { "cell_type": "markdown", "id": "f745cc9b-2776-4fe1-9c16-ca6c2d7831c8", "metadata": {}, "source": [ "Tree nodes are can connected together by the ``add_child`` function. We first pick a root and then add two children to the root" ] }, { "cell_type": "code", "execution_count": 4, "id": "5c53cfa1-c843-4ed3-a6c8-562daebc6b73", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.731389Z", "iopub.status.busy": "2026-10-14T01:46:39.731238Z", "iopub.status.idle": "2026-10-14T01:46:39.734858Z", "shell.execute_reply": "2026-10-14T01:46:39.734088Z" } }, "outputs": [ { "data": { "text/plain": [ "TreeNodeBasis(BasisHalfSpin(dof: 0, nbas: 2))" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "root = nodes[0]\n", "root.add_child(nodes[1:3])" ] }, { "cell_type": "markdown", "id": "ed87c607-01a7-4a60-89da-74205b3f3be7", "metadata": {}, "source": [ "We can check they are already connected through ``.children`` and ``.parent`` attributes. Note that a node can have multiple children but can only have one parent." ] }, { "cell_type": "code", "execution_count": 5, "id": "dfa757c3-1ce2-47be-bfb5-6941c333372d", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.736522Z", "iopub.status.busy": "2026-10-14T01:46:39.736368Z", "iopub.status.idle": "2026-10-14T01:46:39.740415Z", "shell.execute_reply": "2026-10-14T01:46:39.739366Z" } }, "outputs": [ { "data": { "text/plain": [ "[TreeNodeBasis(BasisHalfSpin(dof: 1, nbas: 2)),\n", " TreeNodeBasis(BasisHalfSpin(dof: 2, nbas: 2))]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "root.children" ] }, { "cell_type": "code", "execution_count": 6, "id": "771dfe52-7dac-447e-9fab-2682c2e451a3", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.741929Z", "iopub.status.busy": "2026-10-14T01:46:39.741745Z", "iopub.status.idle": "2026-10-14T01:46:39.745451Z", "shell.execute_reply": "2026-10-14T01:46:39.744677Z" } }, "outputs": [ { "data": { "text/plain": [ "TreeNodeBasis(BasisHalfSpin(dof: 0, nbas: 2))" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "nodes[1].parent" ] }, { "cell_type": "markdown", "id": "8cae1287-eeea-4dfe-a67c-72d0778544d4", "metadata": {}, "source": [ "We then connect the rest of the nodes to one of the children" ] }, { "cell_type": "code", "execution_count": 7, "id": "557c7b54-fb5c-401a-8db8-7a3acf1e9b7a", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.747268Z", "iopub.status.busy": "2026-10-14T01:46:39.747118Z", "iopub.status.idle": "2026-10-14T01:46:39.750826Z", "shell.execute_reply": "2026-10-14T01:46:39.750025Z" } }, "outputs": [ { "data": { "text/plain": [ "TreeNodeBasis(BasisHalfSpin(dof: 1, nbas: 2))" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "root.children[0].add_child(nodes[3:])" ] }, { "cell_type": "markdown", "id": "f4b12c95-2ffc-4503-89ce-8cb170f372c2", "metadata": {}, "source": [ "Now all of the nodes are connected, we can construct the tree by feeding the root node to the `BasisTree` class. \n", "\n", "We can visualize the tree structure through the `print` function, which shows the degrees of freedom in the tree." ] }, { "cell_type": "code", "execution_count": 8, "id": "e4e84ba5-5265-45a8-9a7a-dcffae16153b", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.752534Z", "iopub.status.busy": "2026-10-14T01:46:39.752382Z", "iopub.status.idle": "2026-10-14T01:46:39.755996Z", "shell.execute_reply": "2026-10-14T01:46:39.755104Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "   ┌[(3,)]\n", " ┌[(1,)]┤\n", " │ └[(4,)]\n", "[(0,)]┤\n", " └[(2,)]\n" ] } ], "source": [ "tree = BasisTree(root)\n", "tree.print()" ] }, { "cell_type": "markdown", "id": "4ce9bcb0-8e3b-4f3b-aff0-8cfbd7976799", "metadata": {}, "source": [ "All nodes in a tree, including ``TTNS`` and ``TTNO``, can be accessed via a list, according to [pre-order traversal](https://en.wikipedia.org/wiki/Tree_traversal#Pre-order,_NLR)." ] }, { "cell_type": "code", "execution_count": 9, "id": "1265a011-6997-4966-84ec-3a237c35c097", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.757555Z", "iopub.status.busy": "2026-10-14T01:46:39.757386Z", "iopub.status.idle": "2026-10-14T01:46:39.761353Z", "shell.execute_reply": "2026-10-14T01:46:39.760447Z" } }, "outputs": [ { "data": { "text/plain": [ "[TreeNodeBasis(BasisHalfSpin(dof: 0, nbas: 2)),\n", " TreeNodeBasis(BasisHalfSpin(dof: 1, nbas: 2)),\n", " TreeNodeBasis(BasisHalfSpin(dof: 3, nbas: 2)),\n", " TreeNodeBasis(BasisHalfSpin(dof: 4, nbas: 2)),\n", " TreeNodeBasis(BasisHalfSpin(dof: 2, nbas: 2))]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tree.node_list" ] }, { "cell_type": "markdown", "id": "36d84392-d96c-48a3-bf75-aa8e5d0676b7", "metadata": {}, "source": [ "The `BasisTree` object can be considered as immutable. If a new tree is desired by modifying the existing tree, the `BasisTree` instance should be recreated with the corresponding root node." ] }, { "cell_type": "markdown", "id": "081fdf6f-50db-49da-9d39-12561d3081a3", "metadata": {}, "source": [ "## Advanced Tree Structure\n", "\n", "In the example above, the number of `BasisSet`s in each node is one. Renormalizer permits any number of `BasisSet`s for each node.\n", "\n", "First of all, if no `BasisSet` is provided, the node will become purely virtual and will not associated with any physical degree of freedom.\n", "A dummy basis set is attached to the node for programming convenience.\n", "The dimension of the Hilbert space of this dummy degree of freedom is 1 and the only allowed operator is identity." ] }, { "cell_type": "code", "execution_count": 10, "id": "18922854-3f98-46b3-9fd4-44bdef8c52a8", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.762948Z", "iopub.status.busy": "2026-10-14T01:46:39.762773Z", "iopub.status.idle": "2026-10-14T01:46:39.766540Z", "shell.execute_reply": "2026-10-14T01:46:39.765737Z" } }, "outputs": [ { "data": { "text/plain": [ "TreeNodeBasis(BasisDummy(dof: ('Virtual DOF', 0), nbas: 1))" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "node1 = TreeNodeBasis()\n", "node1" ] }, { "cell_type": "markdown", "id": "601b79fa-7e14-49e0-a81c-3966b3a31e87", "metadata": {}, "source": [ "In addition, each tree node can have multiple associated `BasisSet`." ] }, { "cell_type": "code", "execution_count": 11, "id": "8e40d4c3-e5cf-401d-b210-16f0e533b241", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.768237Z", "iopub.status.busy": "2026-10-14T01:46:39.768088Z", "iopub.status.idle": "2026-10-14T01:46:39.772026Z", "shell.execute_reply": "2026-10-14T01:46:39.771106Z" } }, "outputs": [ { "data": { "text/plain": [ "TreeNodeBasis(BasisHalfSpin(dof: 0, nbas: 2), BasisHalfSpin(dof: 1, nbas: 2), BasisHalfSpin(dof: 2, nbas: 2))" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "node2 = TreeNodeBasis([BasisHalfSpin(i) for i in range(3)])\n", "node2" ] }, { "cell_type": "markdown", "id": "8036cb38-4f67-4baf-be6e-25d250d208cb", "metadata": {}, "source": [ "Since building the tree structure can be tedious, Rernomalizer has a number of builtin tree structure that can be used out of box.\n", "The most simple example is the MPS (linear) tree strucure." ] }, { "cell_type": "code", "execution_count": 12, "id": "d8477d77-5c42-4855-a629-bfdfeb3ab586", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.773505Z", "iopub.status.busy": "2026-10-14T01:46:39.773340Z", "iopub.status.idle": "2026-10-14T01:46:39.776936Z", "shell.execute_reply": "2026-10-14T01:46:39.776185Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "[(0,)]─[(1,)]─[(2,)]─[(3,)]─[(4,)]\n" ] } ], "source": [ "BasisTree.linear([BasisHalfSpin(i) for i in range(5)]).print()" ] }, { "cell_type": "markdown", "id": "d6e8c2d3-0ff7-45fa-8eda-70cd620a1ec5", "metadata": {}, "source": [ "Another example is simple binary tree" ] }, { "cell_type": "code", "execution_count": 13, "id": "660a5757-7790-4f75-a950-c9fb1c2b708c", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.778705Z", "iopub.status.busy": "2026-10-14T01:46:39.778558Z", "iopub.status.idle": "2026-10-14T01:46:39.782194Z", "shell.execute_reply": "2026-10-14T01:46:39.781169Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "   ┌[(3,)]\n", " ┌[(1,)]┤\n", " │ └[(4,)]\n", "[(0,)]┤\n", " │ ┌[(5,)]\n", " └[(2,)]┤\n", "   └[(6,)]\n" ] } ], "source": [ "BasisTree.binary([BasisHalfSpin(i) for i in range(7)]).print()" ] }, { "cell_type": "markdown", "id": "c7b071db-6eb7-411c-9205-3246544e2019", "metadata": {}, "source": [ "Another frequent tree structure is the \"MCTDH-style\" tree, or hierarchical Tucker format.\n", "\n", "The feature of this type of tree is that all physical degrees of freedom are attached to the leaf nodes.\n", "Also, each leaf node typically has more than one physical degrees of freedom.\n", "\n", "The following shows this type of tree with a binary structure and a ternary structure" ] }, { "cell_type": "code", "execution_count": 14, "id": "7f9ec768-236f-4db0-a93d-06049b8bad1a", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.783747Z", "iopub.status.busy": "2026-10-14T01:46:39.783581Z", "iopub.status.idle": "2026-10-14T01:46:39.787364Z", "shell.execute_reply": "2026-10-14T01:46:39.786555Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "   ┌[(0,), (1,)]\n", " ┌[(('MCTDH virtual', 1),)]┤\n", " │ └[(2,), (3,)]\n", "[(('MCTDH virtual', 0),)]┤\n", " │ ┌[(4,), (5,)]\n", " └[(('MCTDH virtual', 2),)]┤\n", "   └[(6,), (7,)]\n" ] } ], "source": [ "BasisTree.binary_mctdh([BasisHalfSpin(i) for i in range(8)]).print()" ] }, { "cell_type": "code", "execution_count": 15, "id": "be27b9a4-ad39-4019-a82c-06098d62ed04", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.789025Z", "iopub.status.busy": "2026-10-14T01:46:39.788842Z", "iopub.status.idle": "2026-10-14T01:46:39.792070Z", "shell.execute_reply": "2026-10-14T01:46:39.791233Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", " ┌[(0,), (1,), (2,)]\n", "[(('MCTDH virtual', 0),)]┼[(3,), (4,), (5,)]\n", " └[(6,), (7,), (8,)]\n" ] } ], "source": [ "BasisTree.ternary_mctdh([BasisHalfSpin(i) for i in range(9)]).print()" ] }, { "cell_type": "markdown", "id": "650c934c-3492-44dc-962f-e06b8f97ca92", "metadata": {}, "source": [ "Note that the internal nodes (non-leaf nodes) is not associated with any physical degree of freedom and a virtual degree of freedom is attached." ] }, { "cell_type": "markdown", "id": "9a10b61b-1da2-49b9-beaa-e0611d5cf38d", "metadata": {}, "source": [ "## TTNS and TTNO\n", "Having defined the tree structure using `BasisTree`. We can now construct TTNS and TTNO accordingly.\n", "The interfaces are very similar to that of MPS, but `BasisTree` take over the roles of `Model`.\n", "With this modification it is more convenient to perform TTNO/TTNS algebra when the idea of the Hamiltonian is not well defined, such as in the case of quantum circuit simulation.\n", "\n", "We recommend reading previous tutorials if the following code seems to be too complicated." ] }, { "cell_type": "markdown", "id": "e0896c15-b4f8-4150-abc0-14ee1d9e65dc", "metadata": {}, "source": [ "### TTNS\n", "We first construct TTNS based on a complete binary spin tree with 7 sites in total." ] }, { "cell_type": "code", "execution_count": 16, "id": "5fac4366-805b-4464-b608-9ac7915ad8b0", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.793974Z", "iopub.status.busy": "2026-10-14T01:46:39.793788Z", "iopub.status.idle": "2026-10-14T01:46:39.796998Z", "shell.execute_reply": "2026-10-14T01:46:39.796209Z" } }, "outputs": [], "source": [ "from renormalizer.tn import TTNS, TTNO\n", "basis = BasisTree.binary([BasisHalfSpin(i) for i in range(7)])" ] }, { "cell_type": "code", "execution_count": 17, "id": "09040eb5-e46b-437c-8537-c5db6ae2c33b", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.798634Z", "iopub.status.busy": "2026-10-14T01:46:39.798487Z", "iopub.status.idle": "2026-10-14T01:46:39.805503Z", "shell.execute_reply": "2026-10-14T01:46:39.804577Z" } }, "outputs": [ { "data": { "text/plain": [ " with 7 nodes" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ttns = TTNS.random(basis, qntot=0, m_max=5)\n", "ttns" ] }, { "cell_type": "markdown", "id": "be8d5809-452d-49be-9920-0e563a43b7ad", "metadata": {}, "source": [ "Each node in ``TTNS`` is a ``TreeNodeTensor`` whose core data is the numerical tensor.\n", "The tensor indices are arranged as follows: indices to the children, physical indices (if any) and the index to the parent." ] }, { "cell_type": "code", "execution_count": 18, "id": "1d859d1b-1cc5-448e-af1a-73d91784492a", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.807203Z", "iopub.status.busy": "2026-10-14T01:46:39.807055Z", "iopub.status.idle": "2026-10-14T01:46:39.810928Z", "shell.execute_reply": "2026-10-14T01:46:39.810019Z" } }, "outputs": [ { "data": { "text/plain": [ "[TreeNodeTensor((5, 5, 2, 1),float64),\n", " TreeNodeTensor((2, 2, 2, 5),float64),\n", " TreeNodeTensor((2, 2),float64),\n", " TreeNodeTensor((2, 2),float64),\n", " TreeNodeTensor((2, 2, 2, 5),float64),\n", " TreeNodeTensor((2, 2),float64),\n", " TreeNodeTensor((2, 2),float64)]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ttns.node_list" ] }, { "cell_type": "code", "execution_count": 19, "id": "63549a24-0510-4cd8-97b9-23a64954f54c", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.812488Z", "iopub.status.busy": "2026-10-14T01:46:39.812342Z", "iopub.status.idle": "2026-10-14T01:46:39.816001Z", "shell.execute_reply": "2026-10-14T01:46:39.815230Z" } }, "outputs": [ { "data": { "text/plain": [ "array([[-0.3001646 , 0.95388742],\n", " [-0.95388742, -0.3001646 ]])" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ttns.node_list[2].tensor" ] }, { "cell_type": "code", "execution_count": 20, "id": "9b7b37f0-b52f-4f7d-919f-8cf5e3e28a1e", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.817543Z", "iopub.status.busy": "2026-10-14T01:46:39.817392Z", "iopub.status.idle": "2026-10-14T01:46:39.841769Z", "shell.execute_reply": "2026-10-14T01:46:39.840868Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2026-10-14 01:46:39,818[DEBUG] # of operator terms: 1\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026-10-14 01:46:39,819[DEBUG] Input operator terms: 1\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026-10-14 01:46:39,820[DEBUG] After combination of the same terms: 1\n" ] }, { "data": { "text/plain": [ "{0: array([[ 0.4740985 , -0.14972037],\n", " [-0.14972037, 0.5259015 ]]),\n", " 1: array([[ 0.4537315, -0.0110545],\n", " [-0.0110545, 0.5462685]]),\n", " 2: array([[ 0.60091036, -0.04768257],\n", " [-0.04768257, 0.39908964]]),\n", " 3: array([[0.53667262, 0.05222021],\n", " [0.05222021, 0.46332738]]),\n", " 4: array([[0.37583785, 0.04340422],\n", " [0.04340422, 0.62416215]]),\n", " 5: array([[0.5363176 , 0.04671489],\n", " [0.04671489, 0.4636824 ]]),\n", " 6: array([[ 0.45690134, -0.05808942],\n", " [-0.05808942, 0.54309866]])}" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ttns.calc_1site_rdm()" ] }, { "cell_type": "markdown", "id": "c0bea77c-d57a-4db8-8d3e-448c27ee6f7a", "metadata": {}, "source": [ "``TTNS`` by default will construct a hartree product state given the basis tree" ] }, { "cell_type": "code", "execution_count": 21, "id": "a0235b24-0834-4b08-88f4-44fc03163575", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.843555Z", "iopub.status.busy": "2026-10-14T01:46:39.843264Z", "iopub.status.idle": "2026-10-14T01:46:39.848066Z", "shell.execute_reply": "2026-10-14T01:46:39.847173Z" } }, "outputs": [ { "data": { "text/plain": [ "[1, 1, 1, 1, 1, 1, 1]" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "TTNS(basis).bond_dims" ] }, { "cell_type": "markdown", "id": "1553a943-0013-4078-bc0d-bd365c1d797b", "metadata": {}, "source": [ "The bond dimension is the dimension of the parent index for each node in pre-order traversal." ] }, { "cell_type": "markdown", "id": "6ce2e5cf-7aa3-45a4-86f4-6286c5dac123", "metadata": {}, "source": [ "### TTNO\n", "We next turn to TTNO.\n", "We will boroow the testing Holstein Hamiltonian for MPS to illustrate TTNO construction." ] }, { "cell_type": "code", "execution_count": 22, "id": "f0be8fa3-7115-4f32-9964-52da54578366", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.849712Z", "iopub.status.busy": "2026-10-14T01:46:39.849563Z", "iopub.status.idle": "2026-10-14T01:46:39.854611Z", "shell.execute_reply": "2026-10-14T01:46:39.853775Z" } }, "outputs": [], "source": [ "from renormalizer.tests.parameter import holstein_model" ] }, { "cell_type": "code", "execution_count": 23, "id": "3a6cf4f8-a821-4746-8d05-ddb02aaeae55", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.856204Z", "iopub.status.busy": "2026-10-14T01:46:39.856059Z", "iopub.status.idle": "2026-10-14T01:46:39.859771Z", "shell.execute_reply": "2026-10-14T01:46:39.858843Z" } }, "outputs": [ { "data": { "text/plain": [ "[BasisSimpleElectron(dof: 0, nbas: 2, qn: [[0], [1]]),\n", " BasisSHO(dof: (0, 0), x0: 0.0, omega: 0.0004852952677877878, nbas: 4),\n", " BasisSHO(dof: (0, 1), x0: 0.0, omega: 0.007087607302669169, nbas: 4),\n", " BasisSimpleElectron(dof: 1, nbas: 2, qn: [[0], [1]]),\n", " BasisSHO(dof: (1, 0), x0: 0.0, omega: 0.0004852952677877878, nbas: 4),\n", " BasisSHO(dof: (1, 1), x0: 0.0, omega: 0.007087607302669169, nbas: 4),\n", " BasisSimpleElectron(dof: 2, nbas: 2, qn: [[0], [1]]),\n", " BasisSHO(dof: (2, 0), x0: 0.0, omega: 0.0004852952677877878, nbas: 4),\n", " BasisSHO(dof: (2, 1), x0: 0.0, omega: 0.007087607302669169, nbas: 4)]" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "holstein_model.basis" ] }, { "cell_type": "code", "execution_count": 24, "id": "6f5b3f05-1b1b-4433-989c-2eab1058e9f0", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.861385Z", "iopub.status.busy": "2026-10-14T01:46:39.861212Z", "iopub.status.idle": "2026-10-14T01:46:39.865495Z", "shell.execute_reply": "2026-10-14T01:46:39.864616Z" } }, "outputs": [ { "data": { "text/plain": [ "[Op('a^\\\\dagger a', [0, 0], 0.10016074648885956, [[1], [-1]]),\n", " Op('a^\\\\dagger a', [0, 1], -0.0036749322175664446, [[1], [-1]]),\n", " Op('a^\\\\dagger a', [0, 2], -0.007349864435132889, [[1], [-1]]),\n", " Op('a^\\\\dagger a', [1, 0], -0.0036749322175664446, [[1], [-1]]),\n", " Op('a^\\\\dagger a', [1, 1], 0.10016074648885956, [[1], [-1]]),\n", " Op('a^\\\\dagger a', [1, 2], -0.011024796652699332, [[1], [-1]]),\n", " Op('a^\\\\dagger a', [2, 0], -0.007349864435132889, [[1], [-1]]),\n", " Op('a^\\\\dagger a', [2, 1], -0.011024796652699332, [[1], [-1]]),\n", " Op('a^\\\\dagger a', [2, 2], 0.10016074648885956, [[1], [-1]]),\n", " Op('p^2', [(0, 0)], 0.5),\n", " Op('x^2', [(0, 0)], 1.1775574846861032e-07),\n", " Op('p^2', [(0, 1)], 0.5),\n", " Op('x^2', [(0, 1)], 2.5117088638424668e-05),\n", " Op('p^2', [(1, 0)], 0.5),\n", " Op('x^2', [(1, 0)], 1.1775574846861032e-07),\n", " Op('p^2', [(1, 1)], 0.5),\n", " Op('x^2', [(1, 1)], 2.5117088638424668e-05),\n", " Op('p^2', [(2, 0)], 0.5),\n", " Op('x^2', [(2, 0)], 1.1775574846861032e-07),\n", " Op('p^2', [(2, 1)], 0.5),\n", " Op('x^2', [(2, 1)], 2.5117088638424668e-05),\n", " Op('a^\\\\dagger a x', [0, 0, (0, 0)], -7.097609983197019e-06, [[1], [-1], [0]]),\n", " Op('a^\\\\dagger a x', [0, 0, (0, 1)], -0.00044069941383207155, [[1], [-1], [0]]),\n", " Op('a^\\\\dagger a x', [1, 1, (1, 0)], -7.097609983197019e-06, [[1], [-1], [0]]),\n", " Op('a^\\\\dagger a x', [1, 1, (1, 1)], -0.00044069941383207155, [[1], [-1], [0]]),\n", " Op('a^\\\\dagger a x', [2, 2, (2, 0)], -7.097609983197019e-06, [[1], [-1], [0]]),\n", " Op('a^\\\\dagger a x', [2, 2, (2, 1)], -0.00044069941383207155, [[1], [-1], [0]])]" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "holstein_model.ham_terms" ] }, { "cell_type": "markdown", "id": "15259dac-74aa-4ebe-9f40-5f630fe58e5f", "metadata": {}, "source": [ "The basis tree is construct manually to reflect the interaction in the Hamiltonian" ] }, { "cell_type": "code", "execution_count": 25, "id": "1d2bb037-4bb4-4d79-a07b-a5dde5ffe5d9", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.867051Z", "iopub.status.busy": "2026-10-14T01:46:39.866881Z", "iopub.status.idle": "2026-10-14T01:46:39.871536Z", "shell.execute_reply": "2026-10-14T01:46:39.870635Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", " ┌[((1, 0),), ((1, 1),)]\n", "[(1,)]┼[(0,)]─[((0, 0),), ((0, 1),)]\n", " └[(2,)]─[((2, 0),), ((2, 1),)]\n" ] } ], "source": [ "nodes = []\n", "for i in range(3):\n", " node1 = TreeNodeBasis(holstein_model.basis[3*i])\n", " node2 = TreeNodeBasis(holstein_model.basis[3*i+1:3*i+3])\n", " node1.add_child(node2)\n", " nodes.append(node1)\n", "nodes[1].add_child([nodes[0], nodes[2]])\n", "\n", "basis = BasisTree(nodes[1])\n", "basis.print()" ] }, { "cell_type": "code", "execution_count": 26, "id": "1397e508-d880-4004-a87e-54354bf6aae6", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.873129Z", "iopub.status.busy": "2026-10-14T01:46:39.872981Z", "iopub.status.idle": "2026-10-14T01:46:39.891653Z", "shell.execute_reply": "2026-10-14T01:46:39.890935Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2026-10-14 01:46:39,874[DEBUG] # of operator terms: 27\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026-10-14 01:46:39,875[DEBUG] Input operator terms: 27\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2026-10-14 01:46:39,876[DEBUG] After combination of the same terms: 27\n" ] } ], "source": [ "ttno = TTNO(basis, holstein_model.ham_terms)" ] }, { "cell_type": "code", "execution_count": 27, "id": "2a8dd3ae-8f22-430f-a5b7-67a0a6810fa7", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.893560Z", "iopub.status.busy": "2026-10-14T01:46:39.893412Z", "iopub.status.idle": "2026-10-14T01:46:39.897137Z", "shell.execute_reply": "2026-10-14T01:46:39.896307Z" } }, "outputs": [ { "data": { "text/plain": [ "[1, 3, 4, 3, 4, 3]" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ttno.bond_dims" ] }, { "cell_type": "code", "execution_count": 28, "id": "4a46835e-fd37-4166-941e-8d533631b6d8", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.898638Z", "iopub.status.busy": "2026-10-14T01:46:39.898492Z", "iopub.status.idle": "2026-10-14T01:46:39.902204Z", "shell.execute_reply": "2026-10-14T01:46:39.901430Z" } }, "outputs": [ { "data": { "text/plain": [ "[TreeNodeTensor((3, 4, 4, 2, 2, 1),float64),\n", " TreeNodeTensor((4, 4, 4, 4, 3),float64),\n", " TreeNodeTensor((3, 2, 2, 4),float64),\n", " TreeNodeTensor((4, 4, 4, 4, 3),float64),\n", " TreeNodeTensor((3, 2, 2, 4),float64),\n", " TreeNodeTensor((4, 4, 4, 4, 3),float64)]" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ttno.node_list" ] }, { "cell_type": "markdown", "id": "33136503-6c32-46d0-b320-0fb6ab2ffb61", "metadata": {}, "source": [ "### TTNO/TTNS manipulation\n", "We demonstrate TTNO/TTNS manipulation using the Holstein model" ] }, { "cell_type": "code", "execution_count": 29, "id": "09de6a17-3d33-4968-a40b-291bc18569d2", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.903923Z", "iopub.status.busy": "2026-10-14T01:46:39.903744Z", "iopub.status.idle": "2026-10-14T01:46:39.907220Z", "shell.execute_reply": "2026-10-14T01:46:39.906387Z" } }, "outputs": [], "source": [ "ttns = TTNS(basis)" ] }, { "cell_type": "code", "execution_count": 30, "id": "172af695-f19f-47c5-8118-e0962c3ef704", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.908743Z", "iopub.status.busy": "2026-10-14T01:46:39.908597Z", "iopub.status.idle": "2026-10-14T01:46:39.913208Z", "shell.execute_reply": "2026-10-14T01:46:39.912310Z" } }, "outputs": [ { "data": { "text/plain": [ " with 6 nodes" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ttns + ttns" ] }, { "cell_type": "code", "execution_count": 31, "id": "9a4f0713-74af-4227-9c7c-d3ccb9c6ea7b", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.914673Z", "iopub.status.busy": "2026-10-14T01:46:39.914523Z", "iopub.status.idle": "2026-10-14T01:46:39.919758Z", "shell.execute_reply": "2026-10-14T01:46:39.918908Z" } }, "outputs": [ { "data": { "text/plain": [ " with 6 nodes" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ttno @ ttns" ] }, { "cell_type": "code", "execution_count": 32, "id": "f95c3ea3-5d99-42ac-9045-95b57c0e3fee", "metadata": { "execution": { "iopub.execute_input": "2026-10-14T01:46:39.921306Z", "iopub.status.busy": "2026-10-14T01:46:39.921156Z", "iopub.status.idle": "2026-10-14T01:46:39.930265Z", "shell.execute_reply": "2026-10-14T01:46:39.929509Z" } }, "outputs": [ { "data": { "text/plain": [ "0.011359353855685435" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ttns.expectation(ttno)" ] } ], "metadata": { "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.11.17" } }, "nbformat": 4, "nbformat_minor": 5 }