Skip to content

Commit

Permalink
Kickoff the arithmetics library (#4061)
Browse files Browse the repository at this point in the history
* add functional rotations base class

* refactor first arithmetic circuits

* fixed value comparator (now integer comparator)
* linear rotation (now linear Pauli rotations)
* piecewise linear rotation (now piecewise linear pauli rotations)

Co-authored-by: Stefan Woerner <[email protected]>

* integrate polynomial rotations

Co-authored-by: Almudena Carrera Vazquez <[email protected]>

* update inits

* add tests

* skip test depending on Aqua

* fix imports: no weighted_adder, add functional_rot

* move circ diag in parsed-literal block

* adjust formatting of linear circ diag

* update rendering of docstrings

* move AND/OR gates from Aqua

Co-authored-by: Shaohan Hu <[email protected]>
Co-authored-by: Manoel Marques <[email protected]>

* use data getter not _data in copy

* add missing gate inits

* fix imports

* fix lint

* move WSO from aqua

Co-authored-by: Stefan Woerner <[email protected]>
Co-authored-by: Manoel Marques <[email protected]>
Co-authored-by: Shaohan Hu <[email protected]>

* rename to weighted adder

* refactor weighted adder and make a circuit

* updates inits with weighted adder

* add tests for weighted adder

* fix outdated mcu1 import

* add functional pauli rotations import

* Update test/python/circuit/test_library.py

Co-Authored-By: Ali Javadi-Abhari <[email protected]>

* Update qiskit/circuit/library/arithmetic/weighted_adder.py

Co-Authored-By: Ali Javadi-Abhari <[email protected]>

* add comment on default behaviour of the weights

* fix rst rendering

* include arithmetic circs in sphinx

* fix copyright

* add _invalidate() method

Co-authored-by: Stefan Woerner <[email protected]>
Co-authored-by: Almudena Carrera Vazquez <[email protected]>
Co-authored-by: Shaohan Hu <[email protected]>
Co-authored-by: Manoel Marques <[email protected]>
Co-authored-by: Ali Javadi-Abhari <[email protected]>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
7 people authored Apr 7, 2020
1 parent b2a87e1 commit 5571747
Show file tree
Hide file tree
Showing 12 changed files with 2,073 additions and 6 deletions.
42 changes: 41 additions & 1 deletion qiskit/circuit/library/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# This code is part of Qiskit.
#
# (C) Copyright IBM 2020.
# (C) Copyright IBM 2017, 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
Expand All @@ -28,7 +28,47 @@
InnerProduct
Permutation
XOR
Arithmetic Circuits
===================
Functional Pauli Rotations
++++++++++++++++++++++++++
.. autosummary::
:toctree: ../stubs/
FunctionalPauliRotations
LinearPauliRotations
PolynomialPauliRotations
PiecewiseLinearPauliRotations
Adders
++++++
.. autosummary::
:toctree: ../stubs/
WeightedAdder
Comparators
+++++++++++
.. autosummary::
:toctree: ../stubs/
IntegerComparator
"""


from .boolean_logic import Permutation, XOR, InnerProduct
from .arithmetic import (
FunctionalPauliRotations,
LinearPauliRotations,
PiecewiseLinearPauliRotations,
PolynomialPauliRotations,
IntegerComparator,
WeightedAdder
)
22 changes: 22 additions & 0 deletions qiskit/circuit/library/arithmetic/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-

# This code is part of Qiskit.
#
# (C) Copyright IBM 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.

"""The arithmetic circuit library."""

from .functional_pauli_rotations import FunctionalPauliRotations
from .integer_comparator import IntegerComparator
from .linear_pauli_rotations import LinearPauliRotations
from .piecewise_linear_pauli_rotations import PiecewiseLinearPauliRotations
from .polynomial_pauli_rotations import PolynomialPauliRotations
from .weighted_adder import WeightedAdder
141 changes: 141 additions & 0 deletions qiskit/circuit/library/arithmetic/functional_pauli_rotations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# -*- coding: utf-8 -*-

# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 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.

"""Base class for functional Pauli rotations."""

from typing import Optional, List, Tuple

from abc import ABC, abstractmethod
from qiskit.circuit import QuantumCircuit, Qubit, Clbit, Instruction


class FunctionalPauliRotations(QuantumCircuit, ABC):
"""Base class for functional Pauli rotations."""

def __init__(self,
num_state_qubits: Optional[int] = None,
basis: str = 'Y',
name: str = 'F') -> None:
r"""Create a new functional Pauli rotation circuit.
Args:
num_state_qubits: The number of qubits representing the state :math:`|x\rangle`.
basis: The kind of Pauli rotation to use. Must be 'X', 'Y' or 'Z'.
name: The name of the circuit object.
"""
super().__init__(name=name)

# define internal parameters
self._num_state_qubits = None
self._basis = None

# store parameters
self.num_state_qubits = num_state_qubits
self.basis = basis

@property
def basis(self) -> str:
"""The kind of Pauli rotation to be used.
Set the basis to 'X', 'Y' or 'Z' for controlled-X, -Y, or -Z rotations respectively.
Returns:
The kind of Pauli rotation used in controlled rotation.
"""
return self._basis

@basis.setter
def basis(self, basis: str) -> None:
"""Set the kind of Pauli rotation to be used.
Args:
basis: The Pauli rotation to be used.
Raises:
ValueError: The provided basis in not X, Y or Z.
"""
basis = basis.lower()
if self._basis is None or basis != self._basis:
if basis not in ['x', 'y', 'z']:
raise ValueError('The provided basis must be X, Y or Z, not {}'.format(basis))
self._invalidate()
self._basis = basis

@property
def num_state_qubits(self) -> int:
r"""The number of state qubits representing the state :math:`|x\rangle`.
Returns:
The number of state qubits.
"""
return self._num_state_qubits

@num_state_qubits.setter
def num_state_qubits(self, num_state_qubits: Optional[int]) -> None:
"""Set the number of state qubits.
Note that this may change the underlying quantum register, if the number of state qubits
changes.
Args:
num_state_qubits: The new number of qubits.
"""
if self._num_state_qubits is None or num_state_qubits != self._num_state_qubits:
self._invalidate()
self._num_state_qubits = num_state_qubits

self._reset_registers(num_state_qubits)

def _invalidate(self) -> None:
"""Invalidate the current build of the circuit."""
self._data = None

@abstractmethod
def _reset_registers(self, num_state_qubits: Optional[int]) -> None:
"""Reset the registers according to the new number of state qubits.
Args:
num_state_qubits: The new number of qubits.
"""
raise NotImplementedError

@property
def num_ancilla_qubits(self) -> int:
"""The minimum number of ancilla qubits in the circuit.
Returns:
The minimal number of ancillas required.
"""
return 0

@abstractmethod
def _configuration_is_valid(self, raise_on_failure: bool = True) -> bool:
raise NotImplementedError

@abstractmethod
def _build(self):
# if data is populated we already built the circuit
if self._data:
return

# check if the current configuration is valid and re-initiate the circuit data
_ = self._configuration_is_valid()
self._data = []

@property
def data(self) -> List[Tuple[Instruction, List[Qubit], List[Clbit]]]:
"""Get the circuit definition."""
if self._data is None:
self._build()
return super().data
Loading

0 comments on commit 5571747

Please sign in to comment.