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

Implement qml.equal comparison for BasisRotation #4893

Closed
albi3ro opened this issue Nov 28, 2023 · 3 comments
Closed

Implement qml.equal comparison for BasisRotation #4893

albi3ro opened this issue Nov 28, 2023 · 3 comments
Assignees
Labels
good first issue Good for newcomers

Comments

@albi3ro
Copy link
Contributor

albi3ro commented Nov 28, 2023

The BasisRotation template cannot currently be compared with qml.equal or == due the presence of a numpy array as a hyperparameter.

For example, if we run:

weights = np.array(
    [
        [-0.618452, -0.68369054 - 0.38740723j],
        [-0.78582258, 0.53807284 + 0.30489424j],
    ]
)
op = qml.BasisRotation(wires=range(2), unitary_matrix=weights)
op2 = qml.BasisRotation(wires=range(2), unitary_matrix=np.array(weights))
qml.equal(op, op2)
File /pennylane/ops/functions/equal.py:209, in _equal_operators(op1, op2, check_interface, check_trainability, rtol, atol)
    206 if op1.wires != op2.wires:
    207     return False
--> 209 if op1.hyperparameters != op2.hyperparameters:
    210     return False
    212 if check_trainability:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

To fix this issue, we need to register a custom comparison with the single dispatch function _equal defined here

Examples of custom kernels can be found in that file. Ths op.hyperparameters['unitary_matrix'] hyperparameter should be compared with qml.math.allclose to the requested relative and absolute tolerances (atol, rtol).

The code for BasisRotation can be found:

class BasisRotation(Operation):

Once custom comparison is implemented, the xfail mark can be removed from this test that runs qml.ops.functions.assert_valid:

@pytest.mark.xfail # to be fixed by shortcut story 49160

If the standard validity checks still fail after custom comparison is implemented, we can reassess any further steps.

A PR for this issue should:

  1. Add a kernel to _equal for BasisRotation
  2. Remove the xfail mark from the standard validity test
  3. Add a changelog entry to docs/releases/changelog-dev.md
@minhtriet
Copy link
Contributor

I would like to work on this if you don't mind

@albi3ro
Copy link
Contributor Author

albi3ro commented Nov 29, 2023

I've assigned you the issue @minhtriet . Feel free to combine this and #4894 if that is easiest for you.

albi3ro added a commit that referenced this issue Dec 12, 2023
**Context:** Add comparison for `BasisRotation`

**Description of the Change:**

**Benefits:**

**Possible Drawbacks:** As correctly stated in #4893, hashing a numpy
array is not possible. One potential solution is to write a custom
`_flatten()` and `_unflatten()` for BasisRotation, in which the matrix
is serialized/deserialized to/from JSON. Specifically

```python
rotation_mat = np.array(
        [
             [-0.618452, -0.68369054 - 0.38740723j],
             [-0.78582258, 0.53807284 + 0.30489424j],
         ]
)
# serialize
u = ';'.join(str(__) for _ in rotation_mat for __ in _)   # gives '(-0.618452+0j);(-0.68369054-0.38740723j);(-0.78582258+0j);(0.53807284+0.30489424j)'
# deserialize
v = [complex(_) for _ in u.split(';')]
np.array(v).reshape([int(np.sqrt(len(v)))]*2)
```
This relies on the fact that rotational matrix is small and a square
matrix
**Related GitHub Issues:** #4893

@albi3ro

---------

Co-authored-by: Christina Lee <chrissie.c.l@gmail.com>
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Co-authored-by: Christina Lee <christina@xanadu.ai>
@albi3ro
Copy link
Contributor Author

albi3ro commented Dec 12, 2023

Closed by #4919

@albi3ro albi3ro closed this as completed Dec 12, 2023
mudit2812 pushed a commit that referenced this issue Jan 19, 2024
**Context:** Add comparison for `BasisRotation`

**Description of the Change:**

**Benefits:**

**Possible Drawbacks:** As correctly stated in #4893, hashing a numpy
array is not possible. One potential solution is to write a custom
`_flatten()` and `_unflatten()` for BasisRotation, in which the matrix
is serialized/deserialized to/from JSON. Specifically

```python
rotation_mat = np.array(
        [
             [-0.618452, -0.68369054 - 0.38740723j],
             [-0.78582258, 0.53807284 + 0.30489424j],
         ]
)
# serialize
u = ';'.join(str(__) for _ in rotation_mat for __ in _)   # gives '(-0.618452+0j);(-0.68369054-0.38740723j);(-0.78582258+0j);(0.53807284+0.30489424j)'
# deserialize
v = [complex(_) for _ in u.split(';')]
np.array(v).reshape([int(np.sqrt(len(v)))]*2)
```
This relies on the fact that rotational matrix is small and a square
matrix
**Related GitHub Issues:** #4893

@albi3ro

---------

Co-authored-by: Christina Lee <chrissie.c.l@gmail.com>
Co-authored-by: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Co-authored-by: Christina Lee <christina@xanadu.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants