hermitian conjugate in odd location
The Hermitian conjugation function is currently sitting in operator_utils.py where it's really hard to find, and it also has hardcoded functionality for each subclass of each operator. It should probably be pulled into SymbolicOperator/PolynomialTensor (e.g. as a conj() function to make consistent with numpy) and made more universal. Not entirely sure what the best way forward is here - thoughts?
I'd like to begin contributing to this. I think this is a good way to do it:
- SymbolicOperator should have a conjugate_term() function that Fermion/Boson/Qubit/QuadOperator all implement separately. Then SymbolicOperator should have a H_conj() function (like you mention) that is something like
def H_conj(self):conjugate_operator = type(self)()for term, coefficient in self.terms.items():conjugate_operator[self.conjugate_term(term)] = coefficient.conjugate()
because the conjugations happen independently in each term.
-
It might make sense to have InteractionOperator implement its own H_conj() function because it's the only PolynomialTensor that needs Hermitian conjugation (afaict).
-
As far as sparse matrices and ndarrays are concerned, they could just not have similar H_conj() functions because Hermitian conjugating matrices is commonly done with numpy built-in functions anyway, e.g. .getH() and .T.conj()
That would be great if you could give it a first pass.
I think expanding the Hermitian conjugate function to a general PolynomialTensor class is probably a good idea, even if it's not typically used (@ncrubin @kevinsung , any idea why h.c. isn't implemented for PolynomialTensor in general?).
Also, following python naming standards, I think we'll need to call it h_conj.
Other than that I think that your plan seems reasonable. Thanks!