Skip to content

Commit

Permalink
Merge branch 'master' into import-noise-models
Browse files Browse the repository at this point in the history
  • Loading branch information
obliviateandsurrender authored Nov 6, 2024
2 parents bc26d77 + 5f7ec9b commit 7d53801
Show file tree
Hide file tree
Showing 26 changed files with 575 additions and 130 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ environment:
$$PYTHON_VENV_PATH/bin/python -m pip install --upgrade git+https://github.com/PennyLaneAI/pennylane-cirq.git#egg=pennylane-cirq;\
$$PYTHON_VENV_PATH/bin/python -m pip install --upgrade git+https://github.com/PennyLaneAI/pennylane-qiskit.git#egg=pennylane-qiskit;\
$$PYTHON_VENV_PATH/bin/python -m pip install --upgrade git+https://github.com/PennyLaneAI/pennylane-qulacs.git#egg=pennylane-qulacs;\
$$PYTHON_VENV_PATH/bin/python -m pip install --extra-index-url https://test.pypi.org/simple/ PennyLane-Lightning --pre --upgrade;\
$$PYTHON_VENV_PATH/bin/python -m pip install --extra-index-url https://test.pypi.org/simple/ PennyLane-Catalyst --pre --upgrade;\
$$PYTHON_VENV_PATH/bin/python -m pip install --extra-index-url https://test.pypi.org/simple/ PennyLane-Lightning --pre --upgrade;\
$$PYTHON_VENV_PATH/bin/python -m pip install --upgrade git+https://github.com/PennyLaneAI/pennylane.git#egg=pennylane;\
fi;\
fi
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 22 additions & 13 deletions demonstrations/tutorial_backprop.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
Let's have a go implementing the parameter-shift rule manually in PennyLane.
"""
import pennylane as qml
from jax import numpy as np
from jax import numpy as jnp
from matplotlib import pyplot as plt
import jax

Expand All @@ -69,19 +69,28 @@
# create a device to execute the circuit on
dev = qml.device("default.qubit", wires=3)


def CNOT_ring(wires):
"""Apply CNOTs in a ring pattern"""
n_wires = len(wires)

for w in wires:
qml.CNOT([w % n_wires, (w + 1) % n_wires])


@qml.qnode(dev, diff_method="parameter-shift")
def circuit(params):
qml.RX(params[0], wires=0)
qml.RY(params[1], wires=1)
qml.RZ(params[2], wires=2)

qml.broadcast(qml.CNOT, wires=[0, 1, 2], pattern="ring")
CNOT_ring(wires=[0, 1, 2])

qml.RX(params[3], wires=0)
qml.RY(params[4], wires=1)
qml.RZ(params[5], wires=2)

qml.broadcast(qml.CNOT, wires=[0, 1, 2], pattern="ring")
CNOT_ring(wires=[0, 1, 2])
return qml.expval(qml.PauliY(0) @ qml.PauliZ(2))


Expand Down Expand Up @@ -109,10 +118,10 @@ def circuit(params):

def parameter_shift_term(qnode, params, i):
shifted = params.copy()
shifted = shifted.at[i].add(np.pi/2)
shifted = shifted.at[i].add(jnp.pi/2)
forward = qnode(shifted) # forward evaluation

shifted = shifted.at[i].add(-np.pi)
shifted = shifted.at[i].add(-jnp.pi)
backward = qnode(shifted) # backward evaluation

return 0.5 * (forward - backward)
Expand All @@ -125,7 +134,7 @@ def parameter_shift_term(qnode, params, i):
# to loop over the index ``i``:

def parameter_shift(qnode, params):
gradients = np.zeros([len(params)])
gradients = jnp.zeros([len(params)])

for i in range(len(params)):
gradients = gradients.at[i].set(parameter_shift_term(qnode, params, i))
Expand All @@ -147,7 +156,7 @@ def parameter_shift(qnode, params):
# Alternatively, we can directly compute quantum gradients of QNodes using
# PennyLane's built in :mod:`qml.gradients <pennylane.gradients>` module:

print(np.stack(qml.gradients.param_shift(circuit)(params)))
print(jnp.stack(qml.gradients.param_shift(circuit)(params)))

##############################################################################
# If you count the number of quantum evaluations, you will notice that we had to evaluate the circuit
Expand Down Expand Up @@ -372,10 +381,10 @@ def circuit(params):
t = timeit.repeat("grad_qnode_backprop(params)", globals=globals(), number=num, repeat=reps)
gradient_backprop.append([num_params, min(t) / num])

gradient_shift = np.array(gradient_shift).T
gradient_backprop = np.array(gradient_backprop).T
forward_shift = np.array(forward_shift).T
forward_backprop = np.array(forward_backprop).T
gradient_shift = jnp.array(gradient_shift).T
gradient_backprop = jnp.array(gradient_backprop).T
forward_shift = jnp.array(forward_shift).T
forward_backprop = jnp.array(forward_backprop).T

##############################################################################
# We now import matplotlib, and plot the results.
Expand Down Expand Up @@ -419,8 +428,8 @@ def circuit(params):
# perform a least squares regression to determine the linear best fit/gradient
# for the normalized time vs. number of parameters
x = gradient_shift[0]
m_shift, c_shift = np.polyfit(*gradient_shift, deg=1)
m_back, c_back = np.polyfit(*gradient_backprop, deg=1)
m_shift, c_shift = jnp.polyfit(*gradient_shift, deg=1)
m_back, c_back = jnp.polyfit(*gradient_backprop, deg=1)

ax.plot(x, m_shift * x + c_shift, '--', label=f"{m_shift:.2f}p{c_shift:+.2f}")
ax.plot(x, m_back * x + c_back, '--', label=f"{m_back:.2f}p{c_back:+.2f}")
Expand Down
4 changes: 4 additions & 0 deletions demonstrations/tutorial_bluequbit.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
import matplotlib.pyplot as plt
import numpy as np

# This filter will suppress deprecation warnings for viewability
import warnings
warnings.filterwarnings("ignore", "QubitDevice", qml.PennyLaneDeprecationWarning)


def bell_pair():
qml.Hadamard(0)
Expand Down
14 changes: 8 additions & 6 deletions demonstrations/tutorial_diffable-mitigation.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
Thus, we can improve the estimates of observables without breaking the differentiable workflow of our variational algorithm.
We will briefly introduce these functionalities and afterwards go more in depth to explore what happens under the hood.
We start by initializing a noisy device under the :class:`~.pennylane.DepolarizingChannel`:
We start by initializing a noisy device using a noise model with :class:`~.pennylane.DepolarizingChannel` errors:
"""

import pennylane as qml
Expand All @@ -54,13 +54,14 @@
n_wires = 4
np.random.seed(1234)

# Describe noise
noise_gate = qml.DepolarizingChannel
noise_strength = 0.05
# Describe noise model
fcond = qml.noise.wires_in(range(n_wires))
noise = qml.noise.partial_wires(qml.DepolarizingChannel, 0.05)
noise_model = qml.NoiseModel({fcond: noise})

# Load devices
dev_ideal = qml.device("default.mixed", wires=n_wires)
dev_noisy = qml.transforms.insert(dev_ideal, noise_gate, noise_strength, position="all")
dev_noisy = qml.add_noise(dev_ideal, noise_model=noise_model)

##############################################################################
# We are going to use the transverse field Ising model Hamiltonian :math:`H = - \sum_i X_i X_{i+1} + 0.5 \sum_i Z_i` as our observable:
Expand All @@ -85,8 +86,9 @@ def qfunc(w1, w2):
qml.SimplifiedTwoDesign(w1, w2, wires=range(n_wires))
return qml.expval(H)

qnode_noisy = qml.QNode(qfunc, dev_noisy)
qnode_ideal = qml.QNode(qfunc, dev_ideal)
qnode_noisy = qml.QNode(qfunc, dev_noisy)
qnode_noisy = qml.transforms.decompose(qnode_noisy, gate_set = ["RY", "CZ"])

