Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure valid RST in docstrings #1141

Merged
merged 11 commits into from
Dec 28, 2019
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Changelog
and `check-types` (@karalekas, gh-1133).
- Added type hints to `noise.py` (@rht, gh-1136).
- Fixed string concatenation style (@peterjc, gh-1139).
- Improved reStructuredText markup in docstrings (@peterjc, gh-1141).

### Bugfixes

Expand Down
4 changes: 2 additions & 2 deletions pyquil/api/_base_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,9 @@ class ForestSession(requests.Session):
Two operations are involved in authorization:

* Requesting & storing a user authentication token, used to authenticate calls
to Forest, Dispatch, and other Rigetti services
to Forest, Dispatch, and other Rigetti services
* Requesting a Curve ZeroMQ keypair for connection to the QPU. The response to
this request also comes with service endpoints: compiler server and QPU
this request also comes with service endpoints: compiler server and QPU

The authentication tokens are of the standard JWT format and are issued by Forest Server.

Expand Down
2 changes: 1 addition & 1 deletion pyquil/api/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class PyquilConfig(object):

:attribute get_engagement: A callback to fetch a currently valid engagement from which to read
configuration parameters (i.e., QPU_URL) as needed. This allows the engagement to be fetched
and maintained elsewhere (i.e., by ForestSession or manually).
and maintained elsewhere (i.e., by ForestSession or manually).
"""

FOREST_URL = {
Expand Down
47 changes: 25 additions & 22 deletions pyquil/api/_devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,13 @@ def list_lattices(
Query the Forest 2.0 server for its knowledge of lattices. Optionally filters by underlying
device name and lattice qubit count.

:return: A dictionary keyed on lattice names and valued in dictionaries of the form
{
"device_name": device_name,
"qubits": num_qubits
}
:return: A dictionary keyed on lattice names and valued in dictionaries of the
form::
appleby marked this conversation as resolved.
Show resolved Hide resolved

{
"device_name": device_name,
"qubits": num_qubits
}
"""
if connection is None:
connection = ForestConnection()
Expand All @@ -84,17 +86,17 @@ def list_lattices(
* You do have user authentication credentials, but they are invalid. You can visit
https://qcs.rigetti.com/auth/token and save to ~/.qcs/user_auth_token to update your
authentication credentials. Alternatively, you may provide the path to your credentials in
your config file or with the USER_AUTH_TOKEN_PATH environment variable.
your config file or with the USER_AUTH_TOKEN_PATH environment variable::

[Rigetti Forest]
user_auth_token_path = ~/.qcs/my_auth_credentials
[Rigetti Forest]
user_auth_token_path = ~/.qcs/my_auth_credentials

* You're missing an address for the Forest 2.0 server endpoint, or the address is invalid.
This too can be set through the environment variable FOREST_URL or by changing the
following lines in the QCS config file:
following lines in the QCS config file::

[Rigetti Forest]
url = https://forest-server.qcs.rigetti.com
[Rigetti Forest]
url = https://forest-server.qcs.rigetti.com

For the record, here's the original exception: {}
""".format(
Expand All @@ -119,14 +121,15 @@ def _get_raw_lattice_data(lattice_name: str = None):
"""
Produces a dictionary of raw data for a lattice as queried from the Forest 2.0 server.

Returns a dictionary of the form
{
"name": the name of the lattice as a string,
"device_name": the name of the device, given as a string, that the lattice lies on,
"specs": a Specs object, serialized as a dictionary,
"isa": an ISA object, serialized as a dictionary,
"noise_model": a NoiseModel object, serialized as a dictionary
}
Returns a dictionary of the form::

{
"name": the name of the lattice as a string,
"device_name": the name of the device, given as a string, that the lattice lies on,
"specs": a Specs object, serialized as a dictionary,
"isa": an ISA object, serialized as a dictionary,
"noise_model": a NoiseModel object, serialized as a dictionary
}
"""
from pyquil.api._base_connection import get_session, get_json
from requests.exceptions import MissingSchema
Expand All @@ -143,9 +146,9 @@ def _get_raw_lattice_data(lattice_name: str = None):

Most likely, you're missing an address for the Forest 2.0 server endpoint, or the
address is invalid. This can be set through the environment variable FOREST_URL or
by changing the following lines in the QCS config file (by default, at ~/.qcs_config):
by changing the following lines in the QCS config file (by default, at ~/.qcs_config)::

[Rigetti Forest]
url = https://rigetti.com/valid/forest/url"""
[Rigetti Forest]
url = https://rigetti.com/valid/forest/url"""
)
return res["lattice"]
30 changes: 17 additions & 13 deletions pyquil/api/_qpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,41 +293,45 @@ def _update_variables_shim_with_recalculation_table(self):
Update self._variables_shim with the final values to be patched into the gate parameters,
according to the arithmetic expressions in the original program.

For example:
For example::

DECLARE theta REAL
DECLARE beta REAL
RZ(3 * theta) 0
RZ(beta+theta) 0

gets translated to:
gets translated to::

DECLARE theta REAL
DECLARE __P REAL[2]
RZ(__P[0]) 0
RZ(__P[1]) 0

and the recalculation table will contain:
and the recalculation table will contain::

{
ParameterAref('__P', 0): Mul(3.0, <MemoryReference theta[0]>),
ParameterAref('__P', 1): Add(<MemoryReference beta[0]>, <MemoryReference theta[0]>)
}
{
ParameterAref('__P', 0): Mul(3.0, <MemoryReference theta[0]>),
ParameterAref('__P', 1): Add(<MemoryReference beta[0]>, <MemoryReference theta[0]>)
}

Let's say we've made the following two function calls:

.. code-block:: python

qpu.write_memory(region_name='theta', value=0.5)
qpu.write_memory(region_name='beta', value=0.1)

After executing this function, our self.variables_shim in the above example would contain
the following:

{
ParameterAref('theta', 0): 0.5,
ParameterAref('beta', 0): 0.1,
ParameterAref('__P', 0): 1.5, # (3.0) * theta[0]
ParameterAref('__P', 1): 0.6 # beta[0] + theta[0]
}
.. code-block:: python

{
ParameterAref('theta', 0): 0.5,
ParameterAref('beta', 0): 0.1,
ParameterAref('__P', 0): 1.5, # (3.0) * theta[0]
ParameterAref('__P', 1): 0.6 # beta[0] + theta[0]
}

Once the _variables_shim is filled, execution continues as with regular binary patching.
"""
Expand Down
16 changes: 11 additions & 5 deletions pyquil/api/_quantum_computer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1021,11 +1021,13 @@ def _symmetrization(
qubits are flipped in each program.

The symmetrization types are specified by an int; the types available are:
-1 -- exhaustive symmetrization uses every possible combination of flips
0 -- trivial that is no symmetrization
1 -- symmetrization using an OA with strength 1
2 -- symmetrization using an OA with strength 2
3 -- symmetrization using an OA with strength 3

* -1 -- exhaustive symmetrization uses every possible combination of flips
* 0 -- trivial that is no symmetrization
* 1 -- symmetrization using an OA with strength 1
* 2 -- symmetrization using an OA with strength 2
* 3 -- symmetrization using an OA with strength 3

In the context of readout symmetrization the strength of the orthogonal array enforces the
symmetry of the marginal confusion matrices.

Expand Down Expand Up @@ -1165,19 +1167,23 @@ def hadamard(n, dtype=int):
Construct a Hadamard matrix.
Constructs an n-by-n Hadamard matrix, using Sylvester's
construction. `n` must be a power of 2.

Parameters
----------
n : int
The order of the matrix. `n` must be a power of 2.
dtype : numpy dtype
The data type of the array to be constructed.

Returns
-------
H : (n, n) ndarray
The Hadamard matrix.

Notes
-----
.. versionadded:: 0.8.0

Examples
--------
>>> hadamard(2, dtype=complex)
Expand Down
2 changes: 1 addition & 1 deletion pyquil/experiment/_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class TomographyExperiment:
Note that (default) exhaustive symmetrization requires a number of QPU calls exponential in
the number of qubits in the union of the support of the observables in any group of settings
in ``tomo_experiment``; the number of shots may need to be increased to accommodate this.
see :func:`run_symmetrized_readout` in api._quantum_computer for more information.
see :py:func:`run_symmetrized_readout` in api._quantum_computer for more information.
"""

def __init__(
Expand Down
4 changes: 1 addition & 3 deletions pyquil/experiment/_program.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,14 @@ def parameterized_euler_rotations(
"""
Given a number of qubits (n), build a ``Program`` containing a ZXZXZ-decomposed gate on each
qubit, where each ``RZ`` is parameterized by declared values with labels given by the "prefix"
and "suffix" arguments. Put more plainly, the resulting Quil program on n qubits is:
and "suffix" arguments. Put more plainly, the resulting Quil program on n qubits is::

RZ(alpha_label[0]) 0
RX(pi/2) 0
RZ(beta_label[0]) 0
RX(-pi/2) 0
RZ(gamma_label[0]) 0

...

RZ(alpha_label[n-1]) n-1
RX(pi/2) n-1
RZ(beta_label[0]) n-1
Expand Down
6 changes: 6 additions & 0 deletions pyquil/magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,17 @@ class _IfTransformer(ast.NodeTransformer):
Transformer that unwraps the if and else branches into separate inner functions and then wraps
them in a call to _if_statement. For example:

.. code-block:: python

if 1 + 1 == 2:
print('math works')
else:
print('something is broken')

would be transformed into:

.. code-block:: python

def _if_branch():
print('math works')
def _else_branch():
Expand Down Expand Up @@ -210,6 +214,8 @@ def magicquil(f):

Example usage:

.. code-block:: python

@magicquil
def fast_reset(q1):
reg1 = MEASURE(q1, None)
Expand Down
5 changes: 3 additions & 2 deletions pyquil/noise.py
Original file line number Diff line number Diff line change
Expand Up @@ -683,13 +683,14 @@ def _apply_local_transforms(p: np.ndarray, ts: Iterable[np.ndarray]) -> np.ndarr
and a list of assignment probability matrices (one for each bit in the readout, ordered like
the inner axis of results) apply local 2x2 matrices to each bit index.

:param p: An array that enumerates a function indexed by bitstrings::
:param p: An array that enumerates a function indexed by
bitstrings::
appleby marked this conversation as resolved.
Show resolved Hide resolved

f(ijk...) = p[i,j,k,...]

:param ts: A sequence of 2x2 transform-matrices, one for each bit.
:return: ``p_transformed`` an array with as many dimensions as there are bits with the result of
contracting p along each axis by the corresponding bit transformation.
contracting p along each axis by the corresponding bit transformation::

p_transformed[ijk...] = f'(ijk...) = sum_lmn... ts[0][il] ts[1][jm] ts[2][kn] f(lmn...)
"""
Expand Down
2 changes: 1 addition & 1 deletion pyquil/numpy_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def expectation(self, operator: Union[PauliTerm, PauliSum]):

def reset(self):
"""
Reset the wavefunction to the |000...00> state.
Reset the wavefunction to the ``|000...00>`` state.

:return: ``self`` to support method chaining.
"""
Expand Down
2 changes: 1 addition & 1 deletion pyquil/pyqvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def expectation(self, operator: Union[PauliTerm, PauliSum]) -> complex:
@abstractmethod
def reset(self) -> "AbstractQuantumSimulator":
"""
Reset the wavefunction to the |000...00> state.
Reset the wavefunction to the ``|000...00>`` state.

:return: ``self`` to support method chaining.
"""
Expand Down
14 changes: 7 additions & 7 deletions pyquil/reference_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def expectation(self, operator: Union[PauliTerm, PauliSum]):

def reset(self):
"""
Reset the wavefunction to the |000...00> state.
Reset the wavefunction to the ``|000...00>`` state.

:return: ``self`` to support method chaining.
"""
Expand All @@ -174,10 +174,10 @@ def do_post_gate_noise(

def zero_state_matrix(n_qubits: int) -> np.ndarray:
"""
Construct a matrix corresponding to the tensor product of `n` ground states |0><0|.
Construct a matrix corresponding to the tensor product of `n` ground states ``|0><0|``.

:param n_qubits: The number of qubits.
:return: The state matrix |000...0><000...0| for `n_qubits`.
:return: The state matrix ``|000...0><000...0|`` for `n_qubits`.
"""
state_matrix = np.zeros((2 ** n_qubits, 2 ** n_qubits), dtype=np.complex128)
state_matrix[0, 0] = complex(1.0, 0)
Expand Down Expand Up @@ -209,15 +209,15 @@ def set_initial_state(self, state_matrix: np.ndarray):
"""
This method is the correct way (TM) to update the initial state matrix that is
initialized every time reset() is called. The default initial state of
ReferenceDensitySimulator is |000...00>.
ReferenceDensitySimulator is ``|000...00>``.

Note that the current state matrix, i.e. ``self.density`` is not affected by this
method; you must change it directly or else call reset() after calling this method.

To restore default state initialization behavior of ReferenceDensitySimulator pass in
a ``state_matrix`` equal to the default initial state on `n_qubits` (i.e. |000...00>) and
then call ``reset()``. We have provided a helper function ``n_qubit_zero_state`` in the
``reference_simulator.py`` module to simplify this step.
a ``state_matrix`` equal to the default initial state on `n_qubits` (i.e. ``|000...00>``)
and then call ``reset()``. We have provided a helper function ``n_qubit_zero_state``
in the ``reference_simulator.py`` module to simplify this step.

:param state_matrix: numpy.ndarray or None.
:return: ``self`` to support method chaining.
Expand Down