diff --git a/doc/_static/draw_mpl/main_example.png b/doc/_static/draw_mpl/main_example.png index 655a443a8a3..8abb7bd04a5 100644 Binary files a/doc/_static/draw_mpl/main_example.png and b/doc/_static/draw_mpl/main_example.png differ diff --git a/doc/_static/draw_mpl/postprocessing.png b/doc/_static/draw_mpl/postprocessing.png index c4f10779dfe..d662174c702 100644 Binary files a/doc/_static/draw_mpl/postprocessing.png and b/doc/_static/draw_mpl/postprocessing.png differ diff --git a/doc/_static/draw_mpl/rcparams.png b/doc/_static/draw_mpl/rcparams.png index 9e4fef9fa63..de17d63ffcc 100644 Binary files a/doc/_static/draw_mpl/rcparams.png and b/doc/_static/draw_mpl/rcparams.png differ diff --git a/doc/_static/draw_mpl/show_all_wires.png b/doc/_static/draw_mpl/show_all_wires.png index fcbd5a39681..595655b63da 100644 Binary files a/doc/_static/draw_mpl/show_all_wires.png and b/doc/_static/draw_mpl/show_all_wires.png differ diff --git a/doc/_static/draw_mpl/sketch_style.png b/doc/_static/draw_mpl/sketch_style.png index ca8b521be51..e8454716e08 100644 Binary files a/doc/_static/draw_mpl/sketch_style.png and b/doc/_static/draw_mpl/sketch_style.png differ diff --git a/doc/_static/draw_mpl/wire_order.png b/doc/_static/draw_mpl/wire_order.png index c40973818cc..f0a4ad94446 100644 Binary files a/doc/_static/draw_mpl/wire_order.png and b/doc/_static/draw_mpl/wire_order.png differ diff --git a/doc/_static/draw_mpl/wires_labels.png b/doc/_static/draw_mpl/wires_labels.png index b046adbc770..fc165a02880 100644 Binary files a/doc/_static/draw_mpl/wires_labels.png and b/doc/_static/draw_mpl/wires_labels.png differ diff --git a/doc/introduction/compiling_circuits.rst b/doc/introduction/compiling_circuits.rst index 5591d2646c1..b2beaad0bf3 100644 --- a/doc/introduction/compiling_circuits.rst +++ b/doc/introduction/compiling_circuits.rst @@ -43,17 +43,17 @@ RX(0.09999999999999964, wires=[0]) RX(11.336370614359172, wires=[0]) >>> qml.simplify(qml.ops.Pow(qml.RX(1, 0), 3)) RX(3.0, wires=[0]) ->>> qml.simplify(qml.sum(qml.PauliY(3), qml.PauliY(3))) +>>> qml.simplify(qml.sum(qml.Y(3), qml.Y(3))) 2 * Y(3) >>> qml.simplify(qml.RX(1, 0) @ qml.RX(1, 0)) RX(2.0, wires=[0]) ->>> qml.simplify(qml.prod(qml.PauliX(0), qml.PauliZ(0))) +>>> qml.simplify(qml.prod(qml.X(0), qml.Z(0))) -1j * Y(0) Now lets simplify a nested operator: ->>> sum_op = qml.RX(1, 0) + qml.PauliX(0) ->>> prod1 = qml.PauliX(0) @ sum_op +>>> sum_op = qml.RX(1, 0) + qml.X(0) +>>> prod1 = qml.X(0) @ sum_op >>> nested_op = prod1 @ qml.RX(1, 0) >>> qml.simplify(nested_op) (X(0) @ RX(2.0, wires=[0])) + RX(1.0, wires=[0]) @@ -62,19 +62,19 @@ Several simplifications steps are happening here. First of all, the nested produ .. code-block:: python - qml.prod(qml.PauliX(0), qml.sum(qml.RX(1, 0), qml.PauliX(0)), qml.RX(1, 0)) + qml.prod(qml.X(0), qml.sum(qml.RX(1, 0), qml.X(0)), qml.RX(1, 0)) Then the product of sums is transformed into a sum of products: .. code-block:: python - qml.sum(qml.prod(qml.PauliX(0), qml.RX(1, 0), qml.RX(1, 0)), qml.prod(qml.PauliX(0), qml.PauliX(0), qml.RX(1, 0))) + qml.sum(qml.prod(qml.X(0), qml.RX(1, 0), qml.RX(1, 0)), qml.prod(qml.X(0), qml.X(0), qml.RX(1, 0))) And finally like terms in the obtained products are grouped together, removing all identities: .. code-block:: python - qml.sum(qml.prod(qml.PauliX(0), qml.RX(2, 0)), qml.RX(1, 0)) + qml.sum(qml.prod(qml.X(0), qml.RX(2, 0)), qml.RX(1, 0)) As mentioned earlier we can also simplify QNode objects to, for example, group rotation gates: @@ -219,7 +219,7 @@ For example, suppose we would like to implement the following QNode: def circuit(weights): qml.BasicEntanglerLayers(weights, wires=[0, 1, 2]) - return qml.expval(qml.PauliZ(0)) + return qml.expval(qml.Z(0)) original_dev = qml.device("default.qubit", wires=3) original_qnode = qml.QNode(circuit, original_dev) @@ -333,12 +333,13 @@ by devices to make such measurements possible. On a lower level, the :func:`~.pennylane.pauli.group_observables` function can be used to split lists of observables and coefficients: ->>> obs = [qml.PauliY(0), qml.PauliX(0) @ qml.PauliX(1), qml.PauliZ(1)] +>>> obs = [qml.Y(0), qml.X(0) @ qml.X(1), qml.Z(1)] >>> coeffs = [1.43, 4.21, 0.97] ->>> obs_groupings, coeffs_groupings = qml.pauli.group_observables(obs, coeffs, 'anticommuting', 'lf') +>>> groupings = qml.pauli.group_observables(obs, coeffs, 'anticommuting', 'lf') +>>> obs_groupings, coeffs_groupings = groupings >>> obs_groupings [[Z(1), X(0) @ X(1)], [Y(0)]] >>> coeffs_groupings [[0.97, 4.21], [1.43]] -This and more logic to manipulate Pauli observables is found in the :doc:`pauli module <../code/qml_pauli>`. \ No newline at end of file +This and more logic to manipulate Pauli observables is found in the :doc:`pauli module <../code/qml_pauli>`. diff --git a/doc/introduction/compiling_workflows.rst b/doc/introduction/compiling_workflows.rst index d3d6415755f..d4719334364 100644 --- a/doc/introduction/compiling_workflows.rst +++ b/doc/introduction/compiling_workflows.rst @@ -37,7 +37,7 @@ Check out the Catalyst documentation for Just-in-time compilation ------------------------ -Using Catalyst with PennyLane is a simple as using the :func:`@qjit <.qjit>` decorator to +Using Catalyst with PennyLane is as simple as using the :func:`@qjit <.qjit>` decorator to compile your hybrid workflows: .. code-block:: python @@ -53,7 +53,7 @@ compile your hybrid workflows: qml.RX(jnp.sin(params[0]) ** 2, wires=1) qml.CRY(params[0], wires=[0, 1]) qml.RX(jnp.sqrt(params[1]), wires=1) - return qml.expval(qml.PauliZ(1)) + return qml.expval(qml.Z(1)) The :func:`~.qjit` decorator can also be used on hybrid functions -- that is, functions that include both QNodes and classical processing. @@ -78,7 +78,7 @@ using ``@jax.jit``: # initial parameter params = jnp.array([0.54, 0.3154]) - # define the optimizer + # define the optimizer using a qjit-decorated function opt = jaxopt.GradientDescent(circuit, stepsize=0.4) update = lambda i, args: tuple(opt.update(*args)) @@ -111,7 +111,7 @@ rather than in Python at compile time. You can enable this feature via the else: qml.T(wires=0) - return qml.expval(qml.PauliZ(0)) + return qml.expval(qml.Z(0)) >>> circuit(3) array(0.) @@ -149,7 +149,7 @@ decorator: qml.RX(x[0], wires=0) qml.RY(x[1], wires=1) qml.CNOT(wires=[0, 1]) - return qml.expval(qml.PauliY(0)) + return qml.expval(qml.Y(0)) >>> circuit(jnp.array([0.5, 1.4])) -0.47244976756708373 diff --git a/doc/introduction/inspecting_circuits.rst b/doc/introduction/inspecting_circuits.rst index 2044e7ae41a..71c8373bba8 100644 --- a/doc/introduction/inspecting_circuits.rst +++ b/doc/introduction/inspecting_circuits.rst @@ -47,7 +47,7 @@ For example: qml.Toffoli(wires=(0, 1, 2)) qml.CRY(x[1], wires=(0, 1)) qml.Rot(x[2], x[3], y, wires=0) - return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliX(1)) + return qml.expval(qml.Z(0)), qml.expval(qml.X(1)) We can now use the :func:`~pennylane.specs` transform to generate a function that returns @@ -85,17 +85,20 @@ For example: .. code-block:: python - dev = qml.device('lightning.qubit', wires=(0,1,2,3)) + dev = qml.device('default.qubit') @qml.qnode(dev) def circuit(x, z): qml.QFT(wires=(0,1,2,3)) qml.IsingXX(1.234, wires=(0,2)) qml.Toffoli(wires=(0,1,2)) + mcm = qml.measure(1) + mcm_out = qml.measure(2) qml.CSWAP(wires=(0,2,3)) qml.RX(x, wires=0) + qml.cond(mcm, qml.RY)(np.pi / 4, wires=3) qml.CRZ(z, wires=(3,0)) - return qml.expval(qml.PauliZ(0)) + return qml.expval(qml.Z(0)), qml.probs(op=mcm_out) fig, ax = qml.draw_mpl(circuit)(1.2345,1.2345) @@ -107,10 +110,12 @@ For example: :target: javascript:void(0); >>> print(qml.draw(circuit)(1.2345,1.2345)) -0: ─╭QFT─╭IsingXX(1.23)─╭●─╭●─────RX(1.23)─╭RZ(1.23)─┤ -1: ─├QFT─│──────────────├●─│───────────────│─────────┤ -2: ─├QFT─╰IsingXX(1.23)─╰X─├SWAP───────────│─────────┤ -3: ─╰QFT───────────────────╰SWAP───────────╰●────────┤ +0: ─╭QFT─╭IsingXX(1.23)─╭●───────────╭●─────RX(1.23)─╭RZ(1.23)─┤ +1: ─├QFT─│──────────────├●──┤↗├──────│───────────────│─────────┤ +2: ─├QFT─╰IsingXX(1.23)─╰X───║───┤↗├─├SWAP───────────│─────────┤ +3: ─╰QFT─────────────────────║────║──╰SWAP──RY(0.79)─╰●────────┤ + ╚════║═════════╝ + ╚════════════════════════════╡ Probs[MCM] More information, including various fine-tuning options, can be found in the :doc:`drawing module <../code/qml_drawer>`. @@ -128,7 +133,7 @@ Currently supported devices include: * ``default.mixed``: each snapshot saves the density matrix * ``default.gaussian``: each snapshot saves the covariance matrix and vector of means -During normal execution, the snapshots are ignored: +A :class:`~pennylane.Snapshot` can be used in a QNode like any other operation: .. code-block:: python @@ -136,12 +141,17 @@ During normal execution, the snapshots are ignored: @qml.qnode(dev, interface=None) def circuit(): - qml.Snapshot(measurement=qml.expval(qml.PauliZ(0))) + qml.Snapshot(measurement=qml.expval(qml.Z(0))) qml.Hadamard(wires=0) qml.Snapshot("very_important_state") qml.CNOT(wires=[0, 1]) qml.Snapshot() - return qml.expval(qml.PauliX(0)) + return qml.expval(qml.X(0)) + +During normal execution, the snapshots are ignored: + +>>> circuit() +0.0 However, when using the :func:`~pennylane.snapshots` transform, intermediate device states will be stored and returned alongside the @@ -153,6 +163,9 @@ results. 2: array([0.707+0.j, 0.+0.j, 0.+0.j, 0.707+0.j]), 'execution_results': 0.0} +All snapshots are numbered with consecutive integers, and if no tag was provided, +the number of a snapshot is used as a key in the output dictionary instead. + Graph representation -------------------- @@ -185,7 +198,7 @@ or to check whether two gates causally influence each other. qml.CNOT([1, 2]) qml.CNOT([2, 3]) qml.CNOT([3, 1]) - return qml.expval(qml.PauliZ(0)) + return qml.expval(qml.Z(0)) circuit() @@ -252,7 +265,7 @@ pairwise commutation: ... qml.Hadamard(wires=2) ... qml.CRZ(z, wires=[2, 0]) ... qml.RY(-y, wires=1) -... return qml.expval(qml.PauliZ(0)) +... return qml.expval(qml.Z(0)) >>> dag_fn = qml.commutation_dag(circuit) >>> dag = dag_fn(np.pi / 4, np.pi / 3, np.pi / 2) diff --git a/pennylane/drawer/draw.py b/pennylane/drawer/draw.py index 41fb7fde9ff..38ecfb523c8 100644 --- a/pennylane/drawer/draw.py +++ b/pennylane/drawer/draw.py @@ -370,10 +370,13 @@ def circuit(x, z): qml.QFT(wires=(0,1,2,3)) qml.IsingXX(1.234, wires=(0,2)) qml.Toffoli(wires=(0,1,2)) + mcm = qml.measure(1) + mcm_out = qml.measure(2) qml.CSWAP(wires=(0,2,3)) qml.RX(x, wires=0) + qml.cond(mcm, qml.RY)(np.pi / 4, wires=3) qml.CRZ(z, wires=(3,0)) - return qml.expval(qml.Z(0)) + return qml.expval(qml.Z(0)), qml.probs(op=mcm_out) fig, ax = qml.draw_mpl(circuit)(1.2345,1.2345) @@ -449,8 +452,12 @@ def circuit2(x, y): box1 = plt.Rectangle((-0.5, -0.5), width=3.0, height=4.0, **options) ax.add_patch(box1) - ax.annotate("CSWAP", xy=(3, 2.5), xycoords='data', xytext=(3.8,1.5), textcoords='data', + ax.annotate("CSWAP", xy=(5, 2.5), xycoords='data', xytext=(5.8,1.5), textcoords='data', arrowprops={'facecolor': 'black'}, fontsize=14) + + ax.annotate("classical control flow", xy=(3.5, 4.2), xycoords='data', xytext=(0.8,4.2), + textcoords='data', arrowprops={'facecolor': 'blue'}, fontsize=14, + va="center") fig.show() .. figure:: ../../_static/draw_mpl/postprocessing.png @@ -490,7 +497,7 @@ def circuit2(x, y): plt.rcParams['patch.linewidth'] = 4 plt.rcParams['patch.force_edgecolor'] = True plt.rcParams['lines.color'] = 'indigo' - plt.rcParams['lines.linewidth'] = 5 + plt.rcParams['lines.linewidth'] = 2 plt.rcParams['figure.facecolor'] = 'ghostwhite' fig, ax = qml.draw_mpl(circuit, style="rcParams")(1.2345,1.2345) diff --git a/pennylane/measurements/__init__.py b/pennylane/measurements/__init__.py index d31a4ecab78..1600c0fbfce 100644 --- a/pennylane/measurements/__init__.py +++ b/pennylane/measurements/__init__.py @@ -103,8 +103,10 @@ def circ(x, y): reset to the :math:`|0 \rangle` state by setting the ``reset`` keyword argument of ``qml.measure`` to ``True``. Users can also collect statistics on mid-circuit measurements along with other terminal measurements. Currently, -``qml.expval``, ``qml.probs``, ``qml.sample``, ``qml.counts``, and ``qml.var`` are supported. Users have the -ability to collect statistics on single measurement values. +``qml.expval``, ``qml.probs``, ``qml.sample``, ``qml.counts``, and ``qml.var`` are supported. ``qml.probs``, +``qml.sample``, and ``qml.counts`` support sequences of measurement values, ``qml.expval`` and ``qml.var`` do not. +Statistics of arithmetic combinations of measurement values are supported by all but ``qml.probs``, and only as +long as they are not collected in a sequence, e.g., ``[m1 + m2, m1 - m2]`` is not supported. .. code-block:: python diff --git a/pennylane/qinfo/transforms.py b/pennylane/qinfo/transforms.py index 86c8dc084a3..dc7018de3f1 100644 --- a/pennylane/qinfo/transforms.py +++ b/pennylane/qinfo/transforms.py @@ -57,6 +57,23 @@ def circuit(x): tensor([[0.5+0.j, 0. +0.j], [0. +0.j, 0.5+0.j]], requires_grad=True) + This is equivalent to the state of the wire ``0`` after measuring the wire ``1``: + + .. code-block:: python + + @qml.qnode(dev) + def measured_circuit(x): + qml.IsingXX(x, wires=[0,1]) + m = qml.measure(1) + return qml.density_matrix(wires=[0]), qml.probs(op=m) + + >>> dm, probs = measured_circuit(np.pi/2) + >>> dm + tensor([[0.5+0.j, 0. +0.j], + [0. +0.j, 0.5+0.j]], requires_grad=True) + >>> probs + tensor([0.5, 0.5], requires_grad=True) + .. seealso:: :func:`pennylane.density_matrix` and :func:`pennylane.math.reduce_dm` """ # device_wires is provided by the custom QNode transform @@ -495,30 +512,31 @@ def classical_fisher(qnode, argnums=0): .. code-block:: python import pennylane.numpy as pnp - n_wires = 2 - dev = qml.device("default.qubit", wires=n_wires) + dev = qml.device("default.qubit") @qml.qnode(dev) def circ(params): qml.RX(params[0], wires=0) - qml.RX(params[1], wires=0) - qml.CNOT(wires=(0,1)) - return qml.probs(wires=range(n_wires)) + qml.CNOT([0, 1]) + qml.CRY(params[1], wires=[1, 0]) + qml.Hadamard(1) + return qml.probs(wires=[0, 1]) - Executing this circuit yields the ``2**n_wires`` elements of :math:`p_\ell(\bm{\theta})` + Executing this circuit yields the ``2**2=4`` elements of :math:`p_\ell(\bm{\theta})` + >>> pnp.random.seed(25) >>> params = pnp.random.random(2) >>> circ(params) - [0.61281668 0. 0. 0.38718332] + [0.41850088 0.41850088 0.08149912 0.08149912] We can obtain its ``(2, 2)`` classical fisher information matrix (CFIM) by simply calling the function returned by ``classical_fisher()``: >>> cfim_func = qml.qinfo.classical_fisher(circ) >>> cfim_func(params) - [[1. 1.] - [1. 1.]] + [[ 0.901561 -0.125558] + [-0.125558 0.017486]] This function has the same signature as the :class:`.QNode`. Here is a small example with multiple arguments: @@ -785,7 +803,7 @@ def fidelity(qnode0, qnode1, wires0, wires1): fidelity is simply .. math:: - F( \ket{\psi} , \ket{\phi}) = \left|\braket{\psi, \phi}\right|^2 + F( \ket{\psi} , \ket{\phi}) = \left|\braket{\psi| \phi}\right|^2 .. note:: The second state is coerced to the type and dtype of the first state. The fidelity is returned in the type diff --git a/pennylane/shadows/__init__.py b/pennylane/shadows/__init__.py index 7c1a7eb6997..a525cd5b703 100644 --- a/pennylane/shadows/__init__.py +++ b/pennylane/shadows/__init__.py @@ -74,14 +74,18 @@ .. code-block:: python3 - H = qml.Hamiltonian([1., 1.], [qml.Z(0) @ qml.Z(1), qml.X(0) @ qml.X(1)]) + H = qml.Hamiltonian([1., 1.], [qml.Z(0) @ qml.Z(1), qml.X(0) @ qml.Z(1)]) - dev = qml.device("default.qubit", wires=range(2), shots=10000) + dev = qml.device("default.qubit", shots=10000) + + # shadow_expval + mid-circuit measurements require to defer measurements + @qml.defer_measurements @qml.qnode(dev) def qnode(x): qml.Hadamard(0) qml.CNOT((0,1)) qml.RX(x, wires=0) + qml.measure(1) return qml.shadow_expval(H) x = np.array(0.5, requires_grad=True) @@ -89,9 +93,9 @@ def qnode(x): The big advantage of this way of computing expectation values is that it is differentiable. >>> qnode(x) -array(1.9242) +array(0.8406) >>> qml.grad(qnode)(x) --0.44999999999999984 +-0.49680000000000013 There are more options for post-processing classical shadows in :class:`ClassicalShadow`. """ diff --git a/pennylane/templates/subroutines/qft.py b/pennylane/templates/subroutines/qft.py index f5b5dbb8ec1..2efe83bdcd6 100644 --- a/pennylane/templates/subroutines/qft.py +++ b/pennylane/templates/subroutines/qft.py @@ -61,7 +61,70 @@ def circuit_qft(basis_state): qml.QFT(wires=range(wires)) return qml.state() - circuit_qft(np.array([1.0, 0.0, 0.0], requires_grad=False)) + .. code-block:: pycon + + >>> circuit_qft(np.array([1.0, 0.0, 0.0])) + [ 0.35355339+0.j -0.35355339+0.j 0.35355339+0.j -0.35355339+0.j + 0.35355339+0.j -0.35355339+0.j 0.35355339+0.j -0.35355339+0.j] + + .. details:: + :title: Semiclassical Quantum Fourier transform + + If the QFT is the last subroutine applied within a circuit, it can be + replaced by a + `semiclassical Fourier transform `_. + It makes use of mid-circuit measurements and dynamic circuit control based + on the measurement values, allowing to reduce the number of two-qubit gates. + + As an example, consider the following circuit implementing addition between two + numbers with ``n_wires`` bits (modulo ``2**n_wires``): + + .. code-block:: python + + dev = qml.device("default.qubit", shots=1) + + @qml.qnode(dev) + def qft_add(m, k, n_wires): + qml.BasisEmbedding(m, wires=range(n_wires)) + qml.adjoint(qml.QFT)(wires=range(n_wires)) + for j in range(n_wires): + qml.RZ(-k * np.pi / (2**j), wires=j) + qml.QFT(wires=range(n_wires)) + return qml.sample() + + .. code-block:: pycon + + >>> qft_add(7, 3, n_wires=4) + [1 0 1 0] + + The last building block of this circuit is a QFT, so we may replace it by its + semiclassical counterpart: + + .. code-block:: python + + def scFT(n_wires): + '''semiclassical Fourier transform''' + for w in range(n_wires-1): + qml.Hadamard(w) + mcm = qml.measure(w) + for m in range(w + 1, n_wires): + qml.cond(mcm, qml.PhaseShift)(np.pi / 2 ** (m + 1), wires=m) + qml.Hadamard(n_wires-1) + + @qml.qnode(dev) + def scFT_add(m, k, n_wires): + qml.BasisEmbedding(m, wires=range(n_wires)) + qml.adjoint(qml.QFT)(wires=range(n_wires)) + for j in range(n_wires): + qml.RZ(-k * np.pi / (2**j), wires=j) + scFT(n_wires) + # Revert wire order because of PL's QFT convention + return qml.sample(wires=list(range(n_wires-1, -1, -1))) + + .. code-block:: pycon + + >>> scFT_add(7, 3, n_wires=4) + [1 0 1 0] """ num_wires = AnyWires diff --git a/pennylane/transforms/__init__.py b/pennylane/transforms/__init__.py index e96abb880d2..7df898f2ee5 100644 --- a/pennylane/transforms/__init__.py +++ b/pennylane/transforms/__init__.py @@ -206,10 +206,10 @@ def remove_rx(tape: QuantumTape) -> (Sequence[QuantumTape], Callable): operations = filter(lambda op: op.name != "RX", tape.operations) new_tape = type(tape)(operations, tape.measurements, shots=tape.shots) - def postprocessing(results): + def null_postprocessing(results): return results[0] - return [new_tape], postprocessing + return [new_tape], null_postprocessing To make your transform applicable to both :class:`~.QNode` and quantum functions, you can use the :func:`pennylane.transform` decorator. @@ -218,7 +218,10 @@ def postprocessing(results): dispatched_transform = qml.transform(remove_rx) For a more advanced example, let's consider a transform that sums a circuit with its adjoint. We define the adjoint -of the tape operations, create a new tape, and return both tapes. The processing function then sums the results. +of the tape operations, create a new tape with these new operations, and return both tapes. +The processing function then sums the results of the original and the adjoint tape. +In this example, we use ``qml.transform`` in the form of a decorator in order to turn the custom +function into a quantum transform. .. code-block:: python @@ -231,10 +234,10 @@ def sum_circuit_and_adjoint(tape: QuantumTape) -> (Sequence[QuantumTape], Callab operations = [qml.adjoint(op) for op in tape.operation] new_tape = type(tape)(operations, tape.measurements, shots=tape.shots) - def null_postprocessing(results): + def sum_postprocessing(results): return qml.sum(results) - return [tape, shifted_tape], null_postprocessing + return [tape, new_tape], sum_postprocessing Composability of transforms --------------------------- @@ -267,7 +270,7 @@ def circuit(x, y): Explore practical examples of transforms focused on compiling circuits in the :doc:`compiling circuits documentation `. For gradient transforms, refer to the examples in :doc:`gradients documentation <../code/qml_gradients>`. Discover quantum information transformations in the :doc:`quantum information documentation <../code/qml_qinfo>`. Finally, -for a comprehensive overview of transforms and core functionalities, consult the :doc:`transforms documentation <../code/qml_transforms>`. +for a comprehensive overview of transforms and core functionalities, consult the :doc:`summary above <../code/qml_transforms>`. """ # Leave as alias for backwards-compatibility diff --git a/pennylane/transforms/optimization/pattern_matching.py b/pennylane/transforms/optimization/pattern_matching.py index 84ec45c5c93..83085bf44dc 100644 --- a/pennylane/transforms/optimization/pattern_matching.py +++ b/pennylane/transforms/optimization/pattern_matching.py @@ -158,7 +158,7 @@ def circuit(): ] tape = qml.tape.QuantumTape(ops) - For optimizing the circuit given the given following pattern of CNOTs we apply the `pattern_matching` + For optimizing the circuit given the following pattern of CNOTs we apply the ``pattern_matching`` transform. >>> dev = qml.device('default.qubit', wires=5)