diff --git a/demonstrations/adjoint_diff/scaling.png b/demonstrations/adjoint_diff/scaling.png index 2f6ec2ca50..632a9eb3f4 100644 Binary files a/demonstrations/adjoint_diff/scaling.png and b/demonstrations/adjoint_diff/scaling.png differ diff --git a/demonstrations/ensemble_multi_qpu.py b/demonstrations/ensemble_multi_qpu.py index 7fbda17859..12e16abe60 100644 --- a/demonstrations/ensemble_multi_qpu.py +++ b/demonstrations/ensemble_multi_qpu.py @@ -29,6 +29,7 @@ from collections import Counter +import dask import matplotlib.pyplot as plt import numpy as np import pennylane as qml @@ -229,14 +230,14 @@ def circuit1(params, x=None): ############################################################################## -# We finally combine the two devices into a :class:`~.pennylane.QNodeCollection` that uses the +# We finally combine the two devices into a :class:`~.pennylane.QNode` list that uses the # PyTorch interface: -qnodes = qml.QNodeCollection( - [qml.QNode(circuit0, dev0, interface="torch"), - qml.QNode(circuit1, dev1, interface="torch")] -) +qnodes = [ + qml.QNode(circuit0, dev0, interface="torch"), + qml.QNode(circuit1, dev1, interface="torch"), +] ############################################################################## # Postprocessing into a prediction @@ -245,19 +246,23 @@ def circuit1(params, x=None): # The ``predict_point`` function below allows us to find the ensemble prediction, as well as keeping # track of the individual predictions from each QPU. # -# We include a ``parallel`` keyword argument for evaluating the :class:`~.pennylane.QNodeCollection` +# We include a ``parallel`` keyword argument for evaluating the :class:`~.pennylane.QNode` list # in a parallel asynchronous manner. This feature requires the ``dask`` library, which can be # installed using ``pip install "dask[delayed]"``. When ``parallel=True``, we are able to make # predictions faster because we do not need to wait for one QPU to output before running on the # other. - def decision(softmax): return int(torch.argmax(softmax)) def predict_point(params, x_point=None, parallel=True): - results = qnodes(params, x=x_point, parallel=parallel) + if parallel: + results = tuple(dask.delayed(q)(params, x=x_point) for q in qnodes) + results = torch.tensor(dask.compute(*results, scheduler="threads")) + else: + results = tuple(q(params, x=x_point) for q in qnodes) + results = torch.tensor(results) softmax = torch.nn.functional.softmax(results, dim=1) choice = torch.where(softmax == torch.max(softmax))[0][0] chosen_softmax = softmax[choice] @@ -364,7 +369,7 @@ def accuracy(predictions, actuals): # # Training accuracy (ensemble): 0.824 # Training accuracy (QPU0): 0.648 -# Training accuracy (QPU1): 0.28 +# Training accuracy (QPU1): 0.296 ############################################################################## diff --git a/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_001.png b/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_001.png index de9411b250..bdb4aae9f0 100644 Binary files a/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_001.png and b/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_001.png differ diff --git a/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_002.png b/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_002.png index 03ca3f330f..c27d64c966 100644 Binary files a/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_002.png and b/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_002.png differ diff --git a/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_003.png b/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_003.png index 479f9e3f16..dc60873ef7 100644 Binary files a/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_003.png and b/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_003.png differ diff --git a/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_004.png b/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_004.png index f64bb52eda..b6fdcfce22 100644 Binary files a/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_004.png and b/demonstrations/ensemble_multi_qpu/ensemble_multi_qpu_004.png differ diff --git a/demonstrations/tutorial_gbs.metadata.json b/demonstrations/gbs.metadata.json similarity index 100% rename from demonstrations/tutorial_gbs.metadata.json rename to demonstrations/gbs.metadata.json diff --git a/demonstrations/tutorial_gbs.py b/demonstrations/gbs.py similarity index 85% rename from demonstrations/tutorial_gbs.py rename to demonstrations/gbs.py index f57a171385..bd5a5345e9 100644 --- a/demonstrations/tutorial_gbs.py +++ b/demonstrations/gbs.py @@ -8,7 +8,7 @@ .. meta:: :property="og:description": Using light to perform tasks beyond the reach of classical computers. - :property="og:image": https://pennylane.ai/qml/_images/tutorial_gbs_expt2.png + :property="og:image": https://pennylane.ai/qml/_images/gbs_expt2.png .. related:: @@ -19,6 +19,9 @@ *Authors: Josh Izaac and Nathan Killoran — Posted: 04 December 2020. Last updated: 04 December 2020.* +.. warning:: + This demo is only compatible with PennyLane version ``0.29`` or below. + On the journey to large-scale fault-tolerant quantum computers, one of the first major milestones is to demonstrate a quantum device carrying out tasks that are beyond the reach of any classical algorithm. The launch of Xanadu's Borealis device marked an important milestone @@ -45,12 +48,12 @@ | -.. image:: /demonstrations/tutorial_gbs_expt2.png +.. image:: /demonstrations/gbs_expt2.png :align: center :width: 80% :target: javascript:void(0); -.. figure:: /demonstrations/tutorial_gbs_expt1.png +.. figure:: /demonstrations/gbs_expt1.png :align: center :width: 80% :target: javascript:void(0); @@ -116,7 +119,7 @@ matrix :math:`U`. When decomposed into a quantum optical circuit, the interferometer will be made up of beamsplitters and phase shifters. -.. image:: /demonstrations/tutorial_gbs_circuit2.png +.. image:: /demonstrations/gbs_circuit2.png :align: center :width: 90% :target: javascript:void(0); @@ -147,7 +150,22 @@ U = unitary_group.rvs(4) print(U) -###################################################################### +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# [[ 0.23648826-0.48221431j 0.06829648+0.04447898j 0.51150074-0.09529866j +# 0.55205719-0.35974699j] +# [-0.11148167+0.69780321j -0.24943828+0.08410701j 0.46705929-0.43192981j +# 0.16220654-0.01817602j] +# [-0.22351926-0.25918352j 0.24364996-0.05375623j -0.09259829-0.53810588j +# 0.27267708+0.66941977j] +# [ 0.11519953-0.28596729j -0.90164923-0.22099186j -0.09627758-0.13105595j +# -0.0200152 +0.12766128j]] +# # We can now use this to construct the circuit, choosing a compatible # device. For the simulation, we can use the Strawberry Fields # Gaussian backend. This backend is perfectly suited for simulation of GBS, @@ -197,7 +215,16 @@ def gbs_circuit(): probs = gbs_circuit().reshape([cutoff] * n_wires) print(probs.shape) -###################################################################### +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# (10, 10, 10, 10) +# +# # For example, element ``[1,2,0,1]`` represents the probability of # detecting 1 photon on wire # ``0`` and wire ``3``, and 2 photons at wire ``1``, i.e., the value @@ -214,7 +241,19 @@ def gbs_circuit(): for i in measure_states: print(f"|{''.join(str(j) for j in i)}>: {probs[i]}") -###################################################################### +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# |0000>: 0.17637844761413496 +# |1100>: 0.03473293649420282 +# |0101>: 0.011870900427255589 +# |1111>: 0.005957399165336106 +# |2000>: 0.02957384308320549 +# # The GBS Distribution # -------------------- # @@ -292,6 +331,16 @@ def gbs_circuit(): print(A[:, [0, 1]][[0, 1]]) +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# [[ 0.19343159-0.54582922j 0.43418269-0.09169615j] +# [ 0.43418269-0.09169615j -0.27554025-0.46222197j]] +# ###################################################################### # i.e., we consider only the rows and columns where a photon was detected, which gives us # the submatrix corresponding to indices :math:`0` and :math:`1`. @@ -310,6 +359,16 @@ def gbs_circuit(): print(1 / np.cosh(1) ** 4) print(probs[0, 0, 0, 0]) +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# 0.1763784476141347 +# 0.17637844761413496 +# ###################################################################### # **Measuring** :math:`|1,1,0,0\rangle` **at the output** @@ -317,6 +376,16 @@ def gbs_circuit(): print(np.abs(haf(A)) ** 2 / np.cosh(1) ** 4) print(probs[1, 1, 0, 0]) +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# 0.03473293649420271 +# 0.03473293649420282 +# ###################################################################### # **Measuring** :math:`|0,1,0,1\rangle` **at the output** @@ -324,7 +393,16 @@ def gbs_circuit(): print(np.abs(haf(A)) ** 2 / np.cosh(1) ** 4) print(probs[0, 1, 0, 1]) -###################################################################### +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# 0.011870900427255558 +# 0.011870900427255589 +# # **Measuring** :math:`|1,1,1,1\rangle` **at the output** # # This corresponds to the hafnian of the full matrix :math:`A=UU^T\mathrm{tanh}(r)`: @@ -333,7 +411,16 @@ def gbs_circuit(): print(np.abs(haf(A)) ** 2 / np.cosh(1) ** 4) print(probs[1, 1, 1, 1]) -###################################################################### +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# 0.005957399165336081 +# 0.005957399165336106 +# # **Measuring** :math:`|2,0,0,0\rangle` **at the output** # # Since we have two photons in mode ``q[0]``, we take two copies of the @@ -343,7 +430,16 @@ def gbs_circuit(): print(np.abs(haf(A)) ** 2 / (2 * np.cosh(1) ** 4)) print(probs[2, 0, 0, 0]) -###################################################################### +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# 0.029573843083205383 +# 0.02957384308320549 +# # The PennyLane simulation results agree (with almost negligible numerical error) to the # expected result from the Gaussian boson sampling equation! # diff --git a/demonstrations/tutorial_gbs_circuit.png b/demonstrations/gbs_circuit.png similarity index 100% rename from demonstrations/tutorial_gbs_circuit.png rename to demonstrations/gbs_circuit.png diff --git a/demonstrations/tutorial_gbs_circuit.svg b/demonstrations/gbs_circuit.svg similarity index 100% rename from demonstrations/tutorial_gbs_circuit.svg rename to demonstrations/gbs_circuit.svg diff --git a/demonstrations/tutorial_gbs_circuit2.png b/demonstrations/gbs_circuit2.png similarity index 100% rename from demonstrations/tutorial_gbs_circuit2.png rename to demonstrations/gbs_circuit2.png diff --git a/demonstrations/tutorial_gbs_expt1.png b/demonstrations/gbs_expt1.png similarity index 100% rename from demonstrations/tutorial_gbs_expt1.png rename to demonstrations/gbs_expt1.png diff --git a/demonstrations/tutorial_gbs_expt2.png b/demonstrations/gbs_expt2.png similarity index 100% rename from demonstrations/tutorial_gbs_expt2.png rename to demonstrations/gbs_expt2.png diff --git a/demonstrations/tutorial_gbs_thumbnail.png b/demonstrations/gbs_thumbnail.png similarity index 100% rename from demonstrations/tutorial_gbs_thumbnail.png rename to demonstrations/gbs_thumbnail.png diff --git a/demonstrations/tutorial_plugins_hybrid.metadata.json b/demonstrations/plugins_hybrid.metadata.json similarity index 92% rename from demonstrations/tutorial_plugins_hybrid.metadata.json rename to demonstrations/plugins_hybrid.metadata.json index 805b2a167c..df59495fac 100644 --- a/demonstrations/tutorial_plugins_hybrid.metadata.json +++ b/demonstrations/plugins_hybrid.metadata.json @@ -19,7 +19,7 @@ ], "seoDescription": "This tutorial introduces the notion of hybrid computation by combining several PennyLane device backends to train an algorithm containing both photonic and qubit devices.", "doi": "", - "canonicalURL": "https://pennylane.ai/qml/demos/tutorial_plugins_hybrid.html", + "canonicalURL": "https://pennylane.ai/qml/demos/plugins_hybrid.html", "references": [], "basedOnPapers": [], "referencedByPapers": [], diff --git a/demonstrations/tutorial_plugins_hybrid.py b/demonstrations/plugins_hybrid.py similarity index 84% rename from demonstrations/tutorial_plugins_hybrid.py rename to demonstrations/plugins_hybrid.py index b3bd6669c7..fc7df39cbb 100644 --- a/demonstrations/tutorial_plugins_hybrid.py +++ b/demonstrations/plugins_hybrid.py @@ -24,6 +24,9 @@ Be sure to read through the introductory :ref:`qubit rotation ` and :ref:`Gaussian transformation ` tutorials before attempting this tutorial. +.. warning:: + This demo is only compatible with PennyLane version ``0.29`` or below. + .. note:: To follow along with this tutorial on your own computer, you will require the @@ -195,6 +198,16 @@ def cost(params): init_params = np.array([0.01, 0.01], requires_grad=True) print(cost(init_params)) +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# -9.999666671111081e-05 +# + ############################################################################## # Here, we choose the values of :math:`\theta` and :math:`\phi` to be very close to zero; # this results in :math:`B(\theta,\phi)\approx I`, and the output of the quantum @@ -212,6 +225,16 @@ def cost(params): dphoton_redirection = qml.grad(photon_redirection, argnum=0) print(dphoton_redirection([0.0, 0.0])) +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# [array(0.), array(0.)] +# + ############################################################################## # Now, let's use the :class:`~.pennylane.GradientDescentOptimizer`, and update the circuit # parameters over 100 optimization steps. @@ -233,6 +256,36 @@ def cost(params): print("Optimized rotation angles: {}".format(params)) +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# Cost after step 5: -0.0349558 +# Cost after step 10: -0.9969017 +# Cost after step 15: -1.0000000 +# Cost after step 20: -1.0000000 +# Cost after step 25: -1.0000000 +# Cost after step 30: -1.0000000 +# Cost after step 35: -1.0000000 +# Cost after step 40: -1.0000000 +# Cost after step 45: -1.0000000 +# Cost after step 50: -1.0000000 +# Cost after step 55: -1.0000000 +# Cost after step 60: -1.0000000 +# Cost after step 65: -1.0000000 +# Cost after step 70: -1.0000000 +# Cost after step 75: -1.0000000 +# Cost after step 80: -1.0000000 +# Cost after step 85: -1.0000000 +# Cost after step 90: -1.0000000 +# Cost after step 95: -1.0000000 +# Cost after step 100: -1.0000000 +# Optimized rotation angles: [1.57079633 0.01 ] +# +# ############################################################################## # Comparing this to the :ref:`exact calculation ` above, @@ -342,6 +395,37 @@ def cost(params, phi1=0.5, phi2=0.1): print("Optimized rotation angles: {}".format(params)) + +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# Cost after step 5: 0.2154539 +# Cost after step 10: 0.0000982 +# Cost after step 15: 0.0000011 +# Cost after step 20: 0.0000000 +# Cost after step 25: 0.0000000 +# Cost after step 30: 0.0000000 +# Cost after step 35: 0.0000000 +# Cost after step 40: 0.0000000 +# Cost after step 45: 0.0000000 +# Cost after step 50: 0.0000000 +# Cost after step 55: 0.0000000 +# Cost after step 60: 0.0000000 +# Cost after step 65: 0.0000000 +# Cost after step 70: 0.0000000 +# Cost after step 75: 0.0000000 +# Cost after step 80: 0.0000000 +# Cost after step 85: 0.0000000 +# Cost after step 90: 0.0000000 +# Cost after step 95: 0.0000000 +# Cost after step 100: 0.0000000 +# Optimized rotation angles: [1.20671364 0.01 ] +# +# ############################################################################## # Substituting this into the photon redirection QNode shows that it now produces # the same output as the qubit rotation QNode: @@ -350,6 +434,16 @@ def cost(params, phi1=0.5, phi2=0.1): print(photon_redirection(result)) print(qubit_rotation(0.5, 0.1)) +############################################################################## +# .. rst-class:: sphx-glr-script-out +# +# Out: +# +# .. code-block:: none +# +# 0.8731983021146449 +# 0.8731983044562817 +# ############################################################################## # This is just a simple example of the kind of hybrid computation that can be carried # out in PennyLane. Quantum nodes (bound to different devices) and classical diff --git a/demonstrations/qnspsa.py b/demonstrations/qnspsa.py index 4ed9c8d465..f859b5f48d 100644 --- a/demonstrations/qnspsa.py +++ b/demonstrations/qnspsa.py @@ -383,7 +383,7 @@ def get_overlap_tape(qnode, params1, params2): def get_state_overlap(tape): - return qml.execute([tape], dev, None)[0][0][0] + return qml.execute([tape], dev, None)[0][0] ###################################################################### @@ -810,10 +810,10 @@ def __post_process_tensor(self, tensor_raw_results, tensor_dirs): # is a tensor of shape (d x d), d being the dimension of the input parameter # to the ansatz. tensor_finite_diff = ( - tensor_raw_results[0][0][0] - - tensor_raw_results[1][0][0] - - tensor_raw_results[2][0][0] - + tensor_raw_results[3][0][0] + tensor_raw_results[0][0] + - tensor_raw_results[1][0] + - tensor_raw_results[2][0] + + tensor_raw_results[3][0] ) metric_tensor = ( -( diff --git a/demonstrations/qonn.py b/demonstrations/qonn.py index 7fb1b4e213..1466249d5e 100644 --- a/demonstrations/qonn.py +++ b/demonstrations/qonn.py @@ -14,6 +14,9 @@ *Author: Theodor Isacsson — Posted: 05 August 2020. Last updated: 08 March 2022.* +.. warning:: + This demo is only compatible with PennyLane version ``0.29`` or below. + This tutorial is based on a paper from `Steinbrecher et al. (2019) `__ which explores a Quantum Optical Neural Network (QONN) based on Fock states. Similar to the continuous-variable :doc:`quantum neural network diff --git a/demonstrations/quantum_neural_net.py b/demonstrations/quantum_neural_net.py index fa1cf13b76..bc88c3f26d 100644 --- a/demonstrations/quantum_neural_net.py +++ b/demonstrations/quantum_neural_net.py @@ -19,6 +19,9 @@ *Author: Maria Schuld — Posted: 11 October 2019. Last updated: 25 January 2021.* +.. warning:: + This demo is only compatible with PennyLane version ``0.29`` or below. + In this example we show how a variational circuit can be used to learn a fit for a one-dimensional function when being trained with noisy samples from that function. @@ -140,7 +143,6 @@ def cost(var, features, labels): plt.tick_params(axis="both", which="minor", labelsize=16) plt.show() - ############################################################################## # .. image:: ../demonstrations/quantum_neural_net/qnn_output_20_0.png # diff --git a/demonstrations/quantum_volume.py b/demonstrations/quantum_volume.py index 86af1d07d0..4c052bb141 100644 --- a/demonstrations/quantum_volume.py +++ b/demonstrations/quantum_volume.py @@ -378,7 +378,7 @@ def qv_circuit_layer(num_qubits): # need to run the same random circuit on two devices independently. num_qubits = 5 -dev_ideal = qml.device("default.qubit", shots=None, wires=num_qubits) +dev_ideal = qml.device("lightning.qubit", shots=None, wires=num_qubits) m = 3 # number of qubits diff --git a/demonstrations/tutorial_adaptive_circuits.py b/demonstrations/tutorial_adaptive_circuits.py index 0aa824d66b..fc9e9bdac3 100644 --- a/demonstrations/tutorial_adaptive_circuits.py +++ b/demonstrations/tutorial_adaptive_circuits.py @@ -346,7 +346,7 @@ def circuit(params): t1 = time.time() params, energy = opt.step_and_cost(circuit, params) t2 = time.time() - print("n = {:}, E = {:.8f} H, t = {:.2f} s".format(n, energy, t2 - t1)) + print("n = {:}, E = {:.8f} H, t = {:.2f} s".format(n, energy[0], t2 - t1)) ############################################################################## # Using the sparse method reproduces the ground state energy while the optimization time is diff --git a/demonstrations/tutorial_classical_kernels.py b/demonstrations/tutorial_classical_kernels.py index cecc229c68..e57d743979 100644 --- a/demonstrations/tutorial_classical_kernels.py +++ b/demonstrations/tutorial_classical_kernels.py @@ -701,7 +701,10 @@ def probabilities_threshold_normalize(probabilities, thresh = 1.e-10): # itself, in case it is of use later: def fourier_q(d, thetas, amplitudes): - return np.real(coefficients(lambda x: QK(x, thetas, amplitudes), 1, d-1)) + def QK_partial(x): + squeezed_x = qml.math.squeeze(x) + return QK(squeezed_x, thetas, amplitudes) + return np.real(coefficients(QK_partial, 1, d-1)) ############################################################################### # And with this, we can finally visualize how the Fourier spectrum of the diff --git a/demonstrations/tutorial_error_mitigation.py b/demonstrations/tutorial_error_mitigation.py index 84cd251105..66f5238894 100644 --- a/demonstrations/tutorial_error_mitigation.py +++ b/demonstrations/tutorial_error_mitigation.py @@ -316,7 +316,7 @@ def executor(circuits, dev=dev_noisy): # Run extrapolation zero_noise = fac.reduce() -print(f"ZNE result: {zero_noise[0]}") +print(f"ZNE result: {zero_noise}") ############################################################################## # Let's make a plot of the data and fitted extrapolation function. diff --git a/demonstrations/tutorial_gaussian_transformation.metadata.json b/demonstrations/tutorial_gaussian_transformation.metadata.json index 4d149ba055..0acc7f03ca 100644 --- a/demonstrations/tutorial_gaussian_transformation.metadata.json +++ b/demonstrations/tutorial_gaussian_transformation.metadata.json @@ -26,7 +26,7 @@ "relatedContent": [ { "type": "demonstration", - "id": "tutorial_plugins_hybrid", + "id": "plugins_hybrid", "weight": 1.0 }, { diff --git a/demonstrations/tutorial_gaussian_transformation.py b/demonstrations/tutorial_gaussian_transformation.py index 210ab6f5da..de9d63fea8 100644 --- a/demonstrations/tutorial_gaussian_transformation.py +++ b/demonstrations/tutorial_gaussian_transformation.py @@ -9,7 +9,7 @@ :property="og:image": https://pennylane.ai/qml/_images/gauss-circuit.png .. related:: - tutorial_plugins_hybrid Plugins and Hybrid computation + plugins_hybrid Plugins and Hybrid computation quantum_neural_net Function fitting with a photonic quantum neural network qonn Optimizing a quantum optical neural network diff --git a/demonstrations/tutorial_geometric_qml.py b/demonstrations/tutorial_geometric_qml.py index 1a70803e51..adacad158b 100644 --- a/demonstrations/tutorial_geometric_qml.py +++ b/demonstrations/tutorial_geometric_qml.py @@ -678,7 +678,7 @@ def encode_game(game): # calculate the mean square error for this classification problem def cost_function(params, input, target): - output = torch.stack([circuit(x, params) for x in input]) + output = torch.stack([torch.hstack(circuit(x, params)) for x in input]) vec = output - target sum_sqr = torch.sum(vec * vec, dim=1) return torch.mean(sum_sqr) @@ -707,7 +707,7 @@ def cost_function(params, input, target): def accuracy(p, x_val, y_val): with torch.no_grad(): y_val = torch.tensor(y_val) - y_out = torch.stack([circuit(x, p) for x in x_val]) + y_out = torch.stack([torch.hstack(circuit(x, p)) for x in x_val]) acc = torch.sum(torch.argmax(y_out, axis=1) == torch.argmax(y_val, axis=1)) return acc / len(x_val) @@ -764,7 +764,7 @@ def opt_func(): def cost_function_no_sym(params, input, target): - output = torch.stack([circuit_no_sym(x, params) for x in input]) + output = torch.stack([torch.hstack(circuit_no_sym(x, params)) for x in input]) vec = output - target sum_sqr = torch.sum(vec * vec, dim=1) return torch.mean(sum_sqr) @@ -781,7 +781,7 @@ def cost_function_no_sym(params, input, target): def accuracy_no_sym(p, x_val, y_val): with torch.no_grad(): y_val = torch.tensor(y_val) - y_out = torch.stack([circuit_no_sym(x, p) for x in x_val]) + y_out = torch.stack([torch.hstack(circuit_no_sym(x, p)) for x in x_val]) acc = torch.sum(torch.argmax(y_out, axis=1) == torch.argmax(y_val, axis=1)) return acc / len(x_val) @@ -832,7 +832,6 @@ def opt_func(): from matplotlib import pyplot as plt -plt.style.use("seaborn") plt.title("Validation accuracies") plt.plot(saved_accs_sym, "b", label="Symmetric") plt.plot(saved_accs, "g", label="Standard") @@ -852,7 +851,7 @@ def opt_func(): # ###################################################################### -# The use of symmetries in both quantum and classsical machine learning is a developing field, so we +# The use of symmetries in both quantum and classical machine learning is a developing field, so we # can expect new results to emerge over the coming years. If you want to get # involved, the references given below are a great place to start. diff --git a/demonstrations/tutorial_learning_from_experiments.py b/demonstrations/tutorial_learning_from_experiments.py index b992993a6f..28102d3518 100644 --- a/demonstrations/tutorial_learning_from_experiments.py +++ b/demonstrations/tutorial_learning_from_experiments.py @@ -199,9 +199,9 @@ def circuit(ts=False): # the measurement outcomes for the first 3 shots circuit = generate_circuit(n_shots) -print(circuit(ts=True)[:, 0:3]) +print(np.array(circuit(ts=True))[:, 0:3]) print("\n") -print(circuit(ts=False)[:, 0:3]) +print(np.array(circuit(ts=False))[:, 0:3]) ###################################################################### @@ -231,6 +231,7 @@ def circuit(ts=False): def process_data(raw_data): "convert raw data to vectors of means and variances of each qubit" + raw_data = np.array(raw_data) nc = len(raw_data) # the number of circuits used to generate the data nq = len(raw_data[0]) # the number of qubits in each circuit new_data = np.zeros([nc, 2 * nq]) @@ -437,7 +438,7 @@ def enhanced_circuit(ts=False): # If we look at the raw measurement data for the T-symmetric unitaries: # -raw_data[0][:, 0:5] # outcomes of first 5 shots of the first T-symmetric circuit +np.array(raw_data[0])[:, 0:5] # outcomes of first 5 shots of the first T-symmetric circuit ###################################################################### diff --git a/demonstrations/tutorial_local_cost_functions.py b/demonstrations/tutorial_local_cost_functions.py index 580d64a851..9d0bd016b9 100644 --- a/demonstrations/tutorial_local_cost_functions.py +++ b/demonstrations/tutorial_local_cost_functions.py @@ -129,7 +129,7 @@ def local_cost_simple(rotations): local_circuit = qml.QNode(local_cost_simple, dev, interface="autograd") def cost_local(rotations): - return 1 - np.sum(local_circuit(rotations)[:,0])/wires + return 1 - np.sum([i for (i, _) in local_circuit(rotations)])/wires def cost_global(rotations): diff --git a/demonstrations/tutorial_ml_classical_shadows.py b/demonstrations/tutorial_ml_classical_shadows.py index 3d2d4e12e0..761b1a063f 100644 --- a/demonstrations/tutorial_ml_classical_shadows.py +++ b/demonstrations/tutorial_ml_classical_shadows.py @@ -168,7 +168,7 @@ def corr_function(i, j): import scipy as sp ham = Hamiltonian(J_mat) -eigvals, eigvecs = sp.sparse.linalg.eigs(qml.utils.sparse_hamiltonian(ham)) +eigvals, eigvecs = sp.sparse.linalg.eigs(ham.sparse_matrix()) psi0 = eigvecs[:, np.argmin(eigvals)] @@ -516,7 +516,7 @@ def build_dataset(num_points, Nr, Nc, T=500): for coupling_mat in coupling_mats: ham = Hamiltonian(coupling_mat) - eigvals, eigvecs = sp.sparse.linalg.eigs(qml.utils.sparse_hamiltonian(ham)) + eigvals, eigvecs = sp.sparse.linalg.eigs(ham.sparse_matrix()) psi = eigvecs[:, np.argmin(eigvals)] shadow = gen_class_shadow(circuit_oshot, psi, T, num_qubits) diff --git a/demonstrations/tutorial_noisy_circuits.py b/demonstrations/tutorial_noisy_circuits.py index 5bc14bfd35..9736f50120 100644 --- a/demonstrations/tutorial_noisy_circuits.py +++ b/demonstrations/tutorial_noisy_circuits.py @@ -231,7 +231,7 @@ def depolarizing_circuit(p): # ensure that the trainable parameters give rise to a valid channel parameter, i.e., a number # between 0 and 1. # -ev = np.tensor(0.7781, requires_grad=False) # observed expectation value +ev = 0.7781 # observed expectation value def sigmoid(x): return 1/(1+np.exp(-x)) diff --git a/demonstrations/tutorial_photonics.metadata.json b/demonstrations/tutorial_photonics.metadata.json index ce444132e0..de40f38497 100644 --- a/demonstrations/tutorial_photonics.metadata.json +++ b/demonstrations/tutorial_photonics.metadata.json @@ -134,7 +134,7 @@ }, { "type": "demonstration", - "id": "tutorial_gbs", + "id": "gbs", "weight": 1.0 } ] diff --git a/demonstrations/tutorial_photonics.py b/demonstrations/tutorial_photonics.py index f042bc0527..61fc2429a8 100644 --- a/demonstrations/tutorial_photonics.py +++ b/demonstrations/tutorial_photonics.py @@ -11,7 +11,7 @@ tutorial_pasqal Quantum computation with neutral atoms tutorial_trapped_ions Trapped ion quantum computing tutorial_sc_qubits Quantum computing with superconducting qubits - tutorial_gbs Quantum advantage with Gaussian Boson Sampling + gbs Quantum advantage with Gaussian Boson Sampling *Author: Alvaro Ballon — Posted: 31 May 2022. Last updated: 16 June 2022.* @@ -168,8 +168,8 @@ def vacuum_measure_p(): # Sample measurements in phase space -x_sample = vacuum_measure_x().numpy() -p_sample = vacuum_measure_p().numpy() +x_sample = vacuum_measure_x() +p_sample = vacuum_measure_p() # Import some libraries for a nicer plot from scipy.stats import gaussian_kde @@ -287,8 +287,8 @@ def measure_coherent_p(alpha, phi): # Choose alpha and phi and sample 1000 measurements -x_sample_coherent = measure_coherent_x(3, np.pi / 3).numpy() -p_sample_coherent = measure_coherent_p(3, np.pi / 3).numpy() +x_sample_coherent = measure_coherent_x(3, np.pi / 3) +p_sample_coherent = measure_coherent_p(3, np.pi / 3) # Plot as before xp = vstack([x_sample_coherent, p_sample_coherent]) @@ -514,8 +514,8 @@ def measure_squeezed_p(r): # Choose alpha and phi and sample 1000 measurements -x_sample_squeezed = measure_squeezed_x(0.4).numpy() -p_sample_squeezed = measure_squeezed_p(0.4).numpy() +x_sample_squeezed = measure_squeezed_x(0.4) +p_sample_squeezed = measure_squeezed_p(0.4) # Plot as before xp = vstack([x_sample_squeezed, p_sample_squeezed]) @@ -617,22 +617,29 @@ def measurement(a, phi): @qml.qnode(dev_exact2) -def measurement2(a, theta, alpha, phi): +def measurement2_0(a, theta, alpha, phi): qml.Displacement(a, theta, wires = 0) # We choose the initial to be a displaced vacuum qml.CoherentState(alpha, phi, wires = 1) # Prepare coherent as second qumode qml.Beamsplitter(np.pi / 4, 0, wires=[0, 1]) # Interfere both states - return qml.expval(qml.NumberOperator(0)), qml.expval(qml.NumberOperator(1)) # Read out N + return qml.expval(qml.NumberOperator(0)) # Read out N + +@qml.qnode(dev_exact2) +def measurement2_1(a, theta, alpha, phi): + qml.Displacement(a, theta, wires = 0) # We choose the initial to be a displaced vacuum + qml.CoherentState(alpha, phi, wires = 1) # Prepare coherent as second qumode + qml.Beamsplitter(np.pi / 4, 0, wires=[0, 1]) # Interfere both states + return qml.expval(qml.NumberOperator(1)) # Read out N print( - "Expectation value of x-quadrature after displacement: {}\n".format(measurement(3, 0).numpy()) + "Expectation value of x-quadrature after displacement: {}\n".format(measurement(3, 0)) ) print("Expected current in each detector:") -print("Detector 1: {}".format(measurement2(3, 0, 1, 0)[0].numpy())) -print("Detector 2: {}".format(measurement2(3, 0, 1, 0)[1].numpy())) +print("Detector 1: {}".format(measurement2_0(3, 0, 1, 0))) +print("Detector 2: {}".format(measurement2_1(3, 0, 1, 0))) print( "Difference between currents: {}".format( - measurement2(3, 0, 1, 0)[1].numpy() - measurement2(3, 0, 1, 0)[0].numpy() + measurement2_1(3, 0, 1, 0) - measurement2_0(3, 0, 1, 0) ) ) @@ -683,7 +690,7 @@ def measurement2(a, theta, alpha, phi): # A Gaussian Boson Sampling circuit. The beamsplitters here may include phase shifts. # # Gaussian boson sampling (GBS) is interesting on its own -# (see :doc:`this tutorial ` for an in-depth discussion). +# (see :doc:`this tutorial ` for an in-depth discussion). # So far, two quantum devices have used large-scale versions of this circuit # to achieve quantum advantage on a particular computation, which involves sampling from # a probability distribution that classical computers take too long to simulate. In 2019, USTC's Jiuzhang device took 200 seconds diff --git a/demonstrations/tutorial_quantum_transfer_learning.py b/demonstrations/tutorial_quantum_transfer_learning.py index 94f6a4cf19..b0d852c06a 100644 --- a/demonstrations/tutorial_quantum_transfer_learning.py +++ b/demonstrations/tutorial_quantum_transfer_learning.py @@ -381,7 +381,7 @@ def forward(self, input_features): q_out = torch.Tensor(0, n_qubits) q_out = q_out.to(device) for elem in q_in: - q_out_elem = quantum_net(elem, self.q_params).float().unsqueeze(0) + q_out_elem = torch.hstack(quantum_net(elem, self.q_params)).float().unsqueeze(0) q_out = torch.cat((q_out, q_out_elem)) # return the two-dimensional prediction from the postprocessing layer diff --git a/demonstrations/tutorial_qubit_rotation.metadata.json b/demonstrations/tutorial_qubit_rotation.metadata.json index e846c878f8..428a6b6224 100644 --- a/demonstrations/tutorial_qubit_rotation.metadata.json +++ b/demonstrations/tutorial_qubit_rotation.metadata.json @@ -26,7 +26,7 @@ "relatedContent": [ { "type": "demonstration", - "id": "tutorial_plugins_hybrid", + "id": "plugins_hybrid", "weight": 1.0 }, { diff --git a/demonstrations/tutorial_qubit_rotation.py b/demonstrations/tutorial_qubit_rotation.py index acc9ab0b19..9ce3bfdf5d 100644 --- a/demonstrations/tutorial_qubit_rotation.py +++ b/demonstrations/tutorial_qubit_rotation.py @@ -11,7 +11,7 @@ .. related:: - tutorial_plugins_hybrid Plugins and hybrid computation + plugins_hybrid Plugins and hybrid computation tutorial_gaussian_transformation Gaussian transformation tutorial_state_preparation Training a quantum circuit with PyTorch diff --git a/demonstrations/tutorial_toric_code.py b/demonstrations/tutorial_toric_code.py index f0aa1bd316..871edd7b39 100644 --- a/demonstrations/tutorial_toric_code.py +++ b/demonstrations/tutorial_toric_code.py @@ -333,8 +333,8 @@ def circuit(): E0 = -sum(xgroup_expvals) - sum(zgroup_expvals) -print("X Group expectation values", xgroup_expvals) -print("Z Group expectation values", zgroup_expvals) +print("X Group expectation values", [np.round(val) for val in xgroup_expvals]) +print("Z Group expectation values", [np.round(val) for val in zgroup_expvals]) print("Total energy: ", E0) @@ -436,8 +436,8 @@ def excitations(x_sites, z_sites): x_expvals, z_expvals = separate_expvals(excitations(single_x, [])) -print("XGroup: ", x_expvals) -print("ZGroup: ", z_expvals) +print("XGroup: ", [np.round(val) for val in x_expvals]) +print("ZGroup: ", [np.round(val) for val in z_expvals]) ###################################################################### @@ -448,7 +448,7 @@ def excitations(x_sites, z_sites): # expectation value is :math:`-1`, then a quasiparticle exists in that location. # -occupation_numbers = lambda expvals: 0.5 * (1 - expvals) +occupation_numbers = lambda expvals: [0.5 * (1 - np.round(val)) for val in expvals] def print_info(x_expvals, z_expvals): E = -sum(x_expvals) - sum(z_expvals) diff --git a/demonstrations/vqe_parallel.npz b/demonstrations/vqe_parallel.npz index 774c342051..1b1272dc3f 100644 Binary files a/demonstrations/vqe_parallel.npz and b/demonstrations/vqe_parallel.npz differ diff --git a/demos_getting-started.rst b/demos_getting-started.rst index 42855248ba..a6113d2c91 100644 --- a/demos_getting-started.rst +++ b/demos_getting-started.rst @@ -37,7 +37,7 @@ Here you can discover the basic tools needed to use PennyLane through simple dem .. gallery-item:: :tooltip: Use quantum machine learning in a multi-device quantum algorithm. :figure: demonstrations/plugins_hybrid/photon_redirection.png - :description: :doc:`demos/tutorial_plugins_hybrid` + :description: :doc:`demos/plugins_hybrid` :tags: autograd photonics strawberryfields .. gallery-item:: @@ -110,7 +110,7 @@ Here you can discover the basic tools needed to use PennyLane through simple dem demos/tutorial_qubit_rotation demos/tutorial_backprop demos/tutorial_adjoint_diff - demos/tutorial_plugins_hybrid + demos/plugins_hybrid demos/tutorial_noisy_circuits demos/tutorial_gaussian_transformation demos/braket-parallel-gradients diff --git a/demos_quantum-computing.rst b/demos_quantum-computing.rst index 8952a8b5d8..c34f87b641 100644 --- a/demos_quantum-computing.rst +++ b/demos_quantum-computing.rst @@ -56,8 +56,8 @@ such as benchmarking and characterizing quantum processors. .. gallery-item:: :tooltip: Construct and simulate a Gaussian Boson Sampler. - :figure: demonstrations/tutorial_gbs_thumbnail.png - :description: :doc:`demos/tutorial_gbs` + :figure: demonstrations/gbs_thumbnail.png + :description: :doc:`demos/gbs` :tags: photonics strawberryfields .. gallery-item:: @@ -133,7 +133,7 @@ such as benchmarking and characterizing quantum processors. demos/tutorial_classical_shadows demos/tutorial_pasqal demos/qsim_beyond_classical - demos/tutorial_gbs + demos/gbs demos/tutorial_trapped_ions demos/tutorial_error_mitigation demos/tutorial_sc_qubits diff --git a/requirements.txt b/requirements.txt index 2c82f33515..f0e2e23c75 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,12 +15,11 @@ pyscf==2.1.1 cirq-core==0.14.1 cirq-pasqal==0.14.1 openfermionpyscf==0.5 # required by 2 tutorials: tutorial_quantum_chemistry and tutorial_adaptive_circuits and tutorial_diffable_shadows -pennylane==0.29.1 -pennylane-sf==0.29.0 -pennylane-cirq==0.29.0 -pennylane-qiskit==0.29.0 +git+https://github.com/PennyLaneAI/pennylane.git +git+https://github.com/PennyLaneAI/pennylane-cirq.git +git+https://github.com/PennyLaneAI/pennylane-qiskit.git qulacs==0.1.10.1 -pennylane-qulacs==0.29.0 +git+https://github.com/PennyLaneAI/pennylane-qulacs.git scikit-learn==0.23.2 docutils==0.16 markupsafe==2.0.1 diff --git a/requirements_no_deps.txt b/requirements_no_deps.txt index 2cbcb376ed..4bb3a0b40e 100644 --- a/requirements_no_deps.txt +++ b/requirements_no_deps.txt @@ -1,3 +1,2 @@ mitiq==0.13.0 -pyquil==2.21 -pennylane-lightning \ No newline at end of file +pyquil==2.21 \ No newline at end of file diff --git a/what-is-quantum-computing.rst b/what-is-quantum-computing.rst index 872fc696be..fc660fbb1e 100644 --- a/what-is-quantum-computing.rst +++ b/what-is-quantum-computing.rst @@ -71,7 +71,7 @@ The bigger picture: quantum advantage Whether practical algorithmic speedups are possible in the NISQ regime remains an open problem, but some instances have already been demonstrated of `quantum devices solving computational problems `_ that would take classical computers an unfeasible amount of time. **Quantum computational advantage is already a reality**, -with an :doc:`increasing number ` of commercial and research organizations announcing their :doc:`breakthroughs `—some even +with an :doc:`increasing number ` of commercial and research organizations announcing their :doc:`breakthroughs `—some even making their devices publicly available for further research. Quantum computational advantage does not necessarily need to be demonstrated on problems that are thought of as