sandialabs / pyGSTi

A python implementation of Gate Set Tomography
http://www.pygsti.info
Apache License 2.0
134 stars 56 forks source link

Gauge transformations on SPAM #378

Closed juangmendoza19 closed 8 months ago

juangmendoza19 commented 10 months ago

Describe the bug When using the transform_inplace(s) method for models, I obtained a new model where only the logical operations were gauge transformed, but not the SPAM operators.

To Reproduce Steps to reproduce the behavior: Create your favorite non-TP gauge transformation, "T" import your favorite model from the modelpacks, "model"

ggEl = FullGaugeGroupElement(T) model.transform_inplace(ggEl)

Expected behavior Either a warning message should be displayed telling the user that non-TP gauge transformations are not allowed, or the SPAM should also be transformed.

Additional context Currently we have one if statement in modelmembers/operations/experrorgenop.py in ExpErrorgenOp.spam_transform_inplace() " if isinstance(s, _gaugegroup.UnitaryGaugeGroupElement) \ or isinstance(s, _gaugegroup.TPSpamGaugeGroupElement): "

which is False for non-TP matrices. Thus nothing gets done to the SPAM in this case. I believe this condition is not tested for gates. See modelmember/operations/composedop.py ComposedOp.transform_inplace()

juangmendoza19 commented 10 months ago

Update: Found out that even providing a TP matrix for T (I used the identity) in the code above

"ggEl = FullGaugeGroupElement(T) model.transform_inplace(ggEl)"

Still evaluates

isinstance(s, _gaugegroup.TPSpamGaugeGroupElement)

as False.

sserita commented 8 months ago

Hi @juangmendoza19, thanks for the bug report and sorry for the slow response. I have added the same warning that checks for Unitary/TP gauge groups in LindbladErrorgen.transform_inplace() to the ExpErrorgenOp.spam_transform_inplace(), which I think satisfies your desired solution of an exception being raised.

A few other comments though: In general, non-TP gauge transformations are allowed (in that we don't check whether gauge transformations are TP or not, we just call transform_inplace() recursively on the modelmembers). While trying to reproducing this, I was able to do something like

from pygsti.models.gaugegroup import FullGaugeGroupElement
from pygsti.modelpacks import smq1Q_XYI as modelpack

T = np.diag([0.9, 1, 1, 1])
ggEl = FullGaugeGroupElement(T)
model = modelpack.target_model(gate_type='full')
model.transform_inplace(ggEl)

and the resulting model did have the SPAM modified.

This leads me to believe that you were testing a model that was not "full" parameterized, but maybe "CPTPLND"? Or perhaps just the SPAM was "CPTPLND"? In that case, a non-TP gauge transformation would have been performed on the gates, but not on the SPAM due to the if statement you mention in the issue. (But if your ops were also CPTPLND, then they should have hit the else branch in LindbladErrorgen.transform_inplace()). I could be wrong though.

Finally, with regards to your followup comment: I think this is intended behavior. Even though T is TP in your case, you created a FullGaugeGroupElement with it. That object does not automatically test for TP-ness, so you still fail the if statement.