Skip to content

Commit 4678387

Browse files
Broadcast analysis options to child experiments (#1277)
### 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 <yaelbh@il.ibm.com>
1 parent f3a2668 commit 4678387

File tree

4 files changed

+72
-1
lines changed

4 files changed

+72
-1
lines changed

docs/tutorials/getting_started.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,4 +393,17 @@ into one level:
393393
parallel_data = parallel_exp.run(backend, seed_simulator=101).block_for_results()
394394

395395
for result in parallel_data.analysis_results():
396-
print(result)
396+
print(result)
397+
398+
Broadcasting analysis options to child experiments
399+
--------------------------------------------------
400+
401+
Use the `broadcast` parameter to set analysis options to each of the child experiments.
402+
403+
.. jupyter-execute::
404+
405+
parallel_exp.analysis.set_options(plot=False, broadcast=True)
406+
407+
If the child experiment inherits from :class:`.CompositeExperiment` (such as :class:`.ParallelExperiment`
408+
and :class:`.BatchExperiment` classes), this process will continue to work recursively.
409+
In this instance, the analysis will not generate a figure for the child experiment after the analysis.

qiskit_experiments/framework/composite/composite_analysis.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ def component_analysis(
9696
return self._analyses
9797
return self._analyses[index]
9898

99+
def set_options(self, **fields):
100+
"""Set the analysis options for the experiment. If the `broadcast` argument set to `True`, the
101+
analysis options will cascade to the child experiments."""
102+
super().set_options(**fields)
103+
if fields.get("broadcast", None):
104+
for sub_analysis in self._analyses:
105+
sub_analysis.set_options(**fields)
106+
99107
def copy(self):
100108
ret = super().copy()
101109
# Recursively copy analysis
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
features:
3+
- |
4+
Added a `broadcast` option to the :class:`.CompositeAnalysis`. When `broadcast=True` is passed,
5+
this option will be applied to child experiment analyses within the class. This means it will iterate
6+
through the child analysis classes and apply the given option to each of
7+
them.

test/framework/test_composite.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,49 @@ def _default_options(cls):
624624
self.assertEqual(par_exp.analysis.component_analysis(0).options.option1, opt1_val)
625625
self.assertEqual(par_exp.analysis.component_analysis(1).options.option2, opt2_val)
626626

627+
def test_composite_analysis_options_cascade(self):
628+
"""Test setting component analysis options"""
629+
630+
class Analysis(FakeAnalysis):
631+
"""Fake analysis class with options"""
632+
633+
@classmethod
634+
def _default_options(cls):
635+
opts = super()._default_options()
636+
opts.option1 = None
637+
return opts
638+
639+
exp1 = FakeExperiment([0])
640+
exp1.analysis = Analysis()
641+
exp2 = FakeExperiment([1])
642+
exp2.analysis = Analysis()
643+
par_exp1 = ParallelExperiment([exp1, exp2], flatten_results=True)
644+
645+
exp3 = FakeExperiment([0])
646+
exp3.analysis = Analysis()
647+
exp4 = FakeExperiment([1])
648+
exp4.analysis = Analysis()
649+
par_exp2 = ParallelExperiment([exp3, exp4], flatten_results=True)
650+
651+
# Set a batch experiment
652+
batch_exp = BatchExperiment([par_exp1, par_exp2], flatten_results=True)
653+
654+
# Set new option to the experiment
655+
exp_list = [exp1, exp2, exp3, exp4]
656+
opt1_vals = [9000, 8000, 7000, 6000]
657+
for exp, opt1_val in zip(exp_list, opt1_vals):
658+
exp.analysis.set_options(option1=opt1_val)
659+
660+
opt1_new_val = 1000
661+
batch_exp.analysis.set_options(option1=opt1_new_val, broadcast=False)
662+
663+
for exp in exp_list:
664+
self.assertNotEqual(exp.analysis.options.option1, opt1_new_val)
665+
666+
batch_exp.analysis.set_options(option1=opt1_new_val, broadcast=True)
667+
for exp in exp_list:
668+
self.assertEqual(exp.analysis.options.option1, opt1_new_val)
669+
627670
@data(
628671
["0x0", "0x2", "0x3", "0x0", "0x0", "0x1", "0x3", "0x0", "0x2", "0x3"],
629672
["00", "10", "11", "00", "00", "01", "11", "00", "10", "11"],

0 commit comments

Comments
 (0)