rigetti / pyquil

A Python library for quantum programming using Quil.
http://docs.rigetti.com
Apache License 2.0
1.4k stars 342 forks source link

Decompose measure_observables #1028

Open kylegulshen opened 5 years ago

kylegulshen commented 5 years ago

Measure_observables can be decomposed into separate raw expectation estimation and calibration steps. Each of these in turn can be decomposed into a program generation step and a data collection step. This follows the decomposition done in forest-benchmarking, and is a step in uniting the two implementations.

karalekas commented 5 years ago

@kylegulshen Can you talk a bit about the design of this new refactored interface (as is suggested in the Feature Request Template)? Would be great to be able to discuss it a bit before it is in PR. Thanks!

kylegulshen commented 5 years ago

Sure,

Currently estiamte_observables loops over each group of ExperimentSettings in the TomographyExperiment and performs the following steps:

1) translate the collection of settings into a program

2) collect results for this program either with no symmetrization or exhaustive symmetrization

At this point it loops over individual ExperimentSettings in the group, and for each setting: 3) calculates the expectation and standard error for the setting observable

4) optionally performs calibration on the results of 3) 4a) generate a calibration program, similar to 1) but determined by the setting observable 4b) collects data a la 2) but requires symmetrization. 4c) calculates calibration expectation and std_err, modifies the expectation calculated in 3), and yields the old, new, and calibration statistics wrapped in a ExperimentResult

The proposal is to mostly follow forest-benchmarkings approach, but with estimate_observables as a wrapper that:

1) call a method that translates a TomographyExperiment into a list of programs a la 1) above.

2) for each program and corresponding group of Settings, take results with any level of symmetrization and add to a running list of ExperimentResult with the statistics.

3) Either yield this list to the caller of estimate_observables, or optionally call a calibration method that takes in the list of ExperimentResults and a) scans through all observables in the list of ExperimentResults to remove duplicate observables. b) for each unique observable found in a) generate a program and collect statistics as in 2). c) use this consolidated set of calibration statistics to calibrate the raw statistics and yield these ExperimentResults to the caller of estimate_observables.

There are a number of benefits to this decomposition. E.g. the user has access to intermediate parts of the process where they can interject changes. The check in 3a prevents redundant calls to the QPU.