Skip to content

Commit

Permalink
Merge pull request #12 from ampolloreno/docfixes
Browse files Browse the repository at this point in the history
Cleaning up the docs
  • Loading branch information
ncrubin committed Jan 10, 2017
2 parents e6853b2 + 076b5c6 commit 4c22f29
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 66 deletions.
65 changes: 31 additions & 34 deletions docs/qaoa/qaoa_algorithm_detail.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ algorithm for finding "a 'good' solution to an optimization problem"

What's with the name? For a given NP-Hard problem an approximate algorithm is a
polynomial-time algorithm that solves every instance of the problem with some
guaranteed quality. The value of merit is the ratio between the polynomial time
solution and the true solution.
guaranteed quality in expectation. The value of merit is the ratio between the quality of
the polynomial time solution and the quality of the true solution.

One reason QAOA is interesting is its potential to exhibit quantum supremacy
[`1 <https://arxiv.org/abs/1602.07674>`_].
Expand All @@ -32,7 +32,7 @@ and the NP-hard problem instance used in the original paper.


Our First NP-Hard Problem
-----------------------------
-------------------------
The maximum-cut problem (MAX-CUT) was the first application described in the
original quantum-approximate-optimization-algorithm paper [`2
<https://arxiv.org/abs/1411.4028>`_ ]. This problem is similar to graph coloring.
Expand Down Expand Up @@ -104,25 +104,25 @@ written as follows:
$$\\sum_{e \\in E} w_{e} \\cdot \\mathrm{Pr}(e \\in \\mathrm{cut}) =
\\frac{1}{2} \\sum_{e \\in E}w_{e}$$
Since the sum of all the edges is necessarily an upper bound to the maximum cut
the randomized approach produces a cut that is at least 0.5 times the best cut on
the graph.
the randomized approach produces a cut of expected value of at least 0.5 times the
best cut on the graph.

Other polynomial approaches exist that involve semi-definite programming which
guaruntee a cut to be at least 0.87856 times the maximum cut [`3
give cuts of expected value at least 0.87856 times the maximum cut [`3
<http://dl.acm.org/citation.cfm?id=227684>`_].

Quantum Approximate Optimization
--------------------------------

One can think of the bit strings (or set of bit strings) that correspond to the
maximum cut on a graph as the ground state to a Hamiltonian encoding
maximum cut on a graph as the ground state of a Hamiltonian encoding
the cost function. The form of this Hamiltonian can be determined by
constructing the classical function that returns a 1 (or the weight of the edge) if the edge spans two-nodes in different sets, or 0 if the nodes are in the same set.
\\begin{align}
C_{ij} = \\frac{1}{2}(1 - z_{i}z_{j})
\\end{align}
\\( z_{i}\\) and \\(z_{j}\\) are \\(+1\\) if node \\(i\\) is in \\(S\\)
or \\(-1\\) if node \\(i\\) is in \\(\\overline{S}\\). The total cost is the
\\( z_{i}\\) or \\(z_{j}\\) is \\(+1\\) if node \\(i\\) or node \\(j\\) is in \\(S\\)
or \\(-1\\) if node \\(i\\) or node \\(j\\) is in \\(\\overline{S}\\). The total cost is the
sum of all \\( (i ,j) \\) node pairs that form the edge set of the graph.
This suggests that for MAX-CUT the Hamiltonian that encodes the problem is
$$\\sum_{ij}\\frac{1}{2}(\\mathbf{I} - \\sigma_{i}^{z}\\sigma_{j}^{z})$$
Expand All @@ -133,7 +133,7 @@ perform a measurement on that state. Performing a measurement on the \\(N\\)-bod
quantum state returns the bit string corresponding to the maximum cut with high
probability.

To make this clear let us return to the barbell graph. The graph requires two qubits
To make this concrete let us return to the barbell graph. The graph requires two qubits
in order to represent the nodes. The Hamiltonian has the form
\\begin{align}
\\hat{H} = \\frac{1}{2}(\\mathbf{I} - \\sigma_{z}^{1}\\otimes \\sigma_{z}^{0})
Expand All @@ -144,18 +144,16 @@ in order to represent the nodes. The Hamiltonian has the form
0 & 0 & 0 & 0
\\end{pmatrix}
\\end{align}
where the basis ordering corresponds to increasing integer values in binary format (
the left most bit being the most significant). This corresponds to a basis
where the basis ordering corresponds to increasing integer values in binary format (the left most bit being the most significant). This corresponds to a basis
ordering for the \\(\\hat{H}\\) operator above as
\\begin{align}
(| 00\\rangle, | 01\\rangle, | 10\\rangle, | 11\\rangle).
\\end{align}
Here the Hamiltonian is diagonal with integer eigenvalues.
Clearly each bit string is a eigenstate of the Hamiltonian because of the
diagonal nature of \\(\\hat{H}\\).
Clearly each bit string is an eigenstate of the Hamiltonian because \\(\\hat{H}\\) is diagonal.

The QAO algorithm identifies the ground state of the MAXCUT Hamiltonian by
evolution from a reference state. This reference state is the ground state of
QAOA identifies the ground state of the MAXCUT Hamiltonian by
evolving from a reference state. This reference state is the ground state of
a Hamiltonian that couples all \\( 2^{N} \\) states that form
the basis of the cost Hamiltonian---i.e. the diagonal basis for cost function.
For MAX-CUT this is the \\(Z\\) computational basis.
Expand All @@ -164,21 +162,21 @@ The evolution between the ground state of the reference Hamiltonian
and the ground state of the MAXCUT Hamiltonian can be generated by an
interpolation between the two operators
\\begin{align}
\\hat{H}_{\\alpha} = \\alpha\\hat{H}_{\\mathrm{ref}} + (1 - \\alpha)\\hat{H}_{\\mathrm{MAXCUT}}
\\hat{H}_{\\tau} = \\tau\\hat{H}_{\\mathrm{ref}} + (1 - \\tau)\\hat{H}_{\\mathrm{MAXCUT}}
\\end{align}
where \\(\\alpha\\) changes between 1 and 0. If the ground state of the reference
Hamiltonian is prepared and \\( \\alpha = 1\\) the state is
a stationary state of \\(\\hat{H}_{\\alpha}\\). As \\(\\hat{H}_{\\alpha}\\) transforms
where \\(\\tau\\) changes between 1 and 0. If the ground state of the reference
Hamiltonian is prepared and \\( \\tau = 1\\) the state is
a stationary state of \\(\\hat{H}_{\\tau}\\). As \\(\\hat{H}_{\\tau}\\) transforms
into the MAXCUT Hamiltonian the ground state will evolve as it is no longer
stationary with respect to \\(\\hat{H}_{\\alpha \\neq 1 }\\). This can be thought of
stationary with respect to \\(\\hat{H}_{\\tau \\neq 1 }\\). This can be thought of
as a continuous version of the of the evolution in QAOA.

The appproximate portion of the algorithm comes from how many \\(\\alpha\\) slices are used
for approximating the continuous evolution. The original paper
[`2 <https://arxiv.org/abs/1411.4028>`_] demonstrated that for \\(\\alpha = 1\\) the optimal
The appproximate portion of the algorithm comes from how many values of \\(\\tau\\) are used
for approximating the continuous evolution. We will call this number of slices \\(\\alpha\\).
The original paper [`2 <https://arxiv.org/abs/1411.4028>`_] demonstrated that for \\(\\alpha = 1\\) the optimal
circuit produced a distribution of states with a Hamiltonian expectation value of
0.6924 of the true maximum cut for 3-regular graphs. Furthermore, the ratio between
the true maximum cut and the expectation value from the QAO algorithm could be
the true maximum cut and the expectation value from QAOA could be
improved by increasing the number of slices approximating the evolution.

Details
Expand All @@ -197,7 +195,7 @@ eigenvectors of the \\(\\sigma_{x}\\) operator (\\(\\mid +
\\rangle_{N-2}\\otimes...\\otimes\\mid + \\rangle_{0}
\\end{align}

The reference state is easily generated by performing a Hadmard gate on each
The reference state is easily generated by performing a Hadamard gate on each
qubit--assuming the initial state of the system is all zeros. The Quil code
generating this state is

Expand All @@ -215,16 +213,15 @@ determines the parameters for the rotations (denoted \\(\\beta\\) and
\\(\\gamma\\))
using the quantum-variational-eigensolver method [`4
<http://arxiv.org/abs/1509.04279>`_][`5 <http://arxiv.org/abs/1304.3061>`_]
that maximize the cost function.
that maximizes the cost function.

For example, if (\\(\\alpha = 2\\)) is selected two unitary operators
approximating the continuous evolution are generated.
\\begin{align}
U = U(\\hat{H}_{\\alpha_{1}})U(\\hat{H}_{\\alpha_{0}})
\\label{eq:evolve}
\\end{align}
Each \\( U(\\hat{H}_{\\alpha_{i}})\\) is approximated by a first order Trotter
decomposition with the number of Trotter steps equal to one
Each \\( U(\\hat{H}_{\\alpha_{i}})\\) is approximated by a first order Trotter-Suzuki decomposition with the number of Trotter steps equal to one
\\begin{align}
U(\\hat{H}_{s_{i}}) = U(\\hat{H}_{\\mathrm{ref}}, \\beta_{i})U(\\hat{H}_{\\mathrm{MAXCUT}}, \\gamma_{i})
\\end{align}
Expand All @@ -236,7 +233,7 @@ and
\\begin{align}
U(\\hat{H}_{\\mathrm{MAXCUT}}, \\gamma_{i}) = e^{-i \\hat{H}_{\\mathrm{MAXCUT}} \\gamma_{i}}
\\end{align}
\\( U(\\hat{H}_{\\mathrm{ref}}, \\beta_{i}) \\) and \\( U(\\hat{H}_{\\mathrm{MAXCUT}}, \\gamma_{i})\\) can be expressed as short quantum circuit.
\\( U(\\hat{H}_{\\mathrm{ref}}, \\beta_{i}) \\) and \\( U(\\hat{H}_{\\mathrm{MAXCUT}}, \\gamma_{i})\\) can be expressed as a short quantum circuit.

For the \\(U(\\hat{H}_{\\mathrm{ref}}, \\beta_{i})\\) term (or mixing
term) all operators in the sum commute and thus can be split into a product of
Expand All @@ -261,7 +258,7 @@ is compiled into a set of RX rotations. The Quil code for the cost function
\\begin{align}
e^{-i \\frac{\\gamma_{i}}{2}(\\mathbf{I} - \\sigma_{1}^{z} \\otimes \\sigma_{0}^{z}) }
\\end{align}
looks like this.
looks like this:

.. code-block:: c
Expand Down Expand Up @@ -290,8 +287,8 @@ pyQAOA leverages the classical-quantum hybrid
approach known as the quantum-variational-eigensolver[`4
<http://arxiv.org/abs/1509.04279>`_][`5 <http://arxiv.org/abs/1304.3061>`_]. The quantum processor
is used to prepare a state through a polynomial number of operations which is
then used to evaluate the cost. Evaluating the cost (\\( \\langle \\beta,
\\gamma \\mid \\hat{H}_{\\mathrm{MAXCUT}} \\mid \\beta, \\gamma \\rangle\\)) requires
then used to evaluate the cost. Evaluating the cost
(\\( \\langle \\beta, \\gamma \\mid \\hat{H}_{\\mathrm{MAXCUT}} \\mid \\beta, \\gamma \\rangle\\)) requires
many preparations and measurements to generate enough samples to accurately
construct the distribution. The classical computer then generates a new set of
parameters (\\( \\beta, \\gamma\\)) for maximizing the cost function.
Expand All @@ -301,7 +298,7 @@ parameters (\\( \\beta, \\gamma\\)) for maximizing the cost function.
:scale: 55%

By allowing variational freedom in the \\( \\beta \\) and \\( \\gamma \\)
angles the QAO algorithm finds the optimal path for a fixed
angles QAOA finds the optimal path for a fixed
number of steps. Once optimal angles are determined by the classical
optimization loop one can read off the distribution by many preparations of the
state with \\(\\beta, \\gamma\\) and sampling.
Expand Down
2 changes: 1 addition & 1 deletion docs/qaoa/qaoa_installation_quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ We instantiate the algorithm and run the optimization routine on our QVM:
betas, gammas = inst.get_angles()
to see the final \\(\\mid \\beta, \\gamma \\rangle \\) state we can rebuild the
quil program that gives us \\(\\mid \\beta, \\gamma \\rangle \\) and evaluate the wave function using the **qvm**
quil program that gives us \\(\\mid \\beta, \\gamma \\rangle \\) and evaluate the wave function using the QVM

.. code-block:: python
Expand Down
25 changes: 8 additions & 17 deletions docs/qaoa/qaoa_overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,21 @@ Structure
_________

The pyQAOA package contains separate modules for each type of problem
instance: MAX-CUT, K-SAT, etc.
Each problem instance is a class that inherits the main QAOA object and
overrides the problem specific pieces of the algorithm:

- implementation of the cost function and reference hamiltonian,

- generating the program that evolves the reference state to the problem's ground state,

- and bounds for the angles.

The package currently includes `maxcut_qaoa.py` which implements the cost
clauses and the driver hamiltonian for the MAX-CUT cost function.
instance: MAX-CUT, graph partitioning, etc.
For each problem instance the user specifics the driver Hamiltonian,
cost Hamiltonian, and the approximation order of the algorithm.

The package is structured as follows:

`qaoa.py` contains the base QAOA class and routines for finding optimal
``qaoa.py`` contains the base QAOA class and routines for finding optimal
rotation angles via `Grove's quantum-variational-eigensolver method <../vqe/vqe.html>`_.

The following cost functions come standard with this package:

* `maxcut_qaoa.py` implements the cost function for MAX-CUT problems.
* ``maxcut_qaoa.py`` implements the cost function for MAX-CUT problems.

* `numpartition_qaoa.py` implements the cost function for bipartitioning a list of numbers.
* ``numpartition_qaoa.py`` implements the cost function for bipartitioning a list of numbers.

* `graphparition_qaoa.py` implements the cost function for graph partitioning--i.e. minimial cut between two subgraphs of equal size
* ``graphpartition_qaoa.py`` implements the cost function for graph partitioning--i.e. minimial cut between two subgraphs of equal size

* `graphparitioning_jaynescummingsdriver.py` implements the graph paritioning problem with the constraint that the magnetization equals some constant `m`.
* ``graphpartitioning_jaynescummingsdriver.py`` implements the graph partitioning problem with the constraint that the magnetization equals some constant `m`.
8 changes: 4 additions & 4 deletions docs/teleportation/teleportation_overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ In the canonical description of quantum teleportation [1]_ [2]_ two parties (Ali
and Bob) are trying to transmit a state from one to another. They start with
an Alice having half of an entangled bell pair (Bob having the other half) and
Alice with a third qubit that she would like to transmit to Bob. Alice then
entangles the third qubit with the Bell pair, measures both her qubits, and sends the
measurement result :math:`\{0, 1\}_{2}` to Bob. Bob uses the classical information
entangles the third qubit with her Bell pair qubit, measures both her qubits, and sends the
measurement result :math:`\{0, 1\}^{2}` to Bob. Bob uses the classical information
from Alice to fix up his state and now has his qubit in the state of Alice's
original qubit she wanted to transfer.

Given that Alice's data qubit is labeled 0 and the Bell pair are labeled 1, 2
(Bob having qubit labeled 2) the Quil program performing the transfer is as
(Bob having qubit labeled 2) a Quil program performing the transfer is as
follows:

.. code::
Expand All @@ -24,7 +24,7 @@ follows:
H 0
MEASURE 0 [0]
MEASURE 1 [1]
JUMP-WHEN @ NOX [1]
JUMP-UNLESS @ NOX [1]
X 2
LABEL @NOX
JUMP-UNLESS @NOZ [0]
Expand Down
8 changes: 4 additions & 4 deletions docs/vqe.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The quantum subroutine has two fundamental steps:
The `variational principle <https://en.wikipedia.org/wiki/Variational_method_(quantum_mechanics)>`_ ensures
that this expectation value is always greater than the smallest eigenvalue of :math:`H`.

This bound, allows us to use classical computation to run an optimization loop to find
This bound allows us to use classical computation to run an optimization loop to find
this eigenvalue:

1. Use a classical non-linear optimizer to minimize the expectation value by varying
Expand All @@ -29,10 +29,10 @@ this eigenvalue:

Practically, the quantum subroutine of VQE amounts to preparing a state based off
of a set of parameters :math:`\vec{\theta}` and performing a series of measurements
in the appropriate basis. The paramaterized state (or ansatz) preperation can be tricky
in these algorithms and can dramatically effect performance. Our vqe module allows any
in the appropriate basis. The paramaterized state (or ansatz) preparation can be tricky
in these algorithms and can dramatically affect performance. Our ``VQE`` module allows any
Python function that returns a pyQuil program to be used as an ansatz generator. This
function is passed into `vqe_run` as the `parameteric_state_evolve` argument. More details
function is passed into ``vqe_run`` as the ``parameteric_state_evolve`` argument. More details
are in the `source documentation <./vqe/vqe_source.html#grove.pyvqe.vqe.VQE.vqe_run>`_.

Measurements are then performed on these states based on a Pauli operator decomposition of
Expand Down
11 changes: 5 additions & 6 deletions docs/vqe/vqe_example.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ construct the Hamiltonian that we wish to simulate, we use the
from pyquil.paulis import sZ
initial_angle = [0.0]
# our Hamiltonian is just \sigma_z on the zero-th qubit
# Our Hamiltonian is just \sigma_z on the zeroth qubit
hamiltonian = sZ(0)
We now use the VQE module in Grove to construct a VQE object to perform
We now use the `vqe` module in Grove to construct a ``VQE`` object to perform
our algorithm. In this example, we use ``scipy.optimize.minimize()``
with Nelder-Mead as our classical minimizer, but you can choose other
parameters or write your own minimizer.
Expand Down Expand Up @@ -97,7 +97,6 @@ We can loop over a range of these angles and plot the expectation value.
for angle in angle_range]
import matplotlib.pyplot as plt
%matplotlib inline
plt.xlabel('Angle [radians]')
plt.ylabel('Expectation value')
plt.plot(angle_range, data)
Expand Down Expand Up @@ -145,7 +144,7 @@ Running Noisy VQE
A great thing about VQE is that it is somewhat insensitive to noise. We
can test this out by running the previous algorithm on a noisy qvm.

Remember that pauli channels are defined as a list of three
Remember that Pauli channels are defined as a list of three
probabilities that correspond to the probability of a random X, Y, or Z
gate respectively. First we'll study the impact of a channel that has
the same probability of each random Pauli.
Expand Down Expand Up @@ -198,7 +197,7 @@ noise on the result of this algorithm:
for noise in noises:
pauli_channel = [noise] * 3
noisy_qvm = forest.Connection(gate_noise=pauli_channel)
# we can pass the noise params directly into the vqe_run instead of passing the noisy connection
# We can pass the noise params directly into the vqe_run instead of passing the noisy connection
result = vqe_inst.vqe_run(small_ansatz, hamiltonian, initial_angle,
gate_noise=pauli_channel)
data.append(result['fun'])
Expand Down Expand Up @@ -339,7 +338,7 @@ arguments.
Links and further reading
-------------------------

This concludes our brief tour of VQE. There is lots of fascinating
This concludes our brief tour of VQE. There is a lot of fascinating
literature about this algorithm out there and we encourage you to both
explore those topics as well as come up with new ideas using this
library. Let us know if you have ideas about anything that you would like to
Expand Down
2 changes: 2 additions & 0 deletions grove/phaseestimation/phase_estimation.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
def controlled(m):
"""
Make a one-qubit-controlled version of a matrix.
:param m: (numpy.ndarray) A matrix.
:return: A controlled version of that matrix.
"""
Expand All @@ -40,6 +41,7 @@ def controlled(m):
def phase_estimation(U, accuracy, reg_offset=0):
"""
Generate a circuit for quantum phase estimation.
:param U: (numpy.ndarray) A unitary matrix.
:param accuracy: (int) Number of bits of accuracy desired.
:param reg_offset: (int) Where to start writing measurements (default 0).
Expand Down

0 comments on commit 4c22f29

Please sign in to comment.