diff --git a/_static/demonstration_assets/sc_qubits/JC_circuit.png b/_static/demonstration_assets/sc_qubits/JC_circuit.png index a28d680c04..316e843a64 100644 Binary files a/_static/demonstration_assets/sc_qubits/JC_circuit.png and b/_static/demonstration_assets/sc_qubits/JC_circuit.png differ diff --git a/_static/demonstration_assets/sc_qubits/LC_circuit.png b/_static/demonstration_assets/sc_qubits/LC_circuit.png index 61908f4126..0bece585c2 100644 Binary files a/_static/demonstration_assets/sc_qubits/LC_circuit.png and b/_static/demonstration_assets/sc_qubits/LC_circuit.png differ diff --git a/_static/demonstration_assets/sc_qubits/anharmonic.png b/_static/demonstration_assets/sc_qubits/anharmonic.png index d2a48942e8..acf031891e 100644 Binary files a/_static/demonstration_assets/sc_qubits/anharmonic.png and b/_static/demonstration_assets/sc_qubits/anharmonic.png differ diff --git a/_static/demonstration_assets/sc_qubits/capacitative.png b/_static/demonstration_assets/sc_qubits/capacitative.png index 15235a89cf..784c6d61cb 100644 Binary files a/_static/demonstration_assets/sc_qubits/capacitative.png and b/_static/demonstration_assets/sc_qubits/capacitative.png differ diff --git a/_static/demonstration_assets/sc_qubits/circuit.png b/_static/demonstration_assets/sc_qubits/circuit.png index 48771efdb5..91026e7d46 100644 Binary files a/_static/demonstration_assets/sc_qubits/circuit.png and b/_static/demonstration_assets/sc_qubits/circuit.png differ diff --git a/_static/demonstration_assets/sc_qubits/conduction_band.png b/_static/demonstration_assets/sc_qubits/conduction_band.png index 5d48703877..ec927cf701 100644 Binary files a/_static/demonstration_assets/sc_qubits/conduction_band.png and b/_static/demonstration_assets/sc_qubits/conduction_band.png differ diff --git a/_static/demonstration_assets/sc_qubits/cooper_pairs.png b/_static/demonstration_assets/sc_qubits/cooper_pairs.png index 1b8aaf7b90..8970c3ca13 100644 Binary files a/_static/demonstration_assets/sc_qubits/cooper_pairs.png and b/_static/demonstration_assets/sc_qubits/cooper_pairs.png differ diff --git a/_static/demonstration_assets/sc_qubits/fabry_perot.png b/_static/demonstration_assets/sc_qubits/fabry_perot.png index 8cf10b49ab..810a295a95 100644 Binary files a/_static/demonstration_assets/sc_qubits/fabry_perot.png and b/_static/demonstration_assets/sc_qubits/fabry_perot.png differ diff --git a/_static/demonstration_assets/sc_qubits/phase_space.png b/_static/demonstration_assets/sc_qubits/phase_space.png index 7c6f02bd64..f2ec76a032 100644 Binary files a/_static/demonstration_assets/sc_qubits/phase_space.png and b/_static/demonstration_assets/sc_qubits/phase_space.png differ diff --git a/_static/demonstration_assets/sc_qubits/photon_absorb.png b/_static/demonstration_assets/sc_qubits/photon_absorb.png index 98b86365a5..77a3059420 100644 Binary files a/_static/demonstration_assets/sc_qubits/photon_absorb.png and b/_static/demonstration_assets/sc_qubits/photon_absorb.png differ diff --git a/_static/demonstration_assets/sc_qubits/sc_device.png b/_static/demonstration_assets/sc_qubits/sc_device.png index 15128d43a9..8c3b2b26c8 100644 Binary files a/_static/demonstration_assets/sc_qubits/sc_device.png and b/_static/demonstration_assets/sc_qubits/sc_device.png differ diff --git a/_static/demonstration_assets/sc_qubits/squid.png b/_static/demonstration_assets/sc_qubits/squid.png index 6028519559..0dfc13216e 100644 Binary files a/_static/demonstration_assets/sc_qubits/squid.png and b/_static/demonstration_assets/sc_qubits/squid.png differ diff --git a/_static/demonstration_assets/trapped_ions/CNOTgate.png b/_static/demonstration_assets/trapped_ions/CNOTgate.png index f04ac4e1d7..f4376a915b 100644 Binary files a/_static/demonstration_assets/trapped_ions/CNOTgate.png and b/_static/demonstration_assets/trapped_ions/CNOTgate.png differ diff --git a/_static/demonstration_assets/trapped_ions/CZgate.png b/_static/demonstration_assets/trapped_ions/CZgate.png index 1cb2bb1999..2a9ea613e6 100644 Binary files a/_static/demonstration_assets/trapped_ions/CZgate.png and b/_static/demonstration_assets/trapped_ions/CZgate.png differ diff --git a/_static/demonstration_assets/trapped_ions/atomic.png b/_static/demonstration_assets/trapped_ions/atomic.png index 8c4fe93cba..20ada81d26 100644 Binary files a/_static/demonstration_assets/trapped_ions/atomic.png and b/_static/demonstration_assets/trapped_ions/atomic.png differ diff --git a/_static/demonstration_assets/trapped_ions/hyperfine.png b/_static/demonstration_assets/trapped_ions/hyperfine.png index fc2622c520..7c4ed31312 100644 Binary files a/_static/demonstration_assets/trapped_ions/hyperfine.png and b/_static/demonstration_assets/trapped_ions/hyperfine.png differ diff --git a/_static/demonstration_assets/trapped_ions/measurement.png b/_static/demonstration_assets/trapped_ions/measurement.png index 0313f6276c..f4120d3556 100644 Binary files a/_static/demonstration_assets/trapped_ions/measurement.png and b/_static/demonstration_assets/trapped_ions/measurement.png differ diff --git a/_static/demonstration_assets/trapped_ions/molmer_sorensen.png b/_static/demonstration_assets/trapped_ions/molmer_sorensen.png index 46af8d5384..42156a8aaa 100644 Binary files a/_static/demonstration_assets/trapped_ions/molmer_sorensen.png and b/_static/demonstration_assets/trapped_ions/molmer_sorensen.png differ diff --git a/_static/demonstration_assets/trapped_ions/pumping.png b/_static/demonstration_assets/trapped_ions/pumping.png index 791ada6933..ae53bd40d8 100644 Binary files a/_static/demonstration_assets/trapped_ions/pumping.png and b/_static/demonstration_assets/trapped_ions/pumping.png differ diff --git a/_static/demonstration_assets/trapped_ions/qccd.png b/_static/demonstration_assets/trapped_ions/qccd.png index 2c2c342f28..a513d3c62e 100644 Binary files a/_static/demonstration_assets/trapped_ions/qccd.png and b/_static/demonstration_assets/trapped_ions/qccd.png differ diff --git a/_static/demonstration_assets/trapped_ions/sidebands.png b/_static/demonstration_assets/trapped_ions/sidebands.png index 521fd947df..d1be9926ef 100644 Binary files a/_static/demonstration_assets/trapped_ions/sidebands.png and b/_static/demonstration_assets/trapped_ions/sidebands.png differ diff --git a/demonstrations/tutorial_trapped_ions.py b/demonstrations/tutorial_trapped_ions.py index 88d2841b3b..f66d892ea5 100644 --- a/demonstrations/tutorial_trapped_ions.py +++ b/demonstrations/tutorial_trapped_ions.py @@ -376,7 +376,7 @@ # light wave at the atom's position. The matrices :math:`S_+` and # :math:`S_-` are # -# .. math:: S_+=\left( \begin{array}{cc} 0 & 0 \\ 1 & 0\end{array}\right), \qquad S_-=\left( \begin{array}{cc} 0 & 1 \\ 0 & 0\end{array}\right). +# .. math:: S_+= \frac{1}{2}(X - iY) =\left( \begin{array}{cc} 0 & 0 \\ 1 & 0\end{array}\right), \qquad S_- = \frac{1}{2}(X + iY) =\left( \begin{array}{cc} 0 & 1 \\ 0 & 0\end{array}\right). # # Hamiltonians in physics are helpful because they tell us how systems # change with time in the presence of external interactions. In quantum @@ -392,7 +392,7 @@ # the duration of the interaction, which is controlled using *pulses*, i.e., short # bursts of light. We do not need to # elaborate on how matrix exponentials are calculated, since we can -# implement them using the scipy library in Python. Let us see how our +# implement them using :func:`qml.evolve` . Let us see how our # basis states :math:`\left\lvert g \right\rangle` and # :math:`\left\lvert e \right\rangle` (:math:`\left\lvert 0 \right\rangle` and # :math:`\left\lvert 1 \right\rangle` in PennyLane) evolve under the action of this @@ -402,89 +402,54 @@ import pennylane as qml from pennylane import numpy as np -from scipy.linalg import expm +# Set a fixed value for Omega Omega = 100 -S_plus = np.array([[0, 0], [1, 0]]) -S_minus = np.array([[0, 1], [0, 0]]) +# Define S+ and S- operators +S_plus = 1/2*(qml.PauliX(0)-1j*qml.PauliY(0)) +S_minus = 1/2*(qml.PauliX(0)+1j*qml.PauliY(0)) +# Define the Hamiltonian operator as a function of the phase +def Ham(phi): -def evolution(phi, t): - Ham = Omega / 2 * (S_plus * np.exp(1j * phi) + S_minus * np.exp(-1j * phi)) - return expm(-1j * Ham * t) + return Omega / 2 * (S_plus * np.exp(1j * phi) + S_minus * np.exp(-1j * phi)) + +# Define the evolution operator as a function of the phase and the time +def evolve_Hamiltonian(phi, time): + + qml.evolve(Ham(phi), coeff = time ) ############################################################################## -# With this operator implemented, we can determine the sequences of pulses that +# With the evolution operator implemented, we can determine the sequences of pulses that # produce common gates. For example, there is a combination of pulses # with different phases and durations that yield the Hadamard gate: -dev = qml.device("default.qubit", wires=1) - - -@qml.qnode(dev, interface="autograd") -def ion_hadamard(state): - - if state == 1: - qml.PauliX(wires=0) - - """We use a series of seemingly arbitrary pulses that will give the Hadamard gate. - Why this is the case will become clear later""" - - qml.QubitUnitary(evolution(0, -np.pi / 2 / Omega), wires=0) - qml.QubitUnitary(evolution(np.pi / 2, np.pi / 2 / Omega), wires=0) - qml.QubitUnitary(evolution(0, np.pi / 2 / Omega), wires=0) - qml.QubitUnitary(evolution(np.pi / 2, np.pi / 2 / Omega), wires=0) - qml.QubitUnitary(evolution(0, np.pi / 2 / Omega), wires=0) - - return qml.state() +def ion_hadamard(): + evolve_Hamiltonian(0, -np.pi / 2 / Omega) + evolve_Hamiltonian(np.pi / 2, np.pi / 2 / Omega) + evolve_Hamiltonian(0, np.pi / 2 / Omega) + evolve_Hamiltonian(np.pi / 2, np.pi / 2 / Omega) + evolve_Hamiltonian(0, np.pi / 2 / Omega) -#For comparison, we use the Hadamard built into PennyLane -@qml.qnode(dev, interface="autograd") -def hadamard(state): - - if state == 1: - qml.PauliX(wires=0) - - qml.Hadamard(wires=0) - - return qml.state() - -#We confirm that the values given by both functions are the same up to numerical error -print(np.isclose(1j * ion_hadamard(0), hadamard(0))) -print(np.isclose(1j * ion_hadamard(1), hadamard(1))) +print("Up to a global phase, the matrix for ion_hadamard is \n") +print("{}".format(1j*qml.matrix(ion_hadamard, wire_order = [0])().round(2))) +print("which corresponds to the Hadamard gate.") ############################################################################## # Note that the desired gate was obtained up to a global phase factor. # A similar exercise can be done for the :math:`T` gate: -@qml.qnode(dev, interface="autograd") -def ion_Tgate(state): - - if state == 1: - qml.PauliX(wires=0) - - qml.QubitUnitary(evolution(0, -np.pi / 2 / Omega), wires=0) - qml.QubitUnitary(evolution(np.pi / 2, np.pi / 4 / Omega), wires=0) - qml.QubitUnitary(evolution(0, np.pi / 2 / Omega), wires=0) - - return qml.state() +def ion_Tgate(): + evolve_Hamiltonian(0, -np.pi / 2 / Omega) + evolve_Hamiltonian(np.pi / 2, np.pi / 4 / Omega) + evolve_Hamiltonian(0, np.pi / 2 / Omega) -@qml.qnode(dev, interface="autograd") -def tgate(state): - - if state == 1: - qml.PauliX(wires=0) - - qml.T(wires=0) - - return qml.state() - - -print(np.isclose(np.exp(1j * np.pi / 8) * ion_Tgate(0), tgate(0))) -print(np.isclose(np.exp(1j * np.pi / 8) * ion_Tgate(1), tgate(1))) +print("Up to a global phase, the matrix for ion_Tgate is \n") +print("{}".format((np.exp(1j * np.pi / 8)*qml.matrix(ion_Tgate, wire_order = [0])()).round(3))) +print("which corresponds to the T gate.") ############################################################################## # This PennyLane code shows that we can obtain a Hadamard gate and a @@ -503,13 +468,14 @@ def tgate(state): import matplotlib.pyplot as plt +dev = qml.device('default.qubit', wires = [0]) -@qml.qnode(dev, interface="autograd") +@qml.qnode(dev) def evolution_prob(t): - qml.QubitUnitary(evolution(0, t / Omega), wires=0) + evolve_Hamiltonian(0, t / Omega) - return qml.probs(wires=0) + return qml.probs(wires=0) t = np.linspace(0, 4 * np.pi, 101) @@ -520,8 +486,8 @@ def evolution_prob(t): ax1.plot(t, s, color="#9D2EC5") ax1.set( - xlabel="time (in units of 1/Ω)", - ylabel="Probability", + xlabel="time (in units of 1/Ω)", + ylabel="Probability", title="Probability of measuring the excited state" ) ax1.grid() @@ -773,9 +739,6 @@ def evolution_prob(t): # \right) # -Omega = 100 - - def Molmer_Sorensen(t): ms = np.array( [ @@ -809,38 +772,18 @@ def Molmer_Sorensen(t): # time :math:`t/\Omega_{MS}`. Let us verify that this is indeed the case # by building the circuit in PennyLane: -dev2 = qml.device("default.qubit",wires=2) +def ion_cnot(): -@qml.qnode(dev2, interface="autograd") -def ion_cnot(basis_state): - - #Prepare the two-qubit basis states from the input - qml.templates.BasisStatePreparation(basis_state, wires=range(2)) - - #Implements the circuit shown above - qml.RY(np.pi/2, wires=0) - qml.QubitUnitary(Molmer_Sorensen(np.pi/2/Omega),wires=[0,1]) - qml.RX(-np.pi/2, wires=0) - qml.RX(-np.pi/2, wires=1) - qml.RY(-np.pi/2, wires=0) - - return qml.state() + qml.RY(np.pi/2, wires=0) + qml.QubitUnitary(Molmer_Sorensen(np.pi/2/Omega),wires=[0,1]) + qml.RX(-np.pi/2, wires=0) + qml.RX(-np.pi/2, wires=1) + qml.RY(-np.pi/2, wires=0) -#Compare with built-in CNOT -@qml.qnode(dev2, interface="autograd") -def cnot_gate(basis_state): - - qml.templates.BasisStatePreparation(basis_state, wires=range(2)) - - qml.CNOT(wires=[0,1]) - - return qml.state() +print("Up to a global phase, the matrix for ion_cnot is \n") +print("{}".format((np.exp(-1j * np.pi / 4)*qml.matrix(ion_cnot, wire_order = [0,1])()).round(1))) +print("which corresponds to the CNOT gate.") -#Check that they are the same up to numerical error and global phase -print(np.isclose(np.exp(-1j*np.pi/4)*ion_cnot([0,0]),cnot_gate([0,0]))) -print(np.isclose(np.exp(-1j*np.pi/4)*ion_cnot([0,1]),cnot_gate([0,1]))) -print(np.isclose(np.exp(-1j*np.pi/4)*ion_cnot([1,0]),cnot_gate([1,0]))) -print(np.isclose(np.exp(-1j*np.pi/4)*ion_cnot([1,1]),cnot_gate([1,1]))) ############################################################################## # This is indeed the CNOT gate, up to a global phase.