Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ To install the latest stable version run

pip install mpnum

If you want to install `mpnum` from source, please run (on Unix)
If you want to install this fork of `mpnum` from source, please run (on Unix)

git clone https://github.com/dseuss/mpnum.git
git clone https://github.com/moritzlange/mpnum.git
cd mpnum
pip install .

Expand Down
25 changes: 21 additions & 4 deletions mpnum/mpsmpo.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,16 +125,16 @@
from __future__ import absolute_import, division, print_function

import numpy as np
from numpy.testing import assert_array_equal

from six.moves import range

from . import mparray as mp
from .utils import local_to_global, matdot

from scipy.linalg import eigh

__all__ = ['mps_to_mpo', 'mps_to_pmps', 'pmps_dm_to_array',
'pmps_reduction', 'pmps_to_mpo', 'pmps_to_mps',
'pmps_reduction', 'mpo_to_pmps', 'pmps_to_mpo', 'pmps_to_mps',
'reductions_mpo', 'reductions_mps_as_mpo',
'reductions_mps_as_pmps', 'reductions_pmps', 'reductions']

Expand Down Expand Up @@ -243,7 +243,8 @@ def reductions_mpo(mpa, width=None, startsites=None, stopsites=None):
startsites, stopsites = \
_check_reductions_args(len(mpa), width, startsites, stopsites)

assert_array_equal(mpa.ndims, 2)
if not (np.array(mpa.ndims) == 2).all():
raise ValueError('Every site needs to have exactly two physical legs')
rem_left = {0: np.array(1, ndmin=2)}
rem_right = rem_left.copy()

Expand Down Expand Up @@ -372,6 +373,21 @@ def pmps_to_mpo(pmps):
return mp.dot(pmps, pmps.adj())


def mpo_to_pmps(mpo):
"""Convert a tensor product MPO into a local purification MPS mixed state.

:param MPArray mpo: An MPA with two physical legs and rank one on all sites
:returns: An MPA with two physical legs (system and ancilla)

"""
if not (np.array(mpo.ranks) == 1).all():
raise ValueError('Only implemented for rank-1 MPOs')
eigs = (eigh(lten[0, ..., 0] / np.trace(lten[0, ..., 0])) for lten in mpo.lt)
ltens = (np.sqrt(vals)[None, ...] * vecs for vals, vecs in eigs)
pmps = mp.MPArray.from_kron(ltens)
return pmps / mp.norm(pmps)


def mps_to_pmps(mps):
"""Convert a pure MPS into a local purification MPS mixed state.

Expand All @@ -382,7 +398,8 @@ def mps_to_pmps(mps):
:returns: An MPA with two physical legs (system and ancilla)

"""
assert_array_equal(mps.ndims, 1)
if not (np.array(mps.ndims) == 1).all():
raise ValueError('Only implemented for unit auxiliary dimensions')
ltens = (lten.reshape(lten.shape[0:2] + (1, lten.shape[2])) for lten in mps.lt)
return mp.MPArray(ltens)

Expand Down
14 changes: 14 additions & 0 deletions tests/mpsmpo_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import numpy as np
import pytest as pt
from numpy.testing import assert_array_almost_equal
from numpy.testing import assert_almost_equal

import mpnum.factory as factory
import mpnum.mparray as mp
Expand Down Expand Up @@ -223,6 +224,19 @@ def test_pmps_to_mpo(nr_sites, local_dim, rank, rgen):
assert_array_almost_equal(rho_mp, rho_np)


@pt.mark.parametrize('nr_sites, local_dim', [(1, 7), (2, 3), (3, 2), (6, 2),
(4, 3), (5, 2)])
def test_mpo_to_pmps(nr_sites, local_dim, rgen):
pmps = factory.random_mpa(nr_sites, (local_dim, local_dim), 1,
dtype=np.complex_, randstate=rgen)
assert_almost_equal(mp.normdist(mm.mpo_to_pmps(mm.pmps_to_mpo(pmps)),
pmps), 0)
mpo = factory.random_mpa(nr_sites, (local_dim, local_dim), 1,
dtype=np.complex_, randstate=rgen, normalized=True)
assert_almost_equal(mp.normdist(mm.pmps_to_mpo(mm.mpo_to_pmps(mpo)),
mpo), 0)


@pt.mark.parametrize('nr_sites, local_dim, rank', pt.MP_TEST_PARAMETERS)
def test_mps_to_mpo(nr_sites, local_dim, rank, rgen):
mps = factory.random_mps(nr_sites, local_dim, rank, randstate=rgen)
Expand Down