Skip to content

Commit

Permalink
TN: add build_mpo_propagator_trotterized
Browse files Browse the repository at this point in the history
  • Loading branch information
jcmgray committed Jan 25, 2024
1 parent 472f687 commit 777fa75
Show file tree
Hide file tree
Showing 7 changed files with 369 additions and 95 deletions.
24 changes: 17 additions & 7 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,18 @@ Release notes for `quimb`.

**Enhancements:**

- add [TensorNetwork.visualize_tensors](quimb.tensor.drawing.visualize_tensors)
- add [`TensorNetwork.visualize_tensors`](quimb.tensor.drawing.visualize_tensors)
for visualizing the actual data entries of an entire tensor network.
- add [`ham.build_mpo_propagator_trotterized`](quimb.tensor.tensor_1d_tebd.LocalHam1D.build_mpo_propagator_trotterized)
for building a trotterized propagator from a local 1D hamiltonian. This
also includes updates for creating 'empty' tensor networks using
[`TensorNetwork.new`](quimb.tensor.tensor_core.TensorNetwork.new), and
building up gates from empty tensor networks using
[`TensorNetwork.gate_inds_with_tn`](quimb.tensor.tensor_core.TensorNetwork.gate_inds_with_tn).
- add more options to [`Tensor.expand_ind`](quimb.tensor.tensor_core.Tensor.expand_ind)
and [`Tensor.new_ind`](quimb.tensor.tensor_core.Tensor.new_ind): repeat
tiling mode and random padding mode.
- tensor decomposition: make ``eigh_truncated`` backend agnostic.

**Bug fixes:**

Expand All @@ -20,7 +30,7 @@ Release notes for `quimb`.


(whats-new-1-7-0)=
## v1.7.0 (12-08-2023)
## v1.7.0 (2023-12-08)

**Breaking Changes**

Expand Down Expand Up @@ -178,15 +188,15 @@ Release notes for `quimb`.
triangular R factors.

(whats-new-1-4-2)=
## v1.4.2 (28th November 2022)
## v1.4.2 (2022-11-28)

**Enhancements**

- move from versioneer to to
[setuptools_scm](https://pypi.org/project/setuptools-scm/) for versioning

(whats-new-1-4-1)=
## v1.4.1 (28th November 2022)
## v1.4.1 (2022-11-28)

**Enhancements**

Expand Down Expand Up @@ -219,7 +229,7 @@ Release notes for `quimb`.
> - allow unpickling of `PTensor` objects ({issue}`128`, {pull}`131`)
(whats-new-1-4-0)=
## v1.4.0 (14th June 2022)
## v1.4.0 (2022-06-14)

**Enhancements**

Expand All @@ -238,7 +248,7 @@ Release notes for `quimb`.
- Various graph generators and TN builders

(whats-new-1-3-0)=
## v1.3.0 (18th Feb 2020)
## v1.3.0 (2020-02-18)

**Enhancements**

Expand Down Expand Up @@ -274,7 +284,7 @@ Release notes for `quimb`.
- Make cache import and initilization of `petsc4py` and `slepc4py` more robust.

(whats-new-1-2-0)=
## v1.2.0 (6th June 2019)
## v1.2.0 (2019-06-06)

**Enhancements**

Expand Down
44 changes: 22 additions & 22 deletions docs/examples/schematic-demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"metadata": {},
"source": [
"(schematic)=\n",
"## `schematic` - manual drawing\n",
"# `schematic` - manual drawing\n",
"\n",
"This example demonstrates the basic functionality of the `schematic` module.\n",
"The schematic module is a simple wrapper around `matplotlib` that allows \n",
Expand All @@ -16,13 +16,13 @@
"is the [`Drawing`](quimb.schematic.Drawing) class.\n",
"\n",
"\n",
"### Illustrative full examples\n",
"## Illustrative full examples\n",
"\n",
"The following examples are intended to be illustrative of a full drawing.\n",
"If you supply a dict of `presets` to `Drawing`, then you can provide default\n",
"styling for various elements simply by name.\n",
"\n",
"#### 2D example"
"### 2D example"
]
},
{
Expand Down Expand Up @@ -744,7 +744,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Pseudo-3D example\n",
"### Pseudo-3D example\n",
"\n",
"If you supply 3D coordinates to `Drawing` methods then the objects will be \n",
"mapped by the axonometric projection to 2D and given appropriate z-ordering.\n",
Expand Down Expand Up @@ -8172,7 +8172,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Individual elements:\n",
"## Individual elements:\n",
"\n",
"Here we demonstrate the different types of individual element that can be placed.\n",
"The `hash_to_color` function is useful way to deterministically generate colors\n",
Expand All @@ -8194,7 +8194,7 @@
"metadata": {},
"source": [
"\n",
"#### Circles\n",
"### Circles\n",
"\n",
"[Drawing.circle](quimb.schematic.Drawing.circle) draws a circle with a given\n",
"radius and center coordinates."
Expand Down Expand Up @@ -8506,7 +8506,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Cubes\n",
"### Cubes\n",
"\n",
"[Drawing.cube](quimb.schematic.Drawing.cube) draws a cube with a given\n",
"'radius' and center coordinates, only for 3D coordinates."
Expand Down Expand Up @@ -9362,10 +9362,10 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Text\n",
"### Text\n",
"\n",
"[Drawing.text](quimb.schematic.Drawing.cube) places text in data coordinates \n",
"(including 3D). [Drawing.label_axes](quimb.schematic.Drawing.label_axes) and\n",
"(including 3D). [Drawing.label_ax](quimb.schematic.Drawing.label_ax) and\n",
"[Drawing.label_fig](quimb.schematic.Drawing.label_fig) are the same but default\n",
"to axis and figure coordinates respectively."
]
Expand Down Expand Up @@ -9944,7 +9944,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### General shapes\n",
"### General shapes\n",
"\n",
"[Drawing.shape](quimb.schematic.Drawing.shape) draws a general filled shape \n",
"given a sequence of 2D or 3D coordinates."
Expand Down Expand Up @@ -10723,7 +10723,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Markers\n",
"### Markers\n",
"\n",
"[Drawing.marker](quimb.schematic.Drawing.marker) is a convenience method for\n",
"specifying the shape of a patch using a single string or integer, to yield\n",
Expand Down Expand Up @@ -11221,9 +11221,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Lines and curves\n",
"## Lines and curves\n",
"\n",
"#### Lines\n",
"### Lines\n",
"\n",
"The basic method for drawing lines between a pair of 2D or 3d points is \n",
"[Drawing.line](quimb.schematic.Drawing.line)."
Expand Down Expand Up @@ -11329,7 +11329,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Arrows and labels\n",
"### Arrows and labels\n",
"\n",
"You can easily add text and arrows along lines:"
]
Expand Down Expand Up @@ -11838,7 +11838,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Curves\n",
"### Curves\n",
"\n",
"If you want a line to pass through multiple points, you can use\n",
"[Drawing.curve](quimb.schematic.Drawing.curve) to draw a smooth curve."
Expand Down Expand Up @@ -12862,7 +12862,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Multi-edges\n",
"### Multi-edges\n",
"\n",
"If you want to programmatically draw multiple lines from one place to the other ('multi-edges') you can use `line_offset`:"
]
Expand Down Expand Up @@ -13375,9 +13375,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Highlighting areas and groups of objects\n",
"## Highlighting areas and groups of objects\n",
"\n",
"#### Patches around general areas\n",
"### Patches around general areas\n",
"\n",
"In technical drawings it is often useful to highlight areas. The \n",
"[Drawing.patch](quimb.schematic.Drawing.patch) method does this by filling in\n",
Expand Down Expand Up @@ -13486,7 +13486,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Patches around two circles\n",
"### Patches around two circles\n",
"\n",
"If you want to specifically highlight two circles, you can use\n",
"[Drawing.patch_around_circles](quimb.schematic.Drawing.patch_around_circles),\n",
Expand Down Expand Up @@ -13613,7 +13613,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Patches around arbitrary collections of objects\n",
"### Patches around arbitrary collections of objects\n",
"\n",
"If you want to highlight an arbitrary collection of objects, you can call\n",
"[Drawing.patch_around](quimb.schematic.Drawing.patch_around), this computes\n",
Expand Down Expand Up @@ -14701,9 +14701,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python [conda env:py311]",
"display_name": "py311",
"language": "python",
"name": "conda-env-py311-py"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
Expand Down
113 changes: 113 additions & 0 deletions quimb/tensor/tensor_1d_tebd.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
"""Tools for performing TEBD like algorithms in 1D.
"""
import itertools

import numpy as np
from autoray import do

