Ex A.4.2 Why does the parity need to be 1 when no solution or two solution is found?

Hi,

In Ex A.4.2, I manage to write the code to pass the test after some trial and error. However, I don’t understand the rational behind the code.

Specifically,

  1. Why does the parity need to be 1 when zero or two solution is found which happens when the state of the last qubit is |0>?

  2. Why do I need to “break” when I have found zero or two solutions as code below?

if np.isclose(probs[0], 1):
    parity = 1
    break

Let me know if would help to post the whole code. I didn’t do it as I’m not sure whether it will be good to reveal the full answer.

Thank you.

Hey @jag and welcome to the forum! :slight_smile:

To answer your questions, it might help to take a look at the right side of the Codebook. :wink: Even if you didn’t take a look at the right side in previous nodes, now that you’ve reached A.4, it might be worth it to take a quick look at the earlier nodes, where we go through the algorithm from a more ‘theoretical’ side and step-by-step.

The problem is set up so you can be guaranteed to find at least one solution if there’s an odd number of solutions. The way you measure has you testing in pairs, and you get the number of solutions mod 2 — so if there are 2 solutions present in the pair, you see the same result as if there were zero. However, at least one of the pairs will return a different phase, and you will be able to detect that.
So you might want to think again about the value of the solution parity when you detect a phase change. Parity just means us saying if a number is odd or even. In the case of getting 1 when you take mod 2 of a number, the parity of that number would be odd.

I’m not sure what your code looks like in this codercise, so I can’t fully comment on your second question (if you feel comfortable sharing your code, feel free :smiling_face:), but I hope it’s starting to make sense what the multisol_pair_circuit function from the A.4.1 codercise is trying to do.

Hi @Ivana_at_Xanadu , thank you for the response. I am first going through the right-hand side as much as I could before working on the coding exercise. :blush:

This is my code for A.4.2

def parity_checker(combos):
    """Use multisol_pair_circuit to determine the parity of a solution set.

    Args:
        combos (list[list[int]]): A list of secret combinations.

    Returns: 
        int: The parity of the solution set.
    """
    parity = 0
    x_tilde_strs = [np.binary_repr(n, n_bits-1) for n in range(2**(n_bits-1))]
    x_tildes = [[int(s) for s in x_tilde_str] for x_tilde_str in x_tilde_strs]
        
    for x_tilde in x_tildes:

        ##################
        # YOUR CODE HERE #
        ##################
        
        # IMPLEMENT PARITY COUNTING ALGORITHM
        for i in range(n_bits-1): # Initialize x_tilde part of state
            if x_tilde[i] == 1:
                qml.PauliX(wires=i)

        @qml.qnode(dev)
        def circuit():
            qml.Hadamard(wires=n_bits-1)
            mat = multisol_oracle_matrix(combos)
            qml.QubitUnitary(mat, wires=range(n_bits))
            qml.Hadamard(wires=n_bits-1)
            return qml.probs(wires=n_bits-1)
        
        probs = circuit()
        
        if np.isclose(probs[0], 1): # Zero or Two solutions found?
            parity = 1
            break # Why need to break here?

    return parity

Regarding my questions:

In my code, I am setting parity to 1 when 0 or two solutions in a pair is found and the code works. I am not sure why this is the case.

Hmm, okay, I see where you might have gotten stuck. :slight_smile:
Here’s what you can do. Instead of writing out the whole definition of the multisol_pair_circuit function, you can call it directly in your code. If you’ve already defined it in the node, it exists for you to be able to call in future codercises. :smiley: And that will make your solution a looot simpler to figure out. Can you try that first?