-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Allow expectation values for density matrix, MPS, Clifford #3990
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Conversation
@tonybruguier is there a quick way to add this to MPS as well? I see there is a state_vector field available on the trial result class. Could we add the same two lines there as I did here in state_vector_simulator and expect that to produce valid results? |
@95-martin-orion is it possible to do the same for Clifford simulators? |
@95-martin-orion oops, just saw you already had a fix. Up to you whether you'd rather use this one that generifies things or stick with the yagni approach. |
I am not sure what is required. Do you want the simulator to take a density matrix as initial state and return a density matrix at the output of the circuit? That could be involved to write. Or do you want the simulator to just output a density matrix? |
I think I figured it out. Just needed to add a way to get an expectation value from MPSTrialResult, which turned out to be a one-liner. Took the tests from density matrix simulator tests (stolen from @95-martin-orion's PR), and changed them to use MPS, and they seem to pass. |
Looks like Clifford also provides a function to generate a state vector from a trial result, so we can add an expectation value there too. Will add that before merging. |
Clifford seems to be working now too. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regardless of how this pans out, I think we need to document the Simulator hierarchy somewhere (maybe at the top of simulator.py
?) once it's done. Multiple nested base classes make it tricky to track which one supports what behavior.
@@ -225,6 +225,9 @@ def __str__(self) -> str: | |||
final = self._final_simulator_state | |||
return f'measurements: {samples}\noutput state: {final}' | |||
|
|||
def expectation_from_state(self, obs: 'cirq.PauliSum'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect there is a more efficient way to extract expectiation values from an MPS state than converting it into its full state vector form.
@@ -169,6 +169,9 @@ def __str__(self) -> str: | |||
final = self._final_simulator_state | |||
return f'measurements: {samples}\noutput state: {final}' | |||
|
|||
def expectation_from_state(self, obs: 'cirq.PauliSum'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the MPS simulator, there should be a way of calculating expectation values from the Clifford tableau without expanding it to the full state vector.
@@ -372,6 +374,33 @@ def simulate_sweep( | |||
""" | |||
raise NotImplementedError() | |||
|
|||
def simulate_expectation_values_sweep( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should include a note that this is only a default implementation; depending on the simulator's behavior, there may be a more efficient simulation method that bypasses simulating the full state.
result = self.simulate( | ||
program, param_resolver, qubit_order=qubit_order, initial_state=initial_state | ||
) | ||
swept_evs.append([result.expectation_from_state(obs) for obs in pslist]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My concern here: the fact that expectation_from_state
has no default implementation means that SimulatesFullState
does not fully implement SimulatesExpectationValues
, which means user-created subclasses will have a broken API.
We could update the class docstring to say that users must implement expectation_from_state
in their result class, but that's kind of unwieldy for a class whose base purpose does not include calculating expectation values. This is part of why I mentioned needing a SimulatesEVsAndFullState
type for this in #3979.
@95-martin-orion I agree. I think go ahead and merge your solution for density matrix. I'll look at how to improve this as time comes available. |
Closes #3964.
More generically, this solves it for any
SimulatesFinalState
implementation whoseTSimulationTrialResult
type implementsexpectation_from_state
.