From fc3bd83634771dd564321f4f4627730373f9e711 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Mon, 11 Dec 2023 00:53:20 +0800 Subject: [PATCH 01/21] Added test and release notes update --- test/python/pulse/test_parameter_manager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index baeb30e47498..719b93fc644f 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -18,6 +18,7 @@ from unittest.mock import patch import numpy as np +from qiskit.pulse.library import Gaussian from qiskit import pulse from qiskit.circuit import Parameter From 436f86b5723aed096ecdd817040b2a62f882ec73 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Tue, 12 Dec 2023 16:17:23 +0800 Subject: [PATCH 02/21] Reformatting --- test/python/pulse/test_parameter_manager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index 719b93fc644f..baeb30e47498 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -18,7 +18,6 @@ from unittest.mock import patch import numpy as np -from qiskit.pulse.library import Gaussian from qiskit import pulse from qiskit.circuit import Parameter From 50bdf28a43935a9193cf05b472aadafd21a8f359 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Mon, 11 Dec 2023 00:53:20 +0800 Subject: [PATCH 03/21] Added test and release notes update --- test/python/pulse/test_parameter_manager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index 16cbc7bc8117..a8ecc1637c87 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -19,6 +19,7 @@ import ddt import numpy as np +from qiskit.pulse.library import Gaussian from qiskit import pulse from qiskit.circuit import Parameter From 0e8619a2892e78ed9c2abfaea10071c9e40e3e37 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Tue, 12 Dec 2023 16:17:23 +0800 Subject: [PATCH 04/21] Reformatting --- test/python/pulse/test_parameter_manager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index a8ecc1637c87..16cbc7bc8117 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -19,7 +19,6 @@ import ddt import numpy as np -from qiskit.pulse.library import Gaussian from qiskit import pulse from qiskit.circuit import Parameter From 5c0bf9b2b3c1a309102e74fedac6bbed2f51ee95 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Wed, 20 Mar 2024 16:07:34 +0800 Subject: [PATCH 05/21] Added compatibility of pulse ParameterManager with ParameterVector It is now possible to assign to a pulse schedule parameters in the form of a list of values that can be directly binded to ParameterVector. This PR is based on the current functioning of the analogous method for the QuantumCircuit class. --- qiskit/pulse/parameter_manager.py | 47 +++++++++++++++++-- qiskit/pulse/schedule.py | 21 ++++++--- ...with_ParameterVector-7d31395fd4019827.yaml | 14 ++++++ test/python/pulse/test_parameter_manager.py | 18 ++++++- 4 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml diff --git a/qiskit/pulse/parameter_manager.py b/qiskit/pulse/parameter_manager.py index 5c8163cb10fe..06eedfa71f18 100644 --- a/qiskit/pulse/parameter_manager.py +++ b/qiskit/pulse/parameter_manager.py @@ -52,8 +52,9 @@ """ from __future__ import annotations from copy import copy -from typing import Any +from typing import Any, Mapping +from qiskit.circuit import ParameterVector from qiskit.circuit.parameter import Parameter from qiskit.circuit.parameterexpression import ParameterExpression, ParameterValueType from qiskit.pulse import instructions, channels @@ -360,7 +361,9 @@ def get_parameters(self, parameter_name: str) -> list[Parameter]: def assign_parameters( self, pulse_program: Any, - value_dict: dict[ParameterExpression, ParameterValueType], + value_dict: dict[ + ParameterExpression | ParameterVector, ParameterValueType | list[ParameterValueType] + ], ) -> Any: """Modify and return program data with parameters assigned according to the input. @@ -372,7 +375,10 @@ def assign_parameters( Returns: Updated program data. """ - valid_map = {k: value_dict[k] for k in value_dict.keys() & self._parameters} + unrolled_value_dict = self._unroll_param_dict(value_dict) + valid_map = { + k: unrolled_value_dict[k] for k in unrolled_value_dict.keys() & self._parameters + } if valid_map: visitor = ParameterSetter(param_map=valid_map) return visitor.visit(pulse_program) @@ -387,3 +393,38 @@ def update_parameter_table(self, new_node: Any): visitor = ParameterGetter() visitor.visit(new_node) self._parameters |= visitor.parameters + + def _unroll_param_dict( + self, + parameter_binds: Mapping[ + Parameter | ParameterVector, ParameterValueType | list[ParameterValueType] + ], + ) -> Mapping[Parameter, ParameterValueType]: + """ + Unroll parameter dictionary to a map from parameter to value. + + Args: + parameter_binds: A dictionary from parameter to value or a list of values. + + Returns: + A dictionary from parameter to value. + """ + out = {} + for parameter, value in parameter_binds.items(): + if isinstance(parameter, ParameterVector): + if not isinstance(value, (list, tuple)): + raise PulseError( + f"Parameter vector '{parameter.name}' has length {len(parameter)}," + f" but was assigned to a single value." + ) + if len(parameter) != len(value): + raise PulseError( + f"Parameter vector '{parameter.name}' has length {len(parameter)}," + f" but was assigned to {len(value)} values." + ) + out.update(zip(parameter, value)) + elif isinstance(parameter, str): + out[self.get_parameters(parameter)] = value + else: + out[parameter] = value + return out diff --git a/qiskit/pulse/schedule.py b/qiskit/pulse/schedule.py index 96ef90706ce0..86c885de495f 100644 --- a/qiskit/pulse/schedule.py +++ b/qiskit/pulse/schedule.py @@ -44,6 +44,7 @@ import numpy as np import rustworkx as rx +from qiskit.circuit import ParameterVector from qiskit.circuit.parameter import Parameter from qiskit.circuit.parameterexpression import ParameterExpression, ParameterValueType from qiskit.pulse.channels import Channel @@ -711,13 +712,18 @@ def is_parameterized(self) -> bool: return self._parameter_manager.is_parameterized() def assign_parameters( - self, value_dict: dict[ParameterExpression, ParameterValueType], inplace: bool = True + self, + value_dict: dict[ + ParameterExpression | ParameterVector, ParameterValueType | list[ParameterValueType] + ], + inplace: bool = True, ) -> "Schedule": """Assign the parameters in this schedule according to the input. Args: - value_dict: A mapping from Parameters to either numeric values or another - Parameter expression. + value_dict: A mapping from Parameters (ParameterVectors) to either + numeric values (list of numeric values) + or another Parameter expression (list of Parameter expressions). inplace: Set ``True`` to override this instance with new parameter. Returns: @@ -1408,14 +1414,17 @@ def is_referenced(self) -> bool: def assign_parameters( self, - value_dict: dict[ParameterExpression, ParameterValueType], + value_dict: dict[ + ParameterExpression | ParameterVector, ParameterValueType | list[ParameterValueType] + ], inplace: bool = True, ) -> "ScheduleBlock": """Assign the parameters in this schedule according to the input. Args: - value_dict: A mapping from Parameters to either numeric values or another - Parameter expression. + value_dict: A mapping from Parameters (ParameterVectors) to either numeric values + (list of numeric values) + or another Parameter expression (list of Parameter expression). inplace: Set ``True`` to override this instance with new parameter. Returns: diff --git a/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml new file mode 100644 index 000000000000..40653f7a645e --- /dev/null +++ b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml @@ -0,0 +1,14 @@ +--- +prelude: > + Compatibility of pulse parameter assignment with `ParameterVector` class. +features: + - | + The `ParameterManager` now supports the `ParameterVector` class. This enables + the use of `ParameterVector` in pulse `Schedule`and `ScheduleBlock` objects when using their method + `assign_parameters` to assign simultaneously a list of parameter values. + - | + An additional method `_unroll_param_dict`has been added to the `ParameterManager` class to unroll the + parameter dictionary into a list of parameter values. This method is used to convert the parameter dictionary + into a list of parameter values when using the `ParameterVector` class. This method is a replication of the + analogous method `_unroll_param_dict` in `QuantumCircuit` class. + diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index 16cbc7bc8117..ef1cad41b59d 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -21,7 +21,7 @@ import numpy as np from qiskit import pulse -from qiskit.circuit import Parameter +from qiskit.circuit import Parameter, ParameterVector from qiskit.pulse.exceptions import PulseError, UnassignedDurationError from qiskit.pulse.parameter_manager import ParameterGetter, ParameterSetter from qiskit.pulse.transforms import AlignEquispaced, AlignLeft, inline_subroutines @@ -483,6 +483,22 @@ def test_parametric_pulses(self): self.assertEqual(block.blocks[0].pulse.amp, 0.2) self.assertEqual(block.blocks[0].pulse.sigma, 4.0) + def test_parametric_pulses_with_parameter_vector(self): + """Test Parametric Pulses with parameters determined by a ParameterVector + in the Play instruction.""" + param_vec = ParameterVector("param_vec", 3) + + waveform = pulse.library.Gaussian(duration=128, sigma=param_vec[0], amp=param_vec[1]) + + block = pulse.ScheduleBlock() + block += pulse.Play(waveform, pulse.DriveChannel(10)) + block += pulse.ShiftPhase(param_vec[2], pulse.DriveChannel(10)) + block.assign_parameters({param_vec: [4, 0.2, 0.1]}, inplace=True) + + self.assertEqual(block.blocks[0].pulse.amp, 0.2) + self.assertEqual(block.blocks[0].pulse.sigma, 4.0) + self.assertEqual(block.blocks[1].phase, 0.1) + class TestScheduleTimeslots(QiskitTestCase): """Test for edge cases of timing overlap on parametrized channels. From c754ff27b36c90c28869fe1f49f9a69dec593f10 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Thu, 21 Mar 2024 09:36:45 +0800 Subject: [PATCH 06/21] Commit requested changes Type for submitting a list of parameters has been set to Sequence for the case of ParameterVector. This enables the user to also pass a tuple of values/ParameterExpressions --- qiskit/pulse/parameter_manager.py | 8 ++++---- qiskit/pulse/schedule.py | 12 ++++++------ ...compat_with_ParameterVector-7d31395fd4019827.yaml | 10 +++------- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/qiskit/pulse/parameter_manager.py b/qiskit/pulse/parameter_manager.py index 06eedfa71f18..561eac01f55d 100644 --- a/qiskit/pulse/parameter_manager.py +++ b/qiskit/pulse/parameter_manager.py @@ -52,7 +52,7 @@ """ from __future__ import annotations from copy import copy -from typing import Any, Mapping +from typing import Any, Mapping, Sequence from qiskit.circuit import ParameterVector from qiskit.circuit.parameter import Parameter @@ -362,7 +362,7 @@ def assign_parameters( self, pulse_program: Any, value_dict: dict[ - ParameterExpression | ParameterVector, ParameterValueType | list[ParameterValueType] + ParameterExpression | ParameterVector, ParameterValueType | Sequence[ParameterValueType] ], ) -> Any: """Modify and return program data with parameters assigned according to the input. @@ -397,7 +397,7 @@ def update_parameter_table(self, new_node: Any): def _unroll_param_dict( self, parameter_binds: Mapping[ - Parameter | ParameterVector, ParameterValueType | list[ParameterValueType] + Parameter | ParameterVector, ParameterValueType | Sequence[ParameterValueType] ], ) -> Mapping[Parameter, ParameterValueType]: """ @@ -412,7 +412,7 @@ def _unroll_param_dict( out = {} for parameter, value in parameter_binds.items(): if isinstance(parameter, ParameterVector): - if not isinstance(value, (list, tuple)): + if not isinstance(value, Sequence): raise PulseError( f"Parameter vector '{parameter.name}' has length {len(parameter)}," f" but was assigned to a single value." diff --git a/qiskit/pulse/schedule.py b/qiskit/pulse/schedule.py index 86c885de495f..2a32b06a4780 100644 --- a/qiskit/pulse/schedule.py +++ b/qiskit/pulse/schedule.py @@ -39,7 +39,7 @@ import sys import warnings from collections.abc import Callable, Iterable -from typing import List, Tuple, Union, Dict, Any +from typing import List, Tuple, Union, Dict, Any, Sequence import numpy as np import rustworkx as rx @@ -714,14 +714,14 @@ def is_parameterized(self) -> bool: def assign_parameters( self, value_dict: dict[ - ParameterExpression | ParameterVector, ParameterValueType | list[ParameterValueType] + ParameterExpression | ParameterVector, ParameterValueType | Sequence[ParameterValueType] ], inplace: bool = True, ) -> "Schedule": """Assign the parameters in this schedule according to the input. Args: - value_dict: A mapping from Parameters (ParameterVectors) to either + value_dict: A mapping from parameters (parameter vectors) to either numeric values (list of numeric values) or another Parameter expression (list of Parameter expressions). inplace: Set ``True`` to override this instance with new parameter. @@ -1415,16 +1415,16 @@ def is_referenced(self) -> bool: def assign_parameters( self, value_dict: dict[ - ParameterExpression | ParameterVector, ParameterValueType | list[ParameterValueType] + ParameterExpression | ParameterVector, ParameterValueType | Sequence[ParameterValueType] ], inplace: bool = True, ) -> "ScheduleBlock": """Assign the parameters in this schedule according to the input. Args: - value_dict: A mapping from Parameters (ParameterVectors) to either numeric values + value_dict: A mapping from parameters (parameter vectors) to either numeric values (list of numeric values) - or another Parameter expression (list of Parameter expression). + or another parameter expression (list of parameter expressions). inplace: Set ``True`` to override this instance with new parameter. Returns: diff --git a/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml index 40653f7a645e..6e0e5c748b1e 100644 --- a/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml +++ b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml @@ -1,14 +1,10 @@ --- prelude: > - Compatibility of pulse parameter assignment with `ParameterVector` class. -features: + +features_pulse: - | The `ParameterManager` now supports the `ParameterVector` class. This enables the use of `ParameterVector` in pulse `Schedule`and `ScheduleBlock` objects when using their method `assign_parameters` to assign simultaneously a list of parameter values. - - | - An additional method `_unroll_param_dict`has been added to the `ParameterManager` class to unroll the - parameter dictionary into a list of parameter values. This method is used to convert the parameter dictionary - into a list of parameter values when using the `ParameterVector` class. This method is a replication of the - analogous method `_unroll_param_dict` in `QuantumCircuit` class. + From 0d91204ea799d02f9d35bffd2e386fe4f9654ef1 Mon Sep 17 00:00:00 2001 From: Arthur Strauss <56998701+arthurostrauss@users.noreply.github.com> Date: Fri, 22 Mar 2024 07:13:18 +0800 Subject: [PATCH 07/21] Update pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml Co-authored-by: TsafrirA <113579969+TsafrirA@users.noreply.github.com> --- ...er_manager_compat_with_ParameterVector-7d31395fd4019827.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml index 6e0e5c748b1e..0ddc497c4647 100644 --- a/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml +++ b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml @@ -4,7 +4,7 @@ prelude: > features_pulse: - | The `ParameterManager` now supports the `ParameterVector` class. This enables - the use of `ParameterVector` in pulse `Schedule`and `ScheduleBlock` objects when using their method + the use of `ParameterVector` in pulse `Schedule` and `ScheduleBlock` objects when using their method `assign_parameters` to assign simultaneously a list of parameter values. From a6f9de7fb8d54be7b3e276e1a30b4bb6b1ecb5d3 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Fri, 22 Mar 2024 07:47:55 +0800 Subject: [PATCH 08/21] Added tests for Schedule and case of mix Parameter+numeric values Complementary tests have been added for checking the pulse.Schedule.assign_parameters() method, as well as the functioning of binding to a ParameterVector a collection of numeric values and new ParameterExpression (through Parameter). --- test/python/pulse/test_parameter_manager.py | 24 +++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index ef1cad41b59d..0811fa9abb05 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -487,17 +487,33 @@ def test_parametric_pulses_with_parameter_vector(self): """Test Parametric Pulses with parameters determined by a ParameterVector in the Play instruction.""" param_vec = ParameterVector("param_vec", 3) + param = Parameter("param") waveform = pulse.library.Gaussian(duration=128, sigma=param_vec[0], amp=param_vec[1]) block = pulse.ScheduleBlock() block += pulse.Play(waveform, pulse.DriveChannel(10)) block += pulse.ShiftPhase(param_vec[2], pulse.DriveChannel(10)) - block.assign_parameters({param_vec: [4, 0.2, 0.1]}, inplace=True) + block1 = block.assign_parameters({param_vec: [4, 0.2, 0.1]}, inplace=False) + block2 = block.assign_parameters({param_vec: [4, param, 0.1]}, inplace=False) + self.assertEqual(block1.blocks[0].pulse.amp, 0.2) + self.assertEqual(block1.blocks[0].pulse.sigma, 4.0) + self.assertEqual(block1.blocks[1].phase, 0.1) + self.assertEqual(block2.blocks[0].pulse.amp, param) + self.assertEqual(block2.blocks[0].pulse.sigma, 4.0) + self.assertEqual(block2.blocks[1].phase, 0.1) - self.assertEqual(block.blocks[0].pulse.amp, 0.2) - self.assertEqual(block.blocks[0].pulse.sigma, 4.0) - self.assertEqual(block.blocks[1].phase, 0.1) + sched = pulse.Schedule() + sched += pulse.Play(waveform, pulse.DriveChannel(10)) + sched += pulse.ShiftPhase(param_vec[2], pulse.DriveChannel(10)) + sched1 = sched.assign_parameters({param_vec: [4, 0.2, 0.1]}, inplace=False) + sched2 = sched.assign_parameters({param_vec: [4, param, 0.1]}, inplace=False) + self.assertEqual(sched1.instructions[0][1].pulse.amp, 0.2) + self.assertEqual(sched1.instructions[0][1].pulse.sigma, 4.0) + self.assertEqual(sched1.instructions[1].phase, 0.1) + self.assertEqual(sched2.instructions[0][1].pulse.amp, param) + self.assertEqual(sched2.instructions[0][1].pulse.sigma, 4.0) + self.assertEqual(sched2.instructions[1].phase, 0.1) class TestScheduleTimeslots(QiskitTestCase): From 7e9b724055cdca520bda119b10cecfa4fb2e1cc3 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Fri, 22 Mar 2024 08:55:48 +0800 Subject: [PATCH 09/21] Corrected error for schedule test An error was occurring when trying to get access to an instruction parameter within schedule.instructions --- test/python/pulse/test_parameter_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index 0811fa9abb05..d1749456c4ae 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -510,10 +510,10 @@ def test_parametric_pulses_with_parameter_vector(self): sched2 = sched.assign_parameters({param_vec: [4, param, 0.1]}, inplace=False) self.assertEqual(sched1.instructions[0][1].pulse.amp, 0.2) self.assertEqual(sched1.instructions[0][1].pulse.sigma, 4.0) - self.assertEqual(sched1.instructions[1].phase, 0.1) + self.assertEqual(sched1.instructions[0][1].phase, 0.1) self.assertEqual(sched2.instructions[0][1].pulse.amp, param) self.assertEqual(sched2.instructions[0][1].pulse.sigma, 4.0) - self.assertEqual(sched2.instructions[1].phase, 0.1) + self.assertEqual(sched2.instructions[0][1].phase, 0.1) class TestScheduleTimeslots(QiskitTestCase): From a8098f99e085bb3243f23a23c2887155b7ef6eee Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Fri, 22 Mar 2024 09:22:49 +0800 Subject: [PATCH 10/21] Correction to test schedule --- test/python/pulse/test_parameter_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index d1749456c4ae..54268af14577 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -510,10 +510,10 @@ def test_parametric_pulses_with_parameter_vector(self): sched2 = sched.assign_parameters({param_vec: [4, param, 0.1]}, inplace=False) self.assertEqual(sched1.instructions[0][1].pulse.amp, 0.2) self.assertEqual(sched1.instructions[0][1].pulse.sigma, 4.0) - self.assertEqual(sched1.instructions[0][1].phase, 0.1) + self.assertEqual(sched1.instructions[1][1].phase, 0.1) self.assertEqual(sched2.instructions[0][1].pulse.amp, param) self.assertEqual(sched2.instructions[0][1].pulse.sigma, 4.0) - self.assertEqual(sched2.instructions[0][1].phase, 0.1) + self.assertEqual(sched2.instructions[1][1].phase, 0.1) class TestScheduleTimeslots(QiskitTestCase): From a221faf500856765e490e7eff5239475aa01a280 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Mon, 11 Dec 2023 00:53:20 +0800 Subject: [PATCH 11/21] Added test and release notes update --- test/python/pulse/test_parameter_manager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index 16cbc7bc8117..a8ecc1637c87 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -19,6 +19,7 @@ import ddt import numpy as np +from qiskit.pulse.library import Gaussian from qiskit import pulse from qiskit.circuit import Parameter From 9b5730fb6158a9a26cefa54de82e0b0ce789e244 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Tue, 12 Dec 2023 16:17:23 +0800 Subject: [PATCH 12/21] Reformatting --- test/python/pulse/test_parameter_manager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index a8ecc1637c87..16cbc7bc8117 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -19,7 +19,6 @@ import ddt import numpy as np -from qiskit.pulse.library import Gaussian from qiskit import pulse from qiskit.circuit import Parameter From 7b4b031981efa62e4fd959b14d52a2371c339cf1 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Mon, 11 Dec 2023 00:53:20 +0800 Subject: [PATCH 13/21] Added test and release notes update --- test/python/pulse/test_parameter_manager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index 16cbc7bc8117..a8ecc1637c87 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -19,6 +19,7 @@ import ddt import numpy as np +from qiskit.pulse.library import Gaussian from qiskit import pulse from qiskit.circuit import Parameter From 6713579e4ad161f69d1ef41ffc402e2ed62a1190 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Tue, 12 Dec 2023 16:17:23 +0800 Subject: [PATCH 14/21] Reformatting --- test/python/pulse/test_parameter_manager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index a8ecc1637c87..16cbc7bc8117 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -19,7 +19,6 @@ import ddt import numpy as np -from qiskit.pulse.library import Gaussian from qiskit import pulse from qiskit.circuit import Parameter From d705d2444f3b04479caff526aeb1f477b9ff0cc7 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Wed, 20 Mar 2024 16:07:34 +0800 Subject: [PATCH 15/21] Added compatibility of pulse ParameterManager with ParameterVector It is now possible to assign to a pulse schedule parameters in the form of a list of values that can be directly binded to ParameterVector. This PR is based on the current functioning of the analogous method for the QuantumCircuit class. --- qiskit/pulse/parameter_manager.py | 47 +++++++++++++++++-- qiskit/pulse/schedule.py | 21 ++++++--- ...with_ParameterVector-7d31395fd4019827.yaml | 14 ++++++ test/python/pulse/test_parameter_manager.py | 18 ++++++- 4 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml diff --git a/qiskit/pulse/parameter_manager.py b/qiskit/pulse/parameter_manager.py index 5c8163cb10fe..06eedfa71f18 100644 --- a/qiskit/pulse/parameter_manager.py +++ b/qiskit/pulse/parameter_manager.py @@ -52,8 +52,9 @@ """ from __future__ import annotations from copy import copy -from typing import Any +from typing import Any, Mapping +from qiskit.circuit import ParameterVector from qiskit.circuit.parameter import Parameter from qiskit.circuit.parameterexpression import ParameterExpression, ParameterValueType from qiskit.pulse import instructions, channels @@ -360,7 +361,9 @@ def get_parameters(self, parameter_name: str) -> list[Parameter]: def assign_parameters( self, pulse_program: Any, - value_dict: dict[ParameterExpression, ParameterValueType], + value_dict: dict[ + ParameterExpression | ParameterVector, ParameterValueType | list[ParameterValueType] + ], ) -> Any: """Modify and return program data with parameters assigned according to the input. @@ -372,7 +375,10 @@ def assign_parameters( Returns: Updated program data. """ - valid_map = {k: value_dict[k] for k in value_dict.keys() & self._parameters} + unrolled_value_dict = self._unroll_param_dict(value_dict) + valid_map = { + k: unrolled_value_dict[k] for k in unrolled_value_dict.keys() & self._parameters + } if valid_map: visitor = ParameterSetter(param_map=valid_map) return visitor.visit(pulse_program) @@ -387,3 +393,38 @@ def update_parameter_table(self, new_node: Any): visitor = ParameterGetter() visitor.visit(new_node) self._parameters |= visitor.parameters + + def _unroll_param_dict( + self, + parameter_binds: Mapping[ + Parameter | ParameterVector, ParameterValueType | list[ParameterValueType] + ], + ) -> Mapping[Parameter, ParameterValueType]: + """ + Unroll parameter dictionary to a map from parameter to value. + + Args: + parameter_binds: A dictionary from parameter to value or a list of values. + + Returns: + A dictionary from parameter to value. + """ + out = {} + for parameter, value in parameter_binds.items(): + if isinstance(parameter, ParameterVector): + if not isinstance(value, (list, tuple)): + raise PulseError( + f"Parameter vector '{parameter.name}' has length {len(parameter)}," + f" but was assigned to a single value." + ) + if len(parameter) != len(value): + raise PulseError( + f"Parameter vector '{parameter.name}' has length {len(parameter)}," + f" but was assigned to {len(value)} values." + ) + out.update(zip(parameter, value)) + elif isinstance(parameter, str): + out[self.get_parameters(parameter)] = value + else: + out[parameter] = value + return out diff --git a/qiskit/pulse/schedule.py b/qiskit/pulse/schedule.py index 96ef90706ce0..86c885de495f 100644 --- a/qiskit/pulse/schedule.py +++ b/qiskit/pulse/schedule.py @@ -44,6 +44,7 @@ import numpy as np import rustworkx as rx +from qiskit.circuit import ParameterVector from qiskit.circuit.parameter import Parameter from qiskit.circuit.parameterexpression import ParameterExpression, ParameterValueType from qiskit.pulse.channels import Channel @@ -711,13 +712,18 @@ def is_parameterized(self) -> bool: return self._parameter_manager.is_parameterized() def assign_parameters( - self, value_dict: dict[ParameterExpression, ParameterValueType], inplace: bool = True + self, + value_dict: dict[ + ParameterExpression | ParameterVector, ParameterValueType | list[ParameterValueType] + ], + inplace: bool = True, ) -> "Schedule": """Assign the parameters in this schedule according to the input. Args: - value_dict: A mapping from Parameters to either numeric values or another - Parameter expression. + value_dict: A mapping from Parameters (ParameterVectors) to either + numeric values (list of numeric values) + or another Parameter expression (list of Parameter expressions). inplace: Set ``True`` to override this instance with new parameter. Returns: @@ -1408,14 +1414,17 @@ def is_referenced(self) -> bool: def assign_parameters( self, - value_dict: dict[ParameterExpression, ParameterValueType], + value_dict: dict[ + ParameterExpression | ParameterVector, ParameterValueType | list[ParameterValueType] + ], inplace: bool = True, ) -> "ScheduleBlock": """Assign the parameters in this schedule according to the input. Args: - value_dict: A mapping from Parameters to either numeric values or another - Parameter expression. + value_dict: A mapping from Parameters (ParameterVectors) to either numeric values + (list of numeric values) + or another Parameter expression (list of Parameter expression). inplace: Set ``True`` to override this instance with new parameter. Returns: diff --git a/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml new file mode 100644 index 000000000000..40653f7a645e --- /dev/null +++ b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml @@ -0,0 +1,14 @@ +--- +prelude: > + Compatibility of pulse parameter assignment with `ParameterVector` class. +features: + - | + The `ParameterManager` now supports the `ParameterVector` class. This enables + the use of `ParameterVector` in pulse `Schedule`and `ScheduleBlock` objects when using their method + `assign_parameters` to assign simultaneously a list of parameter values. + - | + An additional method `_unroll_param_dict`has been added to the `ParameterManager` class to unroll the + parameter dictionary into a list of parameter values. This method is used to convert the parameter dictionary + into a list of parameter values when using the `ParameterVector` class. This method is a replication of the + analogous method `_unroll_param_dict` in `QuantumCircuit` class. + diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index 16cbc7bc8117..ef1cad41b59d 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -21,7 +21,7 @@ import numpy as np from qiskit import pulse -from qiskit.circuit import Parameter +from qiskit.circuit import Parameter, ParameterVector from qiskit.pulse.exceptions import PulseError, UnassignedDurationError from qiskit.pulse.parameter_manager import ParameterGetter, ParameterSetter from qiskit.pulse.transforms import AlignEquispaced, AlignLeft, inline_subroutines @@ -483,6 +483,22 @@ def test_parametric_pulses(self): self.assertEqual(block.blocks[0].pulse.amp, 0.2) self.assertEqual(block.blocks[0].pulse.sigma, 4.0) + def test_parametric_pulses_with_parameter_vector(self): + """Test Parametric Pulses with parameters determined by a ParameterVector + in the Play instruction.""" + param_vec = ParameterVector("param_vec", 3) + + waveform = pulse.library.Gaussian(duration=128, sigma=param_vec[0], amp=param_vec[1]) + + block = pulse.ScheduleBlock() + block += pulse.Play(waveform, pulse.DriveChannel(10)) + block += pulse.ShiftPhase(param_vec[2], pulse.DriveChannel(10)) + block.assign_parameters({param_vec: [4, 0.2, 0.1]}, inplace=True) + + self.assertEqual(block.blocks[0].pulse.amp, 0.2) + self.assertEqual(block.blocks[0].pulse.sigma, 4.0) + self.assertEqual(block.blocks[1].phase, 0.1) + class TestScheduleTimeslots(QiskitTestCase): """Test for edge cases of timing overlap on parametrized channels. From 27f91cc41434fd727abe56b81950a3531bb3a591 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Thu, 21 Mar 2024 09:36:45 +0800 Subject: [PATCH 16/21] Commit requested changes Type for submitting a list of parameters has been set to Sequence for the case of ParameterVector. This enables the user to also pass a tuple of values/ParameterExpressions --- qiskit/pulse/parameter_manager.py | 8 ++++---- qiskit/pulse/schedule.py | 12 ++++++------ ...compat_with_ParameterVector-7d31395fd4019827.yaml | 10 +++------- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/qiskit/pulse/parameter_manager.py b/qiskit/pulse/parameter_manager.py index 06eedfa71f18..561eac01f55d 100644 --- a/qiskit/pulse/parameter_manager.py +++ b/qiskit/pulse/parameter_manager.py @@ -52,7 +52,7 @@ """ from __future__ import annotations from copy import copy -from typing import Any, Mapping +from typing import Any, Mapping, Sequence from qiskit.circuit import ParameterVector from qiskit.circuit.parameter import Parameter @@ -362,7 +362,7 @@ def assign_parameters( self, pulse_program: Any, value_dict: dict[ - ParameterExpression | ParameterVector, ParameterValueType | list[ParameterValueType] + ParameterExpression | ParameterVector, ParameterValueType | Sequence[ParameterValueType] ], ) -> Any: """Modify and return program data with parameters assigned according to the input. @@ -397,7 +397,7 @@ def update_parameter_table(self, new_node: Any): def _unroll_param_dict( self, parameter_binds: Mapping[ - Parameter | ParameterVector, ParameterValueType | list[ParameterValueType] + Parameter | ParameterVector, ParameterValueType | Sequence[ParameterValueType] ], ) -> Mapping[Parameter, ParameterValueType]: """ @@ -412,7 +412,7 @@ def _unroll_param_dict( out = {} for parameter, value in parameter_binds.items(): if isinstance(parameter, ParameterVector): - if not isinstance(value, (list, tuple)): + if not isinstance(value, Sequence): raise PulseError( f"Parameter vector '{parameter.name}' has length {len(parameter)}," f" but was assigned to a single value." diff --git a/qiskit/pulse/schedule.py b/qiskit/pulse/schedule.py index 86c885de495f..2a32b06a4780 100644 --- a/qiskit/pulse/schedule.py +++ b/qiskit/pulse/schedule.py @@ -39,7 +39,7 @@ import sys import warnings from collections.abc import Callable, Iterable -from typing import List, Tuple, Union, Dict, Any +from typing import List, Tuple, Union, Dict, Any, Sequence import numpy as np import rustworkx as rx @@ -714,14 +714,14 @@ def is_parameterized(self) -> bool: def assign_parameters( self, value_dict: dict[ - ParameterExpression | ParameterVector, ParameterValueType | list[ParameterValueType] + ParameterExpression | ParameterVector, ParameterValueType | Sequence[ParameterValueType] ], inplace: bool = True, ) -> "Schedule": """Assign the parameters in this schedule according to the input. Args: - value_dict: A mapping from Parameters (ParameterVectors) to either + value_dict: A mapping from parameters (parameter vectors) to either numeric values (list of numeric values) or another Parameter expression (list of Parameter expressions). inplace: Set ``True`` to override this instance with new parameter. @@ -1415,16 +1415,16 @@ def is_referenced(self) -> bool: def assign_parameters( self, value_dict: dict[ - ParameterExpression | ParameterVector, ParameterValueType | list[ParameterValueType] + ParameterExpression | ParameterVector, ParameterValueType | Sequence[ParameterValueType] ], inplace: bool = True, ) -> "ScheduleBlock": """Assign the parameters in this schedule according to the input. Args: - value_dict: A mapping from Parameters (ParameterVectors) to either numeric values + value_dict: A mapping from parameters (parameter vectors) to either numeric values (list of numeric values) - or another Parameter expression (list of Parameter expression). + or another parameter expression (list of parameter expressions). inplace: Set ``True`` to override this instance with new parameter. Returns: diff --git a/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml index 40653f7a645e..6e0e5c748b1e 100644 --- a/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml +++ b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml @@ -1,14 +1,10 @@ --- prelude: > - Compatibility of pulse parameter assignment with `ParameterVector` class. -features: + +features_pulse: - | The `ParameterManager` now supports the `ParameterVector` class. This enables the use of `ParameterVector` in pulse `Schedule`and `ScheduleBlock` objects when using their method `assign_parameters` to assign simultaneously a list of parameter values. - - | - An additional method `_unroll_param_dict`has been added to the `ParameterManager` class to unroll the - parameter dictionary into a list of parameter values. This method is used to convert the parameter dictionary - into a list of parameter values when using the `ParameterVector` class. This method is a replication of the - analogous method `_unroll_param_dict` in `QuantumCircuit` class. + From bf91f02df1d3ee337d5e8927a77c648e9ff43870 Mon Sep 17 00:00:00 2001 From: Arthur Strauss <56998701+arthurostrauss@users.noreply.github.com> Date: Fri, 22 Mar 2024 07:13:18 +0800 Subject: [PATCH 17/21] Update pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml Co-authored-by: TsafrirA <113579969+TsafrirA@users.noreply.github.com> --- ...er_manager_compat_with_ParameterVector-7d31395fd4019827.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml index 6e0e5c748b1e..0ddc497c4647 100644 --- a/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml +++ b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml @@ -4,7 +4,7 @@ prelude: > features_pulse: - | The `ParameterManager` now supports the `ParameterVector` class. This enables - the use of `ParameterVector` in pulse `Schedule`and `ScheduleBlock` objects when using their method + the use of `ParameterVector` in pulse `Schedule` and `ScheduleBlock` objects when using their method `assign_parameters` to assign simultaneously a list of parameter values. From d3dddda402badf0d32ed639a7c384f10bb8df498 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Fri, 22 Mar 2024 07:47:55 +0800 Subject: [PATCH 18/21] Added tests for Schedule and case of mix Parameter+numeric values Complementary tests have been added for checking the pulse.Schedule.assign_parameters() method, as well as the functioning of binding to a ParameterVector a collection of numeric values and new ParameterExpression (through Parameter). --- test/python/pulse/test_parameter_manager.py | 24 +++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index ef1cad41b59d..0811fa9abb05 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -487,17 +487,33 @@ def test_parametric_pulses_with_parameter_vector(self): """Test Parametric Pulses with parameters determined by a ParameterVector in the Play instruction.""" param_vec = ParameterVector("param_vec", 3) + param = Parameter("param") waveform = pulse.library.Gaussian(duration=128, sigma=param_vec[0], amp=param_vec[1]) block = pulse.ScheduleBlock() block += pulse.Play(waveform, pulse.DriveChannel(10)) block += pulse.ShiftPhase(param_vec[2], pulse.DriveChannel(10)) - block.assign_parameters({param_vec: [4, 0.2, 0.1]}, inplace=True) + block1 = block.assign_parameters({param_vec: [4, 0.2, 0.1]}, inplace=False) + block2 = block.assign_parameters({param_vec: [4, param, 0.1]}, inplace=False) + self.assertEqual(block1.blocks[0].pulse.amp, 0.2) + self.assertEqual(block1.blocks[0].pulse.sigma, 4.0) + self.assertEqual(block1.blocks[1].phase, 0.1) + self.assertEqual(block2.blocks[0].pulse.amp, param) + self.assertEqual(block2.blocks[0].pulse.sigma, 4.0) + self.assertEqual(block2.blocks[1].phase, 0.1) - self.assertEqual(block.blocks[0].pulse.amp, 0.2) - self.assertEqual(block.blocks[0].pulse.sigma, 4.0) - self.assertEqual(block.blocks[1].phase, 0.1) + sched = pulse.Schedule() + sched += pulse.Play(waveform, pulse.DriveChannel(10)) + sched += pulse.ShiftPhase(param_vec[2], pulse.DriveChannel(10)) + sched1 = sched.assign_parameters({param_vec: [4, 0.2, 0.1]}, inplace=False) + sched2 = sched.assign_parameters({param_vec: [4, param, 0.1]}, inplace=False) + self.assertEqual(sched1.instructions[0][1].pulse.amp, 0.2) + self.assertEqual(sched1.instructions[0][1].pulse.sigma, 4.0) + self.assertEqual(sched1.instructions[1].phase, 0.1) + self.assertEqual(sched2.instructions[0][1].pulse.amp, param) + self.assertEqual(sched2.instructions[0][1].pulse.sigma, 4.0) + self.assertEqual(sched2.instructions[1].phase, 0.1) class TestScheduleTimeslots(QiskitTestCase): From 35f2fb9ed5cceee206b0436c9afdcaff8d00ae42 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Fri, 22 Mar 2024 08:55:48 +0800 Subject: [PATCH 19/21] Corrected error for schedule test An error was occurring when trying to get access to an instruction parameter within schedule.instructions --- test/python/pulse/test_parameter_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index 0811fa9abb05..d1749456c4ae 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -510,10 +510,10 @@ def test_parametric_pulses_with_parameter_vector(self): sched2 = sched.assign_parameters({param_vec: [4, param, 0.1]}, inplace=False) self.assertEqual(sched1.instructions[0][1].pulse.amp, 0.2) self.assertEqual(sched1.instructions[0][1].pulse.sigma, 4.0) - self.assertEqual(sched1.instructions[1].phase, 0.1) + self.assertEqual(sched1.instructions[0][1].phase, 0.1) self.assertEqual(sched2.instructions[0][1].pulse.amp, param) self.assertEqual(sched2.instructions[0][1].pulse.sigma, 4.0) - self.assertEqual(sched2.instructions[1].phase, 0.1) + self.assertEqual(sched2.instructions[0][1].phase, 0.1) class TestScheduleTimeslots(QiskitTestCase): From 69cf343171957738f1ea974ae39738ae594543c0 Mon Sep 17 00:00:00 2001 From: Arthur Strauss Date: Fri, 22 Mar 2024 09:22:49 +0800 Subject: [PATCH 20/21] Correction to test schedule --- test/python/pulse/test_parameter_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/python/pulse/test_parameter_manager.py b/test/python/pulse/test_parameter_manager.py index d1749456c4ae..54268af14577 100644 --- a/test/python/pulse/test_parameter_manager.py +++ b/test/python/pulse/test_parameter_manager.py @@ -510,10 +510,10 @@ def test_parametric_pulses_with_parameter_vector(self): sched2 = sched.assign_parameters({param_vec: [4, param, 0.1]}, inplace=False) self.assertEqual(sched1.instructions[0][1].pulse.amp, 0.2) self.assertEqual(sched1.instructions[0][1].pulse.sigma, 4.0) - self.assertEqual(sched1.instructions[0][1].phase, 0.1) + self.assertEqual(sched1.instructions[1][1].phase, 0.1) self.assertEqual(sched2.instructions[0][1].pulse.amp, param) self.assertEqual(sched2.instructions[0][1].pulse.sigma, 4.0) - self.assertEqual(sched2.instructions[0][1].phase, 0.1) + self.assertEqual(sched2.instructions[1][1].phase, 0.1) class TestScheduleTimeslots(QiskitTestCase): From b398844322254be799244f6f17b4e05ef6adc1a3 Mon Sep 17 00:00:00 2001 From: Arthur Strauss <56998701+arthurostrauss@users.noreply.github.com> Date: Sat, 23 Mar 2024 00:37:51 +0800 Subject: [PATCH 21/21] Update releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml Co-authored-by: Will Shanks --- ..._compat_with_ParameterVector-7d31395fd4019827.yaml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml index 0ddc497c4647..0cb13cb346c1 100644 --- a/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml +++ b/releasenotes/notes/pulse_parameter_manager_compat_with_ParameterVector-7d31395fd4019827.yaml @@ -1,10 +1,7 @@ --- -prelude: > - features_pulse: - | - The `ParameterManager` now supports the `ParameterVector` class. This enables - the use of `ParameterVector` in pulse `Schedule` and `ScheduleBlock` objects when using their method - `assign_parameters` to assign simultaneously a list of parameter values. - - + The ``assign_parameters`` methods of :class:`.Schedule` and :class:`.ScheduleBlock` + now support assigning a :class:`.ParameterVector` to a list of parameter values + simultaneously in addition to assigning individual :class:`.Parameter` instances to + individual values.