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

[Refactoring] Avoid calling block to tensor on diagonal Hamiltonians #368

Closed
jpmoutinho opened this issue Mar 13, 2024 · 5 comments
Closed
Assignees
Labels
good first issue Good for newcomers refactoring Refactoring of legacy code unitary hack

Comments

@jpmoutinho
Copy link
Collaborator

jpmoutinho commented Mar 13, 2024

When calling HamEvo on diagonal Hamiltonians the dense matrix is built but then only the diagonal is taken.

This is currently done in the PyQHamiltonianEvolution class in qadence/backends/pyqtorch/convert_ops.py, where the __init__ method first builds the full matrix hmat, and then the _unitary method defines the evolution function for diagonal operators which runs diagonal() on the full hamiltonian matrix.

We should instead build only the diagonal. For non-parametric block this is directly possible with the function block_to_diagonal, as done in the PyQObservable class in the same file.

Handling parametric blocks is out of the scope of this issue, and can be done separately. It requires further development in the block_to_tensor side as detailed in #394.

NOTE: Due to ongoing changes in the codebase, we might need to implement this directly in the PyQTorch backend (pasqal-io/pyqtorch#175).

@neogyk
Copy link

neogyk commented Jun 4, 2024

Dear all,
I am trying to solve this issue.
Is it will be enough to add the following lines to the PyQHamiltonianEvolution class constructor:

elif not block.generator.is_parametric and block.generator.diagonal:
           m = block.generator.to(dtype=cdouble)
           hmat = block_to_diagonal(
               MatrixBlock(m, qubit_support=block.qubit_support),
               qubit_support=self.qubit_support,
               use_full_support=False,
           )
           hmat = hmat.permute(1, 2, 0)
           self.register_buffer("hmat", hmat)
           self._hamiltonian = lambda self, values: self.hmat

@jpmoutinho
Copy link
Collaborator Author

Hey @neogyk, thanks for your interest in completing this issue!

The solution should be along those lines, but there is no need to use MatrixBlock. You should be able to run block_to_diagonal on the block.generator.

Feel free to open an MR and add me as a reviewer, then we can discuss it there.

@neogyk
Copy link

neogyk commented Jun 5, 2024

Dear @jpmoutinho, could you please review the changes. I made the PR - #441

@Roland-djee
Copy link
Collaborator

Dear @jpmoutinho, could you please review the changes. I made the PR - #441

Dear @neogyk, just for your information, @jpmoutinho is off today. He will catch-up as soon as he's back, ie. tomorrow. Thanks.

@jpmoutinho
Copy link
Collaborator Author

Closing this issue as completed by @neogyk. The solution will remain unmerged in #478 as explained there.

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 refactoring Refactoring of legacy code unitary hack
Projects
None yet
Development

No branches or pull requests

3 participants