Skip to content

Commit

Permalink
Doc fix ZZ_feature_maps (backport #13231) (#13262)
Browse files Browse the repository at this point in the history
* Doc fix ZZ_feature_maps (#13231)

* initial formatting changes

* .compose used for concatination of two circuits

* updated docstring data property

* updated entanglement_blocks docstring

* updated docstring of num_parameters

* updates docstring of parameters

* update _zz_feature_map.py documentation

* update changes to ZZ_Feature_Map

* update doc strings matched with parent class

* _zz_feature_map.py reformatted

(cherry picked from commit f1b2580)

# Conflicts:
#	qiskit/circuit/library/data_preparation/zz_feature_map.py

* merge conflicy & other typos

---------

Co-authored-by: Shivansh Mittal <88429611+Shivansh20128@users.noreply.github.com>
Co-authored-by: Julien Gacon <jules.gacon@googlemail.com>
  • Loading branch information
3 people authored Oct 3, 2024
1 parent 3f178cb commit 1657a72
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 95 deletions.
64 changes: 64 additions & 0 deletions qiskit/circuit/library/blueprintcircuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ def qregs(self, qregs):

@property
def data(self):
"""The circuit data (instructions and context).
Returns:
QuantumCircuitData: a list-like object containing the :class:`.CircuitInstruction`\\ s
for each instruction.
"""
if not self._is_built:
self._build()
return super().data
Expand All @@ -110,12 +116,70 @@ def draw(self, *args, **kwargs):

@property
def num_parameters(self) -> int:
"""The number of parameter objects in the circuit."""
if not self._is_built:
self._build()
return super().num_parameters

@property
def parameters(self) -> ParameterView:
"""The parameters defined in the circuit.
This attribute returns the :class:`.Parameter` objects in the circuit sorted
alphabetically. Note that parameters instantiated with a :class:`.ParameterVector`
are still sorted numerically.
Examples:
The snippet below shows that insertion order of parameters does not matter.
.. code-block:: python
>>> from qiskit.circuit import QuantumCircuit, Parameter
>>> a, b, elephant = Parameter("a"), Parameter("b"), Parameter("elephant")
>>> circuit = QuantumCircuit(1)
>>> circuit.rx(b, 0)
>>> circuit.rz(elephant, 0)
>>> circuit.ry(a, 0)
>>> circuit.parameters # sorted alphabetically!
ParameterView([Parameter(a), Parameter(b), Parameter(elephant)])
Bear in mind that alphabetical sorting might be unintuitive when it comes to numbers.
The literal "10" comes before "2" in strict alphabetical sorting.
.. code-block:: python
>>> from qiskit.circuit import QuantumCircuit, Parameter
>>> angles = [Parameter("angle_1"), Parameter("angle_2"), Parameter("angle_10")]
>>> circuit = QuantumCircuit(1)
>>> circuit.u(*angles, 0)
>>> circuit.draw()
┌─────────────────────────────┐
q: ┤ U(angle_1,angle_2,angle_10) ├
└─────────────────────────────┘
>>> circuit.parameters
ParameterView([Parameter(angle_1), Parameter(angle_10), Parameter(angle_2)])
To respect numerical sorting, a :class:`.ParameterVector` can be used.
.. code-block:: python
>>> from qiskit.circuit import QuantumCircuit, Parameter, ParameterVector
>>> x = ParameterVector("x", 12)
>>> circuit = QuantumCircuit(1)
>>> for x_i in x:
... circuit.rx(x_i, 0)
>>> circuit.parameters
ParameterView([
ParameterVectorElement(x[0]), ParameterVectorElement(x[1]),
ParameterVectorElement(x[2]), ParameterVectorElement(x[3]),
..., ParameterVectorElement(x[11])
])
Returns:
The sorted :class:`.Parameter` objects in the circuit.
"""
if not self._is_built:
self._build()
return super().parameters
Expand Down
53 changes: 29 additions & 24 deletions qiskit/circuit/library/data_preparation/pauli_feature_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ class PauliFeatureMap(NLocal):
.. parsed-literal::
┌───┐┌─────────────┐┌──────────┐ ┌───────────┐
┤ H ├┤ U1(2.0*x[0]) ├┤ RX(pi/2) ├──■──────────────────────────────────────■──┤ RX(-pi/2) ├
├───┤├─────────────┤├──────────┤┌─┴─┐┌────────────────────────────────┐┌─┴─┐├───────────┤
┤ H ├┤ U1(2.0*x[1]) ├┤ RX(pi/2) ├┤ X ├┤ U1(2.0*(pi - x[0])*(pi - x[1])) ├┤ X ├┤ RX(-pi/2) ├
└───┘└─────────────┘└──────────┘└───┘└────────────────────────────────┘└───┘└───────────┘
┌───┐┌─────────────┐┌──────────┐ ┌───────────┐
┤ H ├┤ P(2.0*x[0]) ├┤ RX(pi/2) ├──■──────────────────────────────────────■──┤ RX(-pi/2) ├
├───┤├─────────────┤├──────────┤┌─┴─┐┌────────────────────────────────┐┌─┴─┐├───────────┤
┤ H ├┤ P(2.0*x[1]) ├┤ RX(pi/2) ├┤ X ├┤ P(2.0*(pi - x[0])*(pi - x[1])) ├┤ X ├┤ RX(-pi/2) ├
└───┘└─────────────┘└──────────┘└───┘└────────────────────────────────┘└───┘└───────────┘
The circuit contains ``reps`` repetitions of this transformation.
Expand All @@ -71,37 +71,37 @@ class PauliFeatureMap(NLocal):
Examples:
>>> prep = PauliFeatureMap(2, reps=1, paulis=['ZZ'])
>>> print(prep)
>>> print(prep.decompose())
┌───┐
q_0: ┤ H ├──■──────────────────────────────────────■──
├───┤┌─┴─┐┌────────────────────────────────┐┌─┴─┐
q_1: ┤ H ├┤ X ├┤ U1(2.0*(pi - x[0])*(pi - x[1])) ├┤ X ├
└───┘└───┘└────────────────────────────────┘└───┘
q_0: ┤ H ├──■──────────────────────────────────────■──
├───┤┌─┴─┐┌────────────────────────────────┐┌─┴─┐
q_1: ┤ H ├┤ X ├┤ P(2.0*(pi - x[0])*(pi - x[1])) ├┤ X ├
└───┘└───┘└────────────────────────────────┘└───┘
>>> prep = PauliFeatureMap(2, reps=1, paulis=['Z', 'XX'])
>>> print(prep)
┌───┐┌─────────────┐┌───┐ ┌───┐
q_0: ┤ H ├┤ U1(2.0*x[0]) ├┤ H ├──■──────────────────────────────────────■──┤ H ├
├───┤├─────────────┤├───┤┌─┴─┐┌────────────────────────────────┐┌─┴─┐├───┤
q_1: ┤ H ├┤ U1(2.0*x[1]) ├┤ H ├┤ X ├┤ U1(2.0*(pi - x[0])*(pi - x[1])) ├┤ X ├┤ H ├
└───┘└─────────────┘└───┘└───┘└────────────────────────────────┘└───┘└───┘
>>> print(prep.decompose())
┌───┐┌─────────────┐┌───┐ ┌───┐
q_0: ┤ H ├┤ P(2.0*x[0]) ├┤ H ├──■──────────────────────────────────────■──┤ H ├
├───┤├─────────────┤├───┤┌─┴─┐┌────────────────────────────────┐┌─┴─┐├───┤
q_1: ┤ H ├┤ P(2.0*x[1]) ├┤ H ├┤ X ├┤ P(2.0*(pi - x[0])*(pi - x[1])) ├┤ X ├┤ H ├
└───┘└─────────────┘└───┘└───┘└────────────────────────────────┘└───┘└───┘
>>> prep = PauliFeatureMap(2, reps=1, paulis=['ZY'])
>>> print(prep)
┌───┐┌──────────┐ ┌───────────┐
q_0: ┤ H ├┤ RX(pi/2) ├──■──────────────────────────────────────■──┤ RX(-pi/2) ├
├───┤└──────────┘┌─┴─┐┌────────────────────────────────┐┌─┴─┐└───────────┘
q_1: ┤ H ├────────────┤ X ├┤ U1(2.0*(pi - x[0])*(pi - x[1])) ├┤ X ├─────────────
└───┘ └───┘└────────────────────────────────┘└───┘
>>> print(prep.decompose())
┌───┐┌──────────┐ ┌───────────┐
q_0: ┤ H ├┤ RX(pi/2) ├──■──────────────────────────────────────■──┤ RX(-pi/2) ├
├───┤└──────────┘┌─┴─┐┌────────────────────────────────┐┌─┴─┐└───────────┘
q_1: ┤ H ├────────────┤ X ├┤ P(2.0*(pi - x[0])*(pi - x[1])) ├┤ X ├─────────────
└───┘ └───┘└────────────────────────────────┘└───┘
>>> from qiskit.circuit.library import EfficientSU2
>>> prep = PauliFeatureMap(3, reps=3, paulis=['Z', 'YY', 'ZXZ'])
>>> wavefunction = EfficientSU2(3)
>>> classifier = prep.compose(wavefunction)
>>> classifier = prep.compose(wavefunction).decompose()
>>> classifier.num_parameters
27
>>> classifier.count_ops()
OrderedDict([('cx', 39), ('rx', 36), ('u1', 21), ('h', 15), ('ry', 12), ('rz', 12)])
OrderedDict([('cx', 39), ('rx', 36), ('p', 21), ('h', 15), ('ry', 12), ('rz', 12)])
References:
Expand Down Expand Up @@ -209,6 +209,11 @@ def alpha(self, alpha: float) -> None:

@property
def entanglement_blocks(self):
"""The blocks in the entanglement layers.
Returns:
The blocks in the entanglement layers.
"""
return [self.pauli_block(pauli) for pauli in self._paulis]

@entanglement_blocks.setter
Expand Down
Loading

0 comments on commit 1657a72

Please sign in to comment.