Skip to content

Commit

Permalink
Merge changes from dev to master (#1092)
Browse files Browse the repository at this point in the history
Co-authored-by: GitHub Nightly Merge Action <[email protected]>
Co-authored-by: Mudit Pandey <[email protected]>
Co-authored-by: Christina Lee <[email protected]>
Co-authored-by: Romain Moyard <[email protected]>
Co-authored-by: Matthew Silverman <[email protected]>
Co-authored-by: lillian542 <[email protected]>
Co-authored-by: Tom Bromley <[email protected]>
Co-authored-by: Josh Izaac <[email protected]>
Co-authored-by: Rashid N H M <[email protected]>
Co-authored-by: Guillermo Alonso-Linaje <[email protected]>
Co-authored-by: soranjh <[email protected]>
Co-authored-by: CatalinaAlbornoz <[email protected]>
Co-authored-by: Jay Soni <[email protected]>
Co-authored-by: soranjh <[email protected]>
Co-authored-by: ixfoduap <[email protected]>
Co-authored-by: Diego <[email protected]>
Co-authored-by: Utkarsh <[email protected]>
Co-authored-by: Stepan Fomichev <[email protected]>
Co-authored-by: soranjh <[email protected]>
Co-authored-by: Alvaro Ballon <[email protected]>
Co-authored-by: Diego <[email protected]>
Co-authored-by: Lee J. O'Riordan <[email protected]>
Co-authored-by: Korbinian Kottmann <[email protected]>
Co-authored-by: DanielNino27 <[email protected]>
Co-authored-by: Paul Finlay <[email protected]>
Co-authored-by: ashishks0522 <[email protected]>
Co-authored-by: Mikhail Andrenkov <[email protected]>
Co-authored-by: David Wierichs <[email protected]>
Co-authored-by: Diksha Dhawan <[email protected]>
  • Loading branch information
1 parent 6ebb9fa commit 1555d29
Show file tree
Hide file tree
Showing 59 changed files with 1,716 additions and 199 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/update-metadata-reminder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
repo: context.repo.repo,
body: `👋 Hey, looks like you've updated some demos!
🐘 Don't forget to update the \`dateOfLastModification\` in the associated metadata files so your changes show up on [pennylane.ai](https://pennylane.ai).
🐘 Don't forget to update the \`dateOfLastModification\` in the associated metadata files so your changes are reflected in Glass Onion (search and recommendations).
Please hide this comment once the field(s) are updated. Thanks!`
})
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,6 @@ 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 -i https://test.pypi.org/simple/ PennyLane-Lightning --pre --upgrade;\
fi;\
fi
Binary file added _static/authors/diksha_dhawan.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions _static/authors/diksha_dhawan.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.. bio:: Diksha Dhawan
:photo: ../_static/authors/diksha_dhawan.png

Diksha is a quantum software developer at Xanadu. Her work is focused on implementing quantum computing algorithms for quantum chemistry.
21 changes: 13 additions & 8 deletions _static/demonstration_assets/barren_gadgets/barren_gadgets.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import pennylane as qml
from pennylane import numpy as np

def non_identity_obs(obs):
return [o for o in obs if not isinstance(o, qml.Identity)]

