Skip to content

Trigger two demos of QA interests #1349

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 31 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
372c23c
Merge branch 'master' into dev
actions-user Jan 21, 2025
2fd2d36
Merge branch 'master' into dev
actions-user Jan 23, 2025
f29da50
Merge branch 'master' into dev
actions-user Jan 23, 2025
55dfa98
Fix deprecated code usage in `tutorial_odegen.py` (#1311)
andrijapau Jan 28, 2025
0aaa21b
Merge branch 'master' into dev
actions-user Feb 3, 2025
68c6f08
Fix controlled qubit unitary usage (#1310)
JerryChen97 Feb 3, 2025
691322d
Fix `tutorial_pulse_programming101.py` to type cast `expval` (#1317)
andrijapau Feb 14, 2025
ea28de2
Merge branch 'master' into dev
actions-user Feb 14, 2025
1c30e26
Merge branch 'master' into dev
actions-user Feb 21, 2025
b354cb0
Merge branch 'master' into dev
actions-user Feb 24, 2025
fd6e502
Merge branch 'master' into dev
actions-user Feb 26, 2025
055b66c
Merge branch 'master' into dev
actions-user Feb 27, 2025
d3f3b93
Merge branch 'master' into dev
actions-user Mar 5, 2025
4cf80ef
Merge branch 'master' into dev
actions-user Mar 5, 2025
cc80022
Update `tutorial_noisy_circuits.py` to port `default.mixed` free of l…
JerryChen97 Mar 12, 2025
97e27db
Upgrade scipy (#1323)
JerryChen97 Mar 13, 2025
88faa1b
Use `qml.lie_closure` and `qml.structure_constants` top level (#1329)
Qottmann Mar 17, 2025
e3199f7
Merge branch 'master' into dev
actions-user Mar 18, 2025
3943dff
Merge branch 'master' into dev
actions-user Mar 21, 2025
75df4db
Add references to new `qml.liealg` functionality in Lie algebraic dem…
dwierichs Mar 26, 2025
99487b2
Merge branch 'master' into dev
actions-user Mar 31, 2025
e562b0e
Update `tutorial_qnn_module_tf` after the deprecation of `qml.qnn.Ker…
JerryChen97 Apr 1, 2025
d4e3721
Merge branch 'master' into dev
actions-user Apr 3, 2025
fc99a50
Merge branch 'master' into dev
actions-user Apr 3, 2025
297410b
Merge branch 'master' into dev
actions-user Apr 3, 2025
2b4c67f
Merge branch 'master' into dev
actions-user Apr 4, 2025
7c9828c
Temp update to makefile to install PL RC (#1338)
PietropaoloFrisoni Apr 7, 2025
631a674
Merge branch 'master' into dev
actions-user Apr 10, 2025
3ed6603
[Bug fix] Update fixed depth hamiltonian simulation demo (#1344)
Qottmann Apr 11, 2025
2208896
Trigger two demos of urgent interests
JerryChen97 Apr 11, 2025
139ad07
Merge branch 'dev' into demo-qa-dummy-trigger
JerryChen97 Apr 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ environment:
$$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-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;\
$$PYTHON_VENV_PATH/bin/python -m pip install --upgrade git+https://github.com/PennyLaneAI/pennylane.git@v0.41.0-rc0#egg=pennylane;\
$$PYTHON_VENV_PATH/bin/python -m pip install --upgrade git+https://github.com/XanaduAI/iqpopt.git#egg=iqpopt;\
fi;\
fi
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
}
],
"dateOfPublication": "2020-11-02T00:00:00+00:00",
"dateOfLastModification": "2024-10-07T00:00:00+00:00",
"dateOfLastModification": "2025-03-21T00:00:00+00:00",
"categories": [
"Devices and Performance",
"Quantum Machine Learning"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
"""
r"""
.. role:: html(raw)
:format: html

Turning quantum nodes into Keras Layers
=======================================

Expand All @@ -10,7 +13,13 @@

tutorial_qnn_module_torch Turning quantum nodes into Torch Layers

*Author: Tom Bromley — Posted: 02 November 2020. Last updated: 28 January 2021.*
*Author: Tom Bromley — Posted: 02 November 2020. Last updated: 21 March 2025.*

.. warning::

This demo is only compatible with PennyLane version 0.40 or below.
For usage with a later version of PennyLane, please consider using
:doc:`PyTorch </demos/tutorial_qnn_module_torch>` or :doc:`JAX </demos/tutorial_How_to_optimize_QML_model_using_JAX_and_Optax>`.

Creating neural networks in `Keras <https://keras.io/>`__ is easy. Models are constructed from
elementary *layers* and can be trained using a high-level API. For example, the following code
Expand Down Expand Up @@ -67,6 +76,11 @@
plt.scatter(X[:, 0], X[:, 1], c=c)
plt.show()

##############################################################################
# .. figure:: /_static/demonstration_assets/qnn_module/sphx_glr_qnn_module_tf_001.png
# :width: 100%
# :align: center

###############################################################################
# Defining a QNode
# ----------------
Expand Down Expand Up @@ -166,7 +180,25 @@ def qnode(inputs, weights):

fitting = model.fit(X, y_hot, epochs=6, batch_size=5, validation_split=0.25, verbose=2)

###############################################################################
##############################################################################
# .. rst-class:: sphx-glr-script-out
#
# .. code-block:: none
#
# Epoch 1/6
# 30/30 - 4s - loss: 0.4153 - accuracy: 0.7333 - val_loss: 0.3183 - val_accuracy: 0.7800 - 4s/epoch - 123ms/step
# Epoch 2/6
# 30/30 - 4s - loss: 0.2927 - accuracy: 0.8000 - val_loss: 0.2475 - val_accuracy: 0.8400 - 4s/epoch - 130ms/step
# Epoch 3/6
# 30/30 - 4s - loss: 0.2272 - accuracy: 0.8333 - val_loss: 0.2111 - val_accuracy: 0.8200 - 4s/epoch - 119ms/step
# Epoch 4/6
# 30/30 - 4s - loss: 0.1963 - accuracy: 0.8667 - val_loss: 0.1917 - val_accuracy: 0.8600 - 4s/epoch - 118ms/step
# Epoch 5/6
# 30/30 - 4s - loss: 0.1772 - accuracy: 0.8667 - val_loss: 0.1828 - val_accuracy: 0.8600 - 4s/epoch - 117ms/step
# Epoch 6/6
# 30/30 - 4s - loss: 0.1603 - accuracy: 0.8733 - val_loss: 0.2006 - val_accuracy: 0.8200 - 4s/epoch - 117ms/step
#
#
# How did we do? The model looks to have successfully trained and the accuracy on both the
# training and validation datasets is reasonably high. In practice, we would aim to push the
# accuracy higher by thinking carefully about the model design and the choice of hyperparameters
Expand Down Expand Up @@ -224,7 +256,25 @@ def qnode(inputs, weights):

fitting = model.fit(X, y_hot, epochs=6, batch_size=5, validation_split=0.25, verbose=2)

###############################################################################
##############################################################################
# .. rst-class:: sphx-glr-script-out
#
# .. code-block:: none
#
# Epoch 1/6
# 30/30 - 7s - loss: 0.3682 - accuracy: 0.7467 - val_loss: 0.2550 - val_accuracy: 0.8000 - 7s/epoch - 229ms/step
# Epoch 2/6
# 30/30 - 7s - loss: 0.2428 - accuracy: 0.8067 - val_loss: 0.2105 - val_accuracy: 0.8400 - 7s/epoch - 224ms/step
# Epoch 3/6
# 30/30 - 7s - loss: 0.2001 - accuracy: 0.8333 - val_loss: 0.1901 - val_accuracy: 0.8200 - 7s/epoch - 220ms/step
# Epoch 4/6
# 30/30 - 7s - loss: 0.1816 - accuracy: 0.8600 - val_loss: 0.1776 - val_accuracy: 0.8200 - 7s/epoch - 224ms/step
# Epoch 5/6
# 30/30 - 7s - loss: 0.1661 - accuracy: 0.8667 - val_loss: 0.1711 - val_accuracy: 0.8600 - 7s/epoch - 224ms/step
# Epoch 6/6
# 30/30 - 7s - loss: 0.1520 - accuracy: 0.8600 - val_loss: 0.1807 - val_accuracy: 0.8200 - 7s/epoch - 221ms/step
#
#
# Great! We've mastered the basics of constructing hybrid classical-quantum models using
# PennyLane and Keras. Can you think of any interesting hybrid models to construct? How do they
# perform on realistic datasets?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
}
],
"dateOfPublication": "2022-10-31T00:00:00+00:00",
"dateOfLastModification": "2024-12-13T00:00:00+00:00",
"dateOfLastModification": "2025-01-23T00:00:00+00:00",
"categories": [
"Quantum Chemistry"
],
Expand Down
2 changes: 1 addition & 1 deletion demonstrations/tutorial_classically_boosted_vqe.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ def hadamard_test(Uq, Ucl, component="real"):

qml.Hadamard(wires=[0])
qml.ControlledQubitUnitary(
Uq.conjugate().T @ Ucl, control_wires=[0], wires=wires[1:]
Uq.conjugate().T @ Ucl, wires=wires
)
qml.Hadamard(wires=[0])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
}
],
"dateOfPublication": "2024-12-19T00:00:00+00:00",
"dateOfLastModification": "2025-01-10T00:00:00+00:00",
"dateOfLastModification": "2025-04-11T00:00:00+00:00",
"categories": [
"Quantum Computing",
"Algorithms"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
Introduction
------------

The :doc:`KAK theorem </demos/tutorial_kak_decomposition>` is an important result from Lie theory that states that any Lie group element :math:`U` can be decomposed
The :doc:`KAK decomposition </demos/tutorial_kak_decomposition>` is an important result from Lie theory that states that any Lie group element :math:`U` can be decomposed
as :math:`U = K_1 A K_2,` where :math:`K_{1, 2}` and :math:`A` are elements of two special sub-groups
:math:`\mathcal{K}` and :math:`\mathcal{A},` respectively. In special cases, the decomposition simplifies to :math:`U = K A K^\dagger.`

Expand All @@ -36,14 +36,14 @@
We can use this general result from Lie theory as a powerful circuit decomposition technique.

.. note:: We recommend a basic understanding of Lie algebras, see e.g. our :doc:`introduction to (dynamical) Lie algebras for quantum practitioners </demos/tutorial_liealgebra>`.
Otherwise, this demo should be self-contained, though for the mathematically inclined, we further recommend our :doc:`demo on the KAK theorem </demos/tutorial_kak_decomposition>`
that dives into the mathematical depths of the theorem and provides more background info.
Otherwise, this demo should be self-contained, though for the mathematically inclined, we further recommend our :doc:`demo on the KAK decomposition </demos/tutorial_kak_decomposition>`
that dives into the mathematical depths of the decomposition and provides more background info.

Goal: Fast-forwarding time evolutions using the KAK decomposition
-----------------------------------------------------------------

Unitary gates in quantum computing are described by the special unitary Lie group :math:`SU(2^n),` so we can use the KAK
theorem to decompose quantum gates into :math:`U = K_1 A K_2.` While the mathematical statement is rather straightforward,
decomposition to factorize quantum gates into :math:`U = K_1 A K_2.` While the mathematical statement is rather straightforward,
actually finding this decomposition is not. We are going to follow the recipe prescribed in
`Fixed Depth Hamiltonian Simulation via Cartan Decomposition <https://arxiv.org/abs/2104.00728>`__ [#Kökcü]_,
which tackles this decomposition on the level of the associated Lie algebra via Cartan decomposition.
Expand Down Expand Up @@ -74,6 +74,7 @@
import numpy as np
import pennylane as qml
from pennylane import X, Y, Z
from pennylane.liealg import even_odd_involution, cartan_decomp, horizontal_cartan_subalgebra

import jax
import jax.numpy as jnp
Expand Down Expand Up @@ -111,10 +112,8 @@
# One common choice of involution is the so-called even-odd involution for Pauli words,
# :math:`P = P_1 \otimes P_2 .. \otimes P_n,` where :math:`P_j \in \{I, X, Y, Z\}.`
# It essentially counts whether the number of non-identity Pauli operators in the Pauli word is even or odd.

def even_odd_involution(op):
[pw] = op.pauli_rep
return len(pw) % 2
# It is readily available in PennyLane as :func:`~.pennylane.liealg.even_odd_involution`, which
# we already imported above.

even_odd_involution(X(0)), even_odd_involution(X(0) @ Y(3))

Expand All @@ -126,30 +125,9 @@ def even_odd_involution(op):
# sort the operators by whether or not they yield a plus or minus sign from the involution function.
# This is possible because the operators and involution nicely align with the eigenspace decomposition.

def cartan_decomposition(g, involution):
"""Cartan Decomposition g = k + m

Args:
g (List[PauliSentence]): the (dynamical) Lie algebra to decompose
involution (callable): Involution function :math:`\Theta(\cdot)` to act on PauliSentence ops, should return ``0/1`` or ``True/False``.

Returns:
k (List[PauliSentence]): the vertical subspace :math:`\Theta(x) = x`
m (List[PauliSentence]): the horizontal subspace :math:`\Theta(x) = -x` """
m = []
k = []

for op in g:
if involution(op): # vertical space when involution returns True
k.append(op)
else: # horizontal space when involution returns False
m.append(op)
return k, m

k, m = cartan_decomposition(g, even_odd_involution)
k, m = cartan_decomp(g, even_odd_involution)
len(g), len(k), len(m)


##############################################################################
# We have successfully decomposed the 60-dimensional Lie algebra
# into a 24-dimensional vertical subspace and a 36-dimensional subspace.
Expand Down Expand Up @@ -187,51 +165,11 @@ def cartan_decomposition(g, involution):
# that commute with it.
#
# We then obtain a further split of the vector space :math:`\mathfrak{m} = \tilde{\mathfrak{m}} \oplus \mathfrak{h},`
# where :math:`\tilde{\mathfrak{m}}` is just the remainder of :math:`\mathfrak{m}.`
# where :math:`\tilde{\mathfrak{m}}` is just the remainder of :math:`\mathfrak{m}.` The function
# :func:`~.pennylane.liealg.horizontal_cartan_subalgebra` returns some additional information, which we will
# not use here.

def _commutes_with_all(candidate, ops):
r"""Check if ``candidate`` commutes with all ``ops``"""
for op in ops:
com = candidate.commutator(op)
com.simplify()

if not len(com) == 0:
return False
return True

def cartan_subalgebra(m, which=0):
"""Compute the Cartan subalgebra from the horizontal subspace :math:`\mathfrak{m}`
of the Cartan decomposition

This implementation is specific for cases of bases of m with pure Pauli words as
detailed in Appendix C in `2104.00728 <https://arxiv.org/abs/2104.00728>`__.

Args:
m (List[PauliSentence]): the horizontal subspace :math:`\Theta(x) = -x
which (int): Choice for the initial element of m from which to construct
the maximal Abelian subalgebra

Returns:
mtilde (List): remaining elements of :math:`\mathfrak{m}`
s.t. :math:`\mathfrak{m} = \tilde{\mathfrak{m}} \oplus \mathfrak{h}`.
h (List): Cartan subalgebra :math:`\mathfrak{h}`.

"""

h = [m[which]] # first candidate
mtilde = m.copy()

for m_i in m:
if _commutes_with_all(m_i, h):
if m_i not in h:
h.append(m_i)

for h_i in h:
mtilde.remove(h_i)

return mtilde, h

mtilde, h = cartan_subalgebra(m)
g, k, mtilde, h, _ = horizontal_cartan_subalgebra(k, m, tol=1e-8)
len(g), len(k), len(mtilde), len(h)

##############################################################################
Expand All @@ -241,7 +179,7 @@ def cartan_subalgebra(m, which=0):
# Variational KhK decomposition
# -----------------------------
#
# The KAK theorem is not constructive in the sense that it proves that there exists such a decomposition, but there is no general way of obtaining
# The KAK decomposition is not constructive in the sense that it proves that there exists such a decomposition, but there is no general way of obtaining
# it. In particular, there are no linear algebra subroutines implemented in ``numpy`` or ``scipy`` that just compute it for us.
# Here, we follow the construction of [#Kökcü]_ for the special case of :math:`H` being in the horizontal space and the decomposition
# simplifying to :math:`H = K^\dagger h K`.
Expand Down Expand Up @@ -282,10 +220,10 @@ def cartan_subalgebra(m, which=0):
#

def run_opt(
value_and_grad,
loss,
theta,
n_epochs=500,
lr=0.1,
n_epochs=1000,
lr=0.05,
):
"""Boilerplate JAX optimization"""
value_and_grad = jax.jit(jax.value_and_grad(loss))
Expand Down Expand Up @@ -336,7 +274,7 @@ def loss(theta):
A = K_m @ v_m @ K_m.conj().T
return jnp.trace(A.conj().T @ H_m).real

theta0 = jnp.ones(len(k), dtype=float)
theta0 = jax.random.normal(jax.random.PRNGKey(0), shape=(len(k),), dtype=float)

thetas, energy, _ = run_opt(loss, theta0, n_epochs=1000, lr=0.05)
plt.plot(energy - np.min(energy))
Expand All @@ -359,13 +297,18 @@ def loss(theta):
# .. math:: h_0 = K_c^\dagger H K_c.

h_0_m = Kc_m.conj().T @ H_m @ Kc_m
h_0 = qml.pauli_decompose(h_0_m)

print(len(h_0))
# decompose h_0_m in terms of the basis of h
basis = [qml.matrix(op, wire_order=range(n_wires)) for op in h]
coeffs = qml.pauli.trace_inner_product(h_0_m, basis)

# ensure that decomposition is correct, i.e. h_0_m is truely an element of just h
h_0_m_recomposed = np.sum([c * op for c, op in zip(coeffs, basis)], axis=0)
print("Decomposition of h_0 is faithful: ", np.allclose(h_0_m_recomposed, h_0_m, atol=1e-10))

# sanity check that the horizontal CSA is Abelian, i.e. all its elements commute
print("All elements in h commute with each other: ", qml.liealg.check_abelian(h))

# assure that h_0 is in \mathfrak{h}
h_vspace = qml.pauli.PauliVSpace(h)
not h_vspace.is_independent(h_0.pauli_rep)

##############################################################################
#
Expand Down Expand Up @@ -393,6 +336,7 @@ def loss(theta):
t = 1.
U_exact = qml.exp(-1j * t * H)
U_exact_m = qml.matrix(U_exact, wire_order=range(n_wires))
h_0 = qml.dot(coeffs, h)

def U_kak(theta_opt, t):
qml.adjoint(K)(theta_opt, k)
Expand Down Expand Up @@ -478,7 +422,7 @@ def compute_res(Us):
# Conclusion
# ----------
#
# The KAK theorem is a very general mathematical result with far-reaching consequences.
# The KAK decomposition is a very general mathematical result with far-reaching consequences.
# While there is no canonical way of obtaining an actual decomposition in practice, we followed
# the approach of [#Kökcü]_ which uses a specifically designed loss function and variational
# optimization to find the decomposition.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
}
],
"dateOfPublication": "2024-11-25T00:00:00+00:00",
"dateOfLastModification": "2024-11-25T00:00:00+00:00",
"dateOfLastModification": "2025-04-11T00:00:00+00:00",
"categories": [
"Quantum Computing",
"How-to"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
custom user-defined or fake backend-based noise models.
"""


######################################################################
# Noise models in Qiskit and PennyLane
# ------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion demonstrations/tutorial_kak_decomposition.metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
}
],
"dateOfPublication": "2024-11-25T00:00:00+00:00",
"dateOfLastModification": "2025-01-07T09:00:00+00:00",
"dateOfLastModification": "2025-03-26T09:00:00+00:00",
"categories": [
"Quantum Computing",
"Algorithms"
Expand Down
Loading