##############################################################################
# We can then simply transform the noisy QNode :math:`f^{⚡}` with :func:`~.pennylane.transforms.mitigate_with_zne` to generate :math:`\tilde{f}.`
Expand Down
35 changes: 21 additions & 14 deletions demonstrations/tutorial_error_mitigation.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,31 +49,35 @@
Mitigating noise in a simple circuit
------------------------------------
We first need a noisy device to execute our circuit on. Let's keep things simple for now by loading
the :mod:`default.mixed <pennylane.devices.default_mixed>` simulator and artificially adding
:class:`PhaseDamping <pennylane.PhaseDamping>` noise.
We first need a noisy device to execute our circuit on. Let's keep things simple
for now by loading the :mod:`default.mixed <pennylane.devices.default_mixed>` simulator
and artificially adding :class:`PhaseDamping <pennylane.PhaseDamping>` noise using a
:class:`NoiseModel <pennylane.NoiseModel>`.
"""

import pennylane as qml

n_wires = 4

# Describe noise
noise_gate = qml.PhaseDamping
noise_strength = 0.1
# Describe noise model
fcond = qml.noise.wires_in(range(n_wires))
noise = qml.noise.partial_wires(qml.PhaseDamping, 0.1)
noise_model = qml.NoiseModel({fcond: noise})

# Load devices
dev_ideal = qml.device("default.mixed", wires=n_wires)
dev_noisy = qml.transforms.insert(dev_ideal, noise_gate, noise_strength)
dev_noisy = qml.add_noise(dev_ideal, noise_model=noise_model)

###############################################################################
# In the above, we load a noise-free device ``dev_ideal`` and a noisy device ``dev_noisy``, which
# is constructed from the :func:`qml.transforms.insert <pennylane.transforms.insert>` transform.
# This transform works by intercepting each circuit executed on the device and adding the
# :class:`PhaseDamping <pennylane.PhaseDamping>` noise channel directly after every gate in the
# circuit. To get a better understanding of noise channels like
# :class:`PhaseDamping <pennylane.PhaseDamping>`, check out the :doc:`tutorial_noisy_circuits`
# tutorial.
# In the above, we load a noise-free device ``dev_ideal`` and a noisy device ``dev_noisy``,
# which is constructed from the :func:`qml.add_noise <pennylane.transforms.add_noise>`
# transform. This transform works by intercepting each circuit executed on the device and
# adding the noise to it based on the ``noise_model``. For example, in this case, it will
# add :class:`PhaseDamping <pennylane.PhaseDamping>` noise channel after every gate in the
# circuit acting on wires :math:`[0, 1, 2, 3]`. To get a better understanding of noise
# channels like :class:`PhaseDamping <pennylane.PhaseDamping>` and using noise models,
# check out the :doc:`tutorial_noisy_circuits` and :doc:`tutorial_how_to_use_noise_models`
# tutorials, respectively.
#
# The next step is to define our circuit. Inspired by the mirror circuits concept introduced by
# Proctor *et al.* [#proctor2020measuring]_ let's fix a circuit that applies a unitary :math:`U`
Expand Down Expand Up @@ -112,6 +116,7 @@ def circuit(w1, w2):

ideal_qnode = qml.QNode(circuit, dev_ideal)
noisy_qnode = qml.QNode(circuit, dev_noisy)
noisy_qnode = qml.transforms.decompose(noisy_qnode, gate_set = ["RY", "CZ"])

##############################################################################
# First, we'll visualize the circuit:
Expand Down Expand Up @@ -490,6 +495,7 @@ def qchem_circuit(phi):

ideal_energy = qml.QNode(qchem_circuit, dev_ideal)
noisy_energy = qml.QNode(qchem_circuit, dev_noisy)
noisy_energy = qml.transforms.decompose(noisy_energy, gate_set=["RX", "RY", "RZ", "CNOT"])

ideal_energies.append(ideal_energy(phi))
noisy_energies.append(noisy_energy(phi))
Expand Down Expand Up @@ -517,6 +523,7 @@ def qchem_circuit(phi):
qml.DoubleExcitation(phi, wires=range(n_wires)),
]
circuit = qml.tape.QuantumTape(ops)
[circuit], _ = qml.transforms.decompose(circuit, gate_set=["RX", "RY", "RZ", "CNOT"])

# Define custom executor that expands Hamiltonian measurement
# into a linear combination of tensor products of Pauli
Expand Down
2 changes: 1 addition & 1 deletion demonstrations/tutorial_fermionic_operators.metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
}
],
"dateOfPublication": "2023-06-27T00:00:00+00:00",
"dateOfLastModification": "2024-10-07T00:00:00+00:00",
"dateOfLastModification": "2024-10-30T00:00:00+00:00",
"categories": [
"Quantum Chemistry"
],
Expand Down
6 changes: 3 additions & 3 deletions demonstrations/tutorial_fermionic_operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@

fermi_word = a0_dag * a1
fermi_sentence = 1.3 * a0_dag * a1 + 2.4 * a1
fermi_sentence
print(fermi_sentence)

##############################################################################
# In this simple example, we first created the operator :math:`a^{\dagger}_0 a_1` and then created
# the linear combination :math:`1.3 a^{\dagger}_0 a_1 + 2.4 a_1.` We can also perform
# arithmetic operations between Fermi words and Fermi sentences.

fermi_sentence = fermi_sentence * fermi_word + 2.3 * fermi_word
fermi_sentence
print(fermi_sentence)

##############################################################################
# Beyond multiplication, summation, and subtraction, we can exponentiate fermionic operators in
Expand All @@ -61,7 +61,7 @@
# in the same way that you would write down the operator on a piece of paper:

fermi_sentence = 1.2 * a0_dag + 0.5 * a1 - 2.3 * (a0_dag * a1) ** 2
fermi_sentence
print(fermi_sentence)

##############################################################################
# This Fermi sentence can be mapped to the qubit basis using the
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"title": "How to use quantum arithmetic operators",
"authors": [
{
"username": "gmlejarza"
},
{
"username": "KetPuntoG"
}
],
"dateOfPublication": "2024-11-05T00:00:00+00:00",
"dateOfLastModification": "2024-11-05T00:00:00+00:00",
"categories": [
"Quantum Computing",
"Algorithms",
"How-to"
],
"tags": [],
"previewImages": [
{
"type": "thumbnail",
"uri": "/_static/demo_thumbnails/regular_demo_thumbnails/thumbnail_how_to_use_quantum_arithmetic_operators.png"
},
{
"type": "large_thumbnail",
"uri": "/_static/demo_thumbnails/large_demo_thumbnails/thumbnail_large_how_to_use_quantum_arithmetic_operators.png"
}
],
"seoDescription": "Learn how to use the quantum arithmetic operators of PennyLane.",
"doi": "",
"references": [
{
"id": "shor_exp",
"type": "article",
"title": "Shor's Factoring Algorithm and Modular Exponentiation Operators",
"authors": "Robert L Singleton Jr",
"year": "2023",
"publisher": "",
"url": "https://arxiv.org/abs/2306.09122/"
},
{
"id": "sanders",
"type": "article",
"title": "Black-box quantum state preparation without arithmetic",
"authors": "Yuval R. Sanders, Guang Hao Low, Artur Scherer, Dominic W. Berry",
"year": "2018",
"publisher": "",
"url": "https://arxiv.org/abs/1807.03206/"
}
],
"basedOnPapers": [],
"referencedByPapers": [],
"relatedContent": [
{
"type": "demonstration",
"id": "tutorial_qft_arithmetics",
"weight": 1.0
},
{
"type": "demonstration",
"id": "tutorial_how_to_use_registers",
"weight": 1.0
}
]
}
Loading

0 comments on commit 7d53801

Please sign in to comment.