├── requirements.txt ├── hhl4x4 ├── __init__.py ├── utils │ ├── __init__.py │ ├── endianness.py │ └── registers.py ├── custom_gates │ ├── __init__.py │ ├── csqtrx.py │ ├── crzz.py │ ├── ccz.py │ ├── crx.py │ ├── comment.py │ ├── hhl4x4.py │ ├── qpe.py │ └── qft.py ├── optimise_parameters.py ├── 4x4.py └── 4x4.qasm ├── README.rst ├── setup.py └── LICENSE /requirements.txt: -------------------------------------------------------------------------------- 1 | qiskit==0.6.1 2 | networkx==2.3 3 | -------------------------------------------------------------------------------- /hhl4x4/__init__.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | -------------------------------------------------------------------------------- /hhl4x4/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | -------------------------------------------------------------------------------- /hhl4x4/custom_gates/__init__.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | -------------------------------------------------------------------------------- /hhl4x4/custom_gates/csqtrx.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | 32 | """This module contains functions to apply a controlled-sqrt(X) gate. 33 | """ 34 | from typing import Tuple 35 | from qiskit import QuantumCircuit, QuantumRegister, CompositeGate 36 | import hhl4x4.custom_gates.comment 37 | 38 | QubitType = Tuple[QuantumRegister, int] 39 | 40 | 41 | class CsqrtX(CompositeGate): 42 | 43 | def __init__(self, ctrl: QubitType, target: QubitType, 44 | circuit: QuantumCircuit = None): 45 | """Initialize the CsqrtX class. 46 | 47 | :param ctrl: The control qubit used to control the sqrt(X) gate. 48 | :param target: The qubit on which the sqrt(X) gate is applied. 49 | :param circuit: The associated quantum circuit. 50 | """ 51 | used_qubits = [ctrl, target] 52 | 53 | super().__init__(self.__class__.__name__, # name 54 | [], # parameters 55 | used_qubits, # qubits 56 | circuit) # circuit 57 | self.comment("c-sqrt(X)") 58 | self.cx(ctrl, target) 59 | self.cz(ctrl, target) 60 | self.h(target) 61 | self.t(target) 62 | self.tdg(ctrl) 63 | self.cx(ctrl, target) 64 | self.tdg(target) 65 | self.h(target) 66 | 67 | 68 | def csqrtx(self, ctrl: QubitType, target: QubitType) -> CsqrtX: 69 | self._check_qubit(ctrl) 70 | self._check_qubit(target) 71 | self._check_dups([ctrl, target]) 72 | return self._attach(CsqrtX(ctrl, target, self)) 73 | 74 | 75 | QuantumCircuit.csqrtx = csqrtx 76 | CompositeGate.csqrtx = csqrtx 77 | -------------------------------------------------------------------------------- /hhl4x4/custom_gates/crzz.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | 32 | """This module contains functions to apply a controlled-RZZ gate. 33 | 34 | The Rzz gate is a phase shift gate: 35 | $R_{zz} = \begin{pmatrix}e^{i\theta} & 0\\0 & e^{i\theta}\end{pmatrix}$ 36 | """ 37 | from typing import Tuple 38 | from qiskit import QuantumCircuit, QuantumRegister, CompositeGate 39 | import hhl4x4.custom_gates.comment 40 | 41 | QubitType = Tuple[QuantumRegister, int] 42 | 43 | 44 | class CRZZGate(CompositeGate): 45 | 46 | def __init__(self, theta: float, ctrl: QubitType, target: QubitType, 47 | circuit: QuantumCircuit = None): 48 | """Initialize the CRzzGate class. 49 | 50 | :param theta: Phase added to the quantum state of qubit. 51 | :param ctrl: The control qubit used to control the RZZ gate. 52 | :param target: The qubit on which the RZZ gate is applied. 53 | :param circuit: The associated quantum circuit. 54 | """ 55 | used_qubits = [ctrl, target] 56 | 57 | super().__init__(self.__class__.__name__, # name 58 | [theta], # parameters 59 | used_qubits, # qubits 60 | circuit) # circuit 61 | 62 | self.comment("c-RZZ") 63 | self.cu1(theta, ctrl, target) 64 | self.cx(ctrl, target) 65 | self.cu1(theta, ctrl, target) 66 | self.cx(ctrl, target) 67 | 68 | 69 | def crzz(self, theta: float, ctrl: QubitType, target: QubitType) -> CRZZGate: 70 | self._check_qubit(ctrl) 71 | self._check_qubit(target) 72 | self._check_dups([ctrl, target]) 73 | return self._attach(CRZZGate(theta, ctrl, target, self)) 74 | 75 | 76 | QuantumCircuit.crzz = crzz 77 | CompositeGate.crzz = crzz 78 | -------------------------------------------------------------------------------- /hhl4x4/custom_gates/ccz.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | 32 | """This module contains functions to apply a doubly controlled Z gate. 33 | """ 34 | from typing import Tuple 35 | from qiskit import QuantumCircuit, QuantumRegister, CompositeGate 36 | import hhl4x4.custom_gates.comment 37 | 38 | QubitType = Tuple[QuantumRegister, int] 39 | 40 | 41 | class CCZGate(CompositeGate): 42 | 43 | def __init__(self, ctrl1: QubitType, ctrl2: QubitType, target: QubitType, 44 | circuit: QuantumCircuit = None): 45 | """Initialize the CCZGate class. 46 | 47 | :param ctrl1: The first control qubit used to control the CCZ gate. 48 | :param ctrl2: The second control qubit used to control the CCZ gate. 49 | :param target: The qubit on which the Z gate is applied. 50 | :param circuit: The associated quantum circuit. 51 | """ 52 | used_qubits = [ctrl1, ctrl2, target] 53 | 54 | super().__init__(self.__class__.__name__, # name 55 | [], # parameters 56 | used_qubits, # qubits 57 | circuit) # circuit 58 | 59 | self.comment("CCZ") 60 | from qiskit.extensions.standard.h import HGate 61 | self._attach(HGate(target, circuit).inverse()) 62 | self.ccx(ctrl1, ctrl2, target) 63 | self._attach(HGate(target, circuit).inverse()) 64 | 65 | 66 | def ccz(self, ctrl1: QubitType, ctrl2: QubitType, target: QubitType) -> CCZGate: 67 | self._check_qubit(ctrl1) 68 | self._check_qubit(ctrl2) 69 | self._check_qubit(target) 70 | self._check_dups([ctrl1, ctrl2, target]) 71 | return self._attach(CCZGate(ctrl1, ctrl2, target, self)) 72 | 73 | 74 | QuantumCircuit.ccz = ccz 75 | CompositeGate.ccz = ccz 76 | -------------------------------------------------------------------------------- /hhl4x4/custom_gates/crx.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | 32 | """This module contains functions to apply a controlled-Rx gate. 33 | """ 34 | from typing import Tuple 35 | from qiskit import QuantumCircuit, QuantumRegister, CompositeGate 36 | import hhl4x4.custom_gates.comment 37 | import hhl4x4.custom_gates.crzz 38 | from sympy import pi 39 | 40 | QubitType = Tuple[QuantumRegister, int] 41 | 42 | 43 | class CRxGate(CompositeGate): 44 | 45 | def __init__(self, theta: float, ctrl: QubitType, target: QubitType, 46 | circuit: QuantumCircuit = None): 47 | """Initialize the CRxGate class. 48 | 49 | :param theta: Phase added to the quantum state of qubit. 50 | :param ctrl: The control qubit used to control the Rx gate. 51 | :param target: The qubit on which the Rx gate is applied. 52 | :param circuit: The associated quantum circuit. 53 | """ 54 | used_qubits = [ctrl, target] 55 | 56 | super().__init__(self.__class__.__name__, # name 57 | [theta], # parameters 58 | used_qubits, # qubits 59 | circuit) # circuit 60 | 61 | self.comment("c-RX") 62 | # Apply the supposed c-RX operation. 63 | self.cu3(theta, pi / 2, 3 * pi / 2, ctrl, target) 64 | # For the moment, QISKit adds a phase to the U-gate, so we 65 | # need to correct this phase with a controlled Rzz. 66 | self.crzz(pi, ctrl, target) 67 | 68 | 69 | def crx(self, theta: float, ctrl: QubitType, target: QubitType) -> CRxGate: 70 | self._check_qubit(ctrl) 71 | self._check_qubit(target) 72 | self._check_dups([ctrl, target]) 73 | return self._attach(CRxGate(theta, ctrl, target, self)) 74 | 75 | 76 | QuantumCircuit.crx = crx 77 | CompositeGate.crx = crx 78 | -------------------------------------------------------------------------------- /hhl4x4/custom_gates/comment.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | 32 | """Implementation of a comment instruction. 33 | 34 | The comment instruction is a hack to be able to insert comments in the 35 | generated OpenQASM code. Comments are then ignored and removed by the 36 | Qiskit compiler so they will only appear in the generated OpenQASM. 37 | 38 | The Comment gate overloads the Barrier gate, which *does not* change the 39 | circuit result but *might change* the final OpenQASM code by preventing 40 | some optimisations. 41 | """ 42 | 43 | import qiskit 44 | from qiskit.extensions.standard.barrier import Barrier 45 | 46 | 47 | class Comment(Barrier): 48 | """Instruction inserting a comment in the OpenQASM code.""" 49 | 50 | def __init__(self, text: str, qubits, circ): 51 | """Create new comment.""" 52 | super().__init__(qubits, circ) 53 | self._text = text 54 | 55 | def inverse(self): 56 | """Do nothing. Return self.""" 57 | return self 58 | 59 | def qasm(self): 60 | """Return OpenQASM string.""" 61 | return "// {}".format(self._text) 62 | 63 | def reapply(self, circ): 64 | """Reapply this comment.""" 65 | self._modifiers(circ.comment(self._text)) 66 | 67 | def q_if(self, *qregs): 68 | self._text = ("c-" * len(qregs)) + self._text 69 | return self 70 | 71 | 72 | def comment(self, text: str): 73 | """Write a comment to circuit.""" 74 | all_qubits = [] 75 | circuit = self 76 | while not hasattr(circuit, 'regs'): 77 | circuit = circuit.circuit 78 | for _, register in circuit.regs.items(): 79 | if isinstance(register, qiskit.QuantumRegister): 80 | all_qubits.extend((register[i] for i in range(len(register)))) 81 | return self._attach(Comment(text, all_qubits, self)) 82 | 83 | 84 | qiskit.QuantumCircuit.comment = comment 85 | qiskit.CompositeGate.comment = comment 86 | -------------------------------------------------------------------------------- /hhl4x4/custom_gates/hhl4x4.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | 32 | """This module contains functions to apply a controlled-Hamiltonian. 33 | """ 34 | 35 | from typing import Tuple, Union, List 36 | from qiskit import QuantumCircuit, QuantumRegister, CompositeGate 37 | from hhl4x4.custom_gates import comment, ccz, crx, csqtrx, crzz 38 | 39 | QubitType = Tuple[QuantumRegister, int] 40 | 41 | 42 | class Hamiltonian4x4Gate(CompositeGate): 43 | 44 | def __init__(self, ctrl: QubitType, targets: Tuple[QubitType], 45 | params: List[float] = None, circuit: QuantumCircuit = None): 46 | """Initialize the Hamiltonian4x4Gate class. 47 | 48 | :param ctrl: The control qubit used to control the Hamiltonian gate. 49 | :param targets: 2 qubits used to apply the Hamiltonian. 50 | :param params: floating point parameters. 51 | :param circuit: The associated quantum circuit. 52 | """ 53 | 54 | if params is None: 55 | # Default parameters for a simple Hamiltonian (no powers) 56 | params = [0.19634953, 0.37900987, 0.9817477, 1.87900984, 0.58904862] 57 | 58 | used_qubits = [ctrl, targets[0], targets[1]] 59 | 60 | super().__init__(self.__class__.__name__, # name 61 | [], # parameters 62 | used_qubits, # qubits 63 | circuit) # circuit 64 | 65 | self.comment("[HS] Start.") 66 | self.ccz(ctrl, targets[0], targets[1]) 67 | self.crx(params[0], ctrl, targets[1]) 68 | self._attach(csqtrx.CsqrtX(ctrl, targets[1], self).inverse()) 69 | self.crzz(params[1], ctrl, targets[1]) 70 | self.crx(params[2], ctrl, targets[0]) 71 | self.crzz(params[3], ctrl, targets[0]) 72 | self.ccx(ctrl, targets[0], targets[1]) 73 | self.crx(params[4], ctrl, targets[0]) 74 | self.ccx(ctrl, targets[0], targets[1]) 75 | self.ccz(ctrl, targets[0], targets[1]) 76 | self.comment("[HS] End.") 77 | 78 | 79 | # Adding the method to the QuantumCircuit and CompositeGate classes. 80 | def hamiltonian4x4(self, ctrl: QubitType, targets: Tuple[QubitType], 81 | params: List[float] = None) -> Hamiltonian4x4Gate: 82 | self._check_qubit(ctrl) 83 | self._check_qubit(targets[0]) 84 | self._check_qubit(targets[1]) 85 | self._check_dups([ctrl, targets[0], targets[1]]) 86 | return self._attach(Hamiltonian4x4Gate(ctrl, targets, params, self)) 87 | 88 | 89 | QuantumCircuit.hamiltonian4x4 = hamiltonian4x4 90 | CompositeGate.hamiltonian4x4 = hamiltonian4x4 91 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | 2 | .. image:: https://zenodo.org/badge/156688451.svg 3 | :target: https://zenodo.org/badge/latestdoi/156688451 4 | 5 | This repository contains an implementation of the HHL algorithm for a specific 6 | 4 x 4 matrix: 7 | 8 | .. code:: python 9 | 10 | A = 1/4 * numpy.array([[15, 9, 5, -3], 11 | [9, 15, 3, -5], 12 | [5, 3, 15, -9], 13 | [-3, -5, -9, 15]]) 14 | 15 | The implementation is inspired from the paper `Quantum Circuit Design for 16 | Solving Linear Systems of Equations`_, written by Yudong Cao, Anmer 17 | Daskin, Steven Frankel and Sabre Kais. 18 | 19 | .. _Quantum Circuit Design for Solving Linear Systems of Equations: https://arxiv.org/abs/1110.2232v2 20 | 21 | Installation 22 | ============ 23 | 24 | The installation procedure is composed of multiple steps, some of them being optional: 25 | 26 | 1) (optional) Create a virtual environment to isolate the installation: 27 | 28 | .. code:: shell 29 | 30 | python3 -m venv hhl_venv 31 | source hhl_venv/bin/activate 32 | 33 | 2) Clone the git repository: 34 | 35 | .. code:: shell 36 | 37 | git clone https://github.com/nelimee/quantum-hhl-4x4.git 38 | cd quantum-hhl-4x4 39 | 40 | 3) Install the requirements: 41 | 42 | .. code:: shell 43 | 44 | pip install -r requirements.txt 45 | 46 | 4) Install the HHL implementation: 47 | 48 | .. code:: shell 49 | 50 | python3 setup.py install 51 | 52 | 53 | Description of the repository structure 54 | ======================================= 55 | 56 | The main directory contains: 57 | 58 | 1) A ``LICENSE`` file explaining under which license this code is distributed. 59 | For more information go read the `Notes about the license`_ section. 60 | 2) This README file. 61 | 3) A ``requirements.txt`` file that can be used to install all the dependencies 62 | of the software. 63 | 4) A ``setup.py`` file used to install the code. 64 | 5) The ``hhl4x4`` directory which contains all the Python code. 65 | 66 | The ``hhl4x4`` folder 67 | --------------------- 68 | 69 | The ``hhl4x4`` folder contains all the Python code used to implement the HHL algorithm 70 | for the matrix :math:`A`. It is organised in 2 folders and 3 python files: 71 | 72 | 1) The ``custom_gates`` folder contains the implementation of user-defined quantum gates 73 | like the doubly-controlled ``Z`` gate (a ``Z`` gate controlled by 2 qubits) or the 74 | controlled Rzz gate (a controlled global phase shift). 75 | The HHL algorithm is implemented a user-defined quantum gate in the file ``hhl4x4.py``. 76 | 2) The ``utils`` folder contains 2 python files: ``endianness.py`` used to take care of 77 | the registers endianness and ``registers.py`` that implements wrapper around the base 78 | register classes used by Qiskit. 79 | 3) ``4x4.py``: the full implementation of the HHL algorithm. Once the software is installed 80 | (after a successful ``python setup.py install``) you can run this file by typing the 81 | command ``HHL4x4`` in your terminal. 82 | 4) ``optimise_parameters.py``: the script used to find the best parameters for the Hamiltonian 83 | simulation part. Once the software is installed (after a successful ``python setup.py install``) 84 | you can run this file by typing the command ``HHL4x4_optimise_parameters`` in your terminal. 85 | You can see the available options with ``HHL4x4_optimise_parameters --help``. 86 | 87 | Note: The ``HHL4x4`` command or the `4x4.py` script will generate the file ``4x4.qasm`` containing 88 | the OpenQASM code of the implemented HHL algorithm in the current directory. A histogram visualisation 89 | of the final quantum state will also pop at the end of the program. 90 | 91 | 92 | Notes about the license 93 | ======================= 94 | 95 | This software is licensed under the CeCILL-B license. The CeCILL-B license enforce the 96 | obligation for anyone who want to use this software (in any way) to cite the original authors 97 | and source. 98 | 99 | If you want to use this software, please cite: 100 | 101 | 1) Adrien Suau, adrien.suau@cerfacs.fr as the main author. 102 | 2) CERFACS, cerfacs.fr as a contributor. 103 | 104 | If you have any doubt, please read the license. If you still have doubts or questions, please 105 | send me a mail at adrien.suau@cerfacs.fr. 106 | -------------------------------------------------------------------------------- /hhl4x4/custom_gates/qpe.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | 32 | """This module contains functions to apply the quantum phase estimation 33 | algorithm. 34 | """ 35 | import typing 36 | from qiskit import QuantumCircuit, QuantumRegister, CompositeGate 37 | from hhl4x4.utils.endianness import QRegisterBE 38 | from hhl4x4.custom_gates.qft import iqft_be 39 | 40 | import hhl4x4.custom_gates.comment 41 | 42 | QubitType = typing.Tuple[QuantumRegister, int] 43 | 44 | 45 | class QuantumPhaseEstimationGate(CompositeGate): 46 | 47 | def __init__(self, phase_quantum_register, eigenvector_quantum_register, 48 | controlled_hamiltonian_powers, precision: float = 0.1, 49 | qcirc=None): 50 | """Initialize the QuantumPhaseEstimationGate class. 51 | 52 | Apply the Quantum Phase Estimation algorithm to estimate the eigenvalue 53 | phase and store it in big-endian in phase_quantum_register. 54 | 55 | :param phase_quantum_register: 0>^n state in input, stores the 56 | approximation of the eigenvalue phase at the end of the algorithm. 57 | :param eigenvector_quantum_register: |psi> state, an eigenvector of U, 58 | in input, the same state in output. 59 | :param controlled_hamiltonian_powers: A callable that implements the 60 | quantum circuits 61 | applying the controlled-U^{2^i} transformations. 62 | c_U_powers(i, circuit, control, quantum_register) applies U^{2^i} on 63 | 'quantum_register', controlled by the qubit 'control'. 64 | :param precision: 65 | :param qcirc: The associated quantum circuit. 66 | """ 67 | 68 | n, m = len(phase_quantum_register), len(eigenvector_quantum_register) 69 | phase_qubits = [phase_quantum_register[i] for i in range(n)] 70 | eigenvector_qubits = [eigenvector_quantum_register[i] for i in range(m)] 71 | used_qubits = phase_qubits + eigenvector_qubits 72 | 73 | super().__init__(self.__class__.__name__, # name 74 | [], # parameters 75 | used_qubits, # qubits 76 | qcirc) # circuit 77 | 78 | self.comment("[QPE] Starting block.") 79 | self.comment("[QPE] 1. Hadamard gate.") 80 | self.h(phase_quantum_register) 81 | self.comment("[QPE] 2. Phase estimation.") 82 | for i in range(n): 83 | self.comment( 84 | "[QPE] 2.{0}. Start of step {0} of phase estimation.".format(i)) 85 | controlled_hamiltonian_powers(i, self, 86 | phase_quantum_register[n - 1 - i], 87 | eigenvector_quantum_register) 88 | self.comment( 89 | "[QPE] 2.{0}. End of step {0} of phase estimation.".format(i)) 90 | 91 | self.comment("[QPE] 3. Inverse QFT.") 92 | iqft_be(self, phase_quantum_register, qcirc) 93 | self.comment("[QPE] End block.") 94 | 95 | 96 | def qpe(self, phase_quantum_register: QRegisterBE, 97 | eigenvector_quantum_register: QRegisterBE, 98 | controlled_hamiltonian_powers: typing.Callable[ 99 | [int, CompositeGate, QubitType, QRegisterBE], None], 100 | precision: float = 0.1) -> QuantumPhaseEstimationGate: 101 | self._check_qreg(phase_quantum_register) 102 | self._check_qreg(eigenvector_quantum_register) 103 | self._check_dups([phase_quantum_register, eigenvector_quantum_register]) 104 | return self._attach(QuantumPhaseEstimationGate(phase_quantum_register, 105 | eigenvector_quantum_register, 106 | controlled_hamiltonian_powers, 107 | precision, self)) 108 | 109 | 110 | QuantumCircuit.qpe = qpe 111 | CompositeGate.qpe = qpe 112 | -------------------------------------------------------------------------------- /hhl4x4/utils/endianness.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | 32 | """This module define some useful functions and types to deal with endianness. 33 | """ 34 | 35 | import typing 36 | import qiskit 37 | 38 | from .registers import QRegisterBase, CRegisterBase 39 | 40 | # Type alias definition 41 | GateContainer = typing.Union[qiskit.QuantumCircuit, qiskit.CompositeGate] 42 | 43 | class QRegisterLE(QRegisterBase): 44 | """Quantum Register Little Endian.""" 45 | pass 46 | 47 | class QRegisterBE(QRegisterBase): 48 | """Quantum Register Big Endian.""" 49 | pass 50 | 51 | class QRegisterPhaseLE(QRegisterBase): 52 | """Quantum Register Little Endian in Quantum Fourier Transform state.""" 53 | pass 54 | 55 | class QRegisterPhaseBE(QRegisterBase): 56 | """Quantum Register Big Endian in Quantum Fourier Transform state.""" 57 | pass 58 | 59 | 60 | class CRegister(CRegisterBase): 61 | """Classical Register.""" 62 | pass 63 | 64 | 65 | def apply_LE_operation(container: GateContainer, 66 | little_endian_operation, 67 | qreg: qiskit.QuantumRegister): 68 | """Apply a little endian operation to a quantum register. 69 | This function will change the endianness of the given register if 70 | it is not already in little endian, apply the operation, and recover 71 | the initial endianness. 72 | Warning: if the type of the given register does not give any 73 | information on its endianness (inheriting from 74 | QRegisterLE or QRegisterBE) then the operation will be 75 | applied on the register without any endianness 76 | consideration. 77 | """ 78 | 79 | if isinstance(qreg, QRegisterBE): 80 | qreg._reverse_access_endian() 81 | 82 | # Here we may have an instance of QRegisterBE which is 83 | # in little endian when we access it. This should be 84 | # avoided, that is why the method _reverse_access_endian 85 | # is "private". 86 | 87 | little_endian_operation(container, qreg) 88 | 89 | # As written above, we may have a strange register (labeled 90 | # as big endian but effectively in little endian). Don't 91 | # forget to fix this register by changing again it's 92 | # endianness. 93 | 94 | if isinstance(qreg, QRegisterBE): 95 | qreg._reverse_access_endian() 96 | 97 | def apply_BE_operation(container: GateContainer, 98 | big_endian_operation, 99 | qreg: qiskit.QuantumRegister): 100 | """Apply a big endian operation to a quantum register. 101 | This function will change the endianness of the given register if 102 | it is not already in big endian, apply the operation, and recover 103 | the initial endianness. 104 | Warning: if the type of the given register does not give any 105 | information on its endianness (inheriting from 106 | QRegisterLE or QRegisterBE) then the operation will be 107 | applied on the register without any endianness 108 | consideration. 109 | """ 110 | 111 | if isinstance(qreg, QRegisterLE): 112 | qreg._reverse_access_endian() 113 | 114 | # Here we may have an instance of QRegisterLE which is 115 | # in big endian when we access it. This should be 116 | # avoided, that is why the method _reverse_access_endian 117 | # is "private". 118 | 119 | big_endian_operation(container, qreg) 120 | 121 | # As written above, we may have a strange register (labeled 122 | # as little endian but effectively in big endian). Don't 123 | # forget to fix this register by changing again it's 124 | # endianness. 125 | 126 | if isinstance(qreg, QRegisterLE): 127 | qreg._reverse_access_endian() 128 | 129 | 130 | def swap_endianness(self: GateContainer, 131 | qreg: typing.Union[QRegisterBE, QRegisterLE]): 132 | """Swaps the endianness of qreg.""" 133 | qubit_number = len(qreg) 134 | for i in range(qubit_number//2): 135 | self.swap(qreg[i], qreg[qubit_number-1-i]) 136 | 137 | 138 | -------------------------------------------------------------------------------- /hhl4x4/optimise_parameters.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | 32 | """Script used to find the best parameters for the Hamiltonian simulation. 33 | 34 | The paper of Cao et al. (https://arxiv.org/abs/1110.2232v2) introduce an 35 | Hamiltonian decomposition for their specific matrix. In this paper, they 36 | also say that the circuit simulating the powers of the simulated 37 | Hamiltonian can be obtained by multiplying the numeric parameters of 5 38 | gates by a constant. After trying, it seems that this technique does not 39 | work. 40 | The method used here is not based on a mathematical analysis and its 41 | convergence has not been studied. In other words, the fact that the 42 | different powers of the Hamiltonian could be expressed just by changing 43 | the coefficients of the circuit given in the paper of Cao et al. has 44 | only been verified experimentally. 45 | """ 46 | 47 | import typing 48 | import qiskit 49 | import numpy as np 50 | import scipy.linalg as la 51 | 52 | import hhl4x4.custom_gates.hhl4x4 53 | 54 | QubitType = typing.Tuple[qiskit.QuantumRegister, int] 55 | 56 | 57 | def hamiltonian_error(power: int, display_digit: int): 58 | """Generate and return a function that will be given to the optimiser. 59 | 60 | The returned function will compute the error between the ideal unitary 61 | matrix (raised to the given power) and the simulated one with the set 62 | a parameters given by the optimizer.https://arxiv.org/abs/1110.2232v2 63 | 64 | :param power: the power we want to simulate. 65 | """ 66 | 67 | def ret(params: typing.Sequence[float]) -> float: 68 | """Computes the error between the ideal matrix and the simulated one. 69 | 70 | :param params: parameters used in the quantum circuit. 71 | :return: the 2-norm distance between the ideal matrix and the simulated 72 | one. 73 | """ 74 | list_format = ','.join( 75 | ["{: ." + str(display_digit) + "f}" for i in range(len(params))]) 76 | print(("Computing U^{:<2} error with [" + list_format + "]: ").format( 77 | 2 ** power, *params), end='') 78 | 79 | def swap(U): 80 | """Change the quantum gate representation. 81 | 82 | Qiskit uses a different endianness which change the unitary matrices 83 | representing quantum gates. This function takes a quantum gate "as 84 | we are used to represent them" and transform it "as Qiskit 85 | represents them". 86 | 87 | :param U: the matrix to change. 88 | :return: the adapted matrix. 89 | """ 90 | from copy import deepcopy 91 | cpy = deepcopy(U) 92 | cpy[[1, 2], :] = cpy[[2, 1], :] 93 | cpy[:, [1, 2]] = cpy[:, [2, 1]] 94 | return cpy 95 | 96 | ancilla = qiskit.QuantumRegister(1) 97 | b = qiskit.QuantumRegister(2) 98 | classical = qiskit.ClassicalRegister(1) 99 | 100 | circuit = qiskit.QuantumCircuit(ancilla, b, classical) 101 | 102 | circuit.hamiltonian4x4(ancilla[0], b, params).inverse() 103 | 104 | unitary_sim = qiskit.Aer.get_backend('unitary_simulator') 105 | res = qiskit.execute([circuit], unitary_sim).result() 106 | unitary = res.get_unitary() 107 | 108 | A = .25 * np.array( 109 | [[15, 9, 5, -3], [9, 15, 3, -5], [5, 3, 15, -9], [-3, -5, -9, 15]]) 110 | t0 = 2 * np.pi 111 | expA = swap(la.expm(-1.j * A * t0 * (2 ** power / 16))) 112 | unit = unitary[1::2, 1::2] 113 | np.set_printoptions(precision=2) 114 | err = la.norm(unit - expA) 115 | print("{: g}".format(err), end='\r', flush=True) 116 | return err 117 | 118 | return ret 119 | 120 | 121 | def main(): 122 | # Optimise! 123 | import scipy.optimize as opt 124 | import argparse 125 | 126 | parser = argparse.ArgumentParser( 127 | description='Find the optimum parameters for Hamiltonian simulation.') 128 | # parser.add_argument('--precision', default=1e-7, type=float, 129 | # help="Desired precision for the final Hamiltonian.") 130 | parser.add_argument("--maxiter", type=int, default=1000, 131 | help="Maximum number of iterations (default to 1000).") 132 | parser.add_argument("--display-precision", type=int, default=8, 133 | help="Number of digits needed when the parameters are " 134 | "displayed (default to 8).") 135 | args = parser.parse_args() 136 | 137 | for power in range(4): 138 | opt_res = opt.minimize(hamiltonian_error(power, args.display_precision), 139 | [0.2, 0.38, 0.98, 1.88, 0.59], 140 | options={"maxiter": args.maxiter}) 141 | print() 142 | 143 | 144 | if __name__ == '__main__': 145 | main() 146 | -------------------------------------------------------------------------------- /hhl4x4/utils/registers.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | 32 | """This module contains all the functions and classes related to registers.""" 33 | 34 | import typing 35 | from copy import deepcopy 36 | import qiskit 37 | 38 | 39 | def _get_slice_size(slice_instance: slice, container_size: int): 40 | start, stop, step = slice_instance.indices(container_size) 41 | return (stop - start) // step + (1 if (stop - start) % step != 0 else 0) 42 | 43 | 44 | class QRegisterBase(qiskit.QuantumRegister): 45 | 46 | def __init__(self, *args, **kwargs): 47 | # Copy constructor 48 | if len(args) == 1 and isinstance(args[0], qiskit.QuantumRegister): 49 | quantum_register = args[0] 50 | super().__init__(quantum_register.size, quantum_register.name) 51 | if isinstance(args[0], QRegisterBase): 52 | self._reversed = quantum_register._reversed 53 | else: 54 | self._reversed = False 55 | self._register = args[0] 56 | 57 | elif len(args) >= 2 and isinstance(args[0], int) and isinstance(args[1], 58 | str): 59 | super().__init__(args[0], args[1]) 60 | self._reversed = False 61 | self._register = self 62 | 63 | else: 64 | raise NotImplementedError("({})".format(','.join(map(type, args)))) 65 | 66 | def _reverse_access_endian(self): 67 | """Reverse the apparent endianness of the register. 68 | This operation does not produce any gate in the quantum circuit because 69 | the endianness is just reversed when accessing to a specific qubit. 70 | """ 71 | # Update the flag 72 | self._reversed = not self._reversed 73 | 74 | def __getitem__(self, key): 75 | if isinstance(key, slice): 76 | return SplittableQuantumRegister(self._register, key) 77 | else: 78 | if self._reversed: 79 | return self._register.__getitem__(len(self._register) - 1 - key) 80 | else: 81 | return self._register.__getitem__(key) 82 | 83 | def __add__(self, other): 84 | return BondableQuantumRegister(self._register, other) 85 | 86 | def __iadd__(self, other): 87 | return BondableQuantumRegister(self._register, other) 88 | 89 | 90 | class SplittableQuantumRegister(QRegisterBase): 91 | """Implement a splittable register. 92 | A splittable register is an instance of QuantumRegister that can be indexed 93 | with Python slices. The SplittableQuantumRegister class implement the 94 | operations: 95 | 1) Creation from an instance of QuantumRegister, with an additional 96 | optional third parameter corresponding to the slice to use. 97 | 2) Use of classical indices and of slices: 98 | splittable_reg = SplittableQuantumRegister("qreg", 10) 99 | qubit_3 = splittable_reg[3] 100 | qubit_6 = splittable_reg[::3][2] 101 | """ 102 | 103 | def __init__(self, qreg: QRegisterBase, *args): 104 | if len(args) >= 1 and isinstance(args[0], slice): 105 | self._slice = args[0] 106 | # Update the size if the slice is given by the user 107 | size = _get_slice_size(self._slice, len(qreg)) 108 | else: 109 | self._slice = slice(len(qreg)) 110 | size = len(qreg) 111 | super().__init__(qreg) 112 | self.size = size 113 | # Deepcopy is terrible if we chain a huge amount of slicings 114 | # but it avoids side effects. 115 | self._register = deepcopy(qreg) 116 | 117 | def __getitem__(self, key: typing.Union[int, slice]): 118 | # If the user gave a slice, then return an other splittable register. 119 | if isinstance(key, slice): 120 | return SplittableQuantumRegister(self, key) 121 | # Else, recursively call __getitem__ on the self._register list. 122 | else: 123 | start, stop, step = self._slice.indices(self.size) 124 | if key < 0 or key >= stop: 125 | raise IndexError( 126 | ("Trying to obtain the bit n°{} from a register of size {" 127 | "}").format(key, self.size)) 128 | if self._reversed: 129 | return self._register.__getitem__( 130 | start + (self.size - 1 - key) * step) 131 | else: 132 | return self._register.__getitem__(start + key * step) 133 | 134 | def __add__(self, other: QRegisterBase): 135 | return BondableQuantumRegister(self, other) 136 | 137 | def __iadd__(self, other: QRegisterBase): 138 | return self + other 139 | 140 | 141 | class BondableQuantumRegister(QRegisterBase): 142 | """Implement a bondable register. 143 | A bondable register is an instance of QuantumRegister that can be 144 | composed of 145 | one or more QuantumRegister that are glued together. 146 | The class BondableQuantumRegister implements the operations: 147 | """ 148 | 149 | def __init__(self, qreg: QRegisterBase, *args): 150 | # Construct from a list of QuantumRegisters 151 | # Deepcopy is terrible if we chain a huge amount of bonding 152 | # but it avoids side effects. 153 | self._registers = [deepcopy(qreg)] 154 | self._registers += [deepcopy(arg) for arg in args if 155 | isinstance(arg, QRegisterBase)] 156 | # Concatenating the names and summing the sizes. 157 | super().__init__("".join(map(lambda x: x.name, self._registers)), 158 | sum(map(lambda x: x.size, self._registers))) 159 | 160 | def __getitem__(self, key: int): 161 | if isinstance(key, slice): 162 | return SplittableQuantumRegister(self, key) 163 | 164 | total_index = 0 165 | registers = self._registers if not self._reversed else self._registers[ 166 | ::-1] 167 | for register in registers: 168 | if (key - total_index) < len(register): 169 | if self._reversed: 170 | return register[len(register) - 1 - (key - total_index)] 171 | else: 172 | return register[key - total_index] 173 | total_index += len(register) 174 | # If we are here, this means that the given key was not a valid index 175 | # for the register, so we raise an exception 176 | raise IndexError( 177 | "Trying to obtain the bit n°{} from a register of size {}".format( 178 | key, self.size)) 179 | 180 | def __add__(self, other: QRegisterBase): 181 | return BondableQuantumRegister(self, other) 182 | 183 | def __iadd__(self, other: QRegisterBase): 184 | return self + other 185 | 186 | 187 | class CRegisterBase(qiskit.ClassicalRegister): 188 | """Classical Register.""" 189 | def __init__(self, *args, **kwargs): 190 | # Copy constructor 191 | if len(args) == 1 and isinstance(args[0], qiskit.ClassicalRegister): 192 | classical_register = args[0] 193 | self.name = classical_register.name 194 | self.size = classical_register.size 195 | # Delegate the constructor to the super class. 196 | else: 197 | super().__init__(*args, **kwargs) 198 | -------------------------------------------------------------------------------- /hhl4x4/4x4.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | 32 | 33 | """Implements the HHL algorithm describer in https://arxiv.org/abs/1110.2232v2. 34 | 35 | 36 | """ 37 | 38 | import copy 39 | 40 | import numpy as np 41 | import qiskit 42 | import scipy.linalg as la 43 | from sympy import pi 44 | 45 | import hhl4x4.utils.endianness as endian 46 | import hhl4x4.custom_gates.comment 47 | import hhl4x4.custom_gates.hhl4x4 48 | import hhl4x4.custom_gates.qpe 49 | 50 | 51 | def postselect(statevector: np.ndarray, qubit_index: int, value: bool): 52 | mask = 1 << qubit_index 53 | if value: 54 | array_mask = np.arange(len(statevector)) & mask 55 | else: 56 | array_mask = not (np.arange(len(statevector)) & mask) 57 | 58 | def normalise(vec: np.ndarray): 59 | from scipy.linalg import norm 60 | return vec / norm(vec) 61 | 62 | return normalise(statevector[array_mask != 0]) 63 | 64 | 65 | def round_to_zero(vec: np.ndarray, tol=2e-15): 66 | vec.real[abs(vec.real) < tol] = 0.0 67 | vec.imag[abs(vec.imag) < tol] = 0.0 68 | return vec 69 | 70 | 71 | def reverse_endianness(i: int, length: int) -> int: 72 | return int(''.join(reversed(('{0:0' + str(length) + 'b}').format(i))), 2) 73 | 74 | 75 | def main(): 76 | qancilla = endian.QRegisterBE(qiskit.QuantumRegister(1)) 77 | qclock = endian.QRegisterBE(qiskit.QuantumRegister(4)) 78 | qb = endian.QRegisterBE(qiskit.QuantumRegister(2)) 79 | classical = endian.CRegister(qiskit.ClassicalRegister(1)) 80 | 81 | circuit = qiskit.QuantumCircuit(qancilla, qclock, qb, classical) 82 | 83 | # 0. Initialise b 84 | circuit.comment("[4x4] Initialising b.") 85 | circuit.h(qb) 86 | circuit.comment("[4x4] Initialisation done!") 87 | 88 | # 1. Quantum Phase Estimation 89 | def controlled_hamiltonian_powers(n: int, circuit, control, target): 90 | # Previous method: just applying an optimized hamiltonian an exponential 91 | # number of times. 92 | # for i in range(2**n): 93 | # #circuit.hamiltonian4x4(control, target).inverse() 94 | # circuit.hamiltonian4x4(control, target) 95 | 96 | # Hard-coded values obtained thanks to optimise_parameters.py 97 | # The error (2-norm of the difference between the unitary matrix of the 98 | # quantum circuit and the true matrix) is bounded by 1e-7, no matter the 99 | # value of n. 100 | power = 2 ** n 101 | if power == 1: 102 | params = [0.19634953, 0.37900987, 0.9817477, 1.87900984, 0.58904862] 103 | elif power == 2: 104 | params = [1.9634954, 1.11532058, 1.9634954, 2.61532069, 1.17809726] 105 | elif power == 4: 106 | params = [-0.78539816, 1.01714584, 3.92699082, 2.51714589, 107 | 2.35619449] 108 | elif power == 8: 109 | params = [-9.01416169e-09, -0.750000046, 1.57079632, 0.750000039, 110 | -1.57079633] 111 | else: 112 | raise NotImplementedError( 113 | "You asked for a non-implemented power: {}".format(power)) 114 | circuit.hamiltonian4x4(control, target, params) 115 | 116 | circuit.comment("[4x4] 1. Quantum phase estimation.") 117 | qpe_gate = circuit.qpe(qclock, qb, controlled_hamiltonian_powers) 118 | 119 | ## 2. Phase rotation controlled by the eigenvalue. 120 | circuit.comment("[4x4] Inverting computed eigenvalues.") 121 | circuit.swap(qclock[1], qclock[2]) 122 | 123 | # r is a parameter of the circuit. 124 | # A good value is between 5 and 6 according to the article. 125 | r = 6 126 | circuit.comment("[4x4] 2. Phase rotation.") 127 | 128 | def cry(circuit, theta, ctrl, target): 129 | circuit.comment("CRY") 130 | # Apply the supposed c-RY operation. 131 | circuit.cu3(theta, 0, 0, ctrl, target) 132 | 133 | for i in range(len(qclock)): 134 | cry(circuit, 2 ** (len(qclock) - i - r) * pi, 135 | qclock[len(qclock) - 1 - i], qancilla[0]) 136 | 137 | circuit.comment("Inverting the inversion of eigenvalues.") 138 | circuit.swap(qclock[1], qclock[2]) 139 | 140 | ## 3. Uncompute the Quantum Phase Estimation. 141 | circuit.comment("[4x4] 3. Inverting quantum phase estimation.") 142 | circuit._attach(copy.deepcopy(qpe_gate).inverse()) 143 | 144 | circuit_no_measure = copy.deepcopy(circuit) 145 | 146 | ## 4. Measure the ancilla qubit to check. 147 | circuit.comment("[4x4] 4. Measurement.") 148 | circuit.measure(qancilla, classical) 149 | 150 | with open('4x4.qasm', 'w') as f: 151 | f.write(circuit.qasm()) 152 | 153 | qasm_sim = qiskit.Aer.get_backend('qasm_simulator') 154 | state_sim = qiskit.Aer.get_backend('statevector_simulator') 155 | unitary_sim = qiskit.Aer.get_backend('unitary_simulator') 156 | 157 | # res_qasm = execute([circuit], qasm_sim, shots=10**5).result() 158 | # counts = res_qasm.get_counts() 159 | # filtered_counts = {key: counts[key] for key in counts if key[-1] == '1'} 160 | # significant_counts = {key: counts[key] for key in counts if counts[key] 161 | # > 100} 162 | # significant_filtered_counts = {key: filtered_counts[key] 163 | # for key in filtered_counts 164 | # if filtered_counts[key] > 5000} 165 | # print("Counts:", counts, sep='\n') 166 | 167 | res_state = qiskit.execute([circuit_no_measure], state_sim).result() 168 | full_state = res_state.get_statevector() 169 | 170 | # The obtained full state is encoded with Qiskit's register order which 171 | # is not 172 | # the order we want. We need to change the array so that we reverse the 173 | # order of each register. 174 | size = full_state.shape[0] 175 | full_state_reversed = np.zeros((size,), dtype=full_state.dtype) 176 | for i in range(size): 177 | qubit_ancilla_value = i & 0b1 178 | qubit_clock_value = (i >> 1) & 0b1111 179 | qubit_b_value = (i >> 5) & 0b11 180 | reversed_regs_id = qubit_b_value | (qubit_clock_value << 2) | ( 181 | qubit_ancilla_value << 6) 182 | full_state_reversed[reversed_regs_id] = full_state[i] 183 | full_state = full_state_reversed 184 | 185 | # full_state = reverse_indices_endianness(full_state) 186 | statevector = round_to_zero(postselect(full_state, 6, True), 1e-3) 187 | 188 | solution = np.sqrt(340) * statevector[:4] 189 | x_exact = np.array([-1, 7, 11, 13]) 190 | 191 | print("Exact solution: {}".format(x_exact)) 192 | print("Experimental solution: {}".format(solution)) 193 | print("Error in found solution: {}".format(la.norm(solution - x_exact))) 194 | 195 | # res_unitary = execute([circuit_no_measure], unitary_sim, 196 | # skip_translation=skip).result() 197 | # unitary = res_unitary.get_unitary() 198 | # print("Unitary matrix:", unitary, sep='\n') 199 | 200 | amplitudes = np.absolute(full_state) ** 2 201 | 202 | X = np.arange(len(full_state)) 203 | import matplotlib.pyplot as plt 204 | 205 | plt.bar(X, np.real(full_state)) 206 | plt.xticks(np.arange(0, len(X), 2), 207 | [' '.join([bin(n)[3], bin(n)[4:8], bin(n)[8:10]]) for n in 208 | np.arange(len(X), 2 * len(X), 2)], usetex=False, 209 | rotation='vertical') 210 | plt.grid(zorder=0) 211 | plt.show() # plot_histogram(counts) 212 | 213 | 214 | if __name__ == '__main__': 215 | main() 216 | -------------------------------------------------------------------------------- /hhl4x4/custom_gates/qft.py: -------------------------------------------------------------------------------- 1 | # ====================================================================== 2 | # Copyright CERFACS (November 2018) 3 | # Contributor: Adrien Suau (suau@cerfacs.fr) 4 | # 5 | # This software is governed by the CeCILL-B license under French law and 6 | # abiding by the rules of distribution of free software. You can use, 7 | # modify and/or redistribute the software under the terms of the 8 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 9 | # URL "http://www.cecill.info". 10 | # 11 | # As a counterpart to the access to the source code and rights to copy, 12 | # modify and redistribute granted by the license, users are provided 13 | # only with a limited warranty and the software's author, the holder of 14 | # the economic rights, and the successive licensors have only limited 15 | # liability. 16 | # 17 | # In this respect, the user's attention is drawn to the risks associated 18 | # with loading, using, modifying and/or developing or reproducing the 19 | # software by the user in light of its specific status of free software, 20 | # that may mean that it is complicated to manipulate, and that also 21 | # therefore means that it is reserved for developers and experienced 22 | # professionals having in-depth computer knowledge. Users are therefore 23 | # encouraged to load and test the software's suitability as regards 24 | # their requirements in conditions enabling the security of their 25 | # systems and/or data to be ensured and, more generally, to use and 26 | # operate it in the same conditions as regards security. 27 | # 28 | # The fact that you are presently reading this means that you have had 29 | # knowledge of the CeCILL-B license and that you accept its terms. 30 | # ====================================================================== 31 | 32 | """This module contains an implementation of the Quantum Fourier Transform. 33 | For the moment the implementation is the most simple quantum fourier transform 34 | implementation. It has a gate complexity of O(n²). The algorithm implemented is 35 | the one presented on the wikipedia page of QFT: 36 | https://en.wikipedia.org/wiki/Quantum_Fourier_transform 37 | """ 38 | 39 | import math 40 | 41 | import sympy as sym 42 | from qiskit import QuantumCircuit, QuantumRegister, CompositeGate 43 | from hhl4x4.utils.endianness import QRegisterBE, \ 44 | QRegisterBase, \ 45 | apply_BE_operation 46 | 47 | 48 | class ApproximateQFTGate(CompositeGate): 49 | """Approximation of the QFT gate on quantum register. 50 | 51 | This implementation follows the one described in the Wikipedia page of the 52 | Quantum Fourier Transform: 53 | https://en.wikipedia.org/wiki/Quantum_Fourier_transform 54 | #Circuit_implementation 55 | This algorithm is also the one choosen by Microsoft in their 56 | Microsoft.Quantum.Canon. 57 | Warning: This gate does not swap the endianness of the output to return a 58 | register with the same endianness as the given one. The endianness of qreg 59 | is reversed by the quantum fourier transform algorithm, and so a big-endian 60 | register will become little-endian, even if its type does not say so. 61 | """ 62 | 63 | def __init__(self, qreg: QuantumRegister, qcirc: QuantumCircuit, 64 | approximation: int = None): 65 | """Initialise an ApproximateQFTGate. 66 | 67 | :param qreg: The quantum register on which to apply the approximate 68 | quantum Fourier transform. 69 | :param qcirc: The associated QuantumCircuit. 70 | :param approximation: The order of approximation. All the controlled 71 | phase gates with an angle inferior to pi/2**approximation will not be 72 | added to the circuit. If not present, takes the best approximation 73 | possible. For more details see https://arxiv.org/abs/quant-ph/9601018. 74 | """ 75 | 76 | qubits_number = len(qreg) 77 | used_qubits = [qreg[i] for i in range(qubits_number)] 78 | # If approximation is not set to a specific value, we choose a value 79 | # which is near to the optimum. 80 | # See https://arxiv.org/pdf/quant-ph/9601018.pdf 81 | if not approximation: 82 | approximation = math.ceil(math.log2(qubits_number)) + 2 83 | 84 | super().__init__(self.__class__.__name__, # name 85 | [approximation], # parameters 86 | used_qubits, # qubits 87 | qcirc) # circuit 88 | 89 | for i in range(qubits_number): 90 | for j in range(max(0, i - approximation + 1), i): 91 | self.cu1(sym.pi / 2 ** (i - j), qreg[i], qreg[j]) 92 | self.h(qreg[i]) 93 | 94 | 95 | def approximate_qft_be(self, qreg: QRegisterBE, qcirc: QuantumCircuit, 96 | approximation: int = None) -> ApproximateQFTGate: 97 | """Add an ApproximateQFTGate.""" 98 | self._check_qreg(qreg) 99 | gate = self._attach(ApproximateQFTGate(qreg, qcirc, approximation)) 100 | # Here the QFT algorithm reversed the endianness, so as we don't want some 101 | # register with a strange behaviour (registers of type QRegisterBE that are 102 | # in little-endian for example), we reverse the endianness. 103 | qreg._reverse_access_endian() 104 | return gate 105 | 106 | 107 | def iapproximate_qft_be(self, qreg: QRegisterBE, qcirc: QuantumCircuit, 108 | approximation: int = None) -> ApproximateQFTGate: 109 | """Add an inverted ApproximateQFTGate.""" 110 | self._check_qreg(qreg) 111 | # The QFT algorithm reverse the endianness, so the inverse QFT algorithm 112 | # also 113 | # and as it is the inverse algorithm, the endianness swap should occurs 114 | # before 115 | # the inverse QFT algorithm. 116 | qreg._reverse_access_endian() 117 | return self._attach( 118 | ApproximateQFTGate(qreg, qcirc, approximation).inverse()) 119 | 120 | 121 | class QFTGate(ApproximateQFTGate): 122 | """Exact QFT gate on quantum register. 123 | 124 | Implementation use the ApproximateQFTGate with an approximation order large 125 | enough to change the approximation in an exact computation. 126 | Warning: This gate does not swap the endianness of the output to return a 127 | register with the same endianness as the one given. The endianness of qreg 128 | is reversed by the quantum fourier transform algorithm, and so a big-endian 129 | register will become little-endian, even if its type does not say so. 130 | """ 131 | 132 | def __init__(self, qreg: QuantumRegister, qcirc: QuantumCircuit): 133 | super().__init__(qreg, qcirc, approximation=len(qreg)) 134 | 135 | 136 | def qft_be(self, qreg: QRegisterBE, qcirc: QuantumCircuit) -> QFTGate: 137 | """Add a QFTGate.""" 138 | self._check_qreg(qreg) 139 | gate = self._attach(QFTGate(qreg, qcirc)) 140 | # Here the QFT algorithm reversed the endianness, so as we don't want some 141 | # register with a strange behaviour (registers of type QRegisterBE that are 142 | # in little-endian for example), we reverse the endianness. 143 | qreg._reverse_access_endian() 144 | return gate 145 | 146 | 147 | def iqft_be(self, qreg: QRegisterBE, qcirc: QuantumCircuit) -> QFTGate: 148 | """Add an inverted QFTBEGate.""" 149 | self._check_qreg(qreg) 150 | # The QFT algorithm reverse the endianness, so the inverse QFT algorithm 151 | # also 152 | # and as it is the inverse algorithm, the endianness swap should occurs 153 | # before 154 | # the inverse QFT algorithm. 155 | qreg._reverse_access_endian() 156 | return self._attach(QFTGate(qreg, qcirc).inverse()) 157 | 158 | 159 | def apply_in_fourier_basis(self, operation, qreg: QRegisterBase, 160 | qcirc: QuantumCircuit, **kwargs): 161 | """Apply the given operation in the Fourier basis.""" 162 | 163 | # Defining first our big endian operation. 164 | def big_endian_operation(self_local, qreg_local): 165 | # Here, 'self' and 'qreg' refer to the local parameters, 166 | # 'qcirc' and 'kwargs' refer to the parameters of the parent scope. 167 | qft_be(self_local, qreg_local, qcirc) 168 | operation(self_local, qreg_local, **kwargs) 169 | iqft_be(self_local, qreg_local, qcirc) 170 | 171 | apply_BE_operation(self, big_endian_operation, qreg) 172 | 173 | 174 | def apply_in_approx_fourier_basis(self, operation, qreg: QRegisterBase, 175 | qcirc: QuantumCircuit, 176 | approximation: int = None, **kwargs): 177 | """Apply the given operation in the approximate Fourier basis.""" 178 | 179 | # Defining first our big endian operation. 180 | def big_endian_operation(self_local, qreg_local): 181 | # Here, 'self' and 'qreg' refer to the local parameters, 182 | # 'qcirc', 'kwargs' and 'approximation' refer to the parameters 183 | # of the parent scope. 184 | approximate_qft_be(self, qreg, qcirc, approximation) 185 | operation(self, qreg, **kwargs) 186 | iapproximate_qft_be(self, qreg, qcirc, approximation) 187 | 188 | apply_BE_operation(self, big_endian_operation, qreg) 189 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # ====================================================================== 4 | # Copyright CERFACS (November 2018) 5 | # Contributor: Adrien Suau (suau@cerfacs.fr) 6 | # 7 | # This software is governed by the CeCILL-B license under French law and 8 | # abiding by the rules of distribution of free software. You can use, 9 | # modify and/or redistribute the software under the terms of the 10 | # CeCILL-B license as circulated by CEA, CNRS and INRIA at the following 11 | # URL "http://www.cecill.info". 12 | # 13 | # As a counterpart to the access to the source code and rights to copy, 14 | # modify and redistribute granted by the license, users are provided 15 | # only with a limited warranty and the software's author, the holder of 16 | # the economic rights, and the successive licensors have only limited 17 | # liability. 18 | # 19 | # In this respect, the user's attention is drawn to the risks associated 20 | # with loading, using, modifying and/or developing or reproducing the 21 | # software by the user in light of its specific status of free software, 22 | # that may mean that it is complicated to manipulate, and that also 23 | # therefore means that it is reserved for developers and experienced 24 | # professionals having in-depth computer knowledge. Users are therefore 25 | # encouraged to load and test the software's suitability as regards 26 | # their requirements in conditions enabling the security of their 27 | # systems and/or data to be ensured and, more generally, to use and 28 | # operate it in the same conditions as regards security. 29 | # 30 | # The fact that you are presently reading this means that you have had 31 | # knowledge of the CeCILL-B license and that you accept its terms. 32 | # ====================================================================== 33 | 34 | 35 | """A setuptools based setup module. 36 | See: 37 | https://packaging.python.org/en/latest/distributing.html 38 | https://github.com/pypa/sampleproject 39 | """ 40 | 41 | from os import path 42 | 43 | # Always prefer setuptools over distutils 44 | from setuptools import setup, find_packages 45 | 46 | here = path.abspath(path.dirname(__file__)) 47 | 48 | # Get the long description from the README file 49 | with open(path.join(here, 'README.rst'), encoding='utf-8') as f: 50 | long_description = f.read() 51 | 52 | with open(path.join(here, "requirements.txt"), encoding='utf-8') as f: 53 | requirements = f.read().split('\n') 54 | 55 | # Arguments marked as "Required" below must be included for upload to PyPI. 56 | # Fields marked as "Optional" may be commented out. 57 | 58 | setup( # This is the name of your project. The first time you publish this 59 | # package, this name will be registered for you. It will determine how 60 | # users can install this project, e.g.: 61 | # 62 | # $ pip install sampleproject 63 | # 64 | # And where it will live on PyPI: https://pypi.org/project/sampleproject/ 65 | # 66 | # There are some restrictions on what makes a valid project name 67 | # specification here: 68 | # https://packaging.python.org/specifications/core-metadata/#name 69 | name='HHL4x4', # Required 70 | 71 | # Versions should comply with PEP 440: 72 | # https://www.python.org/dev/peps/pep-0440/ 73 | # 74 | # For a discussion on single-sourcing the version across setup.py and the 75 | # project code, see 76 | # https://packaging.python.org/en/latest/single_source_version.html 77 | version='1.0.0', # Required 78 | 79 | # This is a one-line description or tagline of what your project does. This 80 | # corresponds to the "Summary" metadata field: 81 | # https://packaging.python.org/specifications/core-metadata/#summary 82 | description='An implementation of the HHL algorithm for a 4x4 matrix.', 83 | 84 | # This is an optional longer description of your project that represents 85 | # the body of text which users will see when they visit PyPI. 86 | # 87 | # Often, this is the same as your README, so you can just read it in from 88 | # that file directly (as we have already done above) 89 | # 90 | # This field corresponds to the "Description" metadata field: 91 | # https://packaging.python.org/specifications/core-metadata/#description 92 | # -optional 93 | long_description=long_description, # Optional 94 | 95 | # Denotes that our long_description is in ReStructuredText; valid values are 96 | # text/plain, text/x-rst, and text/markdown 97 | # 98 | # Optional if long_description is written in reStructuredText (rst) but 99 | # required for plain-text or Markdown; if unspecified, "applications should 100 | # attempt to render [the long_description] as text/x-rst; charset=UTF-8 and 101 | # fall back to text/plain if it is not valid rst" (see link below) 102 | # 103 | # This field corresponds to the "Description-Content-Type" metadata field: 104 | # https://packaging.python.org/specifications/core-metadata/#description 105 | # -content-type-optional 106 | long_description_content_type='text/x-rst', # Optional (see note above) 107 | 108 | # This should be a valid link to your project's main homepage. 109 | # 110 | # This field corresponds to the "Home-Page" metadata field: 111 | # https://packaging.python.org/specifications/core-metadata/#home-page 112 | # -optional 113 | url='https://github.com/nelimee/quantum-hhl-4x4', # Optional 114 | 115 | # This should be your name or the name of the organization which owns the 116 | # project. 117 | author='Adrien Suau', # Optional 118 | 119 | # This should be a valid email address corresponding to the author listed 120 | # above. 121 | author_email='adrien.suau@cerfacs.fr', # Optional 122 | 123 | # Classifiers help users find your project by categorizing it. 124 | # 125 | # For a list of valid classifiers, see https://pypi.org/classifiers/ 126 | classifiers=[ # Optional 127 | # How mature is this project? Common values are 128 | # 3 - Alpha 129 | # 4 - Beta 130 | # 5 - Production/Stable 131 | 'Development Status :: 5 - Production/Stable', 132 | 133 | # Indicate who your project is intended for 134 | 'Intended Audience :: Developers', 'Intended Audience :: Education', 135 | 'Intended Audience :: Science/Research', 136 | 137 | # List the topics 138 | 'Topic :: Scientific/Engineering', 139 | 'Topic :: Scientific/Engineering :: Mathematics', 140 | 141 | # Pick your license as you wish 142 | 'License :: CeCILL-B Free Software License Agreement (CECILL-B)', 143 | 144 | # Specify the language used in the code 145 | 'Natural Language :: English', 146 | 147 | # Indicates that it is pure Python and should be OS independant 148 | 'Operating System :: OS Independent', 149 | 150 | # Specify the Python versions you support here. In particular, ensure 151 | # that you indicate whether you support Python 2, Python 3 or both. 152 | 'Programming Language :: Python :: 3 :: Only'], 153 | 154 | # This field adds keywords for your project which will appear on the 155 | # project page. What does your project relate to? 156 | keywords=['quantum', 'algorithm', 'hhl'], # Optional 157 | 158 | # You can just specify package directories manually here if your project is 159 | # simple. Or you can use find_packages(). 160 | # 161 | # Alternatively, if you just want to distribute a single Python file, use 162 | # the `py_modules` argument instead as follows, which will expect a file 163 | # called `my_module.py` to exist: 164 | # 165 | # py_modules=["my_module"], 166 | # 167 | packages=find_packages(), # Required 168 | 169 | # This field lists other packages that your project depends on to run. 170 | # Any package you put here will be installed by pip when your project is 171 | # installed, so they must be valid existing projects. 172 | # 173 | # For an analysis of "install_requires" vs pip's requirements files see: 174 | # https://packaging.python.org/en/latest/requirements.html 175 | install_requires=requirements, # Optional 176 | 177 | # List additional groups of dependencies here (e.g. development 178 | # dependencies). Users will be able to install these using the "extras" 179 | # syntax, for example: 180 | # 181 | # $ pip install sampleproject[dev] 182 | # 183 | # Similar to `install_requires` above, these must be valid existing 184 | # projects. 185 | extras_require={ # Optional 186 | 'dev': ['check-manifest'], 'test': ['coverage'], 187 | }, 188 | 189 | # If there are data files included in your packages that need to be 190 | # installed, specify them here. 191 | # 192 | # If using Python 2.6 or earlier, then these have to be included in 193 | # MANIFEST.in as well. 194 | package_data={ # Optional 195 | # 'sample': ['package_data.dat'], 196 | }, 197 | 198 | # Although 'package_data' is the preferred approach, in some case you may 199 | # need to place data files outside of your packages. See: 200 | # http://docs.python.org/3.4/distutils/setupscript.html#installing 201 | # -additional-files 202 | # 203 | # In this case, 'data_file' will be installed into '/my_data' 204 | # data_files=[('my_data', ['data/data_file'])], # Optional 205 | 206 | # To provide executable scripts, use entry points in preference to the 207 | # "scripts" keyword. Entry points provide cross-platform support and allow 208 | # `pip` to create the appropriate form of executable for the target 209 | # platform. 210 | # 211 | # For example, the following would provide a command called `sample` which 212 | # executes the function `main` from this package when invoked: 213 | entry_points={ # Optional 214 | 'console_scripts': ['HHL4x4=hhl4x4.4x4:main', 215 | 'HHL4x4_parameter_optimize=hhl4x4.optimise_parameters:main'], 216 | }, 217 | 218 | # List additional URLs that are relevant to your project as a dict. 219 | # 220 | # This field corresponds to the "Project-URL" metadata fields: 221 | # https://packaging.python.org/specifications/core-metadata/#project-url 222 | # -multiple-use 223 | # 224 | # Examples listed include a pattern for specifying where the package tracks 225 | # issues, where the source is hosted, where to say thanks to the package 226 | # maintainers, and where to support the project financially. The key is 227 | # what's used to render the link text on PyPI. 228 | project_urls={ # Optional 229 | 'Bug Reports' : 'https://github.com/nelimee/quantum-hhl-4x4/issues', 230 | 'Source' : 'https://github.com/nelimee/quantum-hhl-4x4', 231 | 'Collaborator': 'https://cerfacs.fr/en' 232 | }, ) 233 | -------------------------------------------------------------------------------- /hhl4x4/4x4.qasm: -------------------------------------------------------------------------------- 1 | OPENQASM 2.0; 2 | include "qelib1.inc"; 3 | qreg q0[1]; 4 | qreg q1[4]; 5 | qreg q2[2]; 6 | creg c0[1]; 7 | // [4x4] Initialising b. 8 | h q2[0]; 9 | h q2[1]; 10 | // [4x4] Initialisation done! 11 | // [4x4] 1. Quantum phase estimation. 12 | // [QPE] Starting block. 13 | // [QPE] 1. Hadamard gate. 14 | h q1[0]; 15 | h q1[1]; 16 | h q1[2]; 17 | h q1[3]; 18 | // [QPE] 2. Phase estimation. 19 | // [QPE] 2.0. Start of step 0 of phase estimation. 20 | // [HS] Start. 21 | // CCZ 22 | h q2[1]; 23 | ccx q1[3],q2[0],q2[1]; 24 | h q2[1]; 25 | // c-RX 26 | cu3(0.196349530000000,pi/2,3*pi/2) q1[3],q2[1]; 27 | // c-RZZ 28 | cu1(pi) q1[3],q2[1]; 29 | cx q1[3],q2[1]; 30 | cu1(pi) q1[3],q2[1]; 31 | cx q1[3],q2[1]; 32 | h q2[1]; 33 | t q2[1]; 34 | cx q1[3],q2[1]; 35 | t q1[3]; 36 | tdg q2[1]; 37 | h q2[1]; 38 | cz q1[3],q2[1]; 39 | cx q1[3],q2[1]; 40 | // c-sqrt(X) 41 | // c-RZZ 42 | cu1(0.379009870000000) q1[3],q2[1]; 43 | cx q1[3],q2[1]; 44 | cu1(0.379009870000000) q1[3],q2[1]; 45 | cx q1[3],q2[1]; 46 | // c-RX 47 | cu3(0.981747700000000,pi/2,3*pi/2) q1[3],q2[0]; 48 | // c-RZZ 49 | cu1(pi) q1[3],q2[0]; 50 | cx q1[3],q2[0]; 51 | cu1(pi) q1[3],q2[0]; 52 | cx q1[3],q2[0]; 53 | // c-RZZ 54 | cu1(1.87900984000000) q1[3],q2[0]; 55 | cx q1[3],q2[0]; 56 | cu1(1.87900984000000) q1[3],q2[0]; 57 | cx q1[3],q2[0]; 58 | ccx q1[3],q2[0],q2[1]; 59 | // c-RX 60 | cu3(0.589048620000000,pi/2,3*pi/2) q1[3],q2[0]; 61 | // c-RZZ 62 | cu1(pi) q1[3],q2[0]; 63 | cx q1[3],q2[0]; 64 | cu1(pi) q1[3],q2[0]; 65 | cx q1[3],q2[0]; 66 | ccx q1[3],q2[0],q2[1]; 67 | // CCZ 68 | h q2[1]; 69 | ccx q1[3],q2[0],q2[1]; 70 | h q2[1]; 71 | // [HS] End. 72 | // [QPE] 2.0. End of step 0 of phase estimation. 73 | // [QPE] 2.1. Start of step 1 of phase estimation. 74 | // [HS] Start. 75 | // CCZ 76 | h q2[1]; 77 | ccx q1[2],q2[0],q2[1]; 78 | h q2[1]; 79 | // c-RX 80 | cu3(1.96349540000000,pi/2,3*pi/2) q1[2],q2[1]; 81 | // c-RZZ 82 | cu1(pi) q1[2],q2[1]; 83 | cx q1[2],q2[1]; 84 | cu1(pi) q1[2],q2[1]; 85 | cx q1[2],q2[1]; 86 | h q2[1]; 87 | t q2[1]; 88 | cx q1[2],q2[1]; 89 | t q1[2]; 90 | tdg q2[1]; 91 | h q2[1]; 92 | cz q1[2],q2[1]; 93 | cx q1[2],q2[1]; 94 | // c-sqrt(X) 95 | // c-RZZ 96 | cu1(1.11532058000000) q1[2],q2[1]; 97 | cx q1[2],q2[1]; 98 | cu1(1.11532058000000) q1[2],q2[1]; 99 | cx q1[2],q2[1]; 100 | // c-RX 101 | cu3(1.96349540000000,pi/2,3*pi/2) q1[2],q2[0]; 102 | // c-RZZ 103 | cu1(pi) q1[2],q2[0]; 104 | cx q1[2],q2[0]; 105 | cu1(pi) q1[2],q2[0]; 106 | cx q1[2],q2[0]; 107 | // c-RZZ 108 | cu1(2.61532069000000) q1[2],q2[0]; 109 | cx q1[2],q2[0]; 110 | cu1(2.61532069000000) q1[2],q2[0]; 111 | cx q1[2],q2[0]; 112 | ccx q1[2],q2[0],q2[1]; 113 | // c-RX 114 | cu3(1.17809726000000,pi/2,3*pi/2) q1[2],q2[0]; 115 | // c-RZZ 116 | cu1(pi) q1[2],q2[0]; 117 | cx q1[2],q2[0]; 118 | cu1(pi) q1[2],q2[0]; 119 | cx q1[2],q2[0]; 120 | ccx q1[2],q2[0],q2[1]; 121 | // CCZ 122 | h q2[1]; 123 | ccx q1[2],q2[0],q2[1]; 124 | h q2[1]; 125 | // [HS] End. 126 | // [QPE] 2.1. End of step 1 of phase estimation. 127 | // [QPE] 2.2. Start of step 2 of phase estimation. 128 | // [HS] Start. 129 | // CCZ 130 | h q2[1]; 131 | ccx q1[1],q2[0],q2[1]; 132 | h q2[1]; 133 | // c-RX 134 | cu3(-0.785398160000000,pi/2,3*pi/2) q1[1],q2[1]; 135 | // c-RZZ 136 | cu1(pi) q1[1],q2[1]; 137 | cx q1[1],q2[1]; 138 | cu1(pi) q1[1],q2[1]; 139 | cx q1[1],q2[1]; 140 | h q2[1]; 141 | t q2[1]; 142 | cx q1[1],q2[1]; 143 | t q1[1]; 144 | tdg q2[1]; 145 | h q2[1]; 146 | cz q1[1],q2[1]; 147 | cx q1[1],q2[1]; 148 | // c-sqrt(X) 149 | // c-RZZ 150 | cu1(1.01714584000000) q1[1],q2[1]; 151 | cx q1[1],q2[1]; 152 | cu1(1.01714584000000) q1[1],q2[1]; 153 | cx q1[1],q2[1]; 154 | // c-RX 155 | cu3(3.92699082000000,pi/2,3*pi/2) q1[1],q2[0]; 156 | // c-RZZ 157 | cu1(pi) q1[1],q2[0]; 158 | cx q1[1],q2[0]; 159 | cu1(pi) q1[1],q2[0]; 160 | cx q1[1],q2[0]; 161 | // c-RZZ 162 | cu1(2.51714589000000) q1[1],q2[0]; 163 | cx q1[1],q2[0]; 164 | cu1(2.51714589000000) q1[1],q2[0]; 165 | cx q1[1],q2[0]; 166 | ccx q1[1],q2[0],q2[1]; 167 | // c-RX 168 | cu3(2.35619449000000,pi/2,3*pi/2) q1[1],q2[0]; 169 | // c-RZZ 170 | cu1(pi) q1[1],q2[0]; 171 | cx q1[1],q2[0]; 172 | cu1(pi) q1[1],q2[0]; 173 | cx q1[1],q2[0]; 174 | ccx q1[1],q2[0],q2[1]; 175 | // CCZ 176 | h q2[1]; 177 | ccx q1[1],q2[0],q2[1]; 178 | h q2[1]; 179 | // [HS] End. 180 | // [QPE] 2.2. End of step 2 of phase estimation. 181 | // [QPE] 2.3. Start of step 3 of phase estimation. 182 | // [HS] Start. 183 | // CCZ 184 | h q2[1]; 185 | ccx q1[0],q2[0],q2[1]; 186 | h q2[1]; 187 | // c-RX 188 | cu3(-9.01416169000000e-9,pi/2,3*pi/2) q1[0],q2[1]; 189 | // c-RZZ 190 | cu1(pi) q1[0],q2[1]; 191 | cx q1[0],q2[1]; 192 | cu1(pi) q1[0],q2[1]; 193 | cx q1[0],q2[1]; 194 | h q2[1]; 195 | t q2[1]; 196 | cx q1[0],q2[1]; 197 | t q1[0]; 198 | tdg q2[1]; 199 | h q2[1]; 200 | cz q1[0],q2[1]; 201 | cx q1[0],q2[1]; 202 | // c-sqrt(X) 203 | // c-RZZ 204 | cu1(-0.750000046000000) q1[0],q2[1]; 205 | cx q1[0],q2[1]; 206 | cu1(-0.750000046000000) q1[0],q2[1]; 207 | cx q1[0],q2[1]; 208 | // c-RX 209 | cu3(1.57079632000000,pi/2,3*pi/2) q1[0],q2[0]; 210 | // c-RZZ 211 | cu1(pi) q1[0],q2[0]; 212 | cx q1[0],q2[0]; 213 | cu1(pi) q1[0],q2[0]; 214 | cx q1[0],q2[0]; 215 | // c-RZZ 216 | cu1(0.750000039000000) q1[0],q2[0]; 217 | cx q1[0],q2[0]; 218 | cu1(0.750000039000000) q1[0],q2[0]; 219 | cx q1[0],q2[0]; 220 | ccx q1[0],q2[0],q2[1]; 221 | // c-RX 222 | cu3(-1.57079633000000,pi/2,3*pi/2) q1[0],q2[0]; 223 | // c-RZZ 224 | cu1(pi) q1[0],q2[0]; 225 | cx q1[0],q2[0]; 226 | cu1(pi) q1[0],q2[0]; 227 | cx q1[0],q2[0]; 228 | ccx q1[0],q2[0],q2[1]; 229 | // CCZ 230 | h q2[1]; 231 | ccx q1[0],q2[0],q2[1]; 232 | h q2[1]; 233 | // [HS] End. 234 | // [QPE] 2.3. End of step 3 of phase estimation. 235 | // [QPE] 3. Inverse QFT. 236 | h q1[0]; 237 | cu1(-pi/2) q1[0],q1[1]; 238 | cu1(-pi/4) q1[0],q1[2]; 239 | cu1(-pi/8) q1[0],q1[3]; 240 | h q1[1]; 241 | cu1(-pi/2) q1[1],q1[2]; 242 | cu1(-pi/4) q1[1],q1[3]; 243 | h q1[2]; 244 | cu1(-pi/2) q1[2],q1[3]; 245 | h q1[3]; 246 | // [QPE] End block. 247 | // [4x4] Inverting computed eigenvalues. 248 | swap q1[2],q1[1]; 249 | // [4x4] 2. Phase rotation. 250 | // CRY 251 | cu3(0.25*pi,0,0) q1[0],q0[0]; 252 | // CRY 253 | cu3(0.125*pi,0,0) q1[1],q0[0]; 254 | // CRY 255 | cu3(0.0625*pi,0,0) q1[2],q0[0]; 256 | // CRY 257 | cu3(0.03125*pi,0,0) q1[3],q0[0]; 258 | // Inverting the inversion of eigenvalues. 259 | swap q1[2],q1[1]; 260 | // [4x4] 3. Inverting quantum phase estimation. 261 | // [QPE] End block. 262 | h q1[3]; 263 | cu1(pi/2) q1[2],q1[3]; 264 | h q1[2]; 265 | cu1(pi/4) q1[1],q1[3]; 266 | cu1(pi/2) q1[1],q1[2]; 267 | h q1[1]; 268 | cu1(pi/8) q1[0],q1[3]; 269 | cu1(pi/4) q1[0],q1[2]; 270 | cu1(pi/2) q1[0],q1[1]; 271 | h q1[0]; 272 | // [QPE] 3. Inverse QFT. 273 | // [QPE] 2.3. End of step 3 of phase estimation. 274 | // [HS] End. 275 | h q2[1]; 276 | ccx q1[0],q2[0],q2[1]; 277 | h q2[1]; 278 | // CCZ 279 | ccx q1[0],q2[0],q2[1]; 280 | cx q1[0],q2[0]; 281 | cu1(-pi) q1[0],q2[0]; 282 | cx q1[0],q2[0]; 283 | cu1(-pi) q1[0],q2[0]; 284 | // c-RZZ 285 | cu3(1.57079633000000,-3*pi/2,-pi/2) q1[0],q2[0]; 286 | // c-RX 287 | ccx q1[0],q2[0],q2[1]; 288 | cx q1[0],q2[0]; 289 | cu1(-0.750000039000000) q1[0],q2[0]; 290 | cx q1[0],q2[0]; 291 | cu1(-0.750000039000000) q1[0],q2[0]; 292 | // c-RZZ 293 | cx q1[0],q2[0]; 294 | cu1(-pi) q1[0],q2[0]; 295 | cx q1[0],q2[0]; 296 | cu1(-pi) q1[0],q2[0]; 297 | // c-RZZ 298 | cu3(-1.57079632000000,-3*pi/2,-pi/2) q1[0],q2[0]; 299 | // c-RX 300 | cx q1[0],q2[1]; 301 | cu1(0.750000046000000) q1[0],q2[1]; 302 | cx q1[0],q2[1]; 303 | cu1(0.750000046000000) q1[0],q2[1]; 304 | // c-RZZ 305 | // c-sqrt(X) 306 | cx q1[0],q2[1]; 307 | cz q1[0],q2[1]; 308 | h q2[1]; 309 | t q2[1]; 310 | tdg q1[0]; 311 | cx q1[0],q2[1]; 312 | tdg q2[1]; 313 | h q2[1]; 314 | cx q1[0],q2[1]; 315 | cu1(-pi) q1[0],q2[1]; 316 | cx q1[0],q2[1]; 317 | cu1(-pi) q1[0],q2[1]; 318 | // c-RZZ 319 | cu3(9.01416169000000e-9,-3*pi/2,-pi/2) q1[0],q2[1]; 320 | // c-RX 321 | h q2[1]; 322 | ccx q1[0],q2[0],q2[1]; 323 | h q2[1]; 324 | // CCZ 325 | // [HS] Start. 326 | // [QPE] 2.3. Start of step 3 of phase estimation. 327 | // [QPE] 2.2. End of step 2 of phase estimation. 328 | // [HS] End. 329 | h q2[1]; 330 | ccx q1[1],q2[0],q2[1]; 331 | h q2[1]; 332 | // CCZ 333 | ccx q1[1],q2[0],q2[1]; 334 | cx q1[1],q2[0]; 335 | cu1(-pi) q1[1],q2[0]; 336 | cx q1[1],q2[0]; 337 | cu1(-pi) q1[1],q2[0]; 338 | // c-RZZ 339 | cu3(-2.35619449000000,-3*pi/2,-pi/2) q1[1],q2[0]; 340 | // c-RX 341 | ccx q1[1],q2[0],q2[1]; 342 | cx q1[1],q2[0]; 343 | cu1(-2.51714589000000) q1[1],q2[0]; 344 | cx q1[1],q2[0]; 345 | cu1(-2.51714589000000) q1[1],q2[0]; 346 | // c-RZZ 347 | cx q1[1],q2[0]; 348 | cu1(-pi) q1[1],q2[0]; 349 | cx q1[1],q2[0]; 350 | cu1(-pi) q1[1],q2[0]; 351 | // c-RZZ 352 | cu3(-3.92699082000000,-3*pi/2,-pi/2) q1[1],q2[0]; 353 | // c-RX 354 | cx q1[1],q2[1]; 355 | cu1(-1.01714584000000) q1[1],q2[1]; 356 | cx q1[1],q2[1]; 357 | cu1(-1.01714584000000) q1[1],q2[1]; 358 | // c-RZZ 359 | // c-sqrt(X) 360 | cx q1[1],q2[1]; 361 | cz q1[1],q2[1]; 362 | h q2[1]; 363 | t q2[1]; 364 | tdg q1[1]; 365 | cx q1[1],q2[1]; 366 | tdg q2[1]; 367 | h q2[1]; 368 | cx q1[1],q2[1]; 369 | cu1(-pi) q1[1],q2[1]; 370 | cx q1[1],q2[1]; 371 | cu1(-pi) q1[1],q2[1]; 372 | // c-RZZ 373 | cu3(0.785398160000000,-3*pi/2,-pi/2) q1[1],q2[1]; 374 | // c-RX 375 | h q2[1]; 376 | ccx q1[1],q2[0],q2[1]; 377 | h q2[1]; 378 | // CCZ 379 | // [HS] Start. 380 | // [QPE] 2.2. Start of step 2 of phase estimation. 381 | // [QPE] 2.1. End of step 1 of phase estimation. 382 | // [HS] End. 383 | h q2[1]; 384 | ccx q1[2],q2[0],q2[1]; 385 | h q2[1]; 386 | // CCZ 387 | ccx q1[2],q2[0],q2[1]; 388 | cx q1[2],q2[0]; 389 | cu1(-pi) q1[2],q2[0]; 390 | cx q1[2],q2[0]; 391 | cu1(-pi) q1[2],q2[0]; 392 | // c-RZZ 393 | cu3(-1.17809726000000,-3*pi/2,-pi/2) q1[2],q2[0]; 394 | // c-RX 395 | ccx q1[2],q2[0],q2[1]; 396 | cx q1[2],q2[0]; 397 | cu1(-2.61532069000000) q1[2],q2[0]; 398 | cx q1[2],q2[0]; 399 | cu1(-2.61532069000000) q1[2],q2[0]; 400 | // c-RZZ 401 | cx q1[2],q2[0]; 402 | cu1(-pi) q1[2],q2[0]; 403 | cx q1[2],q2[0]; 404 | cu1(-pi) q1[2],q2[0]; 405 | // c-RZZ 406 | cu3(-1.96349540000000,-3*pi/2,-pi/2) q1[2],q2[0]; 407 | // c-RX 408 | cx q1[2],q2[1]; 409 | cu1(-1.11532058000000) q1[2],q2[1]; 410 | cx q1[2],q2[1]; 411 | cu1(-1.11532058000000) q1[2],q2[1]; 412 | // c-RZZ 413 | // c-sqrt(X) 414 | cx q1[2],q2[1]; 415 | cz q1[2],q2[1]; 416 | h q2[1]; 417 | t q2[1]; 418 | tdg q1[2]; 419 | cx q1[2],q2[1]; 420 | tdg q2[1]; 421 | h q2[1]; 422 | cx q1[2],q2[1]; 423 | cu1(-pi) q1[2],q2[1]; 424 | cx q1[2],q2[1]; 425 | cu1(-pi) q1[2],q2[1]; 426 | // c-RZZ 427 | cu3(-1.96349540000000,-3*pi/2,-pi/2) q1[2],q2[1]; 428 | // c-RX 429 | h q2[1]; 430 | ccx q1[2],q2[0],q2[1]; 431 | h q2[1]; 432 | // CCZ 433 | // [HS] Start. 434 | // [QPE] 2.1. Start of step 1 of phase estimation. 435 | // [QPE] 2.0. End of step 0 of phase estimation. 436 | // [HS] End. 437 | h q2[1]; 438 | ccx q1[3],q2[0],q2[1]; 439 | h q2[1]; 440 | // CCZ 441 | ccx q1[3],q2[0],q2[1]; 442 | cx q1[3],q2[0]; 443 | cu1(-pi) q1[3],q2[0]; 444 | cx q1[3],q2[0]; 445 | cu1(-pi) q1[3],q2[0]; 446 | // c-RZZ 447 | cu3(-0.589048620000000,-3*pi/2,-pi/2) q1[3],q2[0]; 448 | // c-RX 449 | ccx q1[3],q2[0],q2[1]; 450 | cx q1[3],q2[0]; 451 | cu1(-1.87900984000000) q1[3],q2[0]; 452 | cx q1[3],q2[0]; 453 | cu1(-1.87900984000000) q1[3],q2[0]; 454 | // c-RZZ 455 | cx q1[3],q2[0]; 456 | cu1(-pi) q1[3],q2[0]; 457 | cx q1[3],q2[0]; 458 | cu1(-pi) q1[3],q2[0]; 459 | // c-RZZ 460 | cu3(-0.981747700000000,-3*pi/2,-pi/2) q1[3],q2[0]; 461 | // c-RX 462 | cx q1[3],q2[1]; 463 | cu1(-0.379009870000000) q1[3],q2[1]; 464 | cx q1[3],q2[1]; 465 | cu1(-0.379009870000000) q1[3],q2[1]; 466 | // c-RZZ 467 | // c-sqrt(X) 468 | cx q1[3],q2[1]; 469 | cz q1[3],q2[1]; 470 | h q2[1]; 471 | t q2[1]; 472 | tdg q1[3]; 473 | cx q1[3],q2[1]; 474 | tdg q2[1]; 475 | h q2[1]; 476 | cx q1[3],q2[1]; 477 | cu1(-pi) q1[3],q2[1]; 478 | cx q1[3],q2[1]; 479 | cu1(-pi) q1[3],q2[1]; 480 | // c-RZZ 481 | cu3(-0.196349530000000,-3*pi/2,-pi/2) q1[3],q2[1]; 482 | // c-RX 483 | h q2[1]; 484 | ccx q1[3],q2[0],q2[1]; 485 | h q2[1]; 486 | // CCZ 487 | // [HS] Start. 488 | // [QPE] 2.0. Start of step 0 of phase estimation. 489 | // [QPE] 2. Phase estimation. 490 | h q1[3]; 491 | h q1[2]; 492 | h q1[1]; 493 | h q1[0]; 494 | // [QPE] 1. Hadamard gate. 495 | // [QPE] Starting block. 496 | // [4x4] 4. Measurement. 497 | measure q0[0] -> c0[0]; 498 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | CeCILL-B FREE SOFTWARE LICENSE AGREEMENT 3 | 4 | 5 | Notice 6 | 7 | This Agreement is a Free Software license agreement that is the result 8 | of discussions between its authors in order to ensure compliance with 9 | the two main principles guiding its drafting: 10 | 11 | * firstly, compliance with the principles governing the distribution 12 | of Free Software: access to source code, broad rights granted to 13 | users, 14 | * secondly, the election of a governing law, French law, with which 15 | it is conformant, both as regards the law of torts and 16 | intellectual property law, and the protection that it offers to 17 | both authors and holders of the economic rights over software. 18 | 19 | The authors of the CeCILL-B (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) 20 | license are: 21 | 22 | Commissariat à l'Energie Atomique - CEA, a public scientific, technical 23 | and industrial research establishment, having its principal place of 24 | business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France. 25 | 26 | Centre National de la Recherche Scientifique - CNRS, a public scientific 27 | and technological establishment, having its principal place of business 28 | at 3 rue Michel-Ange, 75794 Paris cedex 16, France. 29 | 30 | Institut National de Recherche en Informatique et en Automatique - 31 | INRIA, a public scientific and technological establishment, having its 32 | principal place of business at Domaine de Voluceau, Rocquencourt, BP 33 | 105, 78153 Le Chesnay cedex, France. 34 | 35 | 36 | Preamble 37 | 38 | This Agreement is an open source software license intended to give users 39 | significant freedom to modify and redistribute the software licensed 40 | hereunder. 41 | 42 | The exercising of this freedom is conditional upon a strong obligation 43 | of giving credits for everybody that distributes a software 44 | incorporating a software ruled by the current license so as all 45 | contributions to be properly identified and acknowledged. 46 | 47 | In consideration of access to the source code and the rights to copy, 48 | modify and redistribute granted by the license, users are provided only 49 | with a limited warranty and the software's author, the holder of the 50 | economic rights, and the successive licensors only have limited liability. 51 | 52 | In this respect, the risks associated with loading, using, modifying 53 | and/or developing or reproducing the software by the user are brought to 54 | the user's attention, given its Free Software status, which may make it 55 | complicated to use, with the result that its use is reserved for 56 | developers and experienced professionals having in-depth computer 57 | knowledge. Users are therefore encouraged to load and test the 58 | suitability of the software as regards their requirements in conditions 59 | enabling the security of their systems and/or data to be ensured and, 60 | more generally, to use and operate it in the same conditions of 61 | security. This Agreement may be freely reproduced and published, 62 | provided it is not altered, and that no provisions are either added or 63 | removed herefrom. 64 | 65 | This Agreement may apply to any or all software for which the holder of 66 | the economic rights decides to submit the use thereof to its provisions. 67 | 68 | 69 | Article 1 - DEFINITIONS 70 | 71 | For the purpose of this Agreement, when the following expressions 72 | commence with a capital letter, they shall have the following meaning: 73 | 74 | Agreement: means this license agreement, and its possible subsequent 75 | versions and annexes. 76 | 77 | Software: means the software in its Object Code and/or Source Code form 78 | and, where applicable, its documentation, "as is" when the Licensee 79 | accepts the Agreement. 80 | 81 | Initial Software: means the Software in its Source Code and possibly its 82 | Object Code form and, where applicable, its documentation, "as is" when 83 | it is first distributed under the terms and conditions of the Agreement. 84 | 85 | Modified Software: means the Software modified by at least one 86 | Contribution. 87 | 88 | Source Code: means all the Software's instructions and program lines to 89 | which access is required so as to modify the Software. 90 | 91 | Object Code: means the binary files originating from the compilation of 92 | the Source Code. 93 | 94 | Holder: means the holder(s) of the economic rights over the Initial 95 | Software. 96 | 97 | Licensee: means the Software user(s) having accepted the Agreement. 98 | 99 | Contributor: means a Licensee having made at least one Contribution. 100 | 101 | Licensor: means the Holder, or any other individual or legal entity, who 102 | distributes the Software under the Agreement. 103 | 104 | Contribution: means any or all modifications, corrections, translations, 105 | adaptations and/or new functions integrated into the Software by any or 106 | all Contributors, as well as any or all Internal Modules. 107 | 108 | Module: means a set of sources files including their documentation that 109 | enables supplementary functions or services in addition to those offered 110 | by the Software. 111 | 112 | External Module: means any or all Modules, not derived from the 113 | Software, so that this Module and the Software run in separate address 114 | spaces, with one calling the other when they are run. 115 | 116 | Internal Module: means any or all Module, connected to the Software so 117 | that they both execute in the same address space. 118 | 119 | Parties: mean both the Licensee and the Licensor. 120 | 121 | These expressions may be used both in singular and plural form. 122 | 123 | 124 | Article 2 - PURPOSE 125 | 126 | The purpose of the Agreement is the grant by the Licensor to the 127 | Licensee of a non-exclusive, transferable and worldwide license for the 128 | Software as set forth in Article 5 hereinafter for the whole term of the 129 | protection granted by the rights over said Software. 130 | 131 | 132 | Article 3 - ACCEPTANCE 133 | 134 | 3.1 The Licensee shall be deemed as having accepted the terms and 135 | conditions of this Agreement upon the occurrence of the first of the 136 | following events: 137 | 138 | * (i) loading the Software by any or all means, notably, by 139 | downloading from a remote server, or by loading from a physical 140 | medium; 141 | * (ii) the first time the Licensee exercises any of the rights 142 | granted hereunder. 143 | 144 | 3.2 One copy of the Agreement, containing a notice relating to the 145 | characteristics of the Software, to the limited warranty, and to the 146 | fact that its use is restricted to experienced users has been provided 147 | to the Licensee prior to its acceptance as set forth in Article 3.1 148 | hereinabove, and the Licensee hereby acknowledges that it has read and 149 | understood it. 150 | 151 | 152 | Article 4 - EFFECTIVE DATE AND TERM 153 | 154 | 155 | 4.1 EFFECTIVE DATE 156 | 157 | The Agreement shall become effective on the date when it is accepted by 158 | the Licensee as set forth in Article 3.1. 159 | 160 | 161 | 4.2 TERM 162 | 163 | The Agreement shall remain in force for the entire legal term of 164 | protection of the economic rights over the Software. 165 | 166 | 167 | Article 5 - SCOPE OF RIGHTS GRANTED 168 | 169 | The Licensor hereby grants to the Licensee, who accepts, the following 170 | rights over the Software for any or all use, and for the term of the 171 | Agreement, on the basis of the terms and conditions set forth hereinafter. 172 | 173 | Besides, if the Licensor owns or comes to own one or more patents 174 | protecting all or part of the functions of the Software or of its 175 | components, the Licensor undertakes not to enforce the rights granted by 176 | these patents against successive Licensees using, exploiting or 177 | modifying the Software. If these patents are transferred, the Licensor 178 | undertakes to have the transferees subscribe to the obligations set 179 | forth in this paragraph. 180 | 181 | 182 | 5.1 RIGHT OF USE 183 | 184 | The Licensee is authorized to use the Software, without any limitation 185 | as to its fields of application, with it being hereinafter specified 186 | that this comprises: 187 | 188 | 1. permanent or temporary reproduction of all or part of the Software 189 | by any or all means and in any or all form. 190 | 191 | 2. loading, displaying, running, or storing the Software on any or 192 | all medium. 193 | 194 | 3. entitlement to observe, study or test its operation so as to 195 | determine the ideas and principles behind any or all constituent 196 | elements of said Software. This shall apply when the Licensee 197 | carries out any or all loading, displaying, running, transmission 198 | or storage operation as regards the Software, that it is entitled 199 | to carry out hereunder. 200 | 201 | 202 | 5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS 203 | 204 | The right to make Contributions includes the right to translate, adapt, 205 | arrange, or make any or all modifications to the Software, and the right 206 | to reproduce the resulting software. 207 | 208 | The Licensee is authorized to make any or all Contributions to the 209 | Software provided that it includes an explicit notice that it is the 210 | author of said Contribution and indicates the date of the creation thereof. 211 | 212 | 213 | 5.3 RIGHT OF DISTRIBUTION 214 | 215 | In particular, the right of distribution includes the right to publish, 216 | transmit and communicate the Software to the general public on any or 217 | all medium, and by any or all means, and the right to market, either in 218 | consideration of a fee, or free of charge, one or more copies of the 219 | Software by any means. 220 | 221 | The Licensee is further authorized to distribute copies of the modified 222 | or unmodified Software to third parties according to the terms and 223 | conditions set forth hereinafter. 224 | 225 | 226 | 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION 227 | 228 | The Licensee is authorized to distribute true copies of the Software in 229 | Source Code or Object Code form, provided that said distribution 230 | complies with all the provisions of the Agreement and is accompanied by: 231 | 232 | 1. a copy of the Agreement, 233 | 234 | 2. a notice relating to the limitation of both the Licensor's 235 | warranty and liability as set forth in Articles 8 and 9, 236 | 237 | and that, in the event that only the Object Code of the Software is 238 | redistributed, the Licensee allows effective access to the full Source 239 | Code of the Software at a minimum during the entire period of its 240 | distribution of the Software, it being understood that the additional 241 | cost of acquiring the Source Code shall not exceed the cost of 242 | transferring the data. 243 | 244 | 245 | 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE 246 | 247 | If the Licensee makes any Contribution to the Software, the resulting 248 | Modified Software may be distributed under a license agreement other 249 | than this Agreement subject to compliance with the provisions of Article 250 | 5.3.4. 251 | 252 | 253 | 5.3.3 DISTRIBUTION OF EXTERNAL MODULES 254 | 255 | When the Licensee has developed an External Module, the terms and 256 | conditions of this Agreement do not apply to said External Module, that 257 | may be distributed under a separate license agreement. 258 | 259 | 260 | 5.3.4 CREDITS 261 | 262 | Any Licensee who may distribute a Modified Software hereby expressly 263 | agrees to: 264 | 265 | 1. indicate in the related documentation that it is based on the 266 | Software licensed hereunder, and reproduce the intellectual 267 | property notice for the Software, 268 | 269 | 2. ensure that written indications of the Software intended use, 270 | intellectual property notice and license hereunder are included in 271 | easily accessible format from the Modified Software interface, 272 | 273 | 3. mention, on a freely accessible website describing the Modified 274 | Software, at least throughout the distribution term thereof, that 275 | it is based on the Software licensed hereunder, and reproduce the 276 | Software intellectual property notice, 277 | 278 | 4. where it is distributed to a third party that may distribute a 279 | Modified Software without having to make its source code 280 | available, make its best efforts to ensure that said third party 281 | agrees to comply with the obligations set forth in this Article . 282 | 283 | If the Software, whether or not modified, is distributed with an 284 | External Module designed for use in connection with the Software, the 285 | Licensee shall submit said External Module to the foregoing obligations. 286 | 287 | 288 | 5.3.5 COMPATIBILITY WITH THE CeCILL AND CeCILL-C LICENSES 289 | 290 | Where a Modified Software contains a Contribution subject to the CeCILL 291 | license, the provisions set forth in Article 5.3.4 shall be optional. 292 | 293 | A Modified Software may be distributed under the CeCILL-C license. In 294 | such a case the provisions set forth in Article 5.3.4 shall be optional. 295 | 296 | 297 | Article 6 - INTELLECTUAL PROPERTY 298 | 299 | 300 | 6.1 OVER THE INITIAL SOFTWARE 301 | 302 | The Holder owns the economic rights over the Initial Software. Any or 303 | all use of the Initial Software is subject to compliance with the terms 304 | and conditions under which the Holder has elected to distribute its work 305 | and no one shall be entitled to modify the terms and conditions for the 306 | distribution of said Initial Software. 307 | 308 | The Holder undertakes that the Initial Software will remain ruled at 309 | least by this Agreement, for the duration set forth in Article 4.2. 310 | 311 | 312 | 6.2 OVER THE CONTRIBUTIONS 313 | 314 | The Licensee who develops a Contribution is the owner of the 315 | intellectual property rights over this Contribution as defined by 316 | applicable law. 317 | 318 | 319 | 6.3 OVER THE EXTERNAL MODULES 320 | 321 | The Licensee who develops an External Module is the owner of the 322 | intellectual property rights over this External Module as defined by 323 | applicable law and is free to choose the type of agreement that shall 324 | govern its distribution. 325 | 326 | 327 | 6.4 JOINT PROVISIONS 328 | 329 | The Licensee expressly undertakes: 330 | 331 | 1. not to remove, or modify, in any manner, the intellectual property 332 | notices attached to the Software; 333 | 334 | 2. to reproduce said notices, in an identical manner, in the copies 335 | of the Software modified or not. 336 | 337 | The Licensee undertakes not to directly or indirectly infringe the 338 | intellectual property rights of the Holder and/or Contributors on the 339 | Software and to take, where applicable, vis-à-vis its staff, any and all 340 | measures required to ensure respect of said intellectual property rights 341 | of the Holder and/or Contributors. 342 | 343 | 344 | Article 7 - RELATED SERVICES 345 | 346 | 7.1 Under no circumstances shall the Agreement oblige the Licensor to 347 | provide technical assistance or maintenance services for the Software. 348 | 349 | However, the Licensor is entitled to offer this type of services. The 350 | terms and conditions of such technical assistance, and/or such 351 | maintenance, shall be set forth in a separate instrument. Only the 352 | Licensor offering said maintenance and/or technical assistance services 353 | shall incur liability therefor. 354 | 355 | 7.2 Similarly, any Licensor is entitled to offer to its licensees, under 356 | its sole responsibility, a warranty, that shall only be binding upon 357 | itself, for the redistribution of the Software and/or the Modified 358 | Software, under terms and conditions that it is free to decide. Said 359 | warranty, and the financial terms and conditions of its application, 360 | shall be subject of a separate instrument executed between the Licensor 361 | and the Licensee. 362 | 363 | 364 | Article 8 - LIABILITY 365 | 366 | 8.1 Subject to the provisions of Article 8.2, the Licensee shall be 367 | entitled to claim compensation for any direct loss it may have suffered 368 | from the Software as a result of a fault on the part of the relevant 369 | Licensor, subject to providing evidence thereof. 370 | 371 | 8.2 The Licensor's liability is limited to the commitments made under 372 | this Agreement and shall not be incurred as a result of in particular: 373 | (i) loss due the Licensee's total or partial failure to fulfill its 374 | obligations, (ii) direct or consequential loss that is suffered by the 375 | Licensee due to the use or performance of the Software, and (iii) more 376 | generally, any consequential loss. In particular the Parties expressly 377 | agree that any or all pecuniary or business loss (i.e. loss of data, 378 | loss of profits, operating loss, loss of customers or orders, 379 | opportunity cost, any disturbance to business activities) or any or all 380 | legal proceedings instituted against the Licensee by a third party, 381 | shall constitute consequential loss and shall not provide entitlement to 382 | any or all compensation from the Licensor. 383 | 384 | 385 | Article 9 - WARRANTY 386 | 387 | 9.1 The Licensee acknowledges that the scientific and technical 388 | state-of-the-art when the Software was distributed did not enable all 389 | possible uses to be tested and verified, nor for the presence of 390 | possible defects to be detected. In this respect, the Licensee's 391 | attention has been drawn to the risks associated with loading, using, 392 | modifying and/or developing and reproducing the Software which are 393 | reserved for experienced users. 394 | 395 | The Licensee shall be responsible for verifying, by any or all means, 396 | the suitability of the product for its requirements, its good working 397 | order, and for ensuring that it shall not cause damage to either persons 398 | or properties. 399 | 400 | 9.2 The Licensor hereby represents, in good faith, that it is entitled 401 | to grant all the rights over the Software (including in particular the 402 | rights set forth in Article 5). 403 | 404 | 9.3 The Licensee acknowledges that the Software is supplied "as is" by 405 | the Licensor without any other express or tacit warranty, other than 406 | that provided for in Article 9.2 and, in particular, without any warranty 407 | as to its commercial value, its secured, safe, innovative or relevant 408 | nature. 409 | 410 | Specifically, the Licensor does not warrant that the Software is free 411 | from any error, that it will operate without interruption, that it will 412 | be compatible with the Licensee's own equipment and software 413 | configuration, nor that it will meet the Licensee's requirements. 414 | 415 | 9.4 The Licensor does not either expressly or tacitly warrant that the 416 | Software does not infringe any third party intellectual property right 417 | relating to a patent, software or any other property right. Therefore, 418 | the Licensor disclaims any and all liability towards the Licensee 419 | arising out of any or all proceedings for infringement that may be 420 | instituted in respect of the use, modification and redistribution of the 421 | Software. Nevertheless, should such proceedings be instituted against 422 | the Licensee, the Licensor shall provide it with technical and legal 423 | assistance for its defense. Such technical and legal assistance shall be 424 | decided on a case-by-case basis between the relevant Licensor and the 425 | Licensee pursuant to a memorandum of understanding. The Licensor 426 | disclaims any and all liability as regards the Licensee's use of the 427 | name of the Software. No warranty is given as regards the existence of 428 | prior rights over the name of the Software or as regards the existence 429 | of a trademark. 430 | 431 | 432 | Article 10 - TERMINATION 433 | 434 | 10.1 In the event of a breach by the Licensee of its obligations 435 | hereunder, the Licensor may automatically terminate this Agreement 436 | thirty (30) days after notice has been sent to the Licensee and has 437 | remained ineffective. 438 | 439 | 10.2 A Licensee whose Agreement is terminated shall no longer be 440 | authorized to use, modify or distribute the Software. However, any 441 | licenses that it may have granted prior to termination of the Agreement 442 | shall remain valid subject to their having been granted in compliance 443 | with the terms and conditions hereof. 444 | 445 | 446 | Article 11 - MISCELLANEOUS 447 | 448 | 449 | 11.1 EXCUSABLE EVENTS 450 | 451 | Neither Party shall be liable for any or all delay, or failure to 452 | perform the Agreement, that may be attributable to an event of force 453 | majeure, an act of God or an outside cause, such as defective 454 | functioning or interruptions of the electricity or telecommunications 455 | networks, network paralysis following a virus attack, intervention by 456 | government authorities, natural disasters, water damage, earthquakes, 457 | fire, explosions, strikes and labor unrest, war, etc. 458 | 459 | 11.2 Any failure by either Party, on one or more occasions, to invoke 460 | one or more of the provisions hereof, shall under no circumstances be 461 | interpreted as being a waiver by the interested Party of its right to 462 | invoke said provision(s) subsequently. 463 | 464 | 11.3 The Agreement cancels and replaces any or all previous agreements, 465 | whether written or oral, between the Parties and having the same 466 | purpose, and constitutes the entirety of the agreement between said 467 | Parties concerning said purpose. No supplement or modification to the 468 | terms and conditions hereof shall be effective as between the Parties 469 | unless it is made in writing and signed by their duly authorized 470 | representatives. 471 | 472 | 11.4 In the event that one or more of the provisions hereof were to 473 | conflict with a current or future applicable act or legislative text, 474 | said act or legislative text shall prevail, and the Parties shall make 475 | the necessary amendments so as to comply with said act or legislative 476 | text. All other provisions shall remain effective. Similarly, invalidity 477 | of a provision of the Agreement, for any reason whatsoever, shall not 478 | cause the Agreement as a whole to be invalid. 479 | 480 | 481 | 11.5 LANGUAGE 482 | 483 | The Agreement is drafted in both French and English and both versions 484 | are deemed authentic. 485 | 486 | 487 | Article 12 - NEW VERSIONS OF THE AGREEMENT 488 | 489 | 12.1 Any person is authorized to duplicate and distribute copies of this 490 | Agreement. 491 | 492 | 12.2 So as to ensure coherence, the wording of this Agreement is 493 | protected and may only be modified by the authors of the License, who 494 | reserve the right to periodically publish updates or new versions of the 495 | Agreement, each with a separate number. These subsequent versions may 496 | address new issues encountered by Free Software. 497 | 498 | 12.3 Any Software distributed under a given version of the Agreement may 499 | only be subsequently distributed under the same version of the Agreement 500 | or a subsequent version. 501 | 502 | 503 | Article 13 - GOVERNING LAW AND JURISDICTION 504 | 505 | 13.1 The Agreement is governed by French law. The Parties agree to 506 | endeavor to seek an amicable solution to any disagreements or disputes 507 | that may arise during the performance of the Agreement. 508 | 509 | 13.2 Failing an amicable solution within two (2) months as from their 510 | occurrence, and unless emergency proceedings are necessary, the 511 | disagreements or disputes shall be referred to the Paris Courts having 512 | jurisdiction, by the more diligent Party. 513 | 514 | 515 | Version 1.0 dated 2006-09-05. 516 | --------------------------------------------------------------------------------