tensor-network-visualization 1.4.0__tar.gz → 1.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. {tensor_network_visualization-1.4.0/src/tensor_network_visualization.egg-info → tensor_network_visualization-1.4.2}/PKG-INFO +49 -21
  2. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/README.md +369 -343
  3. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/pyproject.toml +10 -4
  4. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2/src/tensor_network_visualization.egg-info}/PKG-INFO +49 -21
  5. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_visualization.egg-info/SOURCES.txt +31 -5
  6. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_visualization.egg-info/requires.txt +2 -0
  7. tensor_network_visualization-1.4.2/src/tensor_network_viz/__init__.py +30 -0
  8. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/_draw_common.py +6 -0
  9. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/_core/contractions.py +122 -80
  10. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/__init__.py +46 -0
  11. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/constants.py +138 -0
  12. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/contraction_scheme.py +253 -0
  13. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/disk_metrics.py +73 -0
  14. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/edges.py +728 -0
  15. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/fonts_and_scale.py +182 -0
  16. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/graph_pipeline.py +267 -0
  17. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/hover.py +250 -0
  18. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/labels_misc.py +154 -0
  19. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/pick_distance.py +82 -0
  20. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/plotter.py +285 -0
  21. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/tensors.py +198 -0
  22. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/vectors.py +33 -0
  23. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/draw/viewport_geometry.py +693 -0
  24. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/_core/graph.py +35 -0
  25. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/graph_cache.py +101 -0
  26. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/layout/__init__.py +17 -0
  27. tensor_network_visualization-1.4.0/src/tensor_network_viz/_core/layout.py → tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/layout/body.py +1251 -1178
  28. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/layout/force_directed.py +227 -0
  29. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/layout/parameters.py +52 -0
  30. tensor_network_visualization-1.4.2/src/tensor_network_viz/_core/layout/types.py +13 -0
  31. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/_core/layout_structure.py +103 -20
  32. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/_core/renderer.py +115 -19
  33. tensor_network_visualization-1.4.2/src/tensor_network_viz/_engine_specs.py +35 -0
  34. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/_registry.py +2 -30
  35. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/config.py +41 -11
  36. tensor_network_visualization-1.4.2/src/tensor_network_viz/einsum_module/__init__.py +14 -0
  37. tensor_network_visualization-1.4.2/src/tensor_network_viz/einsum_module/_equation.py +332 -0
  38. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/einsum_module/_trace_state.py +72 -44
  39. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/einsum_module/_trace_types.py +15 -2
  40. tensor_network_visualization-1.4.2/src/tensor_network_viz/einsum_module/graph.py +298 -0
  41. tensor_network_visualization-1.4.2/src/tensor_network_viz/einsum_module/trace.py +148 -0
  42. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/quimb/graph.py +35 -24
  43. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/tenpy/__init__.py +3 -0
  44. tensor_network_visualization-1.4.2/src/tensor_network_viz/tenpy/explicit.py +73 -0
  45. tensor_network_visualization-1.4.2/src/tensor_network_viz/tenpy/graph.py +184 -0
  46. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/viewer.py +93 -88
  47. tensor_network_visualization-1.4.2/tests/test_contraction_groups_once.py +75 -0
  48. tensor_network_visualization-1.4.2/tests/test_contraction_scheme.py +141 -0
  49. tensor_network_visualization-1.4.2/tests/test_demo_cli_scheme.py +45 -0
  50. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_einsum_autotrace.py +80 -19
  51. tensor_network_visualization-1.4.2/tests/test_einsum_backend.py +267 -0
  52. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_examples.py +97 -3
  53. tensor_network_visualization-1.4.2/tests/test_examples_structure.py +38 -0
  54. tensor_network_visualization-1.4.2/tests/test_graph_cache.py +65 -0
  55. tensor_network_visualization-1.4.2/tests/test_label_draw_metrics_perf.py +94 -0
  56. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_layout_core.py +780 -695
  57. tensor_network_visualization-1.4.2/tests/test_node_degrees_perf.py +73 -0
  58. tensor_network_visualization-1.4.2/tests/test_packaging_metadata.py +17 -0
  59. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_plotting.py +615 -628
  60. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_public_api.py +183 -182
  61. tensor_network_visualization-1.4.2/tests/test_show_tensor_network_throughput.py +57 -0
  62. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_tenpy_backend.py +137 -1
  63. tensor_network_visualization-1.4.0/src/tensor_network_viz/__init__.py +0 -19
  64. tensor_network_visualization-1.4.0/src/tensor_network_viz/_core/_draw_common.py +0 -2328
  65. tensor_network_visualization-1.4.0/src/tensor_network_viz/_core/draw_2d.py +0 -36
  66. tensor_network_visualization-1.4.0/src/tensor_network_viz/_core/draw_3d.py +0 -36
  67. tensor_network_visualization-1.4.0/src/tensor_network_viz/einsum_module/__init__.py +0 -10
  68. tensor_network_visualization-1.4.0/src/tensor_network_viz/einsum_module/_equation.py +0 -61
  69. tensor_network_visualization-1.4.0/src/tensor_network_viz/einsum_module/graph.py +0 -175
  70. tensor_network_visualization-1.4.0/src/tensor_network_viz/einsum_module/trace.py +0 -100
  71. tensor_network_visualization-1.4.0/src/tensor_network_viz/tenpy/graph.py +0 -156
  72. tensor_network_visualization-1.4.0/tests/test_einsum_backend.py +0 -155
  73. tensor_network_visualization-1.4.0/tests/test_integration_quimb.py +0 -41
  74. tensor_network_visualization-1.4.0/tests/test_integration_tenpy.py +0 -55
  75. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/LICENSE +0 -0
  76. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/setup.cfg +0 -0
  77. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_visualization.egg-info/dependency_links.txt +0 -0
  78. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_visualization.egg-info/top_level.txt +0 -0
  79. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/_core/__init__.py +0 -0
  80. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/_core/_label_format.py +0 -0
  81. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/_core/_nodes_edges_common.py +0 -0
  82. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/_core/axis_directions.py +0 -0
  83. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/_core/curves.py +0 -0
  84. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/_core/graph_utils.py +0 -0
  85. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/einsum_module/_backend.py +0 -0
  86. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/einsum_module/renderer.py +0 -0
  87. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/py.typed +0 -0
  88. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/quimb/__init__.py +0 -0
  89. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/quimb/renderer.py +0 -0
  90. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/tenpy/renderer.py +0 -0
  91. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/tensorkrowch/__init__.py +0 -0
  92. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/tensorkrowch/graph.py +0 -0
  93. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/tensorkrowch/renderer.py +0 -0
  94. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/tensornetwork/__init__.py +0 -0
  95. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/tensornetwork/graph.py +0 -0
  96. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/src/tensor_network_viz/tensornetwork/renderer.py +0 -0
  97. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_draw_performance.py +0 -0
  98. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_edge_index_label_2d.py +0 -0
  99. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_edge_index_label_3d.py +0 -0
  100. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_integration_einsum.py +0 -0
  101. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_integration_tensorkrowch.py +0 -0
  102. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_integration_tensornetwork.py +0 -0
  103. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_label_format.py +0 -0
  104. {tensor_network_visualization-1.4.0 → tensor_network_visualization-1.4.2}/tests/test_quimb_backend.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tensor-network-visualization
