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

first solution to QFT #40

Closed AmyRouillard closed 11 months ago

AmyRouillard commented 1 year ago

Works assuming the pivot is at a single qubit. Construct a cycle using set of available qubits excluding pivot qubits. Final edge list is constructed as [e+(p,) for zip(pivots, edges)].

matt-lourens commented 1 year ago

Hey @AmyRouillard, great stuff! I think using the cycle to construct edges that connect within the "other" set is key to solving this for the general case.

I spent some time yesterday trying to think about the overlap with Qmask and how we can re-use the code to generate parts of these edges. So far, I'm thinking of pivot and mask as types of opposites of each other. Both partitions the set of available qubits into two classes ("other" and "target"), the pivot enumerates over the "other" and connects them to target, while the mask goes over the "targets" and connects them to the "other". This controls how many edges are created, if we're "masking" two qubits there will only be two edges but if we're pivoting two then there will be N-2 (in the arity=2 case and N = number of qubits). We might be able to combine both into one, but still need to figure out how that would make sense. So I'll keep thinking about that :P

For now, this works for the cases we want and we can do the QFT in one line, which is awesome! To finish the PR, can we add a notebook, to showcase the QFT and one other parameter ("local_pattern") to control where the pivot gets wedged between the edge. I'll elaborate on this in the code.

AmyRouillard commented 1 year ago

The ordering of operations seems to change from the ordering given in the list of edges (Ec_l). Is this expected behavior? Comparing the following two circuits:

u = Qunitary("cnot()^01")
qft = Qinit(10)  + Qpivot(pattern, offset=1, step=2, mapping=u, boundary="open")
circuit= qft(backend="qiskit")
circuit.draw("mpl")
u = Qunitary("cnot()^01")
qft = Qinit(10)  + Qpivot(pattern, offset=1, step=2, mapping=u, boundary="open")
circuit= qft(backend="qiskit")
circuit.draw("mpl")

The edges are correct in my opinion and the order of the "pivoted" items seems shuffled.

AmyRouillard commented 1 year ago

Open: Figure_open

Periodic: Figure_periodic

matt-lourens commented 1 year ago

The ordering of operations seems to change from the ordering given in the list of edges (Ec_l). Is this expected behavior? Comparing the following two circuits:

u = Qunitary("cnot()^01")
qft = Qinit(10)  + Qpivot(pattern, offset=1, step=2, mapping=u, boundary="open")
circuit= qft(backend="qiskit")
circuit.draw("mpl")
u = Qunitary("cnot()^01")
qft = Qinit(10)  + Qpivot(pattern, offset=1, step=2, mapping=u, boundary="open")
circuit= qft(backend="qiskit")
circuit.draw("mpl")

The edges are correct in my opinion and the order of the "pivoted" items seems shuffled.

The operations should occur in the order of the edges, if it doesn't then it's probably qiskit that reorder things. The edges of your second image is: qft[1].E = [('q1', 'q5'), ('q3', 'q5'), ('q6', 'q5'), ('q8', 'q5'), ('q2', 'q10'), ('q7', 'q10'), ('q4', 'q10'), ('q9', 'q10')]

Which is as we "expect" as you mentioned and should produce it in that order but doesn't appear so. I'll investigate it a bit, most likely it's an automatic optimization of qiskit. Two ways to test is try a different backend (note string Qunitaries aren't implemented for them yet) or add a barrier between each edge temporarily, I'll try those out later.