Source code for qiskit.aqua.utils.circuit_factory

# -*- coding: utf-8 -*-

# This code is part of Qiskit.
#
# (C) Copyright IBM 2018, 2020.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# 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.

"""
Abstract CircuitFactory to build a circuit, along with inverse, controlled
and power combinations of the circuit.
"""

from abc import ABC, abstractmethod
from qiskit import QuantumCircuit
from qiskit.aqua.utils.controlled_circuit import get_controlled_circuit


[docs]class CircuitFactory(ABC): """ Base class for CircuitFactories """ def __init__(self, num_target_qubits: int) -> None: self._num_target_qubits = num_target_qubits pass @property def num_target_qubits(self): """ Returns the number of target qubits """ return self._num_target_qubits
[docs] def required_ancillas(self): """ returns required ancillas """ return 0
[docs] def required_ancillas_controlled(self): """ returns required ancillas controlled """ return self.required_ancillas()
[docs] def get_num_qubits(self): """ returns number of qubits """ return self._num_target_qubits + self.required_ancillas()
[docs] def get_num_qubits_controlled(self): """ returns number of qubits controlled """ return self._num_target_qubits + self.required_ancillas_controlled()
[docs] @abstractmethod def build(self, qc, q, q_ancillas=None, params=None): """ Adds corresponding sub-circuit to given circuit Args: qc (QuantumCircuit): quantum circuit q (list): list of qubits (has to be same length as self._num_qubits) q_ancillas (list): list of ancilla qubits (or None if none needed) params (list): parameters for circuit """ raise NotImplementedError()
[docs] def build_inverse(self, qc, q, q_ancillas=None): """ Adds inverse of corresponding sub-circuit to given circuit Args: qc (QuantumCircuit): quantum circuit q (list): list of qubits (has to be same length as self._num_qubits) q_ancillas (list): list of ancilla qubits (or None if none needed) """ qc_ = QuantumCircuit(*qc.qregs) self.build(qc_, q, q_ancillas) qc.extend(qc_.inverse())
[docs] def build_controlled(self, qc, q, q_control, q_ancillas=None, use_basis_gates=True): """ Adds corresponding controlled sub-circuit to given circuit Args: qc (QuantumCircuit): quantum circuit q (list): list of qubits (has to be same length as self._num_qubits) q_control (Qubit): control qubit q_ancillas (list): list of ancilla qubits (or None if none needed) use_basis_gates (bool): use basis gates for expansion of controlled circuit """ uncontrolled_circuit = QuantumCircuit(*qc.qregs) self.build(uncontrolled_circuit, q, q_ancillas) controlled_circuit = get_controlled_circuit(uncontrolled_circuit, q_control, use_basis_gates=use_basis_gates) qc.extend(controlled_circuit)
[docs] def build_controlled_inverse(self, qc, q, q_control, q_ancillas=None, use_basis_gates=True): """ Adds controlled inverse of corresponding sub-circuit to given circuit Args: qc (QuantumCircuit): quantum circuit q (list): list of qubits (has to be same length as self._num_qubits) q_control (Qubit): control qubit q_ancillas (list): list of ancilla qubits (or None if none needed) use_basis_gates (bool): use basis gates for expansion of controlled circuit """ qc_ = QuantumCircuit(*qc.qregs) self.build_controlled(qc_, q, q_control, q_ancillas, use_basis_gates) qc.extend(qc_.inverse())
[docs] def build_power(self, qc, q, power, q_ancillas=None): """ Adds power of corresponding circuit. May be overridden if a more efficient implementation is possible """ for _ in range(power): self.build(qc, q, q_ancillas)
[docs] def build_inverse_power(self, qc, q, power, q_ancillas=None): """ Adds inverse power of corresponding circuit. May be overridden if a more efficient implementation is possible """ for _ in range(power): self.build_inverse(qc, q, q_ancillas)
[docs] def build_controlled_power(self, qc, q, q_control, power, q_ancillas=None, use_basis_gates=True): """ Adds controlled power of corresponding circuit. May be overridden if a more efficient implementation is possible """ for _ in range(power): self.build_controlled(qc, q, q_control, q_ancillas, use_basis_gates)
[docs] def build_controlled_inverse_power(self, qc, q, q_control, power, q_ancillas=None, use_basis_gates=True): """ Adds controlled, inverse, power of corresponding circuit. May be overridden if a more efficient implementation is possible """ for _ in range(power): self.build_controlled_inverse(qc, q, q_control, q_ancillas, use_basis_gates)