3
- Version: 1.4.0
3
+ Version: 1.4.2
4
4
  Summary: Minimal Matplotlib visualizations for TensorKrowch, TensorNetwork, Quimb, TeNPy, and traced PyTorch/NumPy einsum tensor networks.
5
5
  Author: Alejandro Mata Ali
6
6
  License: MIT
@@ -9,7 +9,7 @@ Project-URL: Documentation, https://github.com/DOKOS-TAYOS/Tensor-Network-Visual
9
9
  Project-URL: Changelog, https://github.com/DOKOS-TAYOS/Tensor-Network-Visualization/blob/main/CHANGELOG.md
10
10
  Project-URL: Repository, https://github.com/DOKOS-TAYOS/Tensor-Network-Visualization
11
11
  Project-URL: Issues, https://github.com/DOKOS-TAYOS/Tensor-Network-Visualization/issues
12
- Keywords: tensor-network,visualization,tensorkrowch,tensornetwork,quimb,tenpy,matplotlib
12
+ Keywords: tensor-network,visualization,pytorch,numpy,tensorkrowch,tensornetwork,quimb,tenpy,einsum,quantum-inspired,matplotlib
13
13
  Classifier: License :: OSI Approved :: MIT License
14
14
  Classifier: Programming Language :: Python :: 3
15
15
  Classifier: Programming Language :: Python :: 3 :: Only
