{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"id": "b8ea8078-51fb-4c24-93b9-8016fc1f5c49",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"(tensor-network-2d)=\n",
"\n",
"# 2D Algorithms\n",
"\n",
"As with 1D tensor networks (TNs), 2D TNs in `quimb` are a combination of\n",
"'mixin' subclasses of {class}`~quimb.tensor.tensor_core.TensorNetwork` each\n",
"with some extra details about how the tensors are labelled and indices named.\n",
"Having this extra information about the 2D structure then allows special\n",
"methods for e.g. boundary contraction.\n",
"\n",
"Here's a quick reference of some key objects:\n",
"\n",
"- {class}`~quimb.tensor.tn2d.core.TensorNetwork2D`\n",
"- {class}`~quimb.tensor.tn2d.core.PEPS`\n",
"- {class}`~quimb.tensor.tn2d.core.PEPO`\n",
"- {class}`~quimb.tensor.tn1d.tebd.LocalHam2D`\n",
"\n",
"And key algorithms:\n",
"\n",
"- {class}`~quimb.tensor.tn2d.core.TensorNetwork2D.contract_boundary`\n",
"- {class}`~quimb.tensor.tn2d.core.TensorNetwork2DVector.gate`\n",
"- {class}`~quimb.tensor.tn2d.core.TensorNetwork2DVector.compute_local_expectation`\n",
"- {class}`~quimb.tensor.tn1d.tebd.SimpleUpdate`\n",
"- {class}`~quimb.tensor.tn1d.tebd.FullUpdate`"
]
},
{
"cell_type": "markdown",
"id": "5ff31dc4-2ebb-4ebb-92cf-516493f961c7",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"## Structure of a 2D Tensor Network"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "82e3491a-efa4-4b8d-9f02-347026391d1e",
"metadata": {},
"outputs": [],
"source": [
"%config InlineBackend.figure_formats = ['svg']\n",
"import quimb as qu\n",
"import quimb.tensor as qtn"
]
},
{
"cell_type": "markdown",
"id": "e65622e2-48c9-4c47-8566-3d00c8010422",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"As an example we can take a look at a randomly generated PEPS, which also inherits\n",
"methods from these mixin subclasses: {class}`~quimb.tensor.tn2d.core.TensorNetwork2DVector`\n",
"and {class}`~quimb.tensor.tn2d.core.TensorNetwork2DFlat`,\n",
"since it has a) a single physical index per site and\n",
"b) a single tensor per site, respectively."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "0b8d2263-f589-401d-a4fa-1992dfe176f5",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"PEPS(tensors=25, indices=65, Lx=5, Ly=5, max_bond=3)
Tensor(shape=(3, 3, 2), inds=[_aea46cAAAAA, _aea46cAAAAB, k0,0], tags={I0,0, X0, Y0}),
backend=numpy, dtype=float64, data=array([[[ 0.19758123, -0.20600803],\n",
" [-0.02115149, -0.30155026],\n",
" [ 0.08369179, 0.42321298]],\n",
"\n",
" [[-0.78599677, 0.27198615],\n",
" [-0.01315806, -0.26534693],\n",
" [-0.00531344, 0.33645332]],\n",
"\n",
" [[-0.57577375, 0.10554638],\n",
" [-0.07281841, 0.45726951],\n",
" [ 0.26362141, -0.08463805]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAC, _aea46cAAAAD, _aea46cAAAAB, k0,1], tags={I0,1, X0, Y1}),
backend=numpy, dtype=float64, data=array([[[[-0.0886793 , 0.38960521],\n",
" [-0.07864096, -0.1405622 ],\n",
" [-0.27039043, 0.40912656]],\n",
"\n",
" [[-0.25722849, -0.3621938 ],\n",
" [-0.01145245, 0.07481682],\n",
" [-0.04101569, -0.31399061]],\n",
"\n",
" [[-0.0585233 , 0.08844857],\n",
" [-0.34306234, 0.14325768],\n",
" [ 0.44382168, -0.17613362]]],\n",
"\n",
"\n",
" [[[-0.11086622, -0.07888345],\n",
" [-0.08731526, -0.1098593 ],\n",
" [-0.08997919, -0.25855771]],\n",
"\n",
" [[-0.00974778, -0.06474578],\n",
" [-0.53768285, 0.26626594],\n",
" [ 0.1852418 , -0.17064799]],\n",
"\n",
" [[-0.23546533, 0.10044162],\n",
" [-0.04641026, -0.33127844],\n",
" [ 0.31312999, 0.24287011]]],\n",
"\n",
"\n",
" [[[-0.41959896, -0.14805525],\n",
" [ 0.02569746, -0.49149678],\n",
" [-0.08605362, 0.07599989]],\n",
"\n",
" [[-0.19989431, -0.1171608 ],\n",
" [-0.27427135, -0.18171656],\n",
" [-0.35111996, -0.0948195 ]],\n",
"\n",
" [[ 0.33734665, -0.66881823],\n",
" [ 0.2574683 , -0.32198307],\n",
" [-0.44438948, 0.2297073 ]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAE, _aea46cAAAAF, _aea46cAAAAD, k0,2], tags={I0,2, X0, Y2}),
backend=numpy, dtype=float64, data=array([[[[ 0.00787712, 0.07483492],\n",
" [ 0.23423454, -0.41977078],\n",
" [-0.07098577, -0.08227457]],\n",
"\n",
" [[ 0.58049387, -0.28265144],\n",
" [-0.50102255, -0.1383515 ],\n",
" [ 0.46154386, 0.15899825]],\n",
"\n",
" [[-0.48357646, -0.32435753],\n",
" [-0.24554998, -0.0063898 ],\n",
" [-0.4288379 , 0.28063253]]],\n",
"\n",
"\n",
" [[[ 0.4529943 , 0.12319876],\n",
" [-0.12452825, -0.25212084],\n",
" [ 0.07434282, 0.07358095]],\n",
"\n",
" [[-0.07124641, -0.06452709],\n",
" [-0.10609616, 0.06050403],\n",
" [-0.27691535, 0.18652204]],\n",
"\n",
" [[ 0.18944672, 0.28066808],\n",
" [-0.26338667, 0.05858565],\n",
" [ 0.17191266, 0.09251535]]],\n",
"\n",
"\n",
" [[[-0.40473276, -0.77385977],\n",
" [ 0.15369863, 0.34102213],\n",
" [-0.3052184 , 0.00141725]],\n",
"\n",
" [[ 0.07717418, 0.39021751],\n",
" [ 0.37797629, -0.3581846 ],\n",
" [-0.00915705, -0.21592738]],\n",
"\n",
" [[ 0.21857823, 0.02861824],\n",
" [-0.12619608, 0.21470106],\n",
" [ 0.26837599, 0.3497904 ]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAG, _aea46cAAAAH, _aea46cAAAAF, k0,3], tags={I0,3, X0, Y3}),
backend=numpy, dtype=float64, data=array([[[[-0.35302799, -0.18588165],\n",
" [ 0.06628363, 0.18146305],\n",
" [-0.64362369, -0.2252469 ]],\n",
"\n",
" [[ 0.08364773, 0.01679925],\n",
" [ 0.18941434, -0.14216882],\n",
" [-0.07795615, 0.24121163]],\n",
"\n",
" [[ 0.36766087, 0.18291524],\n",
" [ 0.48242292, 0.17032754],\n",
" [-0.18111091, 0.32120585]]],\n",
"\n",
"\n",
" [[[-0.73965826, 0.12207832],\n",
" [-0.21999 , -0.35361801],\n",
" [-0.36855658, -0.31388888]],\n",
"\n",
" [[ 0.41657027, 0.14911351],\n",
" [-0.03321268, -0.036751 ],\n",
" [ 0.27384496, -0.24498083]],\n",
"\n",
" [[ 0.35392829, 0.46963827],\n",
" [-0.28648917, -0.16491934],\n",
" [ 0.08454636, 0.3485048 ]]],\n",
"\n",
"\n",
" [[[-0.2487877 , -0.81637444],\n",
" [-0.11929533, 0.21710726],\n",
" [-0.05459544, -0.16750029]],\n",
"\n",
" [[-0.12530134, -0.44630833],\n",
" [ 0.22974167, -0.14514381],\n",
" [ 0.32546501, -0.07342843]],\n",
"\n",
" [[-0.26259823, 0.26310325],\n",
" [-0.1439656 , 0.08012546],\n",
" [ 0.14057252, -0.31473198]]]])Tensor(shape=(3, 3, 2), inds=[_aea46cAAAAI, _aea46cAAAAH, k0,4], tags={I0,4, X0, Y4}),
backend=numpy, dtype=float64, data=array([[[ 0.43152581, -0.23969586],\n",
" [-0.16808012, 0.08247557],\n",
" [ 0.33020835, -0.28069495]],\n",
"\n",
" [[-0.15814594, -0.3455025 ],\n",
" [-0.4347297 , -0.65814361],\n",
" [ 0.24335002, 0.01839728]],\n",
"\n",
" [[-0.18092796, 0.07677303],\n",
" [-0.27159058, -0.12283561],\n",
" [-0.37800116, -0.40040474]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAJ, _aea46cAAAAK, _aea46cAAAAA, k1,0], tags={I1,0, X1, Y0}),
backend=numpy, dtype=float64, data=array([[[[ 0.78977302, 0.20610627],\n",
" [-0.17232708, -0.32686794],\n",
" [ 0.12781562, -0.11373377]],\n",
"\n",
" [[ 0.09609733, 0.32360355],\n",
" [-0.14147276, 0.08949845],\n",
" [-0.14720314, -0.19955648]],\n",
"\n",
" [[-0.2027934 , -0.11879961],\n",
" [-0.14779857, 0.06389199],\n",
" [-0.06141446, -0.08943344]]],\n",
"\n",
"\n",
" [[[ 0.01172702, 0.65384372],\n",
" [-0.4016258 , 0.62405045],\n",
" [ 0.0183161 , -0.42458339]],\n",
"\n",
" [[ 0.00276003, 0.25519974],\n",
" [-0.29860681, -0.19277402],\n",
" [ 0.36346475, 0.07670103]],\n",
"\n",
" [[-0.2414894 , 0.04928607],\n",
" [-0.53921085, 0.55625126],\n",
" [ 0.33501048, 0.14937114]]],\n",
"\n",
"\n",
" [[[ 0.47162932, 0.17082597],\n",
" [ 0.06865947, -0.28654631],\n",
" [-0.46735522, -0.20633878]],\n",
"\n",
" [[ 0.24972016, -0.17040072],\n",
" [ 0.15429501, 0.4294151 ],\n",
" [-0.19904102, -0.00177625]],\n",
"\n",
" [[ 0.05496409, 0.03333935],\n",
" [-0.25443675, 0.27334373],\n",
" [ 0.05015645, 0.10742787]]]])Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAL, _aea46cAAAAM, _aea46cAAAAC, _aea46cAAAAK, k1,1], tags={I1,1, X1, Y1}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAN, _aea46cAAAAO, _aea46cAAAAE, _aea46cAAAAM, k1,2], tags={I1,2, X1, Y2}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAP, _aea46cAAAAQ, _aea46cAAAAG, _aea46cAAAAO, k1,3], tags={I1,3, X1, Y3}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAR, _aea46cAAAAI, _aea46cAAAAQ, k1,4], tags={I1,4, X1, Y4}),
backend=numpy, dtype=float64, data=array([[[[ 0.36548229, -0.26015584],\n",
" [ 0.14163331, -0.06427805],\n",
" [ 0.3257745 , -0.53845238]],\n",
"\n",
" [[ 0.49660934, 0.35980179],\n",
" [ 0.35161007, -0.26212529],\n",
" [ 0.17691887, -0.41049041]],\n",
"\n",
" [[ 0.35321357, 0.14903971],\n",
" [ 0.58041384, -0.14440401],\n",
" [ 0.10477843, 0.04271563]]],\n",
"\n",
"\n",
" [[[-0.18523296, 0.08600995],\n",
" [-0.00249853, 0.00309299],\n",
" [-0.38302772, -0.11931442]],\n",
"\n",
" [[-0.01032181, 0.35569799],\n",
" [-0.1177868 , 0.09307973],\n",
" [-0.32977233, 0.31827419]],\n",
"\n",
" [[-0.01066864, 0.5333739 ],\n",
" [-0.51256 , 0.03966059],\n",
" [ 0.25838267, -0.18445352]]],\n",
"\n",
"\n",
" [[[ 0.45910942, 0.03237033],\n",
" [ 0.1103594 , -0.06656127],\n",
" [-0.28261971, 0.47622606]],\n",
"\n",
" [[ 0.2713872 , 0.22772949],\n",
" [-0.70921321, -0.6142656 ],\n",
" [-0.22789126, -0.07517024]],\n",
"\n",
" [[-0.18087422, 0.29178375],\n",
" [-0.17016618, -0.13840751],\n",
" [-0.15878981, -0.07968 ]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAS, _aea46cAAAAT, _aea46cAAAAJ, k2,0], tags={I2,0, X2, Y0}),
backend=numpy, dtype=float64, data=array([[[[-0.38056033, 0.24804757],\n",
" [-0.07572871, -0.13027434],\n",
" [-0.30343203, 0.09497906]],\n",
"\n",
" [[ 0.08621316, -0.30894061],\n",
" [-0.07400557, 0.2997675 ],\n",
" [ 0.13113942, -0.02904785]],\n",
"\n",
" [[-0.47955682, 0.73818644],\n",
" [-0.08958236, -0.44780715],\n",
" [-0.27007575, -0.09415205]]],\n",
"\n",
"\n",
" [[[-0.1108852 , 0.0971295 ],\n",
" [-0.19637978, -0.23722133],\n",
" [-0.3326612 , -0.14791084]],\n",
"\n",
" [[-0.1607138 , -0.3585758 ],\n",
" [ 0.17374931, 0.07621275],\n",
" [-0.13889808, 0.31498138]],\n",
"\n",
" [[-0.00429754, 0.35580526],\n",
" [ 0.23141829, -0.10033515],\n",
" [ 0.08118212, -0.37380152]]],\n",
"\n",
"\n",
" [[[ 0.28702139, -0.00675585],\n",
" [ 0.26061321, 0.16028784],\n",
" [ 0.58456152, 0.66808804]],\n",
"\n",
" [[ 0.12426176, -0.21271792],\n",
" [-0.57620289, 0.1145728 ],\n",
" [-0.12986616, -0.36577064]],\n",
"\n",
" [[ 0.18087245, 0.12187611],\n",
" [ 0.2093346 , -0.4805098 ],\n",
" [ 0.38713581, -0.1013577 ]]]])Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAU, _aea46cAAAAV, _aea46cAAAAL, _aea46cAAAAT, k2,1], tags={I2,1, X2, Y1}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAW, _aea46cAAAAX, _aea46cAAAAN, _aea46cAAAAV, k2,2], tags={I2,2, X2, Y2}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAY, _aea46cAAAAZ, _aea46cAAAAP, _aea46cAAAAX, k2,3], tags={I2,3, X2, Y3}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAa, _aea46cAAAAR, _aea46cAAAAZ, k2,4], tags={I2,4, X2, Y4}),
backend=numpy, dtype=float64, data=array([[[[ 0.01567375, -0.09310011],\n",
" [ 0.24768273, -0.11738978],\n",
" [-0.251629 , -0.1782275 ]],\n",
"\n",
" [[-0.26829665, 0.31267077],\n",
" [-0.22495458, -0.12581883],\n",
" [ 0.26748041, -0.66605332]],\n",
"\n",
" [[-0.023022 , 0.11326969],\n",
" [ 0.18469781, -0.55483234],\n",
" [ 0.32973489, 0.27550022]]],\n",
"\n",
"\n",
" [[[ 0.10759164, -0.63445143],\n",
" [ 0.03337969, 0.25331677],\n",
" [ 0.45157972, -0.17408386]],\n",
"\n",
" [[ 0.20383984, 0.45867942],\n",
" [ 0.01499983, -0.2965261 ],\n",
" [-0.19994835, 0.14174105]],\n",
"\n",
" [[ 0.19374226, -0.60597725],\n",
" [ 0.49222259, 0.19789102],\n",
" [ 0.20171385, 0.0422929 ]]],\n",
"\n",
"\n",
" [[[-0.26715396, -0.16995193],\n",
" [ 0.34863328, 0.45914815],\n",
" [ 0.08663278, 0.61174177]],\n",
"\n",
" [[ 0.22506451, -0.12569846],\n",
" [-0.27588113, -0.29585981],\n",
" [ 0.17803576, 0.11039606]],\n",
"\n",
" [[-0.03518468, -0.36600593],\n",
" [ 0.64683561, 0.09689121],\n",
" [-0.27371473, -0.15114634]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAb, _aea46cAAAAc, _aea46cAAAAS, k3,0], tags={I3,0, X3, Y0}),
backend=numpy, dtype=float64, data=array([[[[-0.03287723, 0.22373023],\n",
" [ 0.21720609, -0.12940337],\n",
" [ 0.26421373, 0.12598597]],\n",
"\n",
" [[-0.05993477, 0.23901176],\n",
" [-0.5080131 , 0.1581344 ],\n",
" [-0.2468453 , -0.24597057]],\n",
"\n",
" [[ 0.05509204, 0.20433684],\n",
" [ 0.25810118, 0.6133055 ],\n",
" [ 0.12314849, 0.09794608]]],\n",
"\n",
"\n",
" [[[ 0.26466672, 0.46330901],\n",
" [-0.37261901, -0.14613522],\n",
" [-0.04725875, -0.05370155]],\n",
"\n",
" [[-0.21671809, -0.6030256 ],\n",
" [ 0.18518784, 0.51043185],\n",
" [ 0.17336402, 0.17334707]],\n",
"\n",
" [[ 0.23415478, 0.31106511],\n",
" [-0.08608762, 0.33643773],\n",
" [-0.02513669, 0.29852203]]],\n",
"\n",
"\n",
" [[[ 0.11660528, -0.63708811],\n",
" [ 0.29317834, 0.55391842],\n",
" [ 0.22281977, 0.02624954]],\n",
"\n",
" [[-0.61615086, 0.31477655],\n",
" [-0.21857305, -0.23485264],\n",
" [-0.07015365, 0.18019487]],\n",
"\n",
" [[ 0.47228582, -0.02025982],\n",
" [ 0.03324436, -0.05201856],\n",
" [ 0.08216902, -0.15068886]]]])Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAd, _aea46cAAAAe, _aea46cAAAAU, _aea46cAAAAc, k3,1], tags={I3,1, X3, Y1}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAf, _aea46cAAAAg, _aea46cAAAAW, _aea46cAAAAe, k3,2], tags={I3,2, X3, Y2}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAh, _aea46cAAAAi, _aea46cAAAAY, _aea46cAAAAg, k3,3], tags={I3,3, X3, Y3}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAj, _aea46cAAAAa, _aea46cAAAAi, k3,4], tags={I3,4, X3, Y4}),
backend=numpy, dtype=float64, data=array([[[[-0.02785434, -0.19377183],\n",
" [ 0.13567531, -0.10062713],\n",
" [-0.07749432, 0.35753385]],\n",
"\n",
" [[-0.25709318, -0.08090333],\n",
" [ 0.10074147, 0.21459987],\n",
" [-0.05594702, 0.48585484]],\n",
"\n",
" [[-0.02995602, -0.12112102],\n",
" [ 0.14817227, 0.37143844],\n",
" [ 0.09314821, 0.2501424 ]]],\n",
"\n",
"\n",
" [[[-0.22927907, -0.16533426],\n",
" [-0.19022857, -0.49516235],\n",
" [ 0.03630534, -0.491662 ]],\n",
"\n",
" [[ 0.66526663, -0.06528429],\n",
" [ 0.19440541, -0.33161728],\n",
" [-0.22234613, -0.22712846]],\n",
"\n",
" [[-0.21079084, -0.07107046],\n",
" [-0.19357984, -0.570392 ],\n",
" [ 0.49999969, 0.07619666]]],\n",
"\n",
"\n",
" [[[-0.36850847, 0.26388082],\n",
" [-0.02058343, -0.5785781 ],\n",
" [-0.13305771, -0.17363738]],\n",
"\n",
" [[-0.01600171, -0.25669566],\n",
" [-0.07669599, 0.34866238],\n",
" [ 0.53794805, -0.77247211]],\n",
"\n",
" [[ 0.46701018, -0.03136358],\n",
" [-0.36865922, 0.55544779],\n",
" [-0.05441975, 0.31138795]]]])Tensor(shape=(3, 3, 2), inds=[_aea46cAAAAk, _aea46cAAAAb, k4,0], tags={I4,0, X4, Y0}),
backend=numpy, dtype=float64, data=array([[[-0.03622255, -0.64783791],\n",
" [-0.35413836, -0.06839641],\n",
" [-0.26610905, -0.4381159 ]],\n",
"\n",
" [[ 0.30796793, -0.02458458],\n",
" [ 0.29830521, -0.13475392],\n",
" [ 0.05871056, -0.29670865]],\n",
"\n",
" [[ 0.08531347, -0.27240719],\n",
" [ 0.03741549, 0.46378323],\n",
" [-0.29799446, -0.68974713]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAl, _aea46cAAAAd, _aea46cAAAAk, k4,1], tags={I4,1, X4, Y1}),
backend=numpy, dtype=float64, data=array([[[[ 7.32071132e-02, 1.63793612e-01],\n",
" [ 1.95103932e-02, 6.34924932e-02],\n",
" [-1.86589186e-01, 5.02850574e-01]],\n",
"\n",
" [[ 2.21822008e-02, 1.45419471e-01],\n",
" [ 1.70098419e-02, -3.45904379e-01],\n",
" [ 1.17070971e-01, 7.49301787e-01]],\n",
"\n",
" [[ 1.82502382e-01, 1.30361449e-01],\n",
" [-6.40960880e-02, -6.50550425e-01],\n",
" [-1.58615286e-01, -2.17396291e-01]]],\n",
"\n",
"\n",
" [[[ 3.36823530e-01, 4.77320168e-01],\n",
" [ 3.33942936e-02, -3.22675181e-01],\n",
" [ 3.00501540e-01, -1.30890164e-01]],\n",
"\n",
" [[-4.93261133e-02, 1.80571112e-01],\n",
" [-8.34259724e-02, -1.36661366e-01],\n",
" [ 6.47967822e-01, 2.89957316e-01]],\n",
"\n",
" [[ 3.51996531e-01, -2.58543810e-01],\n",
" [ 3.93574280e-01, 2.09913863e-01],\n",
" [-1.49833263e-04, -3.14774589e-01]]],\n",
"\n",
"\n",
" [[[ 1.95185567e-01, -3.00442172e-01],\n",
" [ 5.46766593e-01, 2.17461520e-01],\n",
" [ 5.47755703e-01, 1.47049000e-01]],\n",
"\n",
" [[-2.89939243e-02, -2.29325724e-01],\n",
" [-2.19042143e-01, -5.19124212e-01],\n",
" [-2.76151915e-01, -3.36271916e-01]],\n",
"\n",
" [[ 5.01194142e-01, 1.12354943e-01],\n",
" [-2.74712104e-01, 1.17000234e-01],\n",
" [ 1.01969558e-02, -1.37528548e-01]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAm, _aea46cAAAAf, _aea46cAAAAl, k4,2], tags={I4,2, X4, Y2}),
backend=numpy, dtype=float64, data=array([[[[-0.04691427, 0.04518512],\n",
" [-0.48821014, 0.14472043],\n",
" [ 0.2289111 , -0.49996531]],\n",
"\n",
" [[-0.22946103, -0.56242939],\n",
" [-0.1519321 , -0.08036349],\n",
" [-0.07974806, -0.12597931]],\n",
"\n",
" [[ 0.16025181, 0.3009493 ],\n",
" [-0.21928384, -0.14216206],\n",
" [-0.56038647, 0.15624933]]],\n",
"\n",
"\n",
" [[[ 0.24839524, -0.28966023],\n",
" [-0.20838007, -0.18817065],\n",
" [ 0.17665091, -0.02378777]],\n",
"\n",
" [[ 0.35291229, -0.26963928],\n",
" [ 0.16652744, 0.39175549],\n",
" [ 0.00254081, -0.59435346]],\n",
"\n",
" [[ 0.36046884, -0.19522254],\n",
" [-0.00934237, 0.10191553],\n",
" [-0.62675368, 0.20896072]]],\n",
"\n",
"\n",
" [[[ 0.22663422, -0.21799479],\n",
" [-0.10634787, -0.2027503 ],\n",
" [ 0.68532395, -0.02940163]],\n",
"\n",
" [[ 0.1583736 , 0.1362018 ],\n",
" [-0.14871838, 0.16141379],\n",
" [ 0.33185367, 0.43178459]],\n",
"\n",
" [[-0.06391033, 0.27971557],\n",
" [-0.20968179, -0.51190256],\n",
" [ 0.29081901, 0.09433118]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAn, _aea46cAAAAh, _aea46cAAAAm, k4,3], tags={I4,3, X4, Y3}),
backend=numpy, dtype=float64, data=array([[[[-0.04268813, 0.65947468],\n",
" [-0.00643255, -0.57697121],\n",
" [ 0.57728807, 0.70715589]],\n",
"\n",
" [[-0.02511551, 0.29979619],\n",
" [ 0.25984809, 0.37272275],\n",
" [-0.23439044, -0.13467509]],\n",
"\n",
" [[ 0.06414487, 0.11633378],\n",
" [-0.17244477, -0.11933729],\n",
" [-0.06883606, 0.03145422]]],\n",
"\n",
"\n",
" [[[-0.40488939, 0.19470758],\n",
" [ 0.12764037, -0.56489277],\n",
" [-0.18223419, -0.34254078]],\n",
"\n",
" [[ 0.41968604, 0.19940955],\n",
" [ 0.21937432, 0.17137236],\n",
" [-0.09779707, -0.3709037 ]],\n",
"\n",
" [[ 0.09661398, -0.59484165],\n",
" [ 0.16929148, 0.24812902],\n",
" [ 0.23701328, 0.24395429]]],\n",
"\n",
"\n",
" [[[-0.01667156, -0.10023877],\n",
" [-0.00398862, -0.02343363],\n",
" [ 0.47390102, 0.32692523]],\n",
"\n",
" [[ 0.70393136, 0.02803209],\n",
" [-0.21699308, -0.21125616],\n",
" [ 0.30153273, 0.38770508]],\n",
"\n",
" [[-0.16267959, -0.18765657],\n",
" [ 0.00855063, -0.16643927],\n",
" [-0.19250898, 0.23623521]]]])Tensor(shape=(3, 3, 2), inds=[_aea46cAAAAj, _aea46cAAAAn, k4,4], tags={I4,4, X4, Y4}),
backend=numpy, dtype=float64, data=array([[[ 0.04200821, 0.31899505],\n",
" [-0.21784933, -0.42481105],\n",
" [-0.45498257, 0.35867999]],\n",
"\n",
" [[ 0.24995048, -0.17124387],\n",
" [ 0.52845545, 0.69610531],\n",
" [ 0.18589178, -0.07414434]],\n",
"\n",
" [[-0.25978338, -0.16469329],\n",
" [ 0.01989423, -0.17488996],\n",
" [-0.23159834, -0.48782655]]]) "
],
"text/plain": [
"PEPS(tensors=25, indices=65, Lx=5, Ly=5, max_bond=3)"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"peps = qtn.PEPS.rand(Lx=5, Ly=5, bond_dim=3, seed=666)\n",
"peps"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "753061b5-1665-4bc8-9a31-7bafcca55b02",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 3 3 3 3 \n",
" ●━━━━●━━━━●━━━━●━━━━●\n",
"╱┃3 ╱┃3 ╱┃3 ╱┃3 ╱┃3 \n",
" ┃ 3 ┃ 3 ┃ 3 ┃ 3 ┃ \n",
" ●━━━━●━━━━●━━━━●━━━━●\n",
"╱┃3 ╱┃3 ╱┃3 ╱┃3 ╱┃3 \n",
" ┃ 3 ┃ 3 ┃ 3 ┃ 3 ┃ \n",
" ●━━━━●━━━━●━━━━●━━━━●\n",
"╱┃3 ╱┃3 ╱┃3 ╱┃3 ╱┃3 \n",
" ┃ 3 ┃ 3 ┃ 3 ┃ 3 ┃ \n",
" ●━━━━●━━━━●━━━━●━━━━●\n",
"╱┃3 ╱┃3 ╱┃3 ╱┃3 ╱┃3 \n",
" ┃ 3 ┃ 3 ┃ 3 ┃ 3 ┃ \n",
" ●━━━━●━━━━●━━━━●━━━━●\n",
"╱ ╱ ╱ ╱ ╱ \n"
]
}
],
"source": [
"peps.show()"
]
},
{
"cell_type": "markdown",
"id": "bb666f28-cc18-4087-a256-b235efb7e8c9",
"metadata": {},
"source": [
"You can see all the special properties the `PEPS` class carries with:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "88fd3fd0-1a40-408b-bf00-dbe4c854bdee",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"('_site_tag_id', '_x_tag_id', '_y_tag_id', '_Lx', '_Ly', '_site_ind_id')"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"peps._EXTRA_PROPS"
]
},
{
"cell_type": "markdown",
"id": "6a656257-d35f-4a10-9606-06d00ee2c27c",
"metadata": {},
"source": [
"This enable various convenient functions:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "48acf058-6dea-4de6-93ff-500790400902",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'k3,4'"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# index specifying an physical site\n",
"peps.site_ind(3, 4)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "da57336a-ae80-4fb6-a354-b36656692c6b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'I3,4'"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# tag specifying a coordinate\n",
"peps.site_tag(3, 4)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "fa9eabf6-0fdc-40fe-950c-7cfc9793f8e9",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAj, _aea46cAAAAa, _aea46cAAAAi, k3,4], tags={I3,4, X3, Y4}),
backend=numpy, dtype=float64, data=array([[[[-0.02785434, -0.19377183],\n",
" [ 0.13567531, -0.10062713],\n",
" [-0.07749432, 0.35753385]],\n",
"\n",
" [[-0.25709318, -0.08090333],\n",
" [ 0.10074147, 0.21459987],\n",
" [-0.05594702, 0.48585484]],\n",
"\n",
" [[-0.02995602, -0.12112102],\n",
" [ 0.14817227, 0.37143844],\n",
" [ 0.09314821, 0.2501424 ]]],\n",
"\n",
"\n",
" [[[-0.22927907, -0.16533426],\n",
" [-0.19022857, -0.49516235],\n",
" [ 0.03630534, -0.491662 ]],\n",
"\n",
" [[ 0.66526663, -0.06528429],\n",
" [ 0.19440541, -0.33161728],\n",
" [-0.22234613, -0.22712846]],\n",
"\n",
" [[-0.21079084, -0.07107046],\n",
" [-0.19357984, -0.570392 ],\n",
" [ 0.49999969, 0.07619666]]],\n",
"\n",
"\n",
" [[[-0.36850847, 0.26388082],\n",
" [-0.02058343, -0.5785781 ],\n",
" [-0.13305771, -0.17363738]],\n",
"\n",
" [[-0.01600171, -0.25669566],\n",
" [-0.07669599, 0.34866238],\n",
" [ 0.53794805, -0.77247211]],\n",
"\n",
" [[ 0.46701018, -0.03136358],\n",
" [-0.36865922, 0.55544779],\n",
" [-0.05441975, 0.31138795]]]]) "
],
"text/plain": [
"Tensor(shape=(3, 3, 3, 2), inds=('_aea46cAAAAj', '_aea46cAAAAa', '_aea46cAAAAi', 'k3,4'), tags=oset(['I3,4', 'X3', 'Y4']))"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# access by coordinate rather than full tag\n",
"peps[3, 4]"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "0f6b5d94-4c98-420a-93ed-e7abd30395e4",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"peps.draw(color=peps.site_tags)"
]
},
{
"cell_type": "markdown",
"id": "9958ada3-3ea5-4dcb-a705-b4f684fd7840",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"## Combining 2D Tensor Networks\n",
"\n",
"When you combine two 2D tensor networks with the `&` or `|` operators the\n",
"new combined TN will be `~quimb.tensor.tn2d.core.TensorNetwork2D` if they are\n",
"compatible (i.e. all extra properties match). That means that if you combine two\n",
"PEPS for example, the new object still has a boundary contraction method."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "49024af8-a881-4566-b229-481891c8750d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"TensorNetwork2D(tensors=50, indices=105, Lx=5, Ly=5, max_bond=3)
Tensor(shape=(3, 3, 2), inds=[_aea46cAAAAA, _aea46cAAAAB, k0,0], tags={I0,0, X0, Y0}),
backend=numpy, dtype=float64, data=array([[[ 0.19758123, -0.20600803],\n",
" [-0.02115149, -0.30155026],\n",
" [ 0.08369179, 0.42321298]],\n",
"\n",
" [[-0.78599677, 0.27198615],\n",
" [-0.01315806, -0.26534693],\n",
" [-0.00531344, 0.33645332]],\n",
"\n",
" [[-0.57577375, 0.10554638],\n",
" [-0.07281841, 0.45726951],\n",
" [ 0.26362141, -0.08463805]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAC, _aea46cAAAAD, _aea46cAAAAB, k0,1], tags={I0,1, X0, Y1}),
backend=numpy, dtype=float64, data=array([[[[-0.0886793 , 0.38960521],\n",
" [-0.07864096, -0.1405622 ],\n",
" [-0.27039043, 0.40912656]],\n",
"\n",
" [[-0.25722849, -0.3621938 ],\n",
" [-0.01145245, 0.07481682],\n",
" [-0.04101569, -0.31399061]],\n",
"\n",
" [[-0.0585233 , 0.08844857],\n",
" [-0.34306234, 0.14325768],\n",
" [ 0.44382168, -0.17613362]]],\n",
"\n",
"\n",
" [[[-0.11086622, -0.07888345],\n",
" [-0.08731526, -0.1098593 ],\n",
" [-0.08997919, -0.25855771]],\n",
"\n",
" [[-0.00974778, -0.06474578],\n",
" [-0.53768285, 0.26626594],\n",
" [ 0.1852418 , -0.17064799]],\n",
"\n",
" [[-0.23546533, 0.10044162],\n",
" [-0.04641026, -0.33127844],\n",
" [ 0.31312999, 0.24287011]]],\n",
"\n",
"\n",
" [[[-0.41959896, -0.14805525],\n",
" [ 0.02569746, -0.49149678],\n",
" [-0.08605362, 0.07599989]],\n",
"\n",
" [[-0.19989431, -0.1171608 ],\n",
" [-0.27427135, -0.18171656],\n",
" [-0.35111996, -0.0948195 ]],\n",
"\n",
" [[ 0.33734665, -0.66881823],\n",
" [ 0.2574683 , -0.32198307],\n",
" [-0.44438948, 0.2297073 ]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAE, _aea46cAAAAF, _aea46cAAAAD, k0,2], tags={I0,2, X0, Y2}),
backend=numpy, dtype=float64, data=array([[[[ 0.00787712, 0.07483492],\n",
" [ 0.23423454, -0.41977078],\n",
" [-0.07098577, -0.08227457]],\n",
"\n",
" [[ 0.58049387, -0.28265144],\n",
" [-0.50102255, -0.1383515 ],\n",
" [ 0.46154386, 0.15899825]],\n",
"\n",
" [[-0.48357646, -0.32435753],\n",
" [-0.24554998, -0.0063898 ],\n",
" [-0.4288379 , 0.28063253]]],\n",
"\n",
"\n",
" [[[ 0.4529943 , 0.12319876],\n",
" [-0.12452825, -0.25212084],\n",
" [ 0.07434282, 0.07358095]],\n",
"\n",
" [[-0.07124641, -0.06452709],\n",
" [-0.10609616, 0.06050403],\n",
" [-0.27691535, 0.18652204]],\n",
"\n",
" [[ 0.18944672, 0.28066808],\n",
" [-0.26338667, 0.05858565],\n",
" [ 0.17191266, 0.09251535]]],\n",
"\n",
"\n",
" [[[-0.40473276, -0.77385977],\n",
" [ 0.15369863, 0.34102213],\n",
" [-0.3052184 , 0.00141725]],\n",
"\n",
" [[ 0.07717418, 0.39021751],\n",
" [ 0.37797629, -0.3581846 ],\n",
" [-0.00915705, -0.21592738]],\n",
"\n",
" [[ 0.21857823, 0.02861824],\n",
" [-0.12619608, 0.21470106],\n",
" [ 0.26837599, 0.3497904 ]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAG, _aea46cAAAAH, _aea46cAAAAF, k0,3], tags={I0,3, X0, Y3}),
backend=numpy, dtype=float64, data=array([[[[-0.35302799, -0.18588165],\n",
" [ 0.06628363, 0.18146305],\n",
" [-0.64362369, -0.2252469 ]],\n",
"\n",
" [[ 0.08364773, 0.01679925],\n",
" [ 0.18941434, -0.14216882],\n",
" [-0.07795615, 0.24121163]],\n",
"\n",
" [[ 0.36766087, 0.18291524],\n",
" [ 0.48242292, 0.17032754],\n",
" [-0.18111091, 0.32120585]]],\n",
"\n",
"\n",
" [[[-0.73965826, 0.12207832],\n",
" [-0.21999 , -0.35361801],\n",
" [-0.36855658, -0.31388888]],\n",
"\n",
" [[ 0.41657027, 0.14911351],\n",
" [-0.03321268, -0.036751 ],\n",
" [ 0.27384496, -0.24498083]],\n",
"\n",
" [[ 0.35392829, 0.46963827],\n",
" [-0.28648917, -0.16491934],\n",
" [ 0.08454636, 0.3485048 ]]],\n",
"\n",
"\n",
" [[[-0.2487877 , -0.81637444],\n",
" [-0.11929533, 0.21710726],\n",
" [-0.05459544, -0.16750029]],\n",
"\n",
" [[-0.12530134, -0.44630833],\n",
" [ 0.22974167, -0.14514381],\n",
" [ 0.32546501, -0.07342843]],\n",
"\n",
" [[-0.26259823, 0.26310325],\n",
" [-0.1439656 , 0.08012546],\n",
" [ 0.14057252, -0.31473198]]]])Tensor(shape=(3, 3, 2), inds=[_aea46cAAAAI, _aea46cAAAAH, k0,4], tags={I0,4, X0, Y4}),
backend=numpy, dtype=float64, data=array([[[ 0.43152581, -0.23969586],\n",
" [-0.16808012, 0.08247557],\n",
" [ 0.33020835, -0.28069495]],\n",
"\n",
" [[-0.15814594, -0.3455025 ],\n",
" [-0.4347297 , -0.65814361],\n",
" [ 0.24335002, 0.01839728]],\n",
"\n",
" [[-0.18092796, 0.07677303],\n",
" [-0.27159058, -0.12283561],\n",
" [-0.37800116, -0.40040474]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAJ, _aea46cAAAAK, _aea46cAAAAA, k1,0], tags={I1,0, X1, Y0}),
backend=numpy, dtype=float64, data=array([[[[ 0.78977302, 0.20610627],\n",
" [-0.17232708, -0.32686794],\n",
" [ 0.12781562, -0.11373377]],\n",
"\n",
" [[ 0.09609733, 0.32360355],\n",
" [-0.14147276, 0.08949845],\n",
" [-0.14720314, -0.19955648]],\n",
"\n",
" [[-0.2027934 , -0.11879961],\n",
" [-0.14779857, 0.06389199],\n",
" [-0.06141446, -0.08943344]]],\n",
"\n",
"\n",
" [[[ 0.01172702, 0.65384372],\n",
" [-0.4016258 , 0.62405045],\n",
" [ 0.0183161 , -0.42458339]],\n",
"\n",
" [[ 0.00276003, 0.25519974],\n",
" [-0.29860681, -0.19277402],\n",
" [ 0.36346475, 0.07670103]],\n",
"\n",
" [[-0.2414894 , 0.04928607],\n",
" [-0.53921085, 0.55625126],\n",
" [ 0.33501048, 0.14937114]]],\n",
"\n",
"\n",
" [[[ 0.47162932, 0.17082597],\n",
" [ 0.06865947, -0.28654631],\n",
" [-0.46735522, -0.20633878]],\n",
"\n",
" [[ 0.24972016, -0.17040072],\n",
" [ 0.15429501, 0.4294151 ],\n",
" [-0.19904102, -0.00177625]],\n",
"\n",
" [[ 0.05496409, 0.03333935],\n",
" [-0.25443675, 0.27334373],\n",
" [ 0.05015645, 0.10742787]]]])Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAL, _aea46cAAAAM, _aea46cAAAAC, _aea46cAAAAK, k1,1], tags={I1,1, X1, Y1}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAN, _aea46cAAAAO, _aea46cAAAAE, _aea46cAAAAM, k1,2], tags={I1,2, X1, Y2}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAP, _aea46cAAAAQ, _aea46cAAAAG, _aea46cAAAAO, k1,3], tags={I1,3, X1, Y3}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAR, _aea46cAAAAI, _aea46cAAAAQ, k1,4], tags={I1,4, X1, Y4}),
backend=numpy, dtype=float64, data=array([[[[ 0.36548229, -0.26015584],\n",
" [ 0.14163331, -0.06427805],\n",
" [ 0.3257745 , -0.53845238]],\n",
"\n",
" [[ 0.49660934, 0.35980179],\n",
" [ 0.35161007, -0.26212529],\n",
" [ 0.17691887, -0.41049041]],\n",
"\n",
" [[ 0.35321357, 0.14903971],\n",
" [ 0.58041384, -0.14440401],\n",
" [ 0.10477843, 0.04271563]]],\n",
"\n",
"\n",
" [[[-0.18523296, 0.08600995],\n",
" [-0.00249853, 0.00309299],\n",
" [-0.38302772, -0.11931442]],\n",
"\n",
" [[-0.01032181, 0.35569799],\n",
" [-0.1177868 , 0.09307973],\n",
" [-0.32977233, 0.31827419]],\n",
"\n",
" [[-0.01066864, 0.5333739 ],\n",
" [-0.51256 , 0.03966059],\n",
" [ 0.25838267, -0.18445352]]],\n",
"\n",
"\n",
" [[[ 0.45910942, 0.03237033],\n",
" [ 0.1103594 , -0.06656127],\n",
" [-0.28261971, 0.47622606]],\n",
"\n",
" [[ 0.2713872 , 0.22772949],\n",
" [-0.70921321, -0.6142656 ],\n",
" [-0.22789126, -0.07517024]],\n",
"\n",
" [[-0.18087422, 0.29178375],\n",
" [-0.17016618, -0.13840751],\n",
" [-0.15878981, -0.07968 ]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAS, _aea46cAAAAT, _aea46cAAAAJ, k2,0], tags={I2,0, X2, Y0}),
backend=numpy, dtype=float64, data=array([[[[-0.38056033, 0.24804757],\n",
" [-0.07572871, -0.13027434],\n",
" [-0.30343203, 0.09497906]],\n",
"\n",
" [[ 0.08621316, -0.30894061],\n",
" [-0.07400557, 0.2997675 ],\n",
" [ 0.13113942, -0.02904785]],\n",
"\n",
" [[-0.47955682, 0.73818644],\n",
" [-0.08958236, -0.44780715],\n",
" [-0.27007575, -0.09415205]]],\n",
"\n",
"\n",
" [[[-0.1108852 , 0.0971295 ],\n",
" [-0.19637978, -0.23722133],\n",
" [-0.3326612 , -0.14791084]],\n",
"\n",
" [[-0.1607138 , -0.3585758 ],\n",
" [ 0.17374931, 0.07621275],\n",
" [-0.13889808, 0.31498138]],\n",
"\n",
" [[-0.00429754, 0.35580526],\n",
" [ 0.23141829, -0.10033515],\n",
" [ 0.08118212, -0.37380152]]],\n",
"\n",
"\n",
" [[[ 0.28702139, -0.00675585],\n",
" [ 0.26061321, 0.16028784],\n",
" [ 0.58456152, 0.66808804]],\n",
"\n",
" [[ 0.12426176, -0.21271792],\n",
" [-0.57620289, 0.1145728 ],\n",
" [-0.12986616, -0.36577064]],\n",
"\n",
" [[ 0.18087245, 0.12187611],\n",
" [ 0.2093346 , -0.4805098 ],\n",
" [ 0.38713581, -0.1013577 ]]]])Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAU, _aea46cAAAAV, _aea46cAAAAL, _aea46cAAAAT, k2,1], tags={I2,1, X2, Y1}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAW, _aea46cAAAAX, _aea46cAAAAN, _aea46cAAAAV, k2,2], tags={I2,2, X2, Y2}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAY, _aea46cAAAAZ, _aea46cAAAAP, _aea46cAAAAX, k2,3], tags={I2,3, X2, Y3}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAa, _aea46cAAAAR, _aea46cAAAAZ, k2,4], tags={I2,4, X2, Y4}),
backend=numpy, dtype=float64, data=array([[[[ 0.01567375, -0.09310011],\n",
" [ 0.24768273, -0.11738978],\n",
" [-0.251629 , -0.1782275 ]],\n",
"\n",
" [[-0.26829665, 0.31267077],\n",
" [-0.22495458, -0.12581883],\n",
" [ 0.26748041, -0.66605332]],\n",
"\n",
" [[-0.023022 , 0.11326969],\n",
" [ 0.18469781, -0.55483234],\n",
" [ 0.32973489, 0.27550022]]],\n",
"\n",
"\n",
" [[[ 0.10759164, -0.63445143],\n",
" [ 0.03337969, 0.25331677],\n",
" [ 0.45157972, -0.17408386]],\n",
"\n",
" [[ 0.20383984, 0.45867942],\n",
" [ 0.01499983, -0.2965261 ],\n",
" [-0.19994835, 0.14174105]],\n",
"\n",
" [[ 0.19374226, -0.60597725],\n",
" [ 0.49222259, 0.19789102],\n",
" [ 0.20171385, 0.0422929 ]]],\n",
"\n",
"\n",
" [[[-0.26715396, -0.16995193],\n",
" [ 0.34863328, 0.45914815],\n",
" [ 0.08663278, 0.61174177]],\n",
"\n",
" [[ 0.22506451, -0.12569846],\n",
" [-0.27588113, -0.29585981],\n",
" [ 0.17803576, 0.11039606]],\n",
"\n",
" [[-0.03518468, -0.36600593],\n",
" [ 0.64683561, 0.09689121],\n",
" [-0.27371473, -0.15114634]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAb, _aea46cAAAAc, _aea46cAAAAS, k3,0], tags={I3,0, X3, Y0}),
backend=numpy, dtype=float64, data=array([[[[-0.03287723, 0.22373023],\n",
" [ 0.21720609, -0.12940337],\n",
" [ 0.26421373, 0.12598597]],\n",
"\n",
" [[-0.05993477, 0.23901176],\n",
" [-0.5080131 , 0.1581344 ],\n",
" [-0.2468453 , -0.24597057]],\n",
"\n",
" [[ 0.05509204, 0.20433684],\n",
" [ 0.25810118, 0.6133055 ],\n",
" [ 0.12314849, 0.09794608]]],\n",
"\n",
"\n",
" [[[ 0.26466672, 0.46330901],\n",
" [-0.37261901, -0.14613522],\n",
" [-0.04725875, -0.05370155]],\n",
"\n",
" [[-0.21671809, -0.6030256 ],\n",
" [ 0.18518784, 0.51043185],\n",
" [ 0.17336402, 0.17334707]],\n",
"\n",
" [[ 0.23415478, 0.31106511],\n",
" [-0.08608762, 0.33643773],\n",
" [-0.02513669, 0.29852203]]],\n",
"\n",
"\n",
" [[[ 0.11660528, -0.63708811],\n",
" [ 0.29317834, 0.55391842],\n",
" [ 0.22281977, 0.02624954]],\n",
"\n",
" [[-0.61615086, 0.31477655],\n",
" [-0.21857305, -0.23485264],\n",
" [-0.07015365, 0.18019487]],\n",
"\n",
" [[ 0.47228582, -0.02025982],\n",
" [ 0.03324436, -0.05201856],\n",
" [ 0.08216902, -0.15068886]]]])Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAd, _aea46cAAAAe, _aea46cAAAAU, _aea46cAAAAc, k3,1], tags={I3,1, X3, Y1}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAf, _aea46cAAAAg, _aea46cAAAAW, _aea46cAAAAe, k3,2], tags={I3,2, X3, Y2}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAh, _aea46cAAAAi, _aea46cAAAAY, _aea46cAAAAg, k3,3], tags={I3,3, X3, Y3}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAj, _aea46cAAAAa, _aea46cAAAAi, k3,4], tags={I3,4, X3, Y4}),
backend=numpy, dtype=float64, data=array([[[[-0.02785434, -0.19377183],\n",
" [ 0.13567531, -0.10062713],\n",
" [-0.07749432, 0.35753385]],\n",
"\n",
" [[-0.25709318, -0.08090333],\n",
" [ 0.10074147, 0.21459987],\n",
" [-0.05594702, 0.48585484]],\n",
"\n",
" [[-0.02995602, -0.12112102],\n",
" [ 0.14817227, 0.37143844],\n",
" [ 0.09314821, 0.2501424 ]]],\n",
"\n",
"\n",
" [[[-0.22927907, -0.16533426],\n",
" [-0.19022857, -0.49516235],\n",
" [ 0.03630534, -0.491662 ]],\n",
"\n",
" [[ 0.66526663, -0.06528429],\n",
" [ 0.19440541, -0.33161728],\n",
" [-0.22234613, -0.22712846]],\n",
"\n",
" [[-0.21079084, -0.07107046],\n",
" [-0.19357984, -0.570392 ],\n",
" [ 0.49999969, 0.07619666]]],\n",
"\n",
"\n",
" [[[-0.36850847, 0.26388082],\n",
" [-0.02058343, -0.5785781 ],\n",
" [-0.13305771, -0.17363738]],\n",
"\n",
" [[-0.01600171, -0.25669566],\n",
" [-0.07669599, 0.34866238],\n",
" [ 0.53794805, -0.77247211]],\n",
"\n",
" [[ 0.46701018, -0.03136358],\n",
" [-0.36865922, 0.55544779],\n",
" [-0.05441975, 0.31138795]]]])Tensor(shape=(3, 3, 2), inds=[_aea46cAAAAk, _aea46cAAAAb, k4,0], tags={I4,0, X4, Y0}),
backend=numpy, dtype=float64, data=array([[[-0.03622255, -0.64783791],\n",
" [-0.35413836, -0.06839641],\n",
" [-0.26610905, -0.4381159 ]],\n",
"\n",
" [[ 0.30796793, -0.02458458],\n",
" [ 0.29830521, -0.13475392],\n",
" [ 0.05871056, -0.29670865]],\n",
"\n",
" [[ 0.08531347, -0.27240719],\n",
" [ 0.03741549, 0.46378323],\n",
" [-0.29799446, -0.68974713]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAl, _aea46cAAAAd, _aea46cAAAAk, k4,1], tags={I4,1, X4, Y1}),
backend=numpy, dtype=float64, data=array([[[[ 7.32071132e-02, 1.63793612e-01],\n",
" [ 1.95103932e-02, 6.34924932e-02],\n",
" [-1.86589186e-01, 5.02850574e-01]],\n",
"\n",
" [[ 2.21822008e-02, 1.45419471e-01],\n",
" [ 1.70098419e-02, -3.45904379e-01],\n",
" [ 1.17070971e-01, 7.49301787e-01]],\n",
"\n",
" [[ 1.82502382e-01, 1.30361449e-01],\n",
" [-6.40960880e-02, -6.50550425e-01],\n",
" [-1.58615286e-01, -2.17396291e-01]]],\n",
"\n",
"\n",
" [[[ 3.36823530e-01, 4.77320168e-01],\n",
" [ 3.33942936e-02, -3.22675181e-01],\n",
" [ 3.00501540e-01, -1.30890164e-01]],\n",
"\n",
" [[-4.93261133e-02, 1.80571112e-01],\n",
" [-8.34259724e-02, -1.36661366e-01],\n",
" [ 6.47967822e-01, 2.89957316e-01]],\n",
"\n",
" [[ 3.51996531e-01, -2.58543810e-01],\n",
" [ 3.93574280e-01, 2.09913863e-01],\n",
" [-1.49833263e-04, -3.14774589e-01]]],\n",
"\n",
"\n",
" [[[ 1.95185567e-01, -3.00442172e-01],\n",
" [ 5.46766593e-01, 2.17461520e-01],\n",
" [ 5.47755703e-01, 1.47049000e-01]],\n",
"\n",
" [[-2.89939243e-02, -2.29325724e-01],\n",
" [-2.19042143e-01, -5.19124212e-01],\n",
" [-2.76151915e-01, -3.36271916e-01]],\n",
"\n",
" [[ 5.01194142e-01, 1.12354943e-01],\n",
" [-2.74712104e-01, 1.17000234e-01],\n",
" [ 1.01969558e-02, -1.37528548e-01]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAm, _aea46cAAAAf, _aea46cAAAAl, k4,2], tags={I4,2, X4, Y2}),
backend=numpy, dtype=float64, data=array([[[[-0.04691427, 0.04518512],\n",
" [-0.48821014, 0.14472043],\n",
" [ 0.2289111 , -0.49996531]],\n",
"\n",
" [[-0.22946103, -0.56242939],\n",
" [-0.1519321 , -0.08036349],\n",
" [-0.07974806, -0.12597931]],\n",
"\n",
" [[ 0.16025181, 0.3009493 ],\n",
" [-0.21928384, -0.14216206],\n",
" [-0.56038647, 0.15624933]]],\n",
"\n",
"\n",
" [[[ 0.24839524, -0.28966023],\n",
" [-0.20838007, -0.18817065],\n",
" [ 0.17665091, -0.02378777]],\n",
"\n",
" [[ 0.35291229, -0.26963928],\n",
" [ 0.16652744, 0.39175549],\n",
" [ 0.00254081, -0.59435346]],\n",
"\n",
" [[ 0.36046884, -0.19522254],\n",
" [-0.00934237, 0.10191553],\n",
" [-0.62675368, 0.20896072]]],\n",
"\n",
"\n",
" [[[ 0.22663422, -0.21799479],\n",
" [-0.10634787, -0.2027503 ],\n",
" [ 0.68532395, -0.02940163]],\n",
"\n",
" [[ 0.1583736 , 0.1362018 ],\n",
" [-0.14871838, 0.16141379],\n",
" [ 0.33185367, 0.43178459]],\n",
"\n",
" [[-0.06391033, 0.27971557],\n",
" [-0.20968179, -0.51190256],\n",
" [ 0.29081901, 0.09433118]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAn, _aea46cAAAAh, _aea46cAAAAm, k4,3], tags={I4,3, X4, Y3}),
backend=numpy, dtype=float64, data=array([[[[-0.04268813, 0.65947468],\n",
" [-0.00643255, -0.57697121],\n",
" [ 0.57728807, 0.70715589]],\n",
"\n",
" [[-0.02511551, 0.29979619],\n",
" [ 0.25984809, 0.37272275],\n",
" [-0.23439044, -0.13467509]],\n",
"\n",
" [[ 0.06414487, 0.11633378],\n",
" [-0.17244477, -0.11933729],\n",
" [-0.06883606, 0.03145422]]],\n",
"\n",
"\n",
" [[[-0.40488939, 0.19470758],\n",
" [ 0.12764037, -0.56489277],\n",
" [-0.18223419, -0.34254078]],\n",
"\n",
" [[ 0.41968604, 0.19940955],\n",
" [ 0.21937432, 0.17137236],\n",
" [-0.09779707, -0.3709037 ]],\n",
"\n",
" [[ 0.09661398, -0.59484165],\n",
" [ 0.16929148, 0.24812902],\n",
" [ 0.23701328, 0.24395429]]],\n",
"\n",
"\n",
" [[[-0.01667156, -0.10023877],\n",
" [-0.00398862, -0.02343363],\n",
" [ 0.47390102, 0.32692523]],\n",
"\n",
" [[ 0.70393136, 0.02803209],\n",
" [-0.21699308, -0.21125616],\n",
" [ 0.30153273, 0.38770508]],\n",
"\n",
" [[-0.16267959, -0.18765657],\n",
" [ 0.00855063, -0.16643927],\n",
" [-0.19250898, 0.23623521]]]])Tensor(shape=(3, 3, 2), inds=[_aea46cAAAAj, _aea46cAAAAn, k4,4], tags={I4,4, X4, Y4}),
backend=numpy, dtype=float64, data=array([[[ 0.04200821, 0.31899505],\n",
" [-0.21784933, -0.42481105],\n",
" [-0.45498257, 0.35867999]],\n",
"\n",
" [[ 0.24995048, -0.17124387],\n",
" [ 0.52845545, 0.69610531],\n",
" [ 0.18589178, -0.07414434]],\n",
"\n",
" [[-0.25978338, -0.16469329],\n",
" [ 0.01989423, -0.17488996],\n",
" [-0.23159834, -0.48782655]]])Tensor(shape=(3, 3, 2), inds=[_aea46cAAAAs, _aea46cAAAAo, k0,0], tags={I0,0, X0, Y0}),
backend=numpy, dtype=float64, data=array([[[ 0.19758123, -0.20600803],\n",
" [-0.02115149, -0.30155026],\n",
" [ 0.08369179, 0.42321298]],\n",
"\n",
" [[-0.78599677, 0.27198615],\n",
" [-0.01315806, -0.26534693],\n",
" [-0.00531344, 0.33645332]],\n",
"\n",
" [[-0.57577375, 0.10554638],\n",
" [-0.07281841, 0.45726951],\n",
" [ 0.26362141, -0.08463805]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAt, _aea46cAAAAp, _aea46cAAAAo, k0,1], tags={I0,1, X0, Y1}),
backend=numpy, dtype=float64, data=array([[[[-0.0886793 , 0.38960521],\n",
" [-0.07864096, -0.1405622 ],\n",
" [-0.27039043, 0.40912656]],\n",
"\n",
" [[-0.25722849, -0.3621938 ],\n",
" [-0.01145245, 0.07481682],\n",
" [-0.04101569, -0.31399061]],\n",
"\n",
" [[-0.0585233 , 0.08844857],\n",
" [-0.34306234, 0.14325768],\n",
" [ 0.44382168, -0.17613362]]],\n",
"\n",
"\n",
" [[[-0.11086622, -0.07888345],\n",
" [-0.08731526, -0.1098593 ],\n",
" [-0.08997919, -0.25855771]],\n",
"\n",
" [[-0.00974778, -0.06474578],\n",
" [-0.53768285, 0.26626594],\n",
" [ 0.1852418 , -0.17064799]],\n",
"\n",
" [[-0.23546533, 0.10044162],\n",
" [-0.04641026, -0.33127844],\n",
" [ 0.31312999, 0.24287011]]],\n",
"\n",
"\n",
" [[[-0.41959896, -0.14805525],\n",
" [ 0.02569746, -0.49149678],\n",
" [-0.08605362, 0.07599989]],\n",
"\n",
" [[-0.19989431, -0.1171608 ],\n",
" [-0.27427135, -0.18171656],\n",
" [-0.35111996, -0.0948195 ]],\n",
"\n",
" [[ 0.33734665, -0.66881823],\n",
" [ 0.2574683 , -0.32198307],\n",
" [-0.44438948, 0.2297073 ]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAv, _aea46cAAAAq, _aea46cAAAAp, k0,2], tags={I0,2, X0, Y2}),
backend=numpy, dtype=float64, data=array([[[[ 0.00787712, 0.07483492],\n",
" [ 0.23423454, -0.41977078],\n",
" [-0.07098577, -0.08227457]],\n",
"\n",
" [[ 0.58049387, -0.28265144],\n",
" [-0.50102255, -0.1383515 ],\n",
" [ 0.46154386, 0.15899825]],\n",
"\n",
" [[-0.48357646, -0.32435753],\n",
" [-0.24554998, -0.0063898 ],\n",
" [-0.4288379 , 0.28063253]]],\n",
"\n",
"\n",
" [[[ 0.4529943 , 0.12319876],\n",
" [-0.12452825, -0.25212084],\n",
" [ 0.07434282, 0.07358095]],\n",
"\n",
" [[-0.07124641, -0.06452709],\n",
" [-0.10609616, 0.06050403],\n",
" [-0.27691535, 0.18652204]],\n",
"\n",
" [[ 0.18944672, 0.28066808],\n",
" [-0.26338667, 0.05858565],\n",
" [ 0.17191266, 0.09251535]]],\n",
"\n",
"\n",
" [[[-0.40473276, -0.77385977],\n",
" [ 0.15369863, 0.34102213],\n",
" [-0.3052184 , 0.00141725]],\n",
"\n",
" [[ 0.07717418, 0.39021751],\n",
" [ 0.37797629, -0.3581846 ],\n",
" [-0.00915705, -0.21592738]],\n",
"\n",
" [[ 0.21857823, 0.02861824],\n",
" [-0.12619608, 0.21470106],\n",
" [ 0.26837599, 0.3497904 ]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAx, _aea46cAAAAr, _aea46cAAAAq, k0,3], tags={I0,3, X0, Y3}),
backend=numpy, dtype=float64, data=array([[[[-0.35302799, -0.18588165],\n",
" [ 0.06628363, 0.18146305],\n",
" [-0.64362369, -0.2252469 ]],\n",
"\n",
" [[ 0.08364773, 0.01679925],\n",
" [ 0.18941434, -0.14216882],\n",
" [-0.07795615, 0.24121163]],\n",
"\n",
" [[ 0.36766087, 0.18291524],\n",
" [ 0.48242292, 0.17032754],\n",
" [-0.18111091, 0.32120585]]],\n",
"\n",
"\n",
" [[[-0.73965826, 0.12207832],\n",
" [-0.21999 , -0.35361801],\n",
" [-0.36855658, -0.31388888]],\n",
"\n",
" [[ 0.41657027, 0.14911351],\n",
" [-0.03321268, -0.036751 ],\n",
" [ 0.27384496, -0.24498083]],\n",
"\n",
" [[ 0.35392829, 0.46963827],\n",
" [-0.28648917, -0.16491934],\n",
" [ 0.08454636, 0.3485048 ]]],\n",
"\n",
"\n",
" [[[-0.2487877 , -0.81637444],\n",
" [-0.11929533, 0.21710726],\n",
" [-0.05459544, -0.16750029]],\n",
"\n",
" [[-0.12530134, -0.44630833],\n",
" [ 0.22974167, -0.14514381],\n",
" [ 0.32546501, -0.07342843]],\n",
"\n",
" [[-0.26259823, 0.26310325],\n",
" [-0.1439656 , 0.08012546],\n",
" [ 0.14057252, -0.31473198]]]])Tensor(shape=(3, 3, 2), inds=[_aea46cAAAAz, _aea46cAAAAr, k0,4], tags={I0,4, X0, Y4}),
backend=numpy, dtype=float64, data=array([[[ 0.43152581, -0.23969586],\n",
" [-0.16808012, 0.08247557],\n",
" [ 0.33020835, -0.28069495]],\n",
"\n",
" [[-0.15814594, -0.3455025 ],\n",
" [-0.4347297 , -0.65814361],\n",
" [ 0.24335002, 0.01839728]],\n",
"\n",
" [[-0.18092796, 0.07677303],\n",
" [-0.27159058, -0.12283561],\n",
" [-0.37800116, -0.40040474]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAABB, _aea46cAAAAu, _aea46cAAAAs, k1,0], tags={I1,0, X1, Y0}),
backend=numpy, dtype=float64, data=array([[[[ 0.78977302, 0.20610627],\n",
" [-0.17232708, -0.32686794],\n",
" [ 0.12781562, -0.11373377]],\n",
"\n",
" [[ 0.09609733, 0.32360355],\n",
" [-0.14147276, 0.08949845],\n",
" [-0.14720314, -0.19955648]],\n",
"\n",
" [[-0.2027934 , -0.11879961],\n",
" [-0.14779857, 0.06389199],\n",
" [-0.06141446, -0.08943344]]],\n",
"\n",
"\n",
" [[[ 0.01172702, 0.65384372],\n",
" [-0.4016258 , 0.62405045],\n",
" [ 0.0183161 , -0.42458339]],\n",
"\n",
" [[ 0.00276003, 0.25519974],\n",
" [-0.29860681, -0.19277402],\n",
" [ 0.36346475, 0.07670103]],\n",
"\n",
" [[-0.2414894 , 0.04928607],\n",
" [-0.53921085, 0.55625126],\n",
" [ 0.33501048, 0.14937114]]],\n",
"\n",
"\n",
" [[[ 0.47162932, 0.17082597],\n",
" [ 0.06865947, -0.28654631],\n",
" [-0.46735522, -0.20633878]],\n",
"\n",
" [[ 0.24972016, -0.17040072],\n",
" [ 0.15429501, 0.4294151 ],\n",
" [-0.19904102, -0.00177625]],\n",
"\n",
" [[ 0.05496409, 0.03333935],\n",
" [-0.25443675, 0.27334373],\n",
" [ 0.05015645, 0.10742787]]]])Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAABC, _aea46cAAAAw, _aea46cAAAAt, _aea46cAAAAu, k1,1], tags={I1,1, X1, Y1}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAABE, _aea46cAAAAy, _aea46cAAAAv, _aea46cAAAAw, k1,2], tags={I1,2, X1, Y2}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAABG, _aea46cAAABA, _aea46cAAAAx, _aea46cAAAAy, k1,3], tags={I1,3, X1, Y3}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAABI, _aea46cAAAAz, _aea46cAAABA, k1,4], tags={I1,4, X1, Y4}),
backend=numpy, dtype=float64, data=array([[[[ 0.36548229, -0.26015584],\n",
" [ 0.14163331, -0.06427805],\n",
" [ 0.3257745 , -0.53845238]],\n",
"\n",
" [[ 0.49660934, 0.35980179],\n",
" [ 0.35161007, -0.26212529],\n",
" [ 0.17691887, -0.41049041]],\n",
"\n",
" [[ 0.35321357, 0.14903971],\n",
" [ 0.58041384, -0.14440401],\n",
" [ 0.10477843, 0.04271563]]],\n",
"\n",
"\n",
" [[[-0.18523296, 0.08600995],\n",
" [-0.00249853, 0.00309299],\n",
" [-0.38302772, -0.11931442]],\n",
"\n",
" [[-0.01032181, 0.35569799],\n",
" [-0.1177868 , 0.09307973],\n",
" [-0.32977233, 0.31827419]],\n",
"\n",
" [[-0.01066864, 0.5333739 ],\n",
" [-0.51256 , 0.03966059],\n",
" [ 0.25838267, -0.18445352]]],\n",
"\n",
"\n",
" [[[ 0.45910942, 0.03237033],\n",
" [ 0.1103594 , -0.06656127],\n",
" [-0.28261971, 0.47622606]],\n",
"\n",
" [[ 0.2713872 , 0.22772949],\n",
" [-0.70921321, -0.6142656 ],\n",
" [-0.22789126, -0.07517024]],\n",
"\n",
" [[-0.18087422, 0.29178375],\n",
" [-0.17016618, -0.13840751],\n",
" [-0.15878981, -0.07968 ]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAABK, _aea46cAAABD, _aea46cAAABB, k2,0], tags={I2,0, X2, Y0}),
backend=numpy, dtype=float64, data=array([[[[-0.38056033, 0.24804757],\n",
" [-0.07572871, -0.13027434],\n",
" [-0.30343203, 0.09497906]],\n",
"\n",
" [[ 0.08621316, -0.30894061],\n",
" [-0.07400557, 0.2997675 ],\n",
" [ 0.13113942, -0.02904785]],\n",
"\n",
" [[-0.47955682, 0.73818644],\n",
" [-0.08958236, -0.44780715],\n",
" [-0.27007575, -0.09415205]]],\n",
"\n",
"\n",
" [[[-0.1108852 , 0.0971295 ],\n",
" [-0.19637978, -0.23722133],\n",
" [-0.3326612 , -0.14791084]],\n",
"\n",
" [[-0.1607138 , -0.3585758 ],\n",
" [ 0.17374931, 0.07621275],\n",
" [-0.13889808, 0.31498138]],\n",
"\n",
" [[-0.00429754, 0.35580526],\n",
" [ 0.23141829, -0.10033515],\n",
" [ 0.08118212, -0.37380152]]],\n",
"\n",
"\n",
" [[[ 0.28702139, -0.00675585],\n",
" [ 0.26061321, 0.16028784],\n",
" [ 0.58456152, 0.66808804]],\n",
"\n",
" [[ 0.12426176, -0.21271792],\n",
" [-0.57620289, 0.1145728 ],\n",
" [-0.12986616, -0.36577064]],\n",
"\n",
" [[ 0.18087245, 0.12187611],\n",
" [ 0.2093346 , -0.4805098 ],\n",
" [ 0.38713581, -0.1013577 ]]]])Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAABL, _aea46cAAABF, _aea46cAAABC, _aea46cAAABD, k2,1], tags={I2,1, X2, Y1}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAABN, _aea46cAAABH, _aea46cAAABE, _aea46cAAABF, k2,2], tags={I2,2, X2, Y2}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAABP, _aea46cAAABJ, _aea46cAAABG, _aea46cAAABH, k2,3], tags={I2,3, X2, Y3}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAABR, _aea46cAAABI, _aea46cAAABJ, k2,4], tags={I2,4, X2, Y4}),
backend=numpy, dtype=float64, data=array([[[[ 0.01567375, -0.09310011],\n",
" [ 0.24768273, -0.11738978],\n",
" [-0.251629 , -0.1782275 ]],\n",
"\n",
" [[-0.26829665, 0.31267077],\n",
" [-0.22495458, -0.12581883],\n",
" [ 0.26748041, -0.66605332]],\n",
"\n",
" [[-0.023022 , 0.11326969],\n",
" [ 0.18469781, -0.55483234],\n",
" [ 0.32973489, 0.27550022]]],\n",
"\n",
"\n",
" [[[ 0.10759164, -0.63445143],\n",
" [ 0.03337969, 0.25331677],\n",
" [ 0.45157972, -0.17408386]],\n",
"\n",
" [[ 0.20383984, 0.45867942],\n",
" [ 0.01499983, -0.2965261 ],\n",
" [-0.19994835, 0.14174105]],\n",
"\n",
" [[ 0.19374226, -0.60597725],\n",
" [ 0.49222259, 0.19789102],\n",
" [ 0.20171385, 0.0422929 ]]],\n",
"\n",
"\n",
" [[[-0.26715396, -0.16995193],\n",
" [ 0.34863328, 0.45914815],\n",
" [ 0.08663278, 0.61174177]],\n",
"\n",
" [[ 0.22506451, -0.12569846],\n",
" [-0.27588113, -0.29585981],\n",
" [ 0.17803576, 0.11039606]],\n",
"\n",
" [[-0.03518468, -0.36600593],\n",
" [ 0.64683561, 0.09689121],\n",
" [-0.27371473, -0.15114634]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAABT, _aea46cAAABM, _aea46cAAABK, k3,0], tags={I3,0, X3, Y0}),
backend=numpy, dtype=float64, data=array([[[[-0.03287723, 0.22373023],\n",
" [ 0.21720609, -0.12940337],\n",
" [ 0.26421373, 0.12598597]],\n",
"\n",
" [[-0.05993477, 0.23901176],\n",
" [-0.5080131 , 0.1581344 ],\n",
" [-0.2468453 , -0.24597057]],\n",
"\n",
" [[ 0.05509204, 0.20433684],\n",
" [ 0.25810118, 0.6133055 ],\n",
" [ 0.12314849, 0.09794608]]],\n",
"\n",
"\n",
" [[[ 0.26466672, 0.46330901],\n",
" [-0.37261901, -0.14613522],\n",
" [-0.04725875, -0.05370155]],\n",
"\n",
" [[-0.21671809, -0.6030256 ],\n",
" [ 0.18518784, 0.51043185],\n",
" [ 0.17336402, 0.17334707]],\n",
"\n",
" [[ 0.23415478, 0.31106511],\n",
" [-0.08608762, 0.33643773],\n",
" [-0.02513669, 0.29852203]]],\n",
"\n",
"\n",
" [[[ 0.11660528, -0.63708811],\n",
" [ 0.29317834, 0.55391842],\n",
" [ 0.22281977, 0.02624954]],\n",
"\n",
" [[-0.61615086, 0.31477655],\n",
" [-0.21857305, -0.23485264],\n",
" [-0.07015365, 0.18019487]],\n",
"\n",
" [[ 0.47228582, -0.02025982],\n",
" [ 0.03324436, -0.05201856],\n",
" [ 0.08216902, -0.15068886]]]])Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAABU, _aea46cAAABO, _aea46cAAABL, _aea46cAAABM, k3,1], tags={I3,1, X3, Y1}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAABW, _aea46cAAABQ, _aea46cAAABN, _aea46cAAABO, k3,2], tags={I3,2, X3, Y2}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAABY, _aea46cAAABS, _aea46cAAABP, _aea46cAAABQ, k3,3], tags={I3,3, X3, Y3}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAABa, _aea46cAAABR, _aea46cAAABS, k3,4], tags={I3,4, X3, Y4}),
backend=numpy, dtype=float64, data=array([[[[-0.02785434, -0.19377183],\n",
" [ 0.13567531, -0.10062713],\n",
" [-0.07749432, 0.35753385]],\n",
"\n",
" [[-0.25709318, -0.08090333],\n",
" [ 0.10074147, 0.21459987],\n",
" [-0.05594702, 0.48585484]],\n",
"\n",
" [[-0.02995602, -0.12112102],\n",
" [ 0.14817227, 0.37143844],\n",
" [ 0.09314821, 0.2501424 ]]],\n",
"\n",
"\n",
" [[[-0.22927907, -0.16533426],\n",
" [-0.19022857, -0.49516235],\n",
" [ 0.03630534, -0.491662 ]],\n",
"\n",
" [[ 0.66526663, -0.06528429],\n",
" [ 0.19440541, -0.33161728],\n",
" [-0.22234613, -0.22712846]],\n",
"\n",
" [[-0.21079084, -0.07107046],\n",
" [-0.19357984, -0.570392 ],\n",
" [ 0.49999969, 0.07619666]]],\n",
"\n",
"\n",
" [[[-0.36850847, 0.26388082],\n",
" [-0.02058343, -0.5785781 ],\n",
" [-0.13305771, -0.17363738]],\n",
"\n",
" [[-0.01600171, -0.25669566],\n",
" [-0.07669599, 0.34866238],\n",
" [ 0.53794805, -0.77247211]],\n",
"\n",
" [[ 0.46701018, -0.03136358],\n",
" [-0.36865922, 0.55544779],\n",
" [-0.05441975, 0.31138795]]]])Tensor(shape=(3, 3, 2), inds=[_aea46cAAABV, _aea46cAAABT, k4,0], tags={I4,0, X4, Y0}),
backend=numpy, dtype=float64, data=array([[[-0.03622255, -0.64783791],\n",
" [-0.35413836, -0.06839641],\n",
" [-0.26610905, -0.4381159 ]],\n",
"\n",
" [[ 0.30796793, -0.02458458],\n",
" [ 0.29830521, -0.13475392],\n",
" [ 0.05871056, -0.29670865]],\n",
"\n",
" [[ 0.08531347, -0.27240719],\n",
" [ 0.03741549, 0.46378323],\n",
" [-0.29799446, -0.68974713]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAABX, _aea46cAAABU, _aea46cAAABV, k4,1], tags={I4,1, X4, Y1}),
backend=numpy, dtype=float64, data=array([[[[ 7.32071132e-02, 1.63793612e-01],\n",
" [ 1.95103932e-02, 6.34924932e-02],\n",
" [-1.86589186e-01, 5.02850574e-01]],\n",
"\n",
" [[ 2.21822008e-02, 1.45419471e-01],\n",
" [ 1.70098419e-02, -3.45904379e-01],\n",
" [ 1.17070971e-01, 7.49301787e-01]],\n",
"\n",
" [[ 1.82502382e-01, 1.30361449e-01],\n",
" [-6.40960880e-02, -6.50550425e-01],\n",
" [-1.58615286e-01, -2.17396291e-01]]],\n",
"\n",
"\n",
" [[[ 3.36823530e-01, 4.77320168e-01],\n",
" [ 3.33942936e-02, -3.22675181e-01],\n",
" [ 3.00501540e-01, -1.30890164e-01]],\n",
"\n",
" [[-4.93261133e-02, 1.80571112e-01],\n",
" [-8.34259724e-02, -1.36661366e-01],\n",
" [ 6.47967822e-01, 2.89957316e-01]],\n",
"\n",
" [[ 3.51996531e-01, -2.58543810e-01],\n",
" [ 3.93574280e-01, 2.09913863e-01],\n",
" [-1.49833263e-04, -3.14774589e-01]]],\n",
"\n",
"\n",
" [[[ 1.95185567e-01, -3.00442172e-01],\n",
" [ 5.46766593e-01, 2.17461520e-01],\n",
" [ 5.47755703e-01, 1.47049000e-01]],\n",
"\n",
" [[-2.89939243e-02, -2.29325724e-01],\n",
" [-2.19042143e-01, -5.19124212e-01],\n",
" [-2.76151915e-01, -3.36271916e-01]],\n",
"\n",
" [[ 5.01194142e-01, 1.12354943e-01],\n",
" [-2.74712104e-01, 1.17000234e-01],\n",
" [ 1.01969558e-02, -1.37528548e-01]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAABZ, _aea46cAAABW, _aea46cAAABX, k4,2], tags={I4,2, X4, Y2}),
backend=numpy, dtype=float64, data=array([[[[-0.04691427, 0.04518512],\n",
" [-0.48821014, 0.14472043],\n",
" [ 0.2289111 , -0.49996531]],\n",
"\n",
" [[-0.22946103, -0.56242939],\n",
" [-0.1519321 , -0.08036349],\n",
" [-0.07974806, -0.12597931]],\n",
"\n",
" [[ 0.16025181, 0.3009493 ],\n",
" [-0.21928384, -0.14216206],\n",
" [-0.56038647, 0.15624933]]],\n",
"\n",
"\n",
" [[[ 0.24839524, -0.28966023],\n",
" [-0.20838007, -0.18817065],\n",
" [ 0.17665091, -0.02378777]],\n",
"\n",
" [[ 0.35291229, -0.26963928],\n",
" [ 0.16652744, 0.39175549],\n",
" [ 0.00254081, -0.59435346]],\n",
"\n",
" [[ 0.36046884, -0.19522254],\n",
" [-0.00934237, 0.10191553],\n",
" [-0.62675368, 0.20896072]]],\n",
"\n",
"\n",
" [[[ 0.22663422, -0.21799479],\n",
" [-0.10634787, -0.2027503 ],\n",
" [ 0.68532395, -0.02940163]],\n",
"\n",
" [[ 0.1583736 , 0.1362018 ],\n",
" [-0.14871838, 0.16141379],\n",
" [ 0.33185367, 0.43178459]],\n",
"\n",
" [[-0.06391033, 0.27971557],\n",
" [-0.20968179, -0.51190256],\n",
" [ 0.29081901, 0.09433118]]]])Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAABb, _aea46cAAABY, _aea46cAAABZ, k4,3], tags={I4,3, X4, Y3}),
backend=numpy, dtype=float64, data=array([[[[-0.04268813, 0.65947468],\n",
" [-0.00643255, -0.57697121],\n",
" [ 0.57728807, 0.70715589]],\n",
"\n",
" [[-0.02511551, 0.29979619],\n",
" [ 0.25984809, 0.37272275],\n",
" [-0.23439044, -0.13467509]],\n",
"\n",
" [[ 0.06414487, 0.11633378],\n",
" [-0.17244477, -0.11933729],\n",
" [-0.06883606, 0.03145422]]],\n",
"\n",
"\n",
" [[[-0.40488939, 0.19470758],\n",
" [ 0.12764037, -0.56489277],\n",
" [-0.18223419, -0.34254078]],\n",
"\n",
" [[ 0.41968604, 0.19940955],\n",
" [ 0.21937432, 0.17137236],\n",
" [-0.09779707, -0.3709037 ]],\n",
"\n",
" [[ 0.09661398, -0.59484165],\n",
" [ 0.16929148, 0.24812902],\n",
" [ 0.23701328, 0.24395429]]],\n",
"\n",
"\n",
" [[[-0.01667156, -0.10023877],\n",
" [-0.00398862, -0.02343363],\n",
" [ 0.47390102, 0.32692523]],\n",
"\n",
" [[ 0.70393136, 0.02803209],\n",
" [-0.21699308, -0.21125616],\n",
" [ 0.30153273, 0.38770508]],\n",
"\n",
" [[-0.16267959, -0.18765657],\n",
" [ 0.00855063, -0.16643927],\n",
" [-0.19250898, 0.23623521]]]])Tensor(shape=(3, 3, 2), inds=[_aea46cAAABa, _aea46cAAABb, k4,4], tags={I4,4, X4, Y4}),
backend=numpy, dtype=float64, data=array([[[ 0.04200821, 0.31899505],\n",
" [-0.21784933, -0.42481105],\n",
" [-0.45498257, 0.35867999]],\n",
"\n",
" [[ 0.24995048, -0.17124387],\n",
" [ 0.52845545, 0.69610531],\n",
" [ 0.18589178, -0.07414434]],\n",
"\n",
" [[-0.25978338, -0.16469329],\n",
" [ 0.01989423, -0.17488996],\n",
" [-0.23159834, -0.48782655]]]) "
],
"text/plain": [
"TensorNetwork2D(tensors=50, indices=105, Lx=5, Ly=5, max_bond=3)"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"norm = peps.H & peps\n",
"norm"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "a4cf759f-ae7a-4a26-95d9-e28330f31039",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"norm.draw(color=norm.site_tags, figsize=(4, 4))"
]
},
{
"cell_type": "markdown",
"id": "6f0b0d46-dc88-4d9c-9596-f55df99fd8e0",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"## Contracting 2D Tensor Networks\n",
"\n",
"Note that unlike 1D tensor networks, 2D tensor networks cannot be efficiently\n",
"contracted exactly, and so care should taken when calling `.contract`\n",
"directly. Our PEPS here is still small enough however for our memory:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "6b0d38a7-b6a5-42d4-8059-1424a4bba4fd",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.5077521135992215"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"norm.contract(all, optimize=\"auto-hq\")"
]
},
{
"cell_type": "markdown",
"id": "e8f2dfda-6f65-4213-8b73-a8ba5eae9f42",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"The `contract` function then treats it as any other tensor network.\n",
"\n",
"More generally, one would want to use **boundary contraction** to approximately\n",
"contract any 2D tensor networks, using one of the following methods:\n",
"\n",
"- {meth}`~quimb.tensor.tn2d.core.TensorNetwork2D.contract_boundary`,\n",
"- {meth}`~quimb.tensor.tn2d.core.TensorNetwork2D.contract_boundary_from_bottom`,\n",
"- {meth}`~quimb.tensor.tn2d.core.TensorNetwork2D.contract_boundary_from_left`,\n",
"- {meth}`~quimb.tensor.tn2d.core.TensorNetwork2D.contract_boundary_from_top`,\n",
"- {meth}`~quimb.tensor.tn2d.core.TensorNetwork2D.contract_boundary_from_right`,\n",
"\n",
"Here, one *compresses* between tensors as we\n",
"contract to limit bonds from growing beyond a maximum size:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "cdc75e9d-fc49-4baf-9e10-2f57ffa0982b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 1.62 s, sys: 34.8 ms, total: 1.65 s\n",
"Wall time: 234 ms\n"
]
},
{
"data": {
"text/plain": [
"0.506999178700516"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%time\n",
"norm.contract_boundary(max_bond=32)"
]
},
{
"cell_type": "markdown",
"id": "ba1d189a-427d-4d39-9998-2b39db631b02",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"We can see here than the answer is slightly off, even with a large bond\n",
"dimension of `64` (random PEPS are harder than 'physical' PEPS to\n",
"contract usually).\n",
"\n",
":::{warning}\n",
"The default options for\n",
"{meth}`~quimb.tensor.tn2d.core.TensorNetwork2D.contract_boundary` are those\n",
"of {func}`~quimb.tensor.tensor_core.tensor_split`, meaning\n",
"`max_bond=None` (no dimension limit) and `cutoff=1e-10` (only remove\n",
"very small singular values). **These won't be nearly aggressive enough to\n",
"contract most 2D TNs efficiently - you should set these!**\n",
":::"
]
},
{
"cell_type": "markdown",
"id": "9866d316-2ca2-4862-9499-0ab974cd9c68",
"metadata": {},
"source": [
"By default `contract_boundary` also flattens the TN as it goes.\n",
"If you want to do a multilayer boundary contraction you need to tag\n",
"the different layers and specify them:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "3e2d29b1-0520-48b7-8011-b6dae7f58236",
"metadata": {},
"outputs": [],
"source": [
"peps.add_tag(\"KET\")\n",
"pepsH = peps.conj().retag({\"KET\": \"BRA\"})\n",
"norm = pepsH & peps"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "dafeca62-cd01-4bd6-b97f-b85502474ca0",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"norm.draw(color=[\"KET\", \"BRA\"], figsize=(3, 3))"
]
},
{
"cell_type": "markdown",
"id": "41252ed8-b5db-4648-bf6f-e55cce15cdef",
"metadata": {},
"source": [
"Now we can specify `layer_tags=['KET', 'BRA']` to any of the boundary\n",
"contraction methods. Here we perform an inplace boundary contraction around\n",
"the sites `(2, 2)` and `(2, 3)`."
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "ada08cfa-e0e9-499a-9061-7ae10a245328",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"TensorNetwork2D(tensors=15, indices=29, Lx=5, Ly=5, max_bond=64)
Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAW, _aea46cAAAAX, _aea46cAAAAN, _aea46cAAAAV, k2,2], tags={I2,2, X2, Y2, BRA}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAAAY, _aea46cAAAAZ, _aea46cAAAAP, _aea46cAAAAX, k2,3], tags={I2,3, X2, Y3, BRA}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAAAa, _aea46cAAAAR, _aea46cAAAAZ, k2,4], tags={I2,4, X2, Y4, BRA}),
backend=numpy, dtype=float64, data=array([[[[ 0.01567375, -0.09310011],\n",
" [ 0.24768273, -0.11738978],\n",
" [-0.251629 , -0.1782275 ]],\n",
"\n",
" [[-0.26829665, 0.31267077],\n",
" [-0.22495458, -0.12581883],\n",
" [ 0.26748041, -0.66605332]],\n",
"\n",
" [[-0.023022 , 0.11326969],\n",
" [ 0.18469781, -0.55483234],\n",
" [ 0.32973489, 0.27550022]]],\n",
"\n",
"\n",
" [[[ 0.10759164, -0.63445143],\n",
" [ 0.03337969, 0.25331677],\n",
" [ 0.45157972, -0.17408386]],\n",
"\n",
" [[ 0.20383984, 0.45867942],\n",
" [ 0.01499983, -0.2965261 ],\n",
" [-0.19994835, 0.14174105]],\n",
"\n",
" [[ 0.19374226, -0.60597725],\n",
" [ 0.49222259, 0.19789102],\n",
" [ 0.20171385, 0.0422929 ]]],\n",
"\n",
"\n",
" [[[-0.26715396, -0.16995193],\n",
" [ 0.34863328, 0.45914815],\n",
" [ 0.08663278, 0.61174177]],\n",
"\n",
" [[ 0.22506451, -0.12569846],\n",
" [-0.27588113, -0.29585981],\n",
" [ 0.17803576, 0.11039606]],\n",
"\n",
" [[-0.03518468, -0.36600593],\n",
" [ 0.64683561, 0.09689121],\n",
" [-0.27371473, -0.15114634]]]])Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAACl, _aea46cAAACf, _aea46cAAACc, _aea46cAAACd, k2,2], tags={I2,2, X2, Y2, KET}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 3, 2), inds=[_aea46cAAACn, _aea46cAAACh, _aea46cAAACe, _aea46cAAACf, k2,3], tags={I2,3, X2, Y3, KET}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 3, 3, 2), inds=[_aea46cAAACp, _aea46cAAACg, _aea46cAAACh, k2,4], tags={I2,4, X2, Y4, KET}),
backend=numpy, dtype=float64, data=array([[[[ 0.01567375, -0.09310011],\n",
" [ 0.24768273, -0.11738978],\n",
" [-0.251629 , -0.1782275 ]],\n",
"\n",
" [[-0.26829665, 0.31267077],\n",
" [-0.22495458, -0.12581883],\n",
" [ 0.26748041, -0.66605332]],\n",
"\n",
" [[-0.023022 , 0.11326969],\n",
" [ 0.18469781, -0.55483234],\n",
" [ 0.32973489, 0.27550022]]],\n",
"\n",
"\n",
" [[[ 0.10759164, -0.63445143],\n",
" [ 0.03337969, 0.25331677],\n",
" [ 0.45157972, -0.17408386]],\n",
"\n",
" [[ 0.20383984, 0.45867942],\n",
" [ 0.01499983, -0.2965261 ],\n",
" [-0.19994835, 0.14174105]],\n",
"\n",
" [[ 0.19374226, -0.60597725],\n",
" [ 0.49222259, 0.19789102],\n",
" [ 0.20171385, 0.0422929 ]]],\n",
"\n",
"\n",
" [[[-0.26715396, -0.16995193],\n",
" [ 0.34863328, 0.45914815],\n",
" [ 0.08663278, 0.61174177]],\n",
"\n",
" [[ 0.22506451, -0.12569846],\n",
" [-0.27588113, -0.29585981],\n",
" [ 0.17803576, 0.11039606]],\n",
"\n",
" [[-0.03518468, -0.36600593],\n",
" [ 0.64683561, 0.09689121],\n",
" [-0.27371473, -0.15114634]]]])Tensor(shape=(3, 64, 64, 3), inds=[_aea46cAAAAN, _aea46cAAAAO, _aea46cAAAAM, _aea46cAAACc], tags={I1,2, X1, Y2, BRA, I0,2, X0, KET}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 9, 64, 3), inds=[_aea46cAAAAP, _aea46cAAAAQ, _aea46cAAAAO, _aea46cAAACe], tags={I1,3, X1, Y3, BRA, I0,3, X0, KET}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 9, 3), inds=[_aea46cAAAAR, _aea46cAAAAQ, _aea46cAAACg], tags={I1,4, X1, Y4, BRA, I0,4, X0, KET}),
backend=numpy, dtype=float64, data=array([[[ 3.56981949e-01, -1.00848316e-01, -2.99876514e-02],\n",
" [-7.47813095e-02, 5.10592372e-02, 9.14969049e-02],\n",
" [ 5.78916294e-02, 6.67496076e-02, 2.51375552e-02],\n",
" [ 1.95345094e-02, -2.59605747e-02, 4.49697344e-02],\n",
" [-2.49502542e-16, 2.33798059e-03, -1.79005072e-02],\n",
" [-9.95379525e-17, 6.49172701e-03, -6.21682059e-02],\n",
" [ 1.72158407e-02, 2.49273391e-02, -1.80900169e-02],\n",
" [ 3.13082868e-02, -6.19052797e-03, 1.26882184e-02],\n",
" [ 9.54505940e-18, -2.92696256e-02, -3.10374293e-03]],\n",
"\n",
" [[-1.00848316e-01, 2.18405978e-01, 7.80502424e-02],\n",
" [ 5.10592372e-02, -3.02687053e-02, 3.19057027e-02],\n",
" [ 6.67496076e-02, 5.33148577e-02, -3.61814356e-02],\n",
" [-2.59605747e-02, 2.70028274e-02, 4.04028883e-02],\n",
" [-2.33798059e-03, 1.77209692e-16, 7.02352038e-02],\n",
" [-6.49172701e-03, -2.46153143e-16, -1.60606062e-02],\n",
" [ 2.49273391e-02, -2.13476966e-02, 3.43397018e-02],\n",
" [-6.19052797e-03, -4.52032230e-02, -1.07501528e-02],\n",
" [ 2.92696256e-02, -2.88552932e-17, 1.83287627e-04]],\n",
"\n",
" [[-2.99876514e-02, 7.80502424e-02, 4.03700019e-01],\n",
" [ 9.14969049e-02, 3.19057027e-02, 1.09269202e-01],\n",
" [ 2.51375552e-02, -3.61814356e-02, -2.89616215e-02],\n",
" [ 4.49697344e-02, 4.04028883e-02, -5.37950028e-02],\n",
" [ 1.79005072e-02, -7.02352038e-02, 4.56094424e-16],\n",
" [ 6.21682059e-02, 1.60606062e-02, 2.28696561e-17],\n",
" [-1.80900169e-02, 3.43397018e-02, -7.18582529e-03],\n",
" [ 1.26882184e-02, -1.07501528e-02, -2.80812365e-04],\n",
" [ 3.10374293e-03, -1.83287627e-04, 2.38880536e-18]]])Tensor(shape=(64, 3, 64, 3), inds=[_aea46cAAAAg, _aea46cAAAAW, _aea46cAAAAe, _aea46cAAACl], tags={I3,2, X3, Y2, BRA, I4,2, X4, KET}),
backend=numpy, dtype=float64, data=...Tensor(shape=(9, 3, 64, 3), inds=[_aea46cAAAAi, _aea46cAAAAY, _aea46cAAAAg, _aea46cAAACn], tags={I3,3, X3, Y3, BRA, I4,3, X4, KET}),
backend=numpy, dtype=float64, data=...Tensor(shape=(3, 9, 3), inds=[_aea46cAAAAa, _aea46cAAAAi, _aea46cAAACp], tags={I3,4, X3, Y4, BRA, I4,4, X4, KET}),
backend=numpy, dtype=float64, data=array([[[ 5.68399455e-01, 2.42506402e-01, 3.33555033e-01],\n",
" [ 1.25079009e-01, 3.22513869e-02, -6.98697546e-02],\n",
" [ 1.36470626e-01, 2.04575948e-01, 7.27566005e-02],\n",
" [-2.52472701e-15, 7.86496048e-02, 2.75969908e-01],\n",
" [-1.37359123e-01, -6.42711321e-02, -1.05580199e-01],\n",
" [-1.97268264e-16, 5.12335106e-02, 1.36836294e-02],\n",
" [ 7.72843563e-02, 6.63680258e-02, -1.45256898e-01],\n",
" [ 1.46159349e-01, -8.93871796e-02, -6.26766907e-03],\n",
" [-3.92703429e-15, -1.29140581e-01, 4.03399323e-02]],\n",
"\n",
" [[ 2.42506402e-01, 1.00877466e+00, 3.27177597e-01],\n",
" [ 3.22513869e-02, 3.95720591e-01, -3.10805564e-01],\n",
" [ 2.04575948e-01, 4.24565134e-02, 1.44756191e-01],\n",
" [-7.86496048e-02, 4.75938793e-17, 3.54393752e-02],\n",
" [-6.42711321e-02, 1.77794095e-01, 1.21196914e-01],\n",
" [-5.12335106e-02, -3.61675374e-16, -2.20256855e-01],\n",
" [ 6.63680258e-02, -5.24617194e-02, 5.14089461e-03],\n",
" [-8.93871796e-02, -8.18299437e-03, 2.68972269e-02],\n",
" [ 1.29140581e-01, 2.83517873e-16, -2.75329848e-02]],\n",
"\n",
" [[ 3.33555033e-01, 3.27177597e-01, 1.27000956e+00],\n",
" [-6.98697546e-02, -3.10805564e-01, -1.85779727e-01],\n",
" [ 7.27566005e-02, 1.44756191e-01, -2.85729711e-01],\n",
" [-2.75969908e-01, -3.54393752e-02, 3.63606034e-15],\n",
" [-1.05580199e-01, 1.21196914e-01, -6.21878949e-02],\n",
" [-1.36836294e-02, 2.20256855e-01, 6.31910812e-17],\n",
" [-1.45256898e-01, 5.14089461e-03, 5.53875299e-02],\n",
" [-6.26766907e-03, 2.68972269e-02, -3.53440529e-02],\n",
" [-4.03399323e-02, 2.75329848e-02, 8.59657667e-16]]])Tensor(shape=(64, 64), inds=[_aea46cAAAAL, _aea46cAAAAM], tags={I1,0, X1, Y0, BRA, I0,0, X0, KET, I1,1, Y1, I0,1}),
backend=numpy, dtype=float64, data=...Tensor(shape=(64, 3, 64, 3), inds=[_aea46cAAAAS, _aea46cAAAAV, _aea46cAAAAL, _aea46cAAACd], tags={I2,1, X2, Y1, BRA, I2,0, Y0, KET}),
backend=numpy, dtype=float64, data=...Tensor(shape=(64, 64), inds=[_aea46cAAAAS, _aea46cAAAAe], tags={I3,0, X3, Y0, BRA, I4,0, X4, KET, I3,1, Y1, I4,1}),
backend=numpy, dtype=float64, data=... "
],
"text/plain": [
"TensorNetwork2D(tensors=15, indices=29, Lx=5, Ly=5, max_bond=64)"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"norm.contract_boundary_(\n",
" max_bond=64, layer_tags=[\"KET\", \"BRA\"], around=((2, 2), (2, 3))\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "5b1ea142-0b7e-47f2-9e9d-33230ba2c7b0",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"norm.draw(color=[norm.site_tag(2, 2), norm.site_tag(2, 3)], show_tags=False)"
]
},
{
"cell_type": "markdown",
"id": "546764fc-52f9-4ffc-b4c1-89a8a8883107",
"metadata": {},
"source": [
"Note the tensors on the right haven't been flattened as they on the boundary already."
]
},
{
"cell_type": "markdown",
"id": "9e81151d-0fff-4984-8035-c40e879cc47d",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"## Computing Quantites\n",
"\n",
"Contracting the boundary of two sandwiched PEPS around regions (which\n",
"can be thought of as the approximate partial trace) is also the main routine\n",
"required inside\n",
"{meth}`~quimb.tensor.tn2d.core.TensorNetwork2DVector.compute_local_expectation`."
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "58066992-5b3b-43ea-b046-172c78c776c8",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.0004870786802363588"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# two spin operator\n",
"H2 = qu.ham_heis(2)\n",
"\n",
"# coordinates to act with operator on\n",
"coo_a = (2, 2)\n",
"coo_b = (2, 3)\n",
"\n",
"# compute expectation\n",
"peps.compute_local_expectation(\n",
" {(coo_a, coo_b): H2},\n",
" max_bond=64,\n",
" normalized=True,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "2aba03f9-884c-4f37-976c-4fc2492b15c3",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
":::{note}\n",
"We have specified the boundary contraction option `max_bond`, and also\n",
"the `normalized=True` option, which computes\n",
"\n",
"$$\n",
"\\langle\\hat{O}\\rangle =\n",
"\\frac{\n",
"\\langle \\psi | \\hat{O} | \\psi \\rangle\n",
"}{\n",
"\\langle \\psi | \\psi \\rangle\n",
"}\n",
"$$\n",
"\n",
"which reuses the environments to 'locally' normalize the state rather than doing\n",
"it in a separate step. By default, two layer boundary contraction is also used\n",
"since this is more efficient (but this can be turned off).\n",
":::\n",
"\n",
"Often we want to compute many of these at once, e.g. when computing the energy\n",
"of a Hamiltonian, without repeating many boundary boundary contractions:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "e7b354ed-e5b9-4296-b33a-df103b82b5e2",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.26752530504966576"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# compute the heisenberg interaction for every bond in the PEPS lattice\n",
"terms = {(coo_a, coo_b): H2 for coo_a, coo_b in peps.gen_bond_coos()}\n",
"\n",
"peps.compute_local_expectation(\n",
" terms,\n",
" max_bond=64,\n",
" normalized=True,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "8555227f-4a83-4bb4-b130-472c791ebcd5",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"This automatically calculates which 'plaquette' environments are required then\n",
"computes them in at most one boundary contraction inwards from each direction.\n",
"There are various options for manually controlling this, with the main driver\n",
"function being\n",
"{meth}`~quimb.tensor.tn2d.core.TensorNetwork2D.compute_plaquette_environments`."
]
},
{
"cell_type": "markdown",
"id": "705445fb-a7ee-42eb-a615-bbdb10b9c4bf",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"## Specifying 2D Hamiltonians\n",
"\n",
"Such a dictionary of terms can also be generated by instantiating a\n",
"{class}`~quimb.tensor.tn1d.tebd.LocalHam2D`, which additionally\n",
"\n",
"- sums two site and one site terms so there is at most one term per pair\n",
"- can generate commuting term groupings for arbitrary range interactions\n",
"- can plot the Hamiltonian for interactive usage with\n",
" {meth}`~quimb.tensor.tn1d.tebd.LocalHam2D.graph`\n",
"\n",
"This is the object that is required for both the\n",
"{class}`~quimb.tensor.tn1d.tebd.SimpleUpdate` and\n",
"{class}`~quimb.tensor.tn1d.tebd.FullUpdate`\n",
"algorithms.\n",
"\n",
"Here we'll first make the translationally invariant Heisenberg Hamiltonian:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "f1043da2-de40-4166-bff0-28d55d4428df",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"(, )"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Lx = 4\n",
"Ly = 4\n",
"\n",
"ham = qtn.LocalHam2D(Lx, Ly, H2=H2)\n",
"ham.draw()"
]
},
{
"cell_type": "markdown",
"id": "edac27f3-42eb-498b-b034-ceb8267ff595",
"metadata": {},
"source": [
"The ``H2`` kwarg describes two site interactions. If an operator is given directly (as here)\n",
"it is used as a default term for all nearest neighbor interactions, as can be seen in the\n",
"visualization above.\n",
"We can also mix default single and two body terms and those for specific sites:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "b94625dc-a6f3-4bb5-8c1d-604344577cb0",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"(, )"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# the default two body term\n",
"H2 = {None: qu.ham_heis(2)}\n",
"\n",
"# single site terms\n",
"H1 = {}\n",
"\n",
"for i in range(Lx):\n",
" for j in range(Ly):\n",
" # add next nearest neighbor interactions\n",
" if (i + 1 < Lx) and (j - 1 >= 0):\n",
" H2[(i, j), (i + 1, j - 1)] = 0.5 * qu.ham_heis(2)\n",
" if (i + 1 < Lx) and (j + 1 < Ly):\n",
" H2[(i, j), (i + 1, j + 1)] = 0.5 * qu.ham_heis(2)\n",
"\n",
" # add a random field\n",
" H1[i, j] = qu.randn() * qu.spin_operator(\"Z\")\n",
"\n",
"ham_nn_r = qtn.LocalHam2D(Lx, Ly, H2=H2, H1=H1)\n",
"ham_nn_r.draw()"
]
},
{
"cell_type": "markdown",
"id": "55e450ef-7bd6-4cb1-8855-67719f3642db",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"The coloring shows a potential grouping of commuting two site terms.\n",
"\n",
"This object has the `.terms` attribute which can be supplied to\n",
"{meth}`~quimb.tensor.tn2d.core.TensorNetwork2DVector.compute_local_expectation`"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "da7f631f-126a-47c6-b26f-b49197d91a12",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.1123889724020653"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"peps.compute_local_expectation(ham_nn_r.terms, max_bond=32)"
]
},
{
"cell_type": "markdown",
"id": "1490db22-c778-4f86-be33-e182c591aedc",
"metadata": {},
"source": [
"In the next few sections we'll try and find the groundstate of the\n",
"4x4 Heisenberg lattice:"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "01fc5b2b-6dd8-47c2-ae0e-d4911e0863d7",
"metadata": {},
"outputs": [],
"source": [
"Lx = 4\n",
"Ly = 4\n",
"\n",
"ham = qtn.LocalHam2D(Lx, Ly, H2=qu.ham_heis(2))"
]
},
{
"cell_type": "markdown",
"id": "5fc6aaf0-29b3-476e-ad43-c0e9692d0e42",
"metadata": {},
"source": [
"This is small enough to easily compute the exact groundstate energy:"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "3abe3b2a-fa7e-4d0c-86da-bb6a3f39ea05",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"-0.5743254415745597"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"energy_exact = qu.groundenergy(qu.ham_heis_2D(Lx, Ly, sparse=True)) / (Lx * Ly)\n",
"energy_exact"
]
},
{
"cell_type": "markdown",
"id": "5cff2f49-f0c5-469b-8987-934d73f82d76",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"## Simple Update\n",
"\n",
"We can use our {class}`~quimb.tensor.tn1d.tebd.LocalHam2D` object as the\n",
"input to the 'Simple Update' (SU) algorithm, for performing imaginary time evolution.\n",
"Here we'll find the \\$D=4\\$ SU groundstate of the Heisenberg Hamiltonian:"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "a63ac600-608e-42c4-8de8-c9cd36ff8ac3",
"metadata": {},
"outputs": [],
"source": [
"D = 4\n",
"psi0 = qtn.PEPS.rand(Lx, Ly, bond_dim=D, seed=666)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "728836c0-2091-4bcc-9eac-05cd6011b7c2",
"metadata": {},
"outputs": [],
"source": [
"su = qtn.SimpleUpdate(\n",
" psi0,\n",
" ham,\n",
" chi=32, # boundary contraction bond dim for computing energy\n",
" compute_energy_every=10,\n",
" compute_energy_per_site=True,\n",
" keep_best=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "266f7504-465b-4023-8687-cda1f6a2323d",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"n=100, tau=0.3000, energy~-0.560196: 100%|##########| 100/100 [00:11<00:00, 8.39it/s]\n",
"n=200, tau=0.1000, energy~-0.562994: 100%|##########| 100/100 [00:09<00:00, 11.08it/s]\n",
"n=300, tau=0.0300, energy~-0.562883: 100%|##########| 100/100 [00:06<00:00, 15.06it/s]\n",
"n=400, tau=0.0100, energy~-0.562843: 100%|##########| 100/100 [00:07<00:00, 13.68it/s]\n"
]
}
],
"source": [
"for tau in [0.3, 0.1, 0.03, 0.01]:\n",
" su.evolve(100, tau=tau)"
]
},
{
"cell_type": "markdown",
"id": "98564239-dc7c-487d-9f04-1dcf312c572e",
"metadata": {},
"source": [
"The current state can be retrieved from `su.state`, or, if you have specified the\n",
"`keep_best` option, the lowest energy state seen can be found in `su.best['state']`."
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "db9475eb-bc35-41fa-b42e-24b06fc71d60",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'energy': -0.5633772517149431,\n",
" 'state': ,\n",
" 'it': 110}"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"su.best"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "04154313-a521-4a63-ae86-6e255f3cd2d7",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from matplotlib import pyplot as plt\n",
"\n",
"with plt.style.context(qu.NEUTRAL_STYLE):\n",
" plt.plot(su.its, su.energies)\n",
" plt.axhline(energy_exact, color=\"black\")\n",
" plt.title(\"Simple Update Convergence\")\n",
" plt.ylabel(\"Energy\")\n",
" plt.xlabel(\"Iteration\")"
]
},
{
"cell_type": "markdown",
"id": "1397bac1-bf70-4306-a9e1-e37f16e794fb",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"## Full Update\n",
"\n",
"Simple Update assumes a particular environment when truncating after each local application\n",
"of the imaginary time evolution operators - a product of diagonal operators - while very cheap\n",
"this can be innacurate. Full Update instead fits the new PEPS after each local evolution using\n",
"the local tensors as well as a boundary contracted environment."
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "e123fa65-7aad-4a33-b118-2d22e646207c",
"metadata": {},
"outputs": [],
"source": [
"# use the best SU state as the starting point for FU\n",
"psi0 = su.best[\"state\"].copy()"
]
},
{
"cell_type": "markdown",
"id": "8753aaf3-9832-4a8c-b574-36738b855333",
"metadata": {},
"source": [
"The way these algorithms are written using\n",
"[autoray](https://github.com/jcmgray/autoray) means that we can convert\n",
"the backend arrays of our PEPS and Hamiltonian to e.g. GPU arrays and\n",
"everything should still run smoothly.\n",
"\n",
"In the following (optional) cell, we convert to the arrays to single\n",
"precision ``cupy`` arrays, since FU is a good candidate for GPU acceleration."
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "fbc58c1d-95e3-4b2b-8973-ffb4354833bb",
"metadata": {},
"outputs": [],
"source": [
"def to_backend(x):\n",
" import cupy as cp\n",
"\n",
" return cp.asarray(x).astype(\"float32\")\n",
"\n",
"\n",
"psi0.apply_to_arrays(to_backend)\n",
"ham.apply_to_arrays(to_backend)"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "853d03fd-c7a3-49b7-8422-cd88243f0a92",
"metadata": {},
"outputs": [],
"source": [
"fu = qtn.FullUpdate(\n",
" psi0=psi0,\n",
" ham=ham,\n",
" # chi again is the boundary contraction max_bond\n",
" # now used for the envs as well as any energy calc\n",
" chi=32,\n",
" # we thus can cheaply compute the energy at every step\n",
" compute_energy_every=1,\n",
" compute_energy_per_site=True,\n",
" keep_best=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "8b532e15-cea2-49c1-804f-e8c09c744e47",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"n=50, tau=0.1000, energy~-0.571752: 100%|##########| 50/50 [01:10<00:00, 1.42s/it]\n"
]
}
],
"source": [
"fu.evolve(50, tau=0.1)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"id": "4812105c-6fd8-4c3b-acef-9a541a34e912",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"n=100, tau=0.0300, energy~-0.573182: 100%|##########| 50/50 [00:57<00:00, 1.14s/it]\n"
]
}
],
"source": [
"fu.evolve(50, tau=0.03)"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "2140e50f-794d-4ecb-a0cb-743cb1107361",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"n=150, tau=0.0100, energy~-0.573563: 100%|##########| 50/50 [00:55<00:00, 1.11s/it]\n"
]
}
],
"source": [
"fu.evolve(50, tau=0.01)"
]
},
{
"cell_type": "markdown",
"id": "2b8f50b4-c1da-4b6f-9276-63ed765d66b8",
"metadata": {},
"source": [
"We can see we have improved on the SU groundstate significantly."
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "221441d4-bf28-4f23-a25c-ab051b47e3a4",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"with plt.style.context(qu.NEUTRAL_STYLE):\n",
" plt.plot(fu.its, fu.energies, color=\"green\")\n",
" plt.axhline(energy_exact, color=\"black\")\n",
" plt.title(\"Full Update Convergence\")\n",
" plt.ylabel(\"Energy\")\n",
" plt.xlabel(\"Iteration\")"
]
},
{
"cell_type": "markdown",
"id": "03305813-8d47-407e-81e4-00a9e3b6d9ee",
"metadata": {},
"source": [
"Full Update has many options relating to the fitting of the imaginary\n",
"time evolution gates, controlling tradeoff between efficiency\n",
"and accuracy, you can view them like so:"
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "7d7588de-7173-4764-99c1-590a7db3238a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'tol': 1e-10,\n",
" 'steps': 20,\n",
" 'init_simple_guess': True,\n",
" 'condition_tensors': True,\n",
" 'condition_maintain_norms': True,\n",
" 'als_dense': True,\n",
" 'als_solver': 'solve',\n",
" 'als_enforce_pos': False,\n",
" 'als_enforce_pos_smudge': 1e-06,\n",
" 'autodiff_backend': 'autograd',\n",
" 'autodiff_optimizer': 'L-BFGS-B'}"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fu.fit_opts"
]
},
{
"cell_type": "markdown",
"id": "e0827125-5059-4008-957d-94dc4f536501",
"metadata": {},
"source": [
"For example, the following might be helpful to converge to very high accuracy:"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "c114839b-b8a4-4091-be95-71377f5e3dbe",
"metadata": {},
"outputs": [],
"source": [
"fu.fit_opts[\"als_enforce_pos\"] = True"
]
},
{
"cell_type": "markdown",
"id": "1dd4e8ad-0276-4324-bae2-fd306783885a",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"## Global Autodiff Optmization\n",
"\n",
"Because of the aforementioned array agnoticism that `quimb` tries to adopt, we can\n",
"also perform nearly all 2D calculations using arrays/tensors from an autodiff library,\n",
"to compute gradients and thus efficiently optimize entire tensor networks at once.\n",
"The {class}`~quimb.tensor.optimize.TNOptimizer` object handles injecting autodiff\n",
"arrays from one of several libraries currently):\n",
"\n",
"- [autograd](https://github.com/HIPS/autograd)\n",
"- [jax](https://github.com/google/jax)\n",
"- [tensorflow](https://www.tensorflow.org/)\n",
"- [pytorch](https://pytorch.org/)\n",
"\n",
"then using the automatically generated gradients from any expression to feed to\n",
"scipy's optimize function. Optimizing for a 2D PEPS energy is a great example\n",
"of this.\n",
"All we need to do is setup a function (a 'loss') that returns a real scalar\n",
"to minimize."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "0ac26233-bf08-4c9d-b913-4a0a806f0d16",
"metadata": {},
"outputs": [],
"source": [
"Lx = Ly = 4\n",
"psi0 = qtn.PEPS.rand(Lx, Ly, bond_dim=4)\n",
"ham = qtn.LocalHam2D(Lx, Ly, H2=qu.ham_heis(2))\n",
"\n",
"\n",
"def loss(psi, terms):\n",
" # the following functions simply scale the various tensors\n",
" # for the sake of numerical stability\n",
" psi.balance_bonds_()\n",
" psi.equalize_norms_(1.0)\n",
"\n",
" # then we just compute the energy of all the terms\n",
" return psi.compute_local_expectation(\n",
" terms, max_bond=32, cutoff=0.0, normalized=True\n",
" ) / (Lx * Ly)"
]
},
{
"cell_type": "markdown",
"id": "f25a4078-572d-4ce2-9f45-cfd95992e5d8",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"(Setting `cutoff=0.0` is required here so that the autodiff doesn't encounter\n",
"bahavior/shapes dependent on actual array values.)\n",
"Next we create a {class}`~quimb.tensor.optimize.TNOptimizer` object:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "1467af0b-8383-4e14-85f5-9c94d780b064",
"metadata": {},
"outputs": [],
"source": [
"tnopt = qtn.TNOptimizer(\n",
" # initial TN to optimize\n",
" psi0,\n",
" # the function to minimize\n",
" loss_fn=loss,\n",
" # constant TNs, tensors, arrays\n",
" loss_constants={\"terms\": ham.terms},\n",
" # the library that computes the gradient\n",
" autodiff_backend=\"jax\",\n",
" # the scipy optimizer that makes use of the gradient\n",
" optimizer=\"L-BFGS-B\",\n",
")"
]
},
{
"cell_type": "markdown",
"id": "88192095-41b5-418b-b13a-1cfa5c8ef52a",
"metadata": {},
"source": [
"The first step might be slow (e.g. with ``'jax'``) as it compiles the whole\n",
"energy and gradient computation:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "b7c594a1-fc11-44fc-a16c-22b47dce592d",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"-0.103467911482 [best: -0.103467911482] : : 2it [00:48, 24.42s/it] \n"
]
},
{
"data": {
"text/plain": [
""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tnopt.optimize(1)"
]
},
{
"cell_type": "markdown",
"id": "d445da62-17b6-4662-9188-c19557b446c2",
"metadata": {},
"source": [
"Subsequent optimization steps should be very quick, especially on a GPU:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "eac7101d-bf06-4242-88ff-94238aeaa4db",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"-0.574177205563 [best: -0.574177205563] : 20%|█▉ | 198/999 [00:32<02:12, 6.06it/s]\n"
]
}
],
"source": [
"psi_opt = tnopt.optimize(999)"
]
},
{
"cell_type": "markdown",
"id": "d1ef4f46-1fa5-47f9-94de-d01fc16233d1",
"metadata": {},
"source": [
"We can then check the convergence:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "6bd2c48e-fd40-42ae-a7d4-a088d8402d87",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"with plt.style.context(qu.NEUTRAL_STYLE):\n",
" plt.plot(tnopt.losses, color=\"purple\")\n",
" plt.axhline(energy_exact, color=\"black\")\n",
" plt.title(\"Global Autodiff Optimize Convergence\")\n",
" plt.ylabel(\"Energy\")\n",
" plt.ylim(-0.575, -0.563)\n",
" plt.xlabel(\"Iteration\")"
]
},
{
"cell_type": "markdown",
"id": "ec703954-7510-4947-84e4-1bc81b93023e",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"We can see that we have rapidly achieved a lower energy than Full Update.\n",
"\n",
":::{warning}\n",
"Global autodiff optimization can be **too powerful** for TN computations\n",
"that involve approximate contraction in the sense that the optimization\n",
"starts to exploit the small errors in the approximation to yield wildly\n",
"low but innacurate energies. That is part of the reason for including\n",
"the conditioning steps:\n",
"\n",
"```{code} python3\n",
"psi.balance_bonds_()\n",
"psi.equalize_norms_(1.0)\n",
"```\n",
"\n",
"in our loss function as well as 'locally normalizing' the energies.\n",
"It is also thus worth checking with a large bond dimension what our final\n",
"energy is more accurately. We can see below it matches well here.\n",
":::"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "38e2c0f9-4262-4d54-ac83-bc02be0a612b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"-0.5741719873138484"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"psi_opt.compute_local_expectation(ham.terms, normalized=True, max_bond=100) / (\n",
" Lx * Ly\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3"
},
"vscode": {
"interpreter": {
"hash": "6132c5c0a7d26b7c311caf7f55df83b87474b489906668e67e2d71a3b39ab16a"
}
}
},
"nbformat": 4,
"nbformat_minor": 4
}