qsharp icon indicating copy to clipboard operation
qsharp copied to clipboard

Mitigating confusing global phase

Open tcNickolas opened this issue 3 months ago • 16 comments

Discussion landed at a few concrete tasks to help with mitigating how confusing global phase in simulation can be:

  • [x] #1370
  • [ ] #1388
  • [x] #1450
  • [x] https://github.com/qir-alliance/qir-runner/issues/162
  • [x] Pull in fix for Rx/Ry phase by updating simulator tag (#1461)
  • [x] Add equivalence check member function for StateDump in Python to make checking states easier with global phase (#1372)
  • [x] Ensure DumpRegister does not add phase on display (#1461)
  • [x] https://github.com/qir-alliance/qir-runner/pull/173
  • [x] Pull in fix for Rx/Ry of 2 Pi by updating simulator tag (#1551)

Describe the bug

QDK sparse simulator introduces a global phase at random that shows up in DumpMachine output (and the outputs derived from it, such as dump_operation).

This is very confusing for several ways:

  1. Pedagogically, global phase is hard enough to explain on its own, and if it appears randomly in contexts where there's nowhere for it to come from, this is very confusing for the learner (in the katas output, in assignments, in experimentation they do on their own, and so on.)
  2. Writing tests becomes a lot more elaborate compared, say, to Qiskit: where in Qiskit I would just write assert state_vector == pytest.approx(a) to compare the state vectors, in Q# I have to first detect the global phase difference between the expected state and the actual state and then as I loop over the elements to remember to include it in every element comparison.

To Reproduce

Several examples:

  • If you run our sample BellState.qs several times, sometimes the last two states have an extra -1 phase.
  • The test TestPreparationCompletion in our libraries prepares states with real amplitudes, but the expected DumpMachine output (starting with states that have both positive and negative) has complex amplitudes.
  • In the katas, phase oracles that are different by a global phase produce the same output when applied to the same state.
  • If I write a simple test for a state preparation operation that uses only Ry and Controlled Ry gates (no gates that might introduce any complex numbers), two of the basis states in the test (the second and the fourth) will acquire a complex phase i.
@pytest.mark.parametrize("a",
    [ [1., 0., 0., 0.],
      [0., 1., 0., 0.],
      [0., 0., 1., 0.],
      [0., 0., 0., 1.]]
def test_prep_two_qubit(a):
  qsharp.init(project_root='.')
  qsharp.eval(f"use qs = Qubit[2]; StatePreparation.PrepTwoQubits(qs, {a});")
  state = qsharp.dump_machine()
  print(state)
  # Do the testing

Expected behavior

Simulator not introducing a random global phase in vast majority of scenarios (for example, when there are only real-valued gates involved).

tcNickolas avatar Mar 26 '24 18:03 tcNickolas