Skip to content

Commit

Permalink
add option to use "order='folded'" for a Chain with periodic boundary…
Browse files Browse the repository at this point in the history
… conditions.
  • Loading branch information
jhauschild committed Oct 15, 2019
1 parent b950280 commit dc5d33c
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Expand Up @@ -25,6 +25,7 @@ Added
- Single-Site DMRG with the :class:`~tenpy.algorithms.dmrg.SingleSiteDMRG`.
- Example function in ``examples/c_tebd.py`` how to run TEBD with a model originally having next-nearest neighbors.
- :meth:`~tenpy.networks.mps.MPS.increase_L` to allow increasing the unit cell of an MPS.
- Additional option ``order='folded'`` for the :class:`~tenpy.models.lattice.Chain`.

Fixed
^^^^^
Expand Down
45 changes: 41 additions & 4 deletions tenpy/models/lattice.py
Expand Up @@ -441,12 +441,12 @@ def mps_lat_idx_fix_u(self, u=None):
return mps_idx, self.order[mps_idx, :-1]

def mps2lat_values(self, A, axes=0, u=None):
"""reshape/reorder A to replace an MPS index by lattice indices.
"""Reshape/reorder `A` to replace an MPS index by lattice indices.
Parameters
----------
A : ndarray
some values. Must have ``A.shape[axes] = self.N_sites`` if `u` is ``None``, or
Some values. Must have ``A.shape[axes] = self.N_sites`` if `u` is ``None``, or
``A.shape[axes] = self.N_cells`` if `u` is an int.
axes : (iterable of) int
chooses the axis which should be replaced.
Expand All @@ -458,7 +458,7 @@ def mps2lat_values(self, A, axes=0, u=None):
Returns
-------
res_A : ndarray
reshaped and reordered verions of A. Such that an MPS index `j` is replaced by
Reshaped and reordered verions of A. Such that an MPS index `j` is replaced by
``res_A[..., self.order, ...] = A[..., np.arange(self.N_sites), ...]``
Examples
Expand All @@ -485,7 +485,7 @@ def mps2lat_values(self, A, axes=0, u=None):
If the unit cell consists of different physical sites, an onsite operator might be defined
only on one of the sites in the unit cell. Then you can use :meth:`mps_idx_fix_u` to get
the indices of sites it is defined on, measure the operator on these sites, and use
the argument `u` of this function. say y
the argument `u` of this function.
>>> u = 0
>>> idx_subset = lat.mps_idx_fix_u(u)
Expand Down Expand Up @@ -1056,6 +1056,43 @@ def __init__(self, L, site, **kwargs):
# and otherwise default values.
SimpleLattice.__init__(self, [L], site, **kwargs)

def ordering(self, order):
"""Provide possible orderings of the `N` lattice sites.
The following orders are defined in this method compared to :meth:`Lattice.ordering`:
================== ============================================================
`order` Resulting order
================== ============================================================
``'default'`` ``0, 1, 2, 3, 4, ... ,L-1``
------------------ ------------------------------------------------------------
``'folded'`` ``0, L-1, 1, L-2, ... , L//2``.
This order might be usefull if you want to consider a
ring with periodic boundary conditions with a finite MPS:
It avoids the ultra-long range of the coupling from site
0 to L present in the default order.
================== ============================================================
"""
if isinstance(order, str) and order == 'default' or order == 'folded':
(L, u) = self.shape
assert u == 1
ordering = np.zeros([L, 2], dtype=np.intp)
if order == 'default':
ordering[:, 0] = np.arange(L, dtype=np.intp)
elif order == 'folded':
order = []
for i in range(L // 2):
order.append(i)
order.append(L - i - 1)
if L % 2 == 1:
order.append(L // 2)
assert len(order) == L
ordering[:, 0] = np.array(order, dtype=np.intp)
else:
assert (False) # should not be possible
return ordering
return super().ordering(order)


class Ladder(Lattice):
"""A ladder coupling two chains.
Expand Down
9 changes: 9 additions & 0 deletions tests/test_lattice.py
Expand Up @@ -105,6 +105,15 @@ def test_number_nn():
def test_lattice_order():
s = site.SpinHalfSite('Sz')
# yapf: disable
chain = lattice.Chain(4, s)
order_default = np.array([[0, 0], [1, 0], [2, 0], [3, 0]])
npt.assert_equal(chain.order, order_default)
chain = lattice.Chain(4, s, order='folded')
order_folded = np.array([[0, 0], [3, 0], [1, 0], [2, 0]])
npt.assert_equal(chain.order, order_folded)
chain = lattice.Chain(5, s, order='folded')
order_folded = np.array([[0, 0], [4, 0], [1, 0], [3, 0], [2, 0]])
npt.assert_equal(chain.order, order_folded)
square = lattice.Square(2, 2, s, order='default')
order_default = np.array([[0, 0, 0], [0, 1, 0], [1, 0, 0], [1, 1, 0]])
npt.assert_equal(square.order, order_default)
Expand Down

0 comments on commit dc5d33c

Please sign in to comment.