@@ -19,11 +19,13 @@ Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
20
  Requires-Dist: matplotlib>=3.7
21
21
  Requires-Dist: networkx>=3.0
22
+ Requires-Dist: numpy
22
23
  Provides-Extra: dev
23
24
  Requires-Dist: pytest; extra == "dev"
24
25
  Requires-Dist: ruff; extra == "dev"
25
26
  Requires-Dist: pyright; extra == "dev"
26
27
  Requires-Dist: ipython; extra == "dev"
28
+ Requires-Dist: tomli>=2.0.1; extra == "dev"
27
29
  Requires-Dist: tensorkrowch; extra == "dev"
28
30
  Requires-Dist: tensornetwork; extra == "dev"
29
31
  Requires-Dist: quimb; extra == "dev"
@@ -78,8 +80,11 @@ PyPI package name: `tensor-network-visualization`. Import module: `tensor_networ
78
80
  python -m pip install tensor-network-visualization
79
81
  ```
80
82
 
81
- Depends on `matplotlib` and `networkx` only. You can render **`einsum`** traces built from ordered
82
- `pair_tensor` entries without installing PyTorch.
83
+ Base runtime dependencies are `numpy`, `matplotlib`, and `networkx` only. You can **build and
84
+ render** rich **`einsum`** graphs from ordered **`pair_tensor`** / **`einsum_trace_step`** entries
85
+ (ellipsis and repeated indices need shapes in metadata); **`tensor-network-visualization[einsum]`**
86
+ (PyTorch) is only needed to **execute** `tensor_network_viz.einsum(..., trace=...)` and record
87
+ those rows automatically.
83
88
 
84
89
  ### Optional backends (extras)
85
90
 
@@ -89,7 +94,7 @@ Depends on `matplotlib` and `networkx` only. You can render **`einsum`** traces
89
94
  | TensorNetwork | `tensornetwork` | `pip install "tensor-network-visualization[tensornetwork]"` |
90
95
  | Quimb | `quimb` | `pip install "tensor-network-visualization[quimb]"` |
91
96
  | TeNPy | `tenpy` | Resolves to PyPI package **`physics-tenpy`**. |
92
- | Einsum tracing | `einsum` | Adds **PyTorch** for the traced `einsum` helper. |
97
+ | Einsum tracing | `einsum` | Adds **PyTorch** for auto-traced `einsum(..., trace=...)` (layout from `pair_tensor` / `einsum_trace_step` lists with metadata as needed). |
93
98
  | Jupyter widgets| `jupyter` | `ipympl`, widgets, JupyterLab / Notebook 7+ for interactive figures. |
94
99
 
95
100
  Combine extras, for example:
@@ -148,7 +153,8 @@ Everything below maps to real parameters—there are no hidden mode switches.
148
153
  | **Display mode** | `show=True` / `False` | If `True`: Jupyter **kernel** uses `IPython.display.display(fig)`; otherwise `plt.show()`. If `False`: neither runs—use for `savefig` / batch. |
149
154
  | **Label policy** | `PlotConfig` + overrides | Defaults: `show_tensor_labels`, `show_index_labels`. Per-call: `show_tensor_network(..., show_tensor_labels=..., show_index_labels=...)`. |
150
155
  | **Hover labels** | `PlotConfig(hover_labels=True)` | Tensor names and bond labels appear on pointer hover (2D axes hit-test; 3D screen-space distance). Needs an **interactive** Matplotlib window. |
151
- | **Einsum workflow** | `engine="einsum"` | **Auto:** `EinsumTrace` + `tensor_network_viz.einsum`. **Manual:** ordered list of `pair_tensor(...)`. |
156
+ | **Contraction scheme** | `PlotConfig(show_contraction_scheme=True)` | **Einsum:** cumulative per-step highlights from the trace. **Other engines:** set **`contraction_scheme_by_name`**. **2D:** rounded boxes (AABB + pad); colored borders (no fill by default). **3D:** wireframe box. See **`docs/guide.md`**. |
157
+ | **Einsum workflow** | `engine="einsum"` | **Auto:** `EinsumTrace` + `einsum` (binary `pair_tensor`, unary/ternary+ `einsum_trace_step`; implicit `->`, `out=`). **Manual:** `pair_tensor` / `einsum_trace_step` (ellipsis needs `metadata` shapes). See **`examples/einsum_general.py`**. |
152
158
 
153
159
  ## Minimal examples
154
160
 