from ..utils import ensure_dict, continuous_progbar, deprecated
from ..utils import progbar as Progbar
Expand Down Expand Up @@ -99,6 +101,117 @@ def mean_norm(self):
for h in self.terms.values()
) / len(self.terms)

def build_mpo_propagator_trotterized(
self,
x,
site_tag_id="I{}",
tags=None,
upper_ind_id="k{}",
lower_ind_id="b{}",
shape="lrud",
contract_sites=True,
**split_opts,
):
"""Build an MPO representation of ``expm(H * x)``, i.e. the imaginary
or real time propagator of this local 1D hamiltonian, using a first
order trotterized decomposition.
Parameters
----------
x : float
The time to evolve for. Note this does **not** include the
imaginary prefactor of the Schrodinger equation, so real ``x``
corresponds to imaginary time evolution, and vice versa.
site_tag_id : str
A string specifiying how to tag the tensors at each site. Should
contain a ``'{}'`` placeholder. It is used to generate the actual tags
like: ``map(site_tag_id.format, range(len(arrays)))``.
tags : str or sequence of str, optional
Global tags to attach to all tensors.
upper_ind_id : str
A string specifiying how to label the upper physical site indices.
Should contain a ``'{}'`` placeholder. It is used to generate the
actual indices like:
``map(upper_ind_id.format, range(len(arrays)))``.
lower_ind_id : str
A string specifiying how to label the lower physical site indices.
Should contain a ``'{}'`` placeholder. It is used to generate the
actual indices like:
``map(lower_ind_id.format, range(len(arrays)))``.
shape : str, optional
String specifying layout of the tensors. E.g. 'lrud' (the default)
indicates the shape corresponds left-bond, right-bond, 'up'
physical index, 'down' physical index.
End tensors have either 'l' or 'r' dropped from the string if not
periodic.
contract_sites : bool, optional
Whether to contract all the decomposed factors at each site to
yield a single tensor per site, by default True.
split_opts
Supplied to :func:`~quimb.tensor.tensor_core.tensor_split`.
"""
from .tensor_core import Tensor
from .tensor_1d import MatrixProductOperator

mpo = MatrixProductOperator.new(
L=self.L,
site_tag_id=site_tag_id,
upper_ind_id=upper_ind_id,
lower_ind_id=lower_ind_id,
cyclic=self.cyclic,
)
imax = self.L - (not self.cyclic)

# process even bonds then odd bonds
layered_sites = itertools.chain(range(0, imax, 2), range(1, imax, 2))

# process even bonds
for i in layered_sites:
j = (i + 1) % self.L

# get a tensor of the local exponentiated term
U = self.get_gate_expm((i, j), x)
U = do("reshape", U, (2, 2, 2, 2))

ki = upper_ind_id.format(i)
kj = upper_ind_id.format(j)
bi = lower_ind_id.format(i)
bj = lower_ind_id.format(j)

# split spatially
tnU = Tensor(
data=U,
inds=(ki, kj, bi, bj),
).split(
left_inds=(ki, bi),
ltags=site_tag_id.format(i),
rtags=site_tag_id.format(j),
**split_opts,
)
# add tensors to mpo
mpo.gate_inds_with_tn_(
inds=(ki, kj),
gate=tnU,
gate_inds_inner=(bi, bj),
gate_inds_outer=(ki, kj),
)

if contract_sites:
# combine site groups into single tensors
for st in mpo.site_tags:
mpo ^= st

if tags is not None:
# global tags
mpo.add_tag(tags)

if shape is not None:
# enforce a canonical ordering of indices within each tensor
mpo.permute_arrays(shape)

return mpo


def __repr__(self):
return f"<LocalHam1D(L={self.L}, cyclic={self.cyclic})>"

Expand Down
8 changes: 8 additions & 0 deletions quimb/tensor/tensor_arbgeom.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ def tensor_network_apply_op_vec(
A, x = tn_op.copy(), tn_vec.copy()

# align the indices
#
# | <- upper_ind_id to be site_ind_id (outerid)
# -A- ...
# | <- lower_ind_id to be innerid
# :
# | <- site_ind_id to be innerid
# -x- ...
#
coordinate_formatter = get_coordinate_formatter(A._NDIMS)
A.lower_ind_id = f"__tmp{coordinate_formatter}__"
A.upper_ind_id = x.site_ind_id
Expand Down
Loading

0 comments on commit 777fa75

Please sign in to comment.