tensorflow / quantum

Hybrid Quantum-Classical Machine Learning in TensorFlow
https://www.tensorflow.org/quantum
Apache License 2.0
1.78k stars 571 forks source link

Arbitrary Input State Capabilities #210

Open zphy opened 4 years ago

zphy commented 4 years ago

Are there functionalities in TFQ that allow one to specify an arbitrary input state in the 2^N Hilbert space? I understand that one could in principle make a circuit to prepare such a state, but in the case where, for example, the input state comes from solving the ground state of a many-body Hamiltonian, this might be very expensive to do, and it would be useful to be able to have an interface directly specifying this as a state vector/density matrix.

MichaelBroughton commented 4 years ago

It isn't on the immediate horizon for TFQ. We have a few more core features we would like to finish first. If you really don't want to write down a circuit and want a way to import an initial wavefunction you could do something like the following:

something_i_made_myself = np.array(...)
class MyFinalStateSimulator(cirq.SimulatesFinalState, cirq.Simulator):
    def run_sweep(program, params, qubit_order, initial_state):
      # this needs to produce something that still looks like a wavefunction or density matrix.
       return my_own_simulation_method(program, intial_sate=something_i_made_myself)

tfq.layers.State(backend=MyFinalStateSimulator())(cirq.Circuit(...))

This would give you a way to power the simulation of the cirq.Circuit(...) with whatever initial state you put into something_i_made_myself (Or do whatever you want really). Here is the interface definition for cirq.SimulatesFinalState : https://github.com/quantumlib/Cirq/blob/0882abb751005191f12d9bae410c9851ea705041/cirq/sim/simulator.py

tfq.layers.State and tfq.layers.Expectation require a backend of either None or something that inherits cirq.SimulatesFinalState. This is explained more here: https://www.tensorflow.org/quantum/api_docs/python/tfq/layers/Expectation#args

Similarly you can also make a new cirq.Sampler in order to get tfq.Sample and tfq.layers.SampledExpectation to have an "imported" initial state as well.

More generally speaking if you have any particular way you want a simulation done, you can implement it via a class implementing cirq.Sampler or cirq.SimulatesFinalState and then plug it in using similar code to what is above to power TFQ. It's also likely that doing this for general circuits will be MUCH slower than our default simulator.

Does that clear things up ?

zphy commented 4 years ago

Thanks, this is very helpful. I'll take a look at it in more detail and let you know if I run into any issues.

github-actions[bot] commented 4 years ago

This issue has not had any activity in a month. Is it stale ?

babbush commented 4 years ago

@MichaelBroughton - this feature would be extremely useful for many projects trying to use TFQ for quantum simulation, and thus I would encourage you to take another look at this issue. Often with quantum simulation the goal is going to be to extract interesting properties from something like a ground state, and we'd like to study that task independently of the method used to prepare the ground state. My team is currently working on a project using TFQ that has a workflow like this. We've hacked together circuits to prepare the states of interest but it's an approximate and it really shouldn't be necessary for our study. Our lives would be much easier if there was a reasonable method of just initializing an arbitrary state. Thus, I think having this feature would improve the usability of TFQ for projects in quantum simulation.

MichaelBroughton commented 4 years ago

Hey Ryan - We can definitely look into this again, there would be a few technical hurdles to overcome in implementing things, but I'm optimistic it can be done one way or another :). To help understand your use case a little more clearly, can I ask how you are coming up with these arbitrary states ? are the upstream workflows to getting these state vectors anything like:

  1. Writing down your operator in terms of Paulis and then diagonalizing them and other matrix stuff
  2. Coming up with state vectors from existing circuits and then modifying certain entries individually

This would help us understand "how truly general" we need to make this arbitrary input capability. What I am hoping is that we can somehow incorporate certain pieces of this arbitrary state creation process into the TensorFlow Quantum compute graph primitives. In doing so we might be able to avoid some pitfalls with massive overheads like:

  1. If a batch of Circuits has a batch of associated initial state vectors and we want to do distributed training then it's very slow to pass around all those state vectors over the internet (where right now passing circuit descriptions is very cheap).

  2. If a batch of circuits has a batch of associated initial state vectors generated completely outside of the compute graph in python, then the communication overhead of sending the large state vector from the python layer to the C++ layer can also be pretty large.

babbush commented 4 years ago

Thanks Michael. In our case we're getting the state vectors by doing something like diagonalizing an operator. In principle the operator we're diagonalizing can be expressed as a linear combination of Pauli strings, but that's not necessarily the most numerically efficient representation in which to diagonalize it (for instance, we are focusing on some chemistry examples and the most efficient thing would be to use an electronic structure package to the get the state and then use OpenFermion to map the representation of that state to whatever format TFQuantum could accept). You're not going to want to interface with an electronic structure package so we'd ideally want the ability to specify an arbitrary state. However, if that is really challenging, we could also use a system where we could specify a linear combination of Pauli strings and TFQuantum diagonalizes it for us. But there are a lot of pitfalls of that. For instance, I don't think TFQuantum is going to know how to correctly resolve degeneracies in the ground state and you're likely not going to want to write your own Lanczos routine, etc.

zphy commented 4 years ago

For reference, the original use case I had been considering when opening this issue was passing in the solution of a ground state found by a separate DMRG routine. Similar to Ryan's use case, in principle TFQ could add that capability, but it seems like it would be take quite a bit of work to make it as efficient as other mature solvers