matt-lourens / hierarqcal

Generate hierarchical quantum circuits for Neural Architecture Search.
https://matt-lourens.github.io/hierarqcal/
BSD 3-Clause "New" or "Revised" License
41 stars 15 forks source link

Quantum Chemistry example notebook for the exponentiation of Pauli operators #29

Closed matt-lourens closed 1 year ago

matt-lourens commented 1 year ago

I don't have any background in quantum chemistry but I have seen these circuits for the exponentiation of tensor products of Pauli operators in a quantum chemistry context: From this paper image and this: image

These should be easy to implement with HierarQcal because of their symmetric nature. I'm hoping someone who knows more of their application can create a notebook example that illustrates their typical use case through using the package. Pennylane also has templates for these.

hrahman12 commented 1 year ago

@matt-lourens can you assign me this issue thank you

I am working on the notebook halfway done

Hi I'm working on this too are you interested in teaming up.

Gopal-Dahale commented 1 year ago

Hi, @matt-lourens, I understand that with hierarqcal we can have that CNOT ladder but I am finding it difficult how to put that one $U(\theta)$ gate in the middle (first circuit diagram). I can create a mapping for the Qunitary object or this but then I have to create an object for every 1 qubit quantum gate (Rx, Ry, Rz, H and so on). Any idea on this or am I missing something?

matt-lourens commented 1 year ago

Hey @Gopal-Dahale, thanks for giving the issue a look!

If you're wondering about how to place a single gate at the end of the circuit, you can use the Qcycle primitive along with it's offset parameter:

n=8
ladder = Qcycle(1, 1, 0, mapping=Qunitary("CNOT()^01"), boundary="open")
single_gate = Qcycle(1, 1, n-1, mapping=Qunitary("RZ(x1)^0"), boundary="open")
hierq = Qinit(n)+ladder+single_gate+ladder
circuit = hierq(backend="qiskit")
circuit.draw("mpl")

If you're asking more generally about what kinds of mappings we can provide to Qunitary, it doesn't have to be single qubit gates, for example the Rx-H-H-Rx unitary in the second image can be created as follows:

def U(bits, symbols=None, circuit=None, **kwargs):
    # Assume bits are strings and in the correct QASM format
    q0, q1, q2, q3 = QuantumRegister(1, bits[0]), QuantumRegister(1, bits[1]), QuantumRegister(1, bits[2]), QuantumRegister(1, bits[3])
    circuit.rx(symbols[0], q0)
    circuit.h(q1)
    circuit.h(q2)
    circuit.rx(symbols[1], q3)
    return circuit

u=Qunitary(U, arity=4, n_symbols=2)
hierq = Qinit(4) + Qcycle(1, 1, 0, mapping=u, boundary="open")
circuit = hierq(backend="qiskit")
circuit.draw("mpl") 

Again using strings to create this function is just Qcycle(1, 1, 0, mapping=Qunitary("RX(x1)^0;h()^1;h()^2;RX(x2)^3"), boundary="open")

But this depends on what the expected "pattern" is, if instead the pattern is to have hadamards and Rx on the ends the following would be better:

n=7
hierq = Qinit(n) + Qmask("1*1", mapping=Qunitary("RX(x1)^0"), share_weights=False)+ Qcycle(mapping=Qunitary("h()^0")) + Qunmask("previous") 
circuit = hierq(backend="qiskit")
circuit.draw("mpl")

Where you can change n as needed, this masks the first and final qubit while also applying a rotation Rx to them, then we apply a ladder/cycle of hadamards, since the first and last qubits are masked the aren't used, then just unmask the previous mask so that all qubits are available again.

I realize the package is not at a point where doing something like that is immediately clear, but hopefully trying to solve different problems with it, will guide us to make tutorials and things that makes it a bit more explicit. For example, I only realized we can do the following pattern as a consequence of your question.

Finally, placing single qubits based on some pattern like "*1" (place at end of circuit), "*1*" (place in middle) is best done at the moment with Qmask and Qunmask. The idea is to add a new primitive Qpivot which does the same but without masking the qubit (making it unavailable). This will hopefully be solved along this issue

Hope that helps :)

Gopal-Dahale commented 1 year ago

Hi @matt-lourens, I am unable to change the qubit pair ordering for a CNOT ladder. The current ordering is like (i, i+1) for i^th qubit but I need to be the reverse of it. I tried passing the reverse sorted list in Qinit and changing the QCycle parameters but it doesn't seem to be working. Should I just append the adjoint of the ladder circuit using qiskit?

matt-lourens commented 1 year ago

Hey @Gopal-Dahale, you can change the definition of your mapping to be a cnot where control and target is swapped:

n=8
ladder = Qcycle(1, 1, 0, mapping=Qunitary("CNOT()^10"), boundary="open")
hierq = Qinit(n)+ladder
circuit = hierq(backend="qiskit")
circuit.draw("mpl")

Is that what you wanted?

You can also change the edge order, if that is what you meant:

n=8
l1 = Qcycle(1, 1, 0, mapping=Qunitary("CNOT()^01"), boundary="open")
single_gate = Qcycle(1, 1, n-1, mapping=Qunitary("RZ(x1)^0"), boundary="open")
l2 = Qcycle(1, 1, 0, mapping=Qunitary("CNOT()^01"), boundary="open", edge_order=[i for i in range(n,1,-1)])
hierq = Qinit(n)+l1+single_gate+l2
circuit = hierq(backend="qiskit")
circuit.draw("mpl")
Gopal-Dahale commented 1 year ago

Great, thanks for the help @matt-lourens .

andresulea commented 1 year ago

hi @matt-lourens the other day you told me that this challenge was open, I've been reading more about the theory of these structures, I think I understand more, is this challenge open?

matt-lourens commented 1 year ago

Hey @andresulea, yeah go ahead. There's no PR's open for this issue, it's still anyone's game :)

Gopal-Dahale commented 1 year ago

Hi @matt-lourens, I have made an initial draft. Need some help with parameter prefixes. If it is fine with you, we can continue the discussion on the PR.

Gopal-Dahale commented 1 year ago

Hi, @matt-lourens can you have a look at #37 ?

matt-lourens commented 1 year ago

Hi, @matt-lourens can you have a look at #37 ?

Hey @Gopal-Dahale, yes I glanced over it this morning (looks great!), I will only have a chance a bit later today to go through it. I know the deadline is tomorrow, so I'll try to get to it asap. But don't worry on the bounty side of things, we'll make a plan if time runs short.

andresulea commented 1 year ago

Hello, @matt-lourens I just did the PR, (I hope I did it well) on this issue, it is a nice calculation on the energy of the ground state of the H2 molecule using hierarqcal, I tried to explain it step by step since you commented above that you were not very familiar, I will I leave a graph about how interesting the results were, thanks[ output2

matt-lourens commented 1 year ago

Hey @andresulea,

Thanks! I've left a comment on your PR as how we can incorporate the work you did, for the hackathon/bounty I'm assigning the issue to @Gopal-Dahale (I've elaborated on your PR), but I have an idea for how we can reward you also.