jcmgray / quimb

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

How to optimize two parameterized gates with the same value but opposite signs? #102

Open cfenglv opened 2 years ago

cfenglv commented 2 years ago

For example, I would like to have

circ = qtn.Circuit(N)
circ.apply_gate('Rz', -param, 0, parametrize=True, contract=False)
circ.apply_gate('Ry', param, 1, parametrize=True, contract=False)

Seems like shared_tags for TNOptimizer/parse_network_to_backend could do the job, but not sure if it can handle the opposite signs.

If it is not trivial, would there be a way to optimize the circuit without the use of the TNOptimizer? I could calculate the loss function with

def loss(params, ham, N, num_layer):
    circ = ansatz(N, params, num_layer)
    ens = [
        circ.local_expectation(G, where, optimize='jax', backend='jax')
        for where, G in ham.items()
    ]
    return sum(ens).real

By trying to use this with jax to do value_and_grad it has some errors in the circuit creating part. Also this is not efficient cause each evaluation will need to rebuild the circuit again. Is there a simple way to update the parameters for the PTensors in the network inplace?

Thanks :)

jcmgray commented 2 years ago

Notionally you should be able to do something like (if you can identify the gates with tags):

def norm_fn(tn):
    tn['GATE_1'].params = -tn['GATE_0'].params
    ....
    return tn

tnopt = qtn.TNOptimizer(
    ...
    norm_fn=norm_fn,
    tags=['GATE_0', ...],
)

in other words, in the norm_fn (or 'constraint') function, explicitly move the params from one tensor to another, then just specify the first tensor to be optimized in tags.

Note that as yet TNOptimizer doesn't explicitly work on Circuit objects so you would have to construct the lightcone cancelled reduced density matrices and contract them manually.