class PerturbativeGadgets:
""" Class to generate the gadget Hamiltonian corresponding to a given
Expand Down Expand Up @@ -28,12 +30,13 @@ def gadgetize(self, Hamiltonian, target_locality=3):
# checking for unaccounted for situations
self.run_checks(Hamiltonian, target_locality)
computational_qubits, computational_locality, computational_terms = self.get_params(Hamiltonian)
Hamiltonian_coeffs, Hamiltonian_ops = Hamiltonian.terms()

# total qubit count, updated progressively when adding ancillaries
total_qubits = computational_qubits
#TODO: check proper convergence guarantee
gap = 1
perturbation_norm = np.sum(np.abs(Hamiltonian.coeffs)) \
perturbation_norm = np.sum(np.abs(Hamiltonian_coeffs)) \
+ computational_terms * (computational_locality - 1)
lambda_max = gap / (4 * perturbation_norm)
l = self.perturbation_factor * lambda_max
Expand All @@ -44,7 +47,7 @@ def gadgetize(self, Hamiltonian, target_locality=3):
obs_anc = []
obs_pert = []
ancillary_register_size = int(computational_locality / (target_locality - 2))
for str_count, string in enumerate(Hamiltonian.ops):
for str_count, string in enumerate(Hamiltonian_ops):
previous_total = total_qubits
total_qubits += ancillary_register_size
# Generating the ancillary part
Expand All @@ -54,10 +57,10 @@ def gadgetize(self, Hamiltonian, target_locality=3):
# Generating the perturbative part
for anc_q in range(ancillary_register_size):
term = qml.PauliX(previous_total+anc_q) @ qml.PauliX(previous_total+(anc_q+1)%ancillary_register_size)
term = qml.operation.Tensor(term, *string.non_identity_obs[
term = qml.prod(term, *non_identity_obs(string.operands)[
(target_locality-2)*anc_q:(target_locality-2)*(anc_q+1)])
obs_pert.append(term)
coeffs_pert += [l * sign_correction * Hamiltonian.coeffs[str_count]] \
coeffs_pert += [l * sign_correction * Hamiltonian_coeffs[str_count]] \
+ [l] * (ancillary_register_size - 1)
coeffs = coeffs_anc + coeffs_pert
obs = obs_anc + obs_pert
Expand All @@ -77,12 +80,13 @@ def get_params(self, Hamiltonian):
computational_terms (int) : number of terms in the sum
composing the Hamiltonian
"""
_, Hamiltonian_ops = Hamiltonian.terms()
# checking how many qubits the Hamiltonian acts on
computational_qubits = len(Hamiltonian.wires)
# getting the number of terms in the Hamiltonian
computational_terms = len(Hamiltonian.ops)
computational_terms = len(Hamiltonian_ops)
# getting the locality, assuming all terms have the same
computational_locality = max([len(Hamiltonian.ops[s].non_identity_obs)
computational_locality = max([len(non_identity_obs(Hamiltonian_ops[s]))
for s in range(computational_terms)])
return computational_qubits, computational_locality, computational_terms

Expand All @@ -96,6 +100,7 @@ def run_checks(self, Hamiltonian, target_locality):
Returns:
None
"""
_, Hamiltonian_ops = Hamiltonian.terms()
computational_qubits, computational_locality, _ = self.get_params(Hamiltonian)
computational_qubits = len(Hamiltonian.wires)
if computational_qubits != Hamiltonian.wires[-1] + 1:
Expand All @@ -104,8 +109,8 @@ def run_checks(self, Hamiltonian, target_locality):
'Decomposition not implemented for this case')
# Check for same string lengths
localities=[]
for string in Hamiltonian.ops:
localities.append(len(string.non_identity_obs))
for string in Hamiltonian_ops:
localities.append(len(non_identity_obs(string)))
if len(np.unique(localities)) > 1:
raise Exception('The given Hamiltonian has terms with different locality.' +
' Gadgetization not implemented for this case')
Expand Down
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.
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.
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.
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.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 13 additions & 8 deletions demonstrations/barren_gadgets/barren_gadgets.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import pennylane as qml
from pennylane import numpy as np

def non_identity_obs(obs):
return [o for o in obs if not isinstance(o, qml.Identity)]

class PerturbativeGadgets:
""" Class to generate the gadget Hamiltonian corresponding to a given
Expand Down Expand Up @@ -28,12 +30,13 @@ def gadgetize(self, Hamiltonian, target_locality=3):
# checking for unaccounted for situations
self.run_checks(Hamiltonian, target_locality)
computational_qubits, computational_locality, computational_terms = self.get_params(Hamiltonian)
Hamiltonian_coeffs, Hamiltonian_ops = Hamiltonian.terms()

# total qubit count, updated progressively when adding ancillaries
total_qubits = computational_qubits
#TODO: check proper convergence guarantee
gap = 1
perturbation_norm = np.sum(np.abs(Hamiltonian.coeffs)) \
perturbation_norm = np.sum(np.abs(Hamiltonian_coeffs)) \
+ computational_terms * (computational_locality - 1)
lambda_max = gap / (4 * perturbation_norm)
l = self.perturbation_factor * lambda_max
Expand All @@ -44,7 +47,7 @@ def gadgetize(self, Hamiltonian, target_locality=3):
obs_anc = []
obs_pert = []
ancillary_register_size = int(computational_locality / (target_locality - 2))
for str_count, string in enumerate(Hamiltonian.ops):
for str_count, string in enumerate(Hamiltonian_ops):
previous_total = total_qubits
total_qubits += ancillary_register_size
# Generating the ancillary part
Expand All @@ -54,10 +57,10 @@ def gadgetize(self, Hamiltonian, target_locality=3):
# Generating the perturbative part
for anc_q in range(ancillary_register_size):
term = qml.PauliX(previous_total+anc_q) @ qml.PauliX(previous_total+(anc_q+1)%ancillary_register_size)
term = qml.operation.Tensor(term, *string.non_identity_obs[
term = qml.prod(term, *non_identity_obs(string.operands)[
(target_locality-2)*anc_q:(target_locality-2)*(anc_q+1)])
obs_pert.append(term)
coeffs_pert += [l * sign_correction * Hamiltonian.coeffs[str_count]] \
coeffs_pert += [l * sign_correction * Hamiltonian_coeffs[str_count]] \
+ [l] * (ancillary_register_size - 1)
coeffs = coeffs_anc + coeffs_pert
obs = obs_anc + obs_pert
Expand All @@ -77,12 +80,13 @@ def get_params(self, Hamiltonian):
computational_terms (int) : number of terms in the sum
composing the Hamiltonian
"""
_, Hamiltonian_ops = Hamiltonian.terms()
# checking how many qubits the Hamiltonian acts on
computational_qubits = len(Hamiltonian.wires)
# getting the number of terms in the Hamiltonian
computational_terms = len(Hamiltonian.ops)
computational_terms = len(Hamiltonian_ops)
# getting the locality, assuming all terms have the same
computational_locality = max([len(Hamiltonian.ops[s].non_identity_obs)
computational_locality = max([len(non_identity_obs(Hamiltonian_ops[s]))
for s in range(computational_terms)])
return computational_qubits, computational_locality, computational_terms

Expand All @@ -96,6 +100,7 @@ def run_checks(self, Hamiltonian, target_locality):
Returns:
None
"""
_, Hamiltonian_ops = Hamiltonian.terms()
computational_qubits, computational_locality, _ = self.get_params(Hamiltonian)
computational_qubits = len(Hamiltonian.wires)
if computational_qubits != Hamiltonian.wires[-1] + 1:
Expand All @@ -104,8 +109,8 @@ def run_checks(self, Hamiltonian, target_locality):
'Decomposition not implemented for this case')
# Check for same string lengths
localities=[]
for string in Hamiltonian.ops:
localities.append(len(string.non_identity_obs))
for string in Hamiltonian_ops:
localities.append(len(non_identity_obs(string)))
if len(np.unique(localities)) > 1:
raise Exception('The given Hamiltonian has terms with different locality.' +
' Gadgetization not implemented for this case')
Expand Down
2 changes: 1 addition & 1 deletion demonstrations/braket-parallel-gradients.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def circuit(params):

# Measure all qubits to make sure all's good with Braket
observables = [qml.PauliZ(n_wires - 1)] + [qml.Identity(i) for i in range(n_wires - 1)]
return qml.expval(qml.operation.Tensor(*observables))
return qml.expval(qml.prod(*observables))


##############################################################################
Expand Down
2 changes: 1 addition & 1 deletion demonstrations/tutorial_barren_gadgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@

gadgetizer = PerturbativeGadgets()
H_gadget = gadgetizer.gadgetize(H_target)
print(H_gadget)
H_gadget

##############################################################################
# So, let's see what we got.
Expand Down
2 changes: 1 addition & 1 deletion demonstrations/tutorial_block_encoding.metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
}
],
"dateOfPublication": "2023-11-28T00:00:00+00:00",
"dateOfLastModification": "2024-01-01T00:00:00+00:00",
"dateOfLastModification": "2024-04-26T00:00:00+00:00",
"categories": [
"Quantum Computing",
"Algorithms"
Expand Down
10 changes: 7 additions & 3 deletions demonstrations/tutorial_block_encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@
be obtained with the :func:`~.pennylane.templates.state_preparations.mottonen.compute_theta`
function of PennyLane.
Let's now construct the FABLE block encoding circuit for a structured matrix.
The :class:`~.pennylane.FABLE` circuit is implemented in PennyLane and
can be easily used to block encode matrices of any given shape. Here, we manually construct the
circuit for a structured :math:`4 \times 4` matrix.
"""

import pennylane as qml
Expand Down Expand Up @@ -116,7 +118,7 @@
# Finally, we obtain the control wires for the C-NOT gates and a wire map that we later use to
# translate the control wires into the wire registers we prepared.

code = gray_code(2*np.sqrt(len(A)))
code = gray_code(2 * np.log2(len(A)))
n_selections = len(code)

control_wires = [int(np.log2(int(code[i], 2) ^ int(code[(i + 1) %
Expand Down Expand Up @@ -173,7 +175,9 @@ def circuit():
##############################################################################
# You can easily confirm that the circuit block encodes the original matrix defined above. Note that
# the dimension of :math:`A` should be :math:`2^n` where :math:`n` is an integer. For matrices with
# an arbitrary size, we can add zeros to reach the correct dimension.
# an arbitrary size, we can add zeros to reach the correct dimension. The padding will be
# automatically applied in :class:`~.pennylane.FABLE` implemented in
# PennyLane.
#
# The interesting point about the FABLE method is that we can eliminate those rotation gates that
# have an angle smaller than a defined threshold. This leaves a sequence of C-NOT gates that in
Expand Down
4 changes: 2 additions & 2 deletions demonstrations/tutorial_classical_shadows.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,8 +512,8 @@ def estimate_shadow_obervable(shadow, observable, k=10):
), np.array([observable.wires[0]])
else:
target_obs, target_locs = np.array(
[map_name_to_int[o.name] for o in observable.obs]
), np.array([o.wires[0] for o in observable.obs])
[map_name_to_int[o.name] for o in observable.operands]
), np.array([o.wires[0] for o in observable.operands])

# classical values
b_lists, obs_lists = shadow
Expand Down
5 changes: 3 additions & 2 deletions demonstrations/tutorial_clifford_circuit_simulations.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,9 @@ def clifford_tableau(op):
for pauli in pauli_ops:
conjugate = qml.prod(qml.adjoint(op), pauli, op).simplify()
decompose = qml.pauli_decompose(conjugate.matrix(), wire_order=op.wires)
phase = "+" if list(decompose.coeffs)[0] >= 0 else "-"
print(pauli, "-—>", phase, list(decompose.ops)[0])
decompose_coeffs, decompose_ops = decompose.terms()
phase = "+" if list(decompose_coeffs)[0] >= 0 else "-"
print(pauli, "-—>", phase, list(decompose_ops)[0])

clifford_tableau(qml.X(0))

Expand Down
3 changes: 2 additions & 1 deletion demonstrations/tutorial_diffable_shadows.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ def qnode_shadow():
method="pyscf",
)

coeffs, obs = H.coeffs, H.ops
coeffs, obs = H.terms()
H_qwc = qml.Hamiltonian(coeffs, obs, grouping_type="qwc")

groups = qml.pauli.group_observables(obs)
Expand Down Expand Up @@ -421,6 +421,7 @@ def circuit():

# execute qwc measurements
dev_finite = qml.device("default.qubit", wires=range(n_wires), shots=int(shots))

@qml.qnode(dev_finite, interface="autograd")
def qnode_finite(H):
circuit()
Expand Down
Loading

0 comments on commit 1555d29

Please sign in to comment.