jcmgray / quimb

A python library for quantum information and many-body calculations including tensor networks.
http://quimb.readthedocs.io
Other
455 stars 107 forks source link

Usage of the `rehearse` option in the `qtn.Circuit` class #240

Open PietropaoloFrisoni opened 1 week ago

PietropaoloFrisoni commented 1 week ago

What is your issue?

Good morning @jcmgray, I hope you are doing well.

I was studying the Rehearsals section of the documentation, which hopefully can be very helpful for optimizing circuits using quimb.

However, I encounter some errors that are probably bugs, but it is also possible that I am missing something and misusing this functionality. I leave a few minimal examples here to show where the problems arise:

import quimb as qu
import quimb.tensor as qtn
import pennylane as qml

cq = qtn.Circuit(10)
op = qml.X(wires=2)

# this works
cq.local_expectation(op.matrix(), *op.wires, rehearse="tn") 

# this fails
cq.local_expectation(op.matrix(), *op.wires, rehearse="tree")  

# this fails
cq.local_expectation(op.matrix(), *op.wires, rehearse=True)

# this fails
cq.local_expectation_rehearse(op.matrix(), *op.wires)

I just noticed that also the following example (taken from the documentation) seems to have issues:

circ = qtn.Circuit(80)

ZZ = qu.pauli('Z') & qu.pauli('Z')
where = (3, 4)

rehs = circ.local_expectation_rehearse(ZZ, where, optimize='greedy')

I am using quimb 1.8.2.

As always, thank you so much for your time!

jcmgray commented 1 week ago

Hi @PietropaoloFrisoni, thanks for the issue, will look into shortly. For info, what is the error that is raised?

PietropaoloFrisoni commented 1 week ago

Thanks @jcmgray!

I forgot to report the output error. I get:

ValueError: math domain error

I suspect that in quimb/tensor/circuit.py:1353, in rehearsal_dict(tn, tree) we are trying to compute the logarithm of a negative number. Thanks again!

jcmgray commented 1 week ago

Ah yes, probably the circuit simplifies to a scalar, with contraction cost 0, which causes the domain error. Probably a simple max(1, tree.contraction_cost()) guard would suffice here.