Tapering operators in PR#3002

Dear Pennylane researchers,

First of all I would like to take the time to thank you for developing such a nice tool as well as working on comprehensive tutorials on many topics in QC.
I mainly focused on quantum chemistry and especially in qubit tapering where I have a question concerning the circuit Ansatz to be used. The only possible path I see would be to taper the operators associated to an Ansatz for untapered states and Hamiltonian, as it is also mentioned in the topic here excitations-for-tapered-hamiltonian/1849/6

After some digging I found that tapering operators will be available in the next version 27.0.0 of pennylane (PR #3002). As I am very unpatient I tried the proposed implementation for the HeH+ example molecule and applying VQE on it : it works like a charm. I also tried with LiH (see notebook). Of course it also works but slowly (much slower than untapered VQE), which brings me to my question.
When doing VQE, the circuit is reevaluated with different parameters, and based on the following proposition of implementation in pennylane/qchem/tapering.py file (PR#3002), it seems to me that the same circuit ansatz is retapered at each VQE iteration in addition to updating the parameter through the classical optimisation.

@qml.qnode(dev)
def circuit(params):
    taper_operation(qml.DoubleExcitation(params[0], wires=[0,1,2,3]),
                                    generators, paulixops, paulix_sector, H.wires)

Hopefully tapering the hamiltonian and basis state are only done once, but it is also time-costly to taper operators. There are some quickly done time benchmarks in the joint notebook. First of all, am I doing anything in the wrong or unoptimized way here ?
Taper_operator_test.py (20.4 KB) (it takes quite long to run, 5min overall)

I also found a very ugly workaround to « separate » the evaluation of the parameters from the tapering operation as you can see in the end of the notebook. Do you think such separation might be worth investigating in the future (for VQE or other) ?

Sorry for the long post (and the long py file, most of it are coming from the PR :slight_smile: ), and have a nice day !
Cheers,
Brian

Hi @bventura,

Thank you for this detailed post, and welcome to the forum! At first glance it doesn’t look like you’re doing anything wrong. It does show that we have potential for improvement!

We’re evaluating options of how the problem could be solved in a more elegant manner. It will probably take a few days to figure it out so please ‘@’ me in case we haven’t come back with more information by the end of next week.

Hey @bventura! Thank you for the post and for bringing this to our attention. We have just pushed an improvement to this functionality. It should now allow you to define the tapered operation outside your circuit definition using its functional form, preventing the need for re-tapering in every circuit execution.

For example, doing the following should now be possible in addition to the previously introduced strategy:

>>> tap_op = qchem.taper_operation(qml.SingleExcitation, generators, paulixops,
...                paulix_sector, wire_order=H.wires, op_wires=[0, 2])
>>> tap_op(3.14159)
[Exp(1.570795j, 'PauliY', wires=[0])]
>>> @qml.qnode(dev)
... def circuit(params):
...      tap_op(params[0])

Please feel free to reach out again in case you would have any further questions about this.

Hello @whatsis !
I sneakily followed the new PR, thanks for the news ! And excellent, the functional form seems indeed to be a very good way to tackle this, thank you very much for the improvement !

Cheers,
Brian

That’s great to hear @bventura!