@@ -255,14 +261,14 @@ Numeric fields with **`None`** use the corresponding `DEFAULT_*` on the class (s
255
261
 
256
262
  | Field | Default | Role |
257
263
  |-------|---------|------|
258
- | `node_color` | `"#E8E8E8"` | Tensor node fill. |
259
- | `node_edge_color` | `"#2D3748"` | Tensor node outline. |
260
- | `node_color_degree_one` | `"#E8D6D6"` | Fill for tensors with total graph degree 1. |
261
- | `node_edge_color_degree_one` | `"#4A3436"` | Outline for degree-1 tensors. |
262
- | `tensor_label_color` | `"#1A202C"` | Tensor name text. |
263
- | `label_color` | `"#0C1319"` | Index / bond label text. |
264
- | `bond_edge_color` | `"#00008B"` | Contraction edges. |
265
- | `dangling_edge_color` | `"#8B0000"` | Dangling (open) legs. |
264
+ | `node_color` | `"#E8EEF5"` | Tensor node fill. |
265
+ | `node_edge_color` | `"#1E293B"` | Tensor node outline. |
266
+ | `node_color_degree_one` | `"#FEE2E2"` | Fill for tensors with total graph degree 1. |
267
+ | `node_edge_color_degree_one` | `"#7F1D1D"` | Outline for degree-1 tensors. |
268
+ | `tensor_label_color` | `"#0F172A"` | Tensor name text. |
269
+ | `label_color` | `"#334155"` | Index / bond label text. |
270
+ | `bond_edge_color` | `"#0369A1"` | Contraction edges. |
271
+ | `dangling_edge_color` | `"#BE123C"` | Dangling (open) legs. |
266
272
  | `figsize` | `(8, 6)` | `inches`; `None` uses Matplotlib fallback `(14, 10)` when the renderer creates a new figure. |
267
273
  | `show_tensor_labels` | `True` | Draw tensor names on nodes. |
268
274
  | `show_index_labels` | `True` | Draw axis names on bonds / stubs. |
@@ -290,6 +296,7 @@ from tensor_network_viz import (
290
296
  PlotConfig,
291
297
  ViewName,
292
298
  einsum,
299
+ einsum_trace_step,
293
300
  pair_tensor,
294
301
  show_tensor_network,
295
302
  )
@@ -301,10 +308,21 @@ Per-backend plotters (optional; same as `show_tensor_network` internals):
301
308
  from tensor_network_viz.tensorkrowch import plot_tensorkrowch_network_2d, plot_tensorkrowch_network_3d
302
309
  from tensor_network_viz.tensornetwork import plot_tensornetwork_network_2d, plot_tensornetwork_network_3d
303
310
  from tensor_network_viz.quimb import plot_quimb_network_2d, plot_quimb_network_3d
304
- from tensor_network_viz.tenpy import plot_tenpy_network_2d, plot_tenpy_network_3d
305
- from tensor_network_viz.einsum_module import plot_einsum_network_2d, plot_einsum_network_3d
311
+ from tensor_network_viz.tenpy import (
312
+ make_tenpy_tensor_network,
313
+ plot_tenpy_network_2d,
314
+ plot_tenpy_network_3d,
315
+ )
316
+ from tensor_network_viz.einsum_module import (
317
+ parse_einsum_equation,
318
+ parse_equation_for_shapes,
319
+ plot_einsum_network_2d,
320
+ plot_einsum_network_3d,
321
+ )
306
322
  ```
307
323
 
324
+ (`parse_equation_for_shapes` — binary only; `parse_einsum_equation` — any arity, NumPy-validated.)
325
+
308
326
  ## Accepted inputs (summary)
309
327
 
310
328
  | Backend | Input |
@@ -312,8 +330,8 @@ from tensor_network_viz.einsum_module import plot_einsum_network_2d, plot_einsum
312
330
  | tensorkrowch | Network with `nodes` / `leaf_nodes`, or iterable of nodes |
313
331
  | tensornetwork | Iterable of `tensornetwork.Node` |
314
332
  | quimb | `TensorNetwork` or iterable of `Tensor` |
315
- | tenpy | Finite/segment/infinite `MPS`, finite/infinite `MPO` |
316
- | einsum | `EinsumTrace` or ordered iterable of `pair_tensor` |
333
+ | tenpy | `TenPyTensorNetwork` / `make_tenpy_tensor_network` (`npc.Array` + bonds); `MPS`, `MPO`, `MomentumMPS`-like; no stable TeNPy PEPS class (hand-built TN ok) |
334
+ | einsum | `EinsumTrace` or ordered iterable of `pair_tensor` / `einsum_trace_step` (ellipsis / hyperedges in the normalized graph) |
317
335
 
318
336
  Details, subgraph behavior, and Quimb hyperindex hubs are in **[docs/guide.md](docs/guide.md)**.
319
337
 
@@ -329,8 +347,10 @@ Runnable demos live under **`examples/`**. From the repo root with the right ext
329
347
  | `mera_tree_demo.py` | Large MERA + binary TTN stress test. |
330
348
  | `cubic_peps_demo.py` | 3D cubic PEPS lattice. |
331
349
  | `quimb_demo.py` | Includes hyper-index example; `--from-list`. |
332
- | `tenpy_demo.py` | Finite and infinite MPS/MPO. |
350
+ | `tenpy_demo.py` | MPS/MPO, purification, uniform, excitation chain (duck-typed like `MomentumMPS`). |
351
+ | `tenpy_explicit_tn_demo.py` | Explicit `TenPyTensorNetwork`: open chain or 3-way hub ([examples/README](examples/README.md)). |
333
352
  | `einsum_demo.py` | Auto trace vs manual `pair_tensor`. |
353
+ | `einsum_general.py` | Ellipsis, batch hubs, multi-step fusion, traces, short MPS, implicit/`out=`, unary, ternary (auto-trace). |
334
354
  | `tn_tsp.py` | Larger TensorKrowch TSP construction. |
335
355
 
336
356
  Catalog and one-liner commands: **[examples/README.md](examples/README.md)**.
@@ -340,7 +360,14 @@ Catalog and one-liner commands: **[examples/README.md](examples/README.md)**.
340
360
  - Quimb **hyper-indices** (three or more tensors) are drawn via internal virtual hubs.
341
361
  - Infinite TeNPy **MPS/MPO** use one periodic unit cell.
342
362
  - The **einsum** backend visualizes the **fundamental** tensor network, not each intermediate
343
- contraction tensor.
363
+ contraction tensor. Pairwise summed indices are drawn as ordinary bonds; repeated or
364
+ output-carrying indices use **virtual hubs** (layout separates colocated hubs, nudges **2D**
365
+ hubs that attach to **one** tensor only—e.g. **`ii->i`**—off that tensor, and offsets hubs on a
366
+ tensor–tensor chord when a **direct** bond also links that pair).
367
+ - Optional **`contraction_steps`** from **einsum**: **running union** of operand physical lineages
368
+ (each step is a superset of the previous); **`PlotConfig`** draws per-step **AABB** highlights
369
+ (**2D:** rounded rectangles; **3D:** wireframe), colored borders (no fill by default), extra
370
+ padding as steps advance, and later steps underneath.
344
371
  - Passing a **subset** of nodes/tensors shows connections outside the subset as **dangling** legs.
345
372
 
346
373
  ## Quick verification (reviewers)
@@ -361,7 +388,8 @@ Expect `quimb_mps.png` and all tests passing.
361
388
  | `ValueError: Unsupported tensor network engine` / `view` | Use only listed `engine` / `view` literals (see above). |
362
389
  | Blank or double figure in Jupyter | Assign `fig, ax = show_tensor_network(...)`; avoid bare tuple as last line; try `%matplotlib widget` or inline. |
363
390
  | Hover labels do nothing | Requires interactive backend and `show` path that runs a GUI or widget event loop; not for `--no-show` PNG only. |
364
- | Huge graphs are slow | `PlotConfig(refine_tensor_labels=False)`; optionally set `layout_iterations` explicitly. |
391
+ | Huge graphs are slow | `PlotConfig(refine_tensor_labels=False)`; lower `layout_iterations` or pass `positions`. Force layout samples repulsion when node count is large (about 72+; see [guide](docs/guide.md#layout-and-draw-scale)). |
392
+ | Einsum unary trace (`ii->i`) looks odd in 2D | Layout offsets the virtual hub off the tensor in 2D; try `view="3d"` or read [Einsum unary / same-tensor trace in 2D](docs/guide.md#toc-einsum-unary-2d-layout) in the guide. |
365
393
 
366
394
  **Full troubleshooting:** [docs/guide.md — Troubleshooting](docs/guide.md#troubleshooting).
367
395