diff --git a/tensornetwork/matrixproductstates/finite_mps.py b/tensornetwork/matrixproductstates/finite_mps.py index 0fc308ee0..0e32d3e2e 100644 --- a/tensornetwork/matrixproductstates/finite_mps.py +++ b/tensornetwork/matrixproductstates/finite_mps.py @@ -29,25 +29,25 @@ class FiniteMPS(BaseMPS): """ - An MPS class for finite systems. + An MPS class for finite systems. MPS tensors are stored as a list of `Node` objects in the `FiniteMPS.nodes` attribute. - `FiniteMPS` has a central site, also called orthogonality center. - The position of this central site is stored in `FiniteMPS.center_position`, - and it can be be shifted using the `FiniteMPS.position` method. + `FiniteMPS` has a central site, also called orthogonality center. + The position of this central site is stored in `FiniteMPS.center_position`, + and it can be be shifted using the `FiniteMPS.position` method. `FiniteMPS.position` uses QR and RQ methods to shift `center_position`. - + `FiniteMPS` can be initialized either from a `list` of tensors, or by calling the classmethod `FiniteMPS.random`. - + By default, `FiniteMPS` is initialized in *canonical* form, i.e. - the state is normalized, and all tensors to the left of - `center_position` are left orthogonal, and all tensors + the state is normalized, and all tensors to the left of + `center_position` are left orthogonal, and all tensors to the right of `center_position` are right orthogonal. The tensor at `FiniteMPS.center_position` is neither left nor right orthogonal. - Note that canonicalization can be computationally relatively + Note that canonicalization can be computationally relatively costly and scales :math:`\\propto ND^3`. """ @@ -62,7 +62,7 @@ def __init__(self, tensors: A list of `Tensor` or `BaseNode` objects. center_position: The initial position of the center site. canonicalize: If `True` the mps is canonicalized at initialization. - backend: The name of the backend that should be used to perform + backend: The name of the backend that should be used to perform contractions. Available backends are currently 'numpy', 'tensorflow', 'pytorch', 'jax' """ @@ -160,10 +160,13 @@ def left_envs(self, sites: Sequence[int]) -> Dict: Args: sites (list of int): A list of sites of the MPS. Returns: - `dict` mapping `int` to `Tensor`: The left-reduced density matrices + `dict` mapping `int` to `Tensor`: The left-reduced density matrices at each site in `sites`. """ + if not sites: + return {} + n2 = max(sites) sites = np.array(sites) #enable logical indexing @@ -227,9 +230,11 @@ def right_envs(self, sites: Sequence[int]) -> Dict: Args: sites (list of int): A list of sites of the MPS. Returns: - `dict` mapping `int` to `Tensor`: The right-reduced density matrices + `dict` mapping `int` to `Tensor`: The right-reduced density matrices at each site in `sites`. """ + if not sites: + return {} n1 = min(sites) sites = np.array(sites) diff --git a/tensornetwork/matrixproductstates/finite_mps_test.py b/tensornetwork/matrixproductstates/finite_mps_test.py index 0afe0f4f6..9b779ad8c 100644 --- a/tensornetwork/matrixproductstates/finite_mps_test.py +++ b/tensornetwork/matrixproductstates/finite_mps_test.py @@ -121,3 +121,33 @@ def test_correlation_measurement_finite_mps(backend_dtype_values): actual[N // 2] = 0.25 np.testing.assert_almost_equal(result_1, actual) np.testing.assert_allclose(result_2, np.ones(N) * 0.25) + + +def test_left_envs_empty_seq(backend_dtype_values): + backend = backend_dtype_values[0] + dtype = backend_dtype_values[1] + + D, d, N = 1, 2, 10 + tensors = [np.ones((1, d, D), dtype=dtype)] + [ + np.ones((D, d, D), dtype=dtype) for _ in range(N - 2) + ] + [np.ones((D, d, 1), dtype=dtype)] + mps = FiniteMPS(tensors, center_position=0, backend=backend) + + assert mps.left_envs(()) == {} + assert mps.left_envs([]) == {} + assert mps.left_envs(range(0)) == {} + + +def test_right_envs_empty_seq(backend_dtype_values): + backend = backend_dtype_values[0] + dtype = backend_dtype_values[1] + + D, d, N = 1, 2, 10 + tensors = [np.ones((1, d, D), dtype=dtype)] + [ + np.ones((D, d, D), dtype=dtype) for _ in range(N - 2) + ] + [np.ones((D, d, 1), dtype=dtype)] + mps = FiniteMPS(tensors, center_position=0, backend=backend) + + assert mps.right_envs(()) == {} + assert mps.right_envs([]) == {} + assert mps.right_envs(range(0)) == {}