Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class SuperOperator1D does not work #196

Open
stfnmangini opened this issue Aug 1, 2023 · 2 comments
Open

Class SuperOperator1D does not work #196

stfnmangini opened this issue Aug 1, 2023 · 2 comments
Labels

Comments

@stfnmangini
Copy link

stfnmangini commented Aug 1, 2023

What happened?

There is a problem with the SuperOperator1D class, as various errors regarding missing site tags, missing tag_map, and oset concatenations are raised when the class is called (see below).

Here is the original definition of the class: https://quimb.readthedocs.io/en/latest/autoapi/quimb/tensor/tensor_1d/index.html#quimb.tensor.tensor_1d.SuperOperator1D

I was able to circumvent the errors with minimal corrections to the original class, even though I am not completely sure that I haven't introduced other mistakes. Here is the updated definition of the class with highlighted changes:

class SuperOperator1D(TensorNetwork1D):
    r"""A 1D tensor network super-operator class::

        0   1   2       n-1
        |   |   |        |     <-- outer_upper_ind_id
        O===O===O==     =O
        |\  |\  |\       |\     <-- inner_upper_ind_id
          )   )   ) ...    )   <-- K (size of local Kraus sum)
        |/  |/  |/       |/     <-- inner_lower_ind_id
        O===O===O==     =O
        |   | : |        |     <-- outer_lower_ind_id
              :
             chi (size of entangling bond dim)

    Parameters
    ----------
    arrays : sequence of arrays
        The data arrays defining the superoperator, this should be a sequence
        of 2n arrays, such that the first two correspond to the upper and lower
        operators acting on site 0 etc. The arrays should be 5 dimensional
        unless OBC conditions are desired, in which case the first two and last
        two should be 4-dimensional. The dimensions of array can be should
        match the ``shape`` option.

    """

    _EXTRA_PROPS = (
        '_site_tag_id',
        '_outer_upper_ind_id',
        '_inner_upper_ind_id',
        '_inner_lower_ind_id',
        '_outer_lower_ind_id',
        'cyclic',
        '_L',
    )

    def __init__(
        self, arrays,
        shape='lrkud',
        site_tag_id='I{}',
        outer_upper_ind_id='kn{}',
        inner_upper_ind_id='k{}',
        inner_lower_ind_id='b{}',
        outer_lower_ind_id='bn{}',
        tags=None,
        tags_upper=None,
        tags_lower=None,
        **tn_opts,
    ):
        # short-circuit for copying
        if isinstance(arrays, SuperOperator1D):
            super().__init__(arrays)
            return

        arrays = tuple(arrays)
        self._L = len(arrays) // 2

        # process indices
        self._outer_upper_ind_id = outer_upper_ind_id
        self._inner_upper_ind_id = inner_upper_ind_id
        self._inner_lower_ind_id = inner_lower_ind_id
        self._outer_lower_ind_id = outer_lower_ind_id

        ### ! Moved process tags section here, and added tuple command() ! ###
        # process tags
        self._site_tag_id = site_tag_id
        tags = tuple(tags_to_oset(tags))
        tags_upper = tuple(tags_to_oset(tags_upper))
        tags_lower = tuple(tags_to_oset(tags_lower))

        ### ! Changed definition of sites_present ! ###
        #sites_present = tuple(self.gen_sites_present())
        sites_present = tuple(self.sites)
        outer_upper_inds = map(outer_upper_ind_id.format, sites_present)
        inner_upper_inds = map(inner_upper_ind_id.format, sites_present)
        inner_lower_inds = map(inner_lower_ind_id.format, sites_present)
        outer_lower_inds = map(outer_lower_ind_id.format, sites_present)

        ### ! Moved this section up ! ###
        # process tags
        # self._site_tag_id = site_tag_id
        # tags = tags_to_oset(tags)
        # tags_upper = tags_to_oset(tags_upper)
        # tags_lower = tags_to_oset(tags_lower)

       # The rest is the same ...
       # ....

What did you expect to happen?

No errors raised.

Minimal Complete Verifiable Example

import quimb.tensor as qtn
L = 2
K = 3
chi = 4
qtn.SuperOperator1D.rand(L, K, chi)

Relevant log output

AttributeError: 'SuperOperator1D' object has no attribute '_site_tag_id'

Anything else we need to know?

The same error arises if you specify the tensor data, instead of instantiating a random SuperOperator as in the example above.

Such error AttributeError: 'SuperOperator1D' object has no attribute '_site_tag_id' is solved by moving the process tags section in the class right after the process indices section (see updated version of the class above).

Then, another error occurs within the function self.gen_sites_present(), namely AttributeError: 'SuperOperator1D' object has no attribute 'tag_map'. In the modified class above, this is solved with the substitution:

#sites_present = tuple(self.gen_sites_present())
sites_present = tuple(self.sites)

Lastly, there is a final error in the function gen_tags(), namely TypeError: can only concatenate tuple (not "oset") to tuple. This is solved by transforming the tags to tuples, as follows.

#tags = tags_to_oset(tags)
tags = tuple(tags_to_oset(tags))

and similarly for the other tags.

As I said earlier, these small modifications fix the class but I'm not proficient enough with quimb to be sure that these do not introduce undesired behaviours.

Environment

quimb.__version__ = '1.5.0'

Open to suggestions and comments :)
And kudos to Johnnie for quimb, it's truly impressive!

@stfnmangini stfnmangini added the bug label Aug 1, 2023
@jcmgray
Copy link
Owner

jcmgray commented Aug 3, 2023

Yes this class was a bit of an experimental afterthought that has become outdated. My suggestion would be simply to remove it for the moment. Since it currently doesn't have a real use case for me! but were you hoping to use for something specific?

@stfnmangini
Copy link
Author

I see, thank you for the quick reply! As for my use case, my goal was to build an LPDO-like tensor network to represent a CP channel, and with the tweaks above it seems to do the job :D

Do you think it is worth working on it to make it compatible again with the newer versions of quimb?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants