-
Notifications
You must be signed in to change notification settings - Fork 269
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Phase Estimation as a Gate in ops (#260)
* First testing version of Phase Estimation with a lot of hardcoding * Adapt to All(Measure) * Adding operators for more than 1 quibit, first version * Adding operators for more than 1 quibit, first versioni: testing * Work in progress: create a PhaseX gate to tests via class * Work in progress: create a PhaseX gate to tests via class. Clean garbaje files * Work in progress: create a PhaseX gate to tests via class. Some enhanement * Work in progress: create a PhaseX gate to tests via class. PhaseX testing * Work in progress: Debugging algorithm * Work in progress: Debugging algorithm * Adding 2qubit example * adding 2 qubit Gate * Initial version * Create Phase Estimation as a new Gate in operations * Solving travis checks * python 2 compatibility + error in StatePreparation normalization * test coverage includes now the string * Improve the check test for no eigenvector test * Start modifying to decomposition * QPE as decomposition and gate * QPE as decomposition and gate: correct a detail in the test * try to get the travis-ci freeze solved * Solve a name not defined error in the phaseestimation tests * Solve coverage in tests * Address comments in review + change how to assert the tests * Enhance statistis in the tests bi more executions * Correct bad calculation in tests * Refine test * Address Andi comments: add detail in the examples and atributes and removing code in the test that is never executed
- Loading branch information
1 parent
6db7038
commit 3ac3c2c
Showing
8 changed files
with
357 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Copyright 2017 ProjectQ-Framework (www.projectq.ch) | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from ._basics import BasicGate | ||
|
||
|
||
class QPE(BasicGate): | ||
""" | ||
Quantum Phase Estimation gate. | ||
See setups.decompositions for the complete implementation | ||
""" | ||
def __init__(self, unitary): | ||
BasicGate.__init__(self) | ||
self.unitary = unitary | ||
|
||
def __str__(self): | ||
return 'QPE({})'.format(str(self.unitary)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Copyright 2017 ProjectQ-Framework (www.projectq.ch) | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""Tests for projectq.ops._qpegate.""" | ||
|
||
from projectq.ops import _qpegate, X | ||
|
||
|
||
def test_qpe_str(): | ||
unitary = X | ||
gate = _qpegate.QPE(unitary) | ||
assert str(gate) == "QPE(X)" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
# Copyright 2018 ProjectQ-Framework (www.projectq.ch) | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
""" | ||
Registers a decomposition for phase estimation. | ||
(reference https://en.wikipedia.org/wiki/Quantum_phase_estimation_algorithm) | ||
The Quantum Phase Estimation (QPE) executes the algorithm up to the inverse | ||
QFT included. The following steps measuring the ancillas and computing the | ||
phase should be executed outside of the QPE. | ||
The decomposition uses as ancillas (qpe_ancillas) the first qubit/qureg in | ||
the Command and as system qubits teh second qubit/qureg in the Command. | ||
The unitary operator for which the phase estimation is estimated (unitary) | ||
is the gate in Command | ||
Example: | ||
.. code-block:: python | ||
# Example using a ProjectQ gate | ||
n_qpe_ancillas = 3 | ||
qpe_ancillas = eng.allocate_qureg(n_qpe_ancillas) | ||
system_qubits = eng.allocate_qureg(1) | ||
angle = cmath.pi*2.*0.125 | ||
U = Ph(angle) # unitary_specfic_to_the_problem() | ||
# Apply Quantum Phase Estimation | ||
QPE(U) | (qpe_ancillas, system_qubits) | ||
All(Measure) | qpe_ancillas | ||
# Compute the phase from the ancilla measurement | ||
#(https://en.wikipedia.org/wiki/Quantum_phase_estimation_algorithm) | ||
phasebinlist = [int(q) for q in qpe_ancillas] | ||
phase_in_bin = ''.join(str(j) for j in phasebinlist) | ||
phase_int = int(phase_in_bin,2) | ||
phase = phase_int / (2 ** n_qpe_ancillas) | ||
print (phase) | ||
# Example using a function (two_qubit_gate). | ||
# Instead of applying QPE on a gate U one could provide a function | ||
def two_qubit_gate(system_q, time): | ||
CNOT | (system_q[0], system_q[1]) | ||
Ph(2.0*cmath.pi*(time * 0.125)) | system_q[1] | ||
CNOT | (system_q[0], system_q[1]) | ||
n_qpe_ancillas = 3 | ||
qpe_ancillas = eng.allocate_qureg(n_qpe_ancillas) | ||
system_qubits = eng.allocate_qureg(2) | ||
X | system_qubits[0] | ||
# Apply Quantum Phase Estimation | ||
QPE(two_qubit_gate) | (qpe_ancillas, system_qubits) | ||
All(Measure) | qpe_ancillas | ||
# Compute the phase from the ancilla measurement | ||
#(https://en.wikipedia.org/wiki/Quantum_phase_estimation_algorithm) | ||
phasebinlist = [int(q) for q in qpe_ancillas] | ||
phase_in_bin = ''.join(str(j) for j in phasebinlist) | ||
phase_int = int(phase_in_bin,2) | ||
phase = phase_int / (2 ** n_qpe_ancillas) | ||
print (phase) | ||
Attributes: | ||
unitary (BasicGate): Unitary Operation either a ProjectQ gate or a function f. | ||
Calling the function with the parameters system_qubits(Qureg) and time (integer), | ||
i.e. f(system_qubits, time), applies to the system qubits a unitary defined in f | ||
with parameter time. | ||
""" | ||
|
||
import numpy as np | ||
|
||
from projectq.cengines import DecompositionRule | ||
from projectq.meta import Control, Loop, get_control_count | ||
from projectq.ops import H, Tensor, get_inverse, QFT | ||
|
||
from projectq.ops import QPE | ||
|
||
|
||
def _decompose_QPE(cmd): | ||
""" Decompose the Quantum Phase Estimation gate. """ | ||
eng = cmd.engine | ||
|
||
# Ancillas is the first qubit/qureg. System-qubit is the second qubit/qureg | ||
qpe_ancillas = cmd.qubits[0] | ||
system_qubits = cmd.qubits[1] | ||
|
||
# Hadamard on the ancillas | ||
Tensor(H) | qpe_ancillas | ||
|
||
# The Unitary Operator | ||
U = cmd.gate.unitary | ||
|
||
# Control U on the system_qubits | ||
if (callable(U)): | ||
# If U is a function | ||
for i in range(len(qpe_ancillas)): | ||
with Control(eng, qpe_ancillas[i]): | ||
U(system_qubits, time=2**i) | ||
else: | ||
for i in range(len(qpe_ancillas)): | ||
ipower = int(2**i) | ||
with Loop(eng, ipower): | ||
with Control(eng, qpe_ancillas[i]): | ||
U | system_qubits | ||
|
||
# Inverse QFT on the ancillas | ||
get_inverse(QFT) | qpe_ancillas | ||
|
||
#: Decomposition rules | ||
all_defined_decomposition_rules = [ | ||
DecompositionRule(QPE, _decompose_QPE) | ||
] |
Oops, something went wrong.