Bit-order of qml.probs Output Solutions

Hello everyone,

I am trying to interpret the output of a QAOA circuit when I use labelled instead of numbered wires. My goal is to solve a QUBO problem, which is defined by the following matrix in pandas.DataFrame format:

ticker      JNPR_long  RCL_long  JNPR_short  RCL_short
ticker                                                
JNPR_long   -3.014872  3.953869    4.914029   3.946705
RCL_long     3.953869 -2.732877    3.946705   4.953599
JNPR_short   4.914029  3.946705   -2.862899   3.953869
RCL_short    3.946705  4.953599    3.953869  -3.224033

The corresponding cost Hamiltonian is

  (-0.05060647606437355) [ZRCL_long]
+ (-0.0497585207586973) [ZJNPR_short]
+ (-0.04899865483748267) [ZJNPR_long]
+ (-0.04815069953180642) [ZRCL_short]
+ (0.06917047107755245) [IJNPR_long]
+ (0.019733527499637107) [ZJNPR_long ZRCL_short]
+ (0.019733527499637107) [ZRCL_long ZJNPR_short]
+ (0.01976934273883488) [ZJNPR_long ZRCL_long]
+ (0.01976934273883488) [ZJNPR_short ZRCL_short]
+ (0.02457014657386209) [ZJNPR_long ZJNPR_short]
+ (0.024767993064001435) [ZRCL_long ZRCL_short]

and when I check its wires I get the same labels as in the index of the pandas DataFrame but sorted

# cost_h.wires output.
<Wires = ['JNPR_long', 'JNPR_short', 'RCL_long', 'RCL_short']>

After defining the circuit and optimising its parameters, I call the following circuit probabilities function with the optimal parameters

@qml.qnode(dev)
def circuit_probabilities(params):
    circuit(params)
    return qml.probs(wires=cost_h.wires)

and get the output probability distribution

# circuit_probabilities(opt_params) output.
array([0.14723998, 0.15039128, 0.14555833, 0.03342168, 0.14674327, 
       0.0471349 , 0.04516574, 0.0010264 , 0.14823591, 0.04789943,
       0.04569813, 0.00105497, 0.03367039, 0.00108493, 0.00098973,
       0.00468493])

which implies that the quantum states [0 0 0 1], [1 0 0 0], [0 0 0 0], [0 1 0 0] and [0 0 1 0] are the most probable ones.

What is the order of the elements in each of those binary vector/strings? The same as in the original pandas DataFrame index? The same as in cost_h.wires? That means, does [0 0 1 0] correspond to
a) JNPR_long = 0; RCL_long = 0; JNPR_short = 1; RCL_short = 0,
b) or to JNPR_long = 0; JNPR_short = 0; RCL_long = 1; RCL_short = 0?

Thank you very much in advance.

Hey @pormelrog!

Great question. probs and state return things in lexicographic order. This means that things are ordered left-to-right. Here’s an example:

dev = qml.device("default.qubit", wires=2)

@qml.qnode(dev)
def circuit():
    qml.Hadamard(wires=1)
    return qml.state()
>>> circuit()
array([0.70710678+0.j, 0.70710678+0.j, 0.        +0.j, 0.        +0.j])

The returned array is in lexicographic order — we have a \tfrac{1}{\sqrt{2}} amplitude in both |00⟩ and |01⟩ — 00 corresponds to the first entry, 01 corresponds to the second, 10 corresponds to the third, and 11 corresponds to the fourth. In your example, 0001 means JNPR_long = 0; RCL_long = 0; JNPR_short = 0; RCL_short = 1.

Also, note that the binary string’s amplitude belongs to the index in the array converted to its base-10 value:

00 \stackrel{\text{to base 10}}{=} 0 \times 2^0 + 0 \times 2^1 = 0 \\ 01 \stackrel{\text{to base 10}}{=} 1 \times 2^0 + 0 \times 2^1 = 1 \\ 10 \stackrel{\text{to base 10}}{=} 0 \times 2^0 + 1 \times 2^1 = 2 \\ 11 \stackrel{\text{to base 10}}{=} 1 \times 2^0 + 1 \times 2^1 = 3

Whoops! I copied down your wire order incorrectly. So, in your example, 0001 means JNPR_long = 0; JNPR_short = 0; RCL_long = 0; RCL_short = 1. :grin: