Skip to content

Commit

Permalink
Broadcast analysis options to child experiments (#1277)
Browse files Browse the repository at this point in the history
### Summary

Adding the ability to set an `option` to all child experiment if
`broadcast=True` as requested in #1249 .


### PR checklist (delete when all criteria are met)

- [x] I have read the contributing guide `CONTRIBUTING.md`.
- [x] I have added the tests to cover my changes.
- [x] I have updated the documentation accordingly.
- [x] I have added a release note file using `reno` if this change needs
to be documented in the release notes.

---------

Co-authored-by: Yael Ben-Haim <[email protected]>
  • Loading branch information
ItamarGoldman and yaelbh authored Oct 16, 2023
1 parent f3a2668 commit 4678387
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 1 deletion.
15 changes: 14 additions & 1 deletion docs/tutorials/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -393,4 +393,17 @@ into one level:
parallel_data = parallel_exp.run(backend, seed_simulator=101).block_for_results()

for result in parallel_data.analysis_results():
print(result)
print(result)

Broadcasting analysis options to child experiments
--------------------------------------------------

Use the `broadcast` parameter to set analysis options to each of the child experiments.

.. jupyter-execute::

parallel_exp.analysis.set_options(plot=False, broadcast=True)

If the child experiment inherits from :class:`.CompositeExperiment` (such as :class:`.ParallelExperiment`
and :class:`.BatchExperiment` classes), this process will continue to work recursively.
In this instance, the analysis will not generate a figure for the child experiment after the analysis.
8 changes: 8 additions & 0 deletions qiskit_experiments/framework/composite/composite_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ def component_analysis(
return self._analyses
return self._analyses[index]

def set_options(self, **fields):
"""Set the analysis options for the experiment. If the `broadcast` argument set to `True`, the
analysis options will cascade to the child experiments."""
super().set_options(**fields)
if fields.get("broadcast", None):
for sub_analysis in self._analyses:
sub_analysis.set_options(**fields)

def copy(self):
ret = super().copy()
# Recursively copy analysis
Expand Down
7 changes: 7 additions & 0 deletions releasenotes/notes/broadcasting-option-8a3b72bfc1df9668.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
features:
- |
Added a `broadcast` option to the :class:`.CompositeAnalysis`. When `broadcast=True` is passed,
this option will be applied to child experiment analyses within the class. This means it will iterate
through the child analysis classes and apply the given option to each of
them.
43 changes: 43 additions & 0 deletions test/framework/test_composite.py
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,49 @@ def _default_options(cls):
self.assertEqual(par_exp.analysis.component_analysis(0).options.option1, opt1_val)
self.assertEqual(par_exp.analysis.component_analysis(1).options.option2, opt2_val)

def test_composite_analysis_options_cascade(self):
"""Test setting component analysis options"""

class Analysis(FakeAnalysis):
"""Fake analysis class with options"""

@classmethod
def _default_options(cls):
opts = super()._default_options()
opts.option1 = None
return opts

exp1 = FakeExperiment([0])
exp1.analysis = Analysis()
exp2 = FakeExperiment([1])
exp2.analysis = Analysis()
par_exp1 = ParallelExperiment([exp1, exp2], flatten_results=True)

exp3 = FakeExperiment([0])
exp3.analysis = Analysis()
exp4 = FakeExperiment([1])
exp4.analysis = Analysis()
par_exp2 = ParallelExperiment([exp3, exp4], flatten_results=True)

# Set a batch experiment
batch_exp = BatchExperiment([par_exp1, par_exp2], flatten_results=True)

# Set new option to the experiment
exp_list = [exp1, exp2, exp3, exp4]
opt1_vals = [9000, 8000, 7000, 6000]
for exp, opt1_val in zip(exp_list, opt1_vals):
exp.analysis.set_options(option1=opt1_val)

opt1_new_val = 1000
batch_exp.analysis.set_options(option1=opt1_new_val, broadcast=False)

for exp in exp_list:
self.assertNotEqual(exp.analysis.options.option1, opt1_new_val)

batch_exp.analysis.set_options(option1=opt1_new_val, broadcast=True)
for exp in exp_list:
self.assertEqual(exp.analysis.options.option1, opt1_new_val)

@data(
["0x0", "0x2", "0x3", "0x0", "0x0", "0x1", "0x3", "0x0", "0x2", "0x3"],
["00", "10", "11", "00", "00", "01", "11", "00", "10", "11"],
Expand Down

0 comments on commit 4678387

Please sign in to comment.