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

Add qml.matrix(op) function #2241

Merged
merged 20 commits into from
Mar 2, 2022
Merged

Add qml.matrix(op) function #2241

merged 20 commits into from
Mar 2, 2022

Conversation

josh146
Copy link
Member

@josh146 josh146 commented Feb 28, 2022

Context:

Currently, to get the matrix of an operator, you must do op.get_matrix(). Alternatively, to get the matrix of a tape/qfunc, you must do qml.transforms.get_unitary_matrix().

However, there are many downsides to this:

  • op.get_matrix() is temporary, and we want to limit users relying on operator methods!

  • qml.transforms.get_unitary_matrix() is hard to find, and also will fail if not all operations on the tape support get_matrix().

It would be nice if there was a single function that covered this singular functionality, while insulating the op.get_matrix() method from changes.

Description of the Change:

  • Adds qml.matrix()

  • This function works on operations, qfuncs, tapes, and QNodes.

  • It accepts wire ordering.

Benefits: As above.

Possible Drawbacks: n/a

Related GitHub Issues: n/a

@github-actions
Copy link
Contributor

Hello. You may have forgotten to update the changelog!
Please edit doc/releases/changelog-dev.md with:

  • A one-to-two sentence description of the change. You may include a small working example for new features.
  • A link back to this PR.
  • Your name (or GitHub username) in the contributors section.

@codecov
Copy link

codecov bot commented Feb 28, 2022

Codecov Report

Merging #2241 (fbd3d94) into master (d091b90) will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #2241   +/-   ##
=======================================
  Coverage   99.28%   99.28%           
=======================================
  Files         233      235    +2     
  Lines       18808    18831   +23     
=======================================
+ Hits        18673    18696   +23     
  Misses        135      135           
Impacted Files Coverage Δ
pennylane/operation.py 95.99% <ø> (ø)
pennylane/__init__.py 100.00% <100.00%> (ø)
pennylane/ops/functions/__init__.py 100.00% <100.00%> (ø)
pennylane/ops/functions/matrix.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d091b90...fbd3d94. Read the comment docs.

@josh146 josh146 changed the title [WIP] Add matrix function Add qml.matrix(op) function Feb 28, 2022
@josh146 josh146 added the review-ready 👌 PRs which are ready for review by someone from the core team. label Feb 28, 2022


@qml.op_transform
def matrix(op, *, wire_order=None):
Copy link
Contributor

Choose a reason for hiding this comment

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

If this can take tapes etc, would you not call it obj?

Copy link
Member Author

Choose a reason for hiding this comment

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

good point!

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, because the wrapper makes sure that by the time it reaches the code in this function, it is an op?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep exactly :) But the documentation will only show the docstring for the first one, hence why I've tried to keep all the information for op/tape/qfunc etc in a single docstring

Returns:
tensor_like or function: Function which accepts the same arguments as the QNode or quantum
function. When called, this function will return the unitary matrix in the appropriate
autodiff framework (Autograd, TensorFlow, PyTorch, JAX) given its parameters.
Copy link
Contributor

Choose a reason for hiding this comment

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

These are two very different return options. Maybe at least describe the other one, since the explanation just talks about the function return type.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry, which one do you mean to describe here? Just the functional one?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, it can return a tensor or a function, hey? It would be good to say "the tensor is the desired matrix; if a function then it accepts..." or so?

@pytest.mark.parametrize("op_class", one_qubit_no_parameter)
def test_non_parametric_gates_qfunc(self, op_class):
"""Verify that the matrices of non-parametric one qubit gates is correct
when provided as a qfunc"""
Copy link
Contributor

Choose a reason for hiding this comment

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

I may be blind, but it's more provided as a class, not a qfunc, no?

Copy link
Member Author

Choose a reason for hiding this comment

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

instantiating an operator is basically the same thing, from PL's point of view, as a qfunc that only queues a single operation 😆 Which is very useful way of thinking when writing the tests


@pytest.mark.xfail(
reason="This test will fail because Hamiltonians are not queued to tapes yet!"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting!

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, I didn't realize this was the case either! something we should really fix.

Copy link
Contributor

@mariaschuld mariaschuld left a comment

Choose a reason for hiding this comment

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

Very minor comments, I didn't find any objections :)

I don't really understand matrix.tape_transform but it seems to work :)

@cvjjm
Copy link
Contributor

cvjjm commented Mar 1, 2022

Extra awesome that qml.matrix() if auto differentiable!

Base automatically changed from op-transform to master March 2, 2022 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
review-ready 👌 PRs which are ready for review by someone from the core team.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improve/implement get_matrix() of Tensor and Hamiltonian
3 participants