Quellcode fÃ¼r qiskit.transpiler.synthesis.aqc.cnot_unit_circuit

```# This code is part of Qiskit.
#
#
# obtain a copy of this license in the LICENSE.txt file in the root directory
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""
This is the Parametric Circuit class: anything that you need for a circuit
to be parametrized and used for approximate compiling optimization.
"""
from __future__ import annotations
from typing import Optional

import numpy as np

from .approximate import ApproximateCircuit

[Doku]class CNOTUnitCircuit(ApproximateCircuit):
"""A class that represents an approximate circuit based on CNOT unit blocks."""

def __init__(
self,
num_qubits: int,
cnots: np.ndarray,
tol: Optional[float] = 0.0,
name: Optional[str] = None,
) -> None:
"""
Args:
num_qubits: the number of qubits in this circuit.
cnots: an array of dimensions ``(2, L)`` indicating where the CNOT units will be placed.
tol: angle parameter less or equal this (small) value is considered equal zero and
corresponding gate is not inserted into the output circuit (because it becomes
identity one in this case).
name: name of this circuit

Raises:
ValueError: if an unsupported parameter is passed.
"""
super().__init__(num_qubits=num_qubits, name=name)

if cnots.ndim != 2 or cnots.shape[0] != 2:
raise ValueError("CNOT structure must be defined as an array of the size (2, N)")

self._cnots = cnots
self._num_cnots = cnots.shape[1]
self._tol = tol

# Thetas to be optimized by the AQC algorithm
self._thetas: np.ndarray | None = None

@property
def thetas(self) -> np.ndarray:
"""
Returns a vector of rotation angles used by CNOT units in this circuit.

Returns:
Parameters of the rotation gates in this circuit.
"""
return self._thetas

[Doku]    def build(self, thetas: np.ndarray) -> None:
"""
Constructs a Qiskit quantum circuit out of the parameters (angles) of this circuit. If a
parameter value is less in absolute value than the specified tolerance then the
corresponding rotation gate will be skipped in the circuit.
"""
n = self.num_qubits
self._thetas = thetas
cnots = self._cnots

for k in range(n):
# add initial three rotation gates for each qubit
p = 4 * self._num_cnots + 3 * k
k = n - k - 1
if np.abs(thetas[2 + p]) > self._tol:
self.rz(thetas[2 + p], k)
if np.abs(thetas[1 + p]) > self._tol:
self.ry(thetas[1 + p], k)
if np.abs(thetas[0 + p]) > self._tol:
self.rz(thetas[0 + p], k)

for c in range(self._num_cnots):
p = 4 * c
# Extract where the CNOT goes
q1 = n - 1 - int(cnots[0, c])
q2 = n - 1 - int(cnots[1, c])
# Construct a CNOT unit
self.cx(q1, q2)
if np.abs(thetas[0 + p]) > self._tol:
self.ry(thetas[0 + p], q1)
if np.abs(thetas[1 + p]) > self._tol:
self.rz(thetas[1 + p], q1)
if np.abs(thetas[2 + p]) > self._tol:
self.ry(thetas[2 + p], q2)
if np.abs(thetas[3 + p]) > self._tol:
self.rx(thetas[3 + p], q2)
```