-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Kickoff the arithmetics library #4061
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
33dd11b
cca3170
bcbad39
75d33b2
14d6c35
dfdda6c
44e4506
2472e5f
b8567ef
e0176cd
a9b6fe7
ebcf7c0
1e59509
a528d92
e0d7ad9
52574e6
2dbed9b
ef8adc2
4645b35
ef8a8b4
c4ca57a
4c72a27
dde459b
1285864
e1eed60
012b92d
5f7a9c9
0ab26aa
f9fb70b
7f5c9c7
47966ab
76c3917
19ce135
c754fcd
cf45675
0e3b792
a3ad68a
bd2662e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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 | ||
| 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: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is the setter input optional?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So that the circuit can be "reset" by Maybe an application checks of the number of qubits has been set or not, though I don't have a concrete example where this would be needed. Should I set it to not support
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's fine. i just see that in this PR some setters accept |
||
| """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 | ||
Uh oh!
There was an error while loading. Please reload this page.