Skip to content
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

Adds Single Excitation operations #1121

Merged
merged 67 commits into from
Mar 22, 2021
Merged

Adds Single Excitation operations #1121

merged 67 commits into from
Mar 22, 2021

Conversation

ixfoduap
Copy link
Contributor

@ixfoduap ixfoduap commented Mar 3, 2021

Context:
Current tools for constructing quantum circuits for quantum chemistry are inefficient. By relying on fermionic-to-qubit mappings to define operations and circuit decompositions to compute gradients, the resulting circuits for creating single and double excitation operations lead to lengthy computations. Through research work, we've identified that Givens rotations perform the same role as fermionic excitation operations, while allowing for simple analytical gradients and faster implementation in hardware and simulators.

Description of the Change:
This PR adds the two-qubit SingleExcitation operation with support across all native devices. Its analytical gradient requires a decomposition into two gates, SingleExcitationPlus and SingleExcitationMinus, which are also added as part of this PR.

A follow-up PR will also add the four-qubit DoubleExcitation operations.

Benefits:
Much faster implementation of quantum circuits for quantum chemistry.

Note:
The SingleExcitationPlus and SingleExcitationMinus have generators G that satisfy G^2=1 (self-inverse). This means they satisfy the standard parameter-shift rule and no custom gradient formula needs to be passed

@ixfoduap ixfoduap added core :atom: Core functionality (Operations, QNodes, CircuitGraphs) WIP 🚧 Work-in-progress qchem ⚛️ Related to the QChem package labels Mar 3, 2021
@ixfoduap ixfoduap self-assigned this Mar 3, 2021
.github/CHANGELOG.md Outdated Show resolved Hide resolved
Copy link
Member

@josh146 josh146 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great @ixfoduap, especially updating all the jax/tf/autograd devices! I'm guessing this is just a pre-review, since there are no tests yet?

.github/CHANGELOG.md Outdated Show resolved Hide resolved
pennylane/ops/qubit.py Outdated Show resolved Hide resolved
pennylane/ops/qubit.py Outdated Show resolved Hide resolved
pennylane/ops/qubit.py Outdated Show resolved Hide resolved
pennylane/ops/qubit.py Show resolved Hide resolved
.github/CHANGELOG.md Outdated Show resolved Hide resolved
.github/CHANGELOG.md Outdated Show resolved Hide resolved
@ixfoduap ixfoduap changed the title Adds Single Excitation operations [WIP] Adds Single Excitation operations Mar 4, 2021
@ixfoduap ixfoduap removed the WIP 🚧 Work-in-progress label Mar 4, 2021
pennylane/devices/autograd_ops.py Outdated Show resolved Hide resolved
pennylane/devices/autograd_ops.py Outdated Show resolved Hide resolved
pennylane/devices/autograd_ops.py Outdated Show resolved Hide resolved
Copy link
Contributor

@agran2018 agran2018 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ixfoduap!. I have enjoyed reviewing this PR while learning how to add new operations to PL.

"""
c = np.cos(phi / 2)
s = np.sin(phi / 2)
return np.array([[1, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, 1]])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstring declares that the function returns array[complex] but the matrix elements s and c are real, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

"""
c = jnp.cos(phi / 2)
s = jnp.sin(phi / 2)
return jnp.array([[1, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, 1]])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment here regarding the type of the returned array, jnp.Tensor[float] ?

phi = tf.cast(phi, dtype=C_DTYPE)
c = tf.cos(phi / 2)
s = tf.sin(phi / 2)
return tf.convert_to_tensor([[1, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, 1]])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably the same here: tf.Tensor[float]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: while true for JAX and autograd above, in this case the tensor will be complex, since phi is cast to complex on line 208. So it should remain tf.Tensor[complex].

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: while true for JAX and autograd above, in this case the tensor will be complex, since phi is cast to complex on line 208. So it should remain tf.Tensor[complex].

Attention to details! 😄

pennylane/ops/qubit.py Show resolved Hide resolved
pennylane/ops/qubit.py Show resolved Hide resolved
phi (float): rotation angle

Returns:
array: the two-qubit Givens rotation describing the single excitation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"describing the single excitation" or "describing the operation"

tests/ops/test_qubit_ops.py Show resolved Hide resolved
"""
c = np.cos(phi / 2)
s = np.sin(phi / 2)
return np.array([[1, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, 1]])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

pennylane/devices/autograd_ops.py Outdated Show resolved Hide resolved
pennylane/devices/jax_ops.py Outdated Show resolved Hide resolved
pennylane/devices/tf_ops.py Show resolved Hide resolved
pennylane/ops/qubit.py Outdated Show resolved Hide resolved
tests/gate_data.py Outdated Show resolved Hide resolved
Copy link
Contributor

@agran2018 agran2018 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ixfoduap. Looks great to me!.

phi = tf.cast(phi, dtype=C_DTYPE)
c = tf.cos(phi / 2)
s = tf.sin(phi / 2)
return tf.convert_to_tensor([[1, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, 1]])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: while true for JAX and autograd above, in this case the tensor will be complex, since phi is cast to complex on line 208. So it should remain tf.Tensor[complex].

Attention to details! 😄

Copy link
Contributor

@antalszava antalszava left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! 💯

Comment on lines 203 to 204
r"""
Single excitation rotation with positive phase-shift outside the rotation subspace.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in the suggestion from the first iteration, this recurs here and in other files too for the newly added docstrings.

Suggested change
r"""
Single excitation rotation with positive phase-shift outside the rotation subspace.
r"""Single excitation rotation with positive phase-shift outside the rotation subspace.

Comment on lines 221 to 222
r"""
Single excitation rotation with negative phase-shift outside the rotation subspace.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
r"""
Single excitation rotation with negative phase-shift outside the rotation subspace.
r"""Single excitation rotation with negative phase-shift outside the rotation subspace.

Comment on lines 229 to 230


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a suggestion for previous docstrings too here and in other files.

Suggested change

Comment on lines 949 to 950

@pytest.mark.parametrize(("excitation", "phi"), [(qml.SingleExcitation, -0.1),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things:

  • Could we parametrize for diff_method here too?
  • How about testing default.qubit for parameter-shift?

.github/CHANGELOG.md Outdated Show resolved Hide resolved
pytest.skip("JAX support for the parameter-shift method is still TBD")

jax = pytest.importorskip("jax")
from jax import numpy as jnp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come this import is here and for tf we don't have one? 🤔 Was there an occurrence for TF already before in the file that imported it?

pennylane/devices/tf_ops.py Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core :atom: Core functionality (Operations, QNodes, CircuitGraphs) qchem ⚛️ Related to the QChem package
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants