Skip to content

Wrong signs in PauliPolynomial propagation (maybe)? #67

@Ectras

Description

@Ectras

I think the signs in the PropagateClifford implementation of PauliPolynomial might be wrong.

Example: Propagating S through an X rotation

For instance, when propagating an S from left to right through an X rotation, we should pick up a minus sign (source):

Image

However, in the code it's

fn s(&mut self, target: IndexType) -> &mut Self {
    let chains_target = self.chains.get_mut(target).unwrap();
    // Update angles
    let y_vec = chains_target.y_bitmask();
    for (angle, flip) in zip(self.angles.write().unwrap().iter_mut(), y_vec.iter()) {
        if *flip {
            *angle *= -1.0;
        }
    }
    chains_target.s();
    self
}

where s() on a chain is defined as

pub(crate) fn s(&self) {
    *self.z.write().unwrap() ^= self.x.read().unwrap().as_bitslice();
}

So for the example of a chain that is just a single X, no sign flip happens (because there is no Y) and only then the X is changed to a Y.

To make it more concrete, the following test code fails contrary to my expectations:

#[test]
fn pass_s_through_x() {
    let mut pp = PauliPolynomial::from_hamiltonian(vec![("X", 1.0)]);
    pp.s(0);
    let pp_ref = PauliPolynomial::from_hamiltonian(vec![("Y", -1.0)]);
    assert_eq!(pp, pp_ref);
}

Other cases

The sign behavior is reversed, for both s() and v().

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions