Skip to content

Commit

Permalink
Update docs according to new opmath changes (#5479)
Browse files Browse the repository at this point in the history
This mainly concerns places where Hamiltonian objects are now
LinearCombinations and thus have a different string representation

Went through "Using PennyLane" docs manually, and systematically
searched for `\[[XYZ][0-9]+\]` regex patterns as well as `<Hamiltonian:
...`.

[sc-53507]
  • Loading branch information
Qottmann authored Apr 15, 2024
1 parent 8e93a37 commit 35de283
Show file tree
Hide file tree
Showing 15 changed files with 155 additions and 168 deletions.
6 changes: 2 additions & 4 deletions doc/introduction/data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,7 @@ To create a dataset, we can do the following:
>>> dataset.data_name
"Example"
>>> dataset.hamiltonian
(0.5) [X1]
+ (1) [Z0]
1.0 * Z(0) + 0.5 * X(1)
>>> dataset.energies
array([-1.5, -0.5, 0.5, 1.5])

Expand All @@ -147,8 +146,7 @@ We can then write this :class:`~pennylane.data.Dataset` to storage and read it a
>>> read_dataset.data_name
"Example"
>>> read_dataset.hamiltonian
(0.5) [X1]
+ (1) [Z0]
1.0 * Z(0) + 0.5 * X(1)
>>> read_dataset.energies
array([-1.5, -0.5, 0.5, 1.5])

Expand Down
5 changes: 2 additions & 3 deletions doc/introduction/operations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,9 @@ For example:
>>> mat = np.array([[1, 1], [1, -1]])
>>> h = qml.pauli_decompose(mat)
>>> type(h)
<class 'pennylane.ops.qubit.hamiltonian.Hamiltonian'>
pennylane.ops.op_math.linear_combination.LinearCombination
>>> print(h)
(1.0) [X0]
+ (1.0) [Z0]
1.0 * X(0) + 1.0 * Z(0)

.. _intro_ref_ops_qubit:

Expand Down
3 changes: 1 addition & 2 deletions pennylane/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@
... eigen = {"eigvals": eigvals, "eigvecs": eigvecs}
... )
>>> dataset.hamiltonian
(1.0) [Z0]
+ (1.0) [Z1]
1.0 * Z(0) + 1.0 * Z(1)
>>> dataset.eigen
{'eigvals': array([-2., 0., 0., 2.]),
'eigvecs': array([[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
Expand Down
2 changes: 1 addition & 1 deletion pennylane/devices/preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ def validate_observables(
... return obj.name in {"PauliX", "PauliY", "PauliZ"}
>>> tape = qml.tape.QuantumScript([], [qml.expval(qml.Z(0) + qml.Y(0))])
>>> validate_observables(tape, accepted_observable)
DeviceError: Observable <Hamiltonian: terms=2, wires=[0]> not supported on device
DeviceError: Observable Z(0) + Y(0) not supported on device
Note that if the observable is a :class:`~.Tensor`, the validation is run on each object in the
``Tensor`` instead.
Expand Down
6 changes: 3 additions & 3 deletions pennylane/measurements/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,11 @@ def circuit(x):
>>> H = 2.0 * qml.X(0)
>>> mp = qml.expval(H)
>>> mp._flatten()
((<Hamiltonian: terms=1, wires=[0]>, None), ())
((2.0 * X(0), None), (('wires', None),))
>>> type(mp)._unflatten(*mp._flatten())
expval( (2) [X0])
expval(2.0 * X(0))
>>> jax.tree_util.tree_leaves(mp)
[2]
[2.0]
Adding your new measurement to PennyLane
----------------------------------------
Expand Down
8 changes: 6 additions & 2 deletions pennylane/ops/functions/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,12 @@ def generator(op: qml.operation.Operator, format="prefactor"):
>>> op = qml.RX(0.2, wires=0)
>>> qml.generator(op, format="prefactor") # output will always be (obs, prefactor)
(X(0), -0.5)
>>> qml.generator(op, format="hamiltonian") # output will always be a Hamiltonian
(-0.5) [X0]
>>> qml.generator(op, format="hamiltonian") # output will always be a Hamiltonian/LinearCombination
-0.5 * X(0)
>>> with qml.operation.disable_new_opmath_cm():
... gen = qml.generator(op, format="hamiltonian")) # legacy Hamiltonian class
... print(gen, type(gen))
(-0.5) [X0] <class 'pennylane.ops.qubit.hamiltonian.Hamiltonian'>
>>> qml.generator(qml.PhaseShift(0.1, wires=0), format="observable") # ouput will be a simplified obs where possible
Projector([1], wires=[0])
>>> qml.generator(op, format="arithmetic") # output is an instance of `SProd`
Expand Down
34 changes: 7 additions & 27 deletions pennylane/qaoa/cost.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ def bit_driver(wires: Union[Iterable, qaoa.Wires], b: int):
>>> wires = range(3)
>>> hamiltonian = qaoa.bit_driver(wires, 1)
>>> print(hamiltonian)
(1) [Z0]
+ (1) [Z1]
+ (1) [Z2]
1 * Z(0) + 1 * Z(1) + 1 * Z(2)
"""
if b == 0:
coeffs = [-1 for _ in wires]
Expand Down Expand Up @@ -96,25 +94,15 @@ def edge_driver(graph: Union[nx.Graph, rx.PyGraph], reward: list):
>>> graph = nx.Graph([(0, 1), (1, 2)])
>>> hamiltonian = qaoa.edge_driver(graph, ["11", "10", "01"])
>>> print(hamiltonian)
(0.25) [Z0]
+ (0.25) [Z1]
+ (0.25) [Z1]
+ (0.25) [Z2]
+ (0.25) [Z0 Z1]
+ (0.25) [Z1 Z2]
0.25 * (Z(0) @ Z(1)) + 0.25 * Z(0) + 0.25 * Z(1) + 0.25 * (Z(1) @ Z(2)) + 0.25 * Z(1) + 0.25 * Z(2)
>>> import rustworkx as rx
>>> graph = rx.PyGraph()
>>> graph.add_nodes_from([0, 1, 2])
>>> graph.add_edges_from([(0, 1,""), (1,2,"")])
>>> hamiltonian = qaoa.edge_driver(graph, ["11", "10", "01"])
>>> print(hamiltonian)
(0.25) [Z0]
+ (0.25) [Z1]
+ (0.25) [Z1]
+ (0.25) [Z2]
+ (0.25) [Z0 Z1]
+ (0.25) [Z1 Z2]
0.25 * (Z(0) @ Z(1)) + 0.25 * Z(0) + 0.25 * Z(1) + 0.25 * (Z(1) @ Z(2)) + 0.25 * Z(1) + 0.25 * Z(2)
In the above example, ``"11"``, ``"10"``, and ``"01"`` are assigned a lower
energy than ``"00"``. For example, a quick calculation of expectation values gives us:
Expand Down Expand Up @@ -275,27 +263,19 @@ def maxcut(graph: Union[nx.Graph, rx.PyGraph]):
>>> graph = nx.Graph([(0, 1), (1, 2)])
>>> cost_h, mixer_h = qml.qaoa.maxcut(graph)
>>> print(cost_h)
(-1.0) [I0]
+ (0.5) [Z0 Z1]
+ (0.5) [Z1 Z2]
0.5 * (Z(0) @ Z(1)) + 0.5 * (Z(1) @ Z(2)) + -0.5 * (I(0) @ I(1)) + -0.5 * (I(1) @ I(2))
>>> print(mixer_h)
(1) [X0]
+ (1) [X1]
+ (1) [X2]
1 * X(0) + 1 * X(1) + 1 * X(2)
>>> import rustworkx as rx
>>> graph = rx.PyGraph()
>>> graph.add_nodes_from([0, 1, 2])
>>> graph.add_edges_from([(0, 1,""), (1,2,"")])
>>> cost_h, mixer_h = qml.qaoa.maxcut(graph)
>>> print(cost_h)
(-1.0) [I0]
+ (0.5) [Z0 Z1]
+ (0.5) [Z1 Z2]
0.5 * (Z(0) @ Z(1)) + 0.5 * (Z(1) @ Z(2)) + -0.5 * (I(0) @ I(1)) + -0.5 * (I(1) @ I(2))
>>> print(mixer_h)
(1) [X0]
+ (1) [X1]
+ (1) [X2]
1 * X(0) + 1 * X(1) + 1 * X(2)
"""

if not isinstance(graph, (nx.Graph, rx.PyGraph)):
Expand Down
30 changes: 17 additions & 13 deletions pennylane/qaoa/cycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,13 +342,15 @@ def loss_hamiltonian(graph: Union[nx.Graph, rx.PyGraph, rx.PyDiGraph]) -> qml.op
>>> for k, v in edge_weight_data.items():
g[k[0]][k[1]]["weight"] = v
>>> h = loss_hamiltonian(g)
>>> print(h)
(-0.6931471805599453) [Z0]
+ (0.0) [Z1]
+ (0.4054651081081644) [Z2]
+ (0.6931471805599453) [Z3]
+ (0.9162907318741551) [Z4]
+ (1.0986122886681098) [Z5]
>>> h
(
-0.6931471805599453 * Z(0)
+ 0.0 * Z(1)
+ 0.4054651081081644 * Z(2)
+ 0.6931471805599453 * Z(3)
+ 0.9162907318741551 * Z(4)
+ 1.0986122886681098 * Z(5)
)
>>> import rustworkx as rx
>>> g = rx.generators.directed_mesh_graph(3)
Expand All @@ -357,12 +359,14 @@ def loss_hamiltonian(graph: Union[nx.Graph, rx.PyGraph, rx.PyDiGraph]) -> qml.op
g.update_edge(k[0], k[1], {"weight": v})
>>> h = loss_hamiltonian(g)
>>> print(h)
(-0.6931471805599453) [Z0]
+ (0.0) [Z1]
+ (0.4054651081081644) [Z2]
+ (0.6931471805599453) [Z3]
+ (0.9162907318741551) [Z4]
+ (1.0986122886681098) [Z5]
(
-0.6931471805599453 * Z(0)
+ 0.0 * Z(1)
+ 0.4054651081081644 * Z(2)
+ 0.6931471805599453 * Z(3)
+ 0.9162907318741551 * Z(4)
+ 1.0986122886681098 * Z(5)
)
Args:
graph (nx.Graph or rx.PyGraph or rx.PyDiGraph): the graph specifying possible edges
Expand Down
42 changes: 22 additions & 20 deletions pennylane/qaoa/mixers.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ def x_mixer(wires: Union[Iterable, Wires]):
>>> wires = range(3)
>>> mixer_h = qaoa.x_mixer(wires)
>>> print(mixer_h)
(1) [X0]
+ (1) [X1]
+ (1) [X2]
1 * X(0) + 1 * X(1) + 1 * X(2)
"""

wires = Wires(wires)
Expand Down Expand Up @@ -172,30 +170,34 @@ def bit_flip_mixer(graph: Union[nx.Graph, rx.PyGraph], b: int):
>>> from networkx import Graph
>>> graph = Graph([(0, 1), (1, 2)])
>>> mixer_h = qaoa.bit_flip_mixer(graph, 0)
>>> print(mixer_h)
(0.25) [X1]
+ (0.5) [X0]
+ (0.5) [X2]
+ (0.25) [X1 Z2]
+ (0.25) [X1 Z0]
+ (0.5) [X0 Z1]
+ (0.5) [X2 Z1]
+ (0.25) [X1 Z0 Z2]
>>> mixer_h
(
0.5 * X(0)
+ 0.5 * (X(0) @ Z(1))
+ 0.25 * X(1)
+ 0.25 * (X(1) @ Z(2))
+ 0.25 * (X(1) @ Z(0))
+ 0.25 * (X(1) @ Z(0) @ Z(2))
+ 0.5 * X(2)
+ 0.5 * (X(2) @ Z(1))
)
>>> import rustworkx as rx
>>> graph = rx.PyGraph()
>>> graph.add_nodes_from([0, 1, 2])
>>> graph.add_edges_from([(0, 1, ""), (1, 2, "")])
>>> mixer_h = qaoa.bit_flip_mixer(graph, 0)
>>> print(mixer_h)
(0.25) [X1]
+ (0.5) [X0]
+ (0.5) [X2]
+ (0.25) [X1 Z0]
+ (0.25) [X1 Z2]
+ (0.5) [X0 Z1]
+ (0.5) [X2 Z1]
+ (0.25) [X1 Z2 Z0]
(
0.5 * X(0)
+ 0.5 * (X(0) @ Z(1))
+ 0.25 * X(1)
+ 0.25 * (X(1) @ Z(2))
+ 0.25 * (X(1) @ Z(0))
+ 0.25 * (X(1) @ Z(0) @ Z(2))
+ 0.5 * X(2)
+ 0.5 * (X(2) @ Z(1))
)
"""

if not isinstance(graph, (nx.Graph, rx.PyGraph)):
Expand Down
2 changes: 1 addition & 1 deletion pennylane/qchem/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def _openfermion_to_pennylane(qubit_operator, wires=None):
**Example**
>>> q_op = 0.1*QubitOperator('X0') + 0.2*QubitOperator('Y0 Z2')
>>> q_op = 0.1 * QubitOperator('X0') + 0.2 * QubitOperator('Y0 Z2')
>>> q_op
0.1 [X0] +
0.2 [Y0 Z2]
Expand Down
12 changes: 7 additions & 5 deletions pennylane/qchem/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ def particle_number(orbitals):
>>> orbitals = 4
>>> print(particle_number(orbitals))
(2.0) [I0]
+ (-0.5) [Z0]
+ (-0.5) [Z1]
+ (-0.5) [Z2]
+ (-0.5) [Z3]
(
2.0 * I(0)
+ -0.5 * Z(0)
+ -0.5 * Z(1)
+ -0.5 * Z(2)
+ -0.5 * Z(3)
)
"""

if orbitals <= 0:
Expand Down
64 changes: 33 additions & 31 deletions pennylane/qchem/openfermion_obs.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,15 @@ def observable(fermion_ops, init_term=0, mapping="jordan_wigner", wires=None):
>>> t = FermionOperator("0^ 0", 0.5) + FermionOperator("1^ 1", 0.25)
>>> v = FermionOperator("1^ 0^ 0 1", -0.15) + FermionOperator("2^ 0^ 2 0", 0.3)
>>> print(observable([t, v], mapping="jordan_wigner"))
(0.2625) [I0]
+ (-0.1375) [Z0]
+ (-0.0875) [Z1]
+ (-0.0375) [Z0 Z1]
+ (0.075) [Z2]
+ (-0.075) [Z0 Z2]
>>> observable([t, v], mapping="jordan_wigner")
(
0.2625 * I(0)
+ -0.1375 * Z(0)
+ -0.0875 * Z(1)
+ -0.0375 * (Z(0) @ Z(1))
+ 0.075 * Z(2)
+ -0.075 * (Z(0) @ Z(2))
)
"""
openfermion, _ = _import_of()

Expand Down Expand Up @@ -563,30 +565,30 @@ def dipole_of(
>>> symbols = ["H", "H", "H"]
>>> coordinates = np.array([0.028, 0.054, 0.0, 0.986, 1.610, 0.0, 1.855, 0.002, 0.0])
>>> dipole_obs = dipole_of(symbols, coordinates, charge=1)
>>> print(dipole_obs)
[<Hamiltonian: terms=18, wires=[0, 1, 2, 3, 4, 5]>,
<Hamiltonian: terms=18, wires=[0, 1, 2, 3, 4, 5]>,
<Hamiltonian: terms=1, wires=[0]>]
>>> print(dipole_obs[0]) # x-component of D
(0.24190977644628117) [Z4]
+ (0.24190977644628117) [Z5]
+ (0.4781123173263878) [Z0]
+ (0.4781123173263878) [Z1]
+ (0.714477906181248) [Z2]
+ (0.714477906181248) [Z3]
+ (-0.3913638489487808) [Y0 Z1 Y2]
+ (-0.3913638489487808) [X0 Z1 X2]
+ (-0.3913638489487808) [Y1 Z2 Y3]
+ (-0.3913638489487808) [X1 Z2 X3]
+ (-0.1173495878099553) [Y2 Z3 Y4]
+ (-0.1173495878099553) [X2 Z3 X4]
+ (-0.1173495878099553) [Y3 Z4 Y5]
+ (-0.1173495878099553) [X3 Z4 X5]
+ (0.26611147045300276) [Y0 Z1 Z2 Z3 Y4]
+ (0.26611147045300276) [X0 Z1 Z2 Z3 X4]
+ (0.26611147045300276) [Y1 Z2 Z3 Z4 Y5]
+ (0.26611147045300276) [X1 Z2 Z3 Z4 X5]
>>> print([(h.wires) for h in dipole_obs])
[<Wires = [0, 1, 2, 3, 4, 5]>, <Wires = [0, 1, 2, 3, 4, 5]>, <Wires = [0]>]
>>> dipole_obs[0] # x-component of D
(
0.4781123173263876 * Z(0)
+ 0.4781123173263876 * Z(1)
+ -0.3913638489489803 * (Y(0) @ Z(1) @ Y(2))
+ -0.3913638489489803 * (X(0) @ Z(1) @ X(2))
+ -0.3913638489489803 * (Y(1) @ Z(2) @ Y(3))
+ -0.3913638489489803 * (X(1) @ Z(2) @ X(3))
+ 0.2661114704527088 * (Y(0) @ Z(1) @ Z(2) @ Z(3) @ Y(4))
+ 0.2661114704527088 * (X(0) @ Z(1) @ Z(2) @ Z(3) @ X(4))
+ 0.2661114704527088 * (Y(1) @ Z(2) @ Z(3) @ Z(4) @ Y(5))
+ 0.2661114704527088 * (X(1) @ Z(2) @ Z(3) @ Z(4) @ X(5))
+ 0.7144779061810713 * Z(2)
+ 0.7144779061810713 * Z(3)
+ -0.11734958781031017 * (Y(2) @ Z(3) @ Y(4))
+ -0.11734958781031017 * (X(2) @ Z(3) @ X(4))
+ -0.11734958781031017 * (Y(3) @ Z(4) @ Y(5))
+ -0.11734958781031017 * (X(3) @ Z(4) @ X(5))
+ 0.24190977644645698 * Z(4)
+ 0.24190977644645698 * Z(5)
)
"""
openfermion, _ = _import_of()

Expand Down
Loading

0 comments on commit 35de283

Please sign in to comment.