QHack Deutsch- Jozsa

Apologies all, if this is an inappropriate place to post this question;

I have a question regarding the QHack Deutsch-Jozsa (first) question and my understanding of the oracle.

My results are the same as the test data.

However, my understanding is that the oracle is supposed to be guaranteed to give constant or balanced output for a binary sequence of any length “n”.

However, the test data gives one result which is “balanced” and another that is “constant”. How can that be?

In fact, the oracle provided gives alternating “balanced” and “constant” output if one simply gives it [0], [0,0], [0,0,0], [0,0,0,0] etc. and the same for [1] etc.

Also, whereas [0,1] and [1,0] are balanced, [0,1,1,0] and [1,0,1,0] are given as constant.

The answer can’t surely be that it is a different Oracle every time dependent on what binary sequence is passed to it? What would be the point of that?

Have I misunderstood the point of the algorithm or is has a bad choice of oracle been used?

Thanks in advance,

Simon

Hi Simon!

I think I understand your question but if not please feel free to say so. In this case, the .in files have nothing to do with the results of the function. It is a way to create the oracle but without making it obvious (to avoid cheating in the exercise).The .in refers to the distribution of a series of CNOT gates that will determine if the function is constant or balanced and in this case we will always work with n=2.

I hope this helps!

Hi Guillermo,

Thanks! Yes, that was it. I stupidly misread the question. I thought the .in files were the providing the input to f: {0,1}^n -> {0,1}.

As a result, even though I could see that the input was being used in the definition of the oracle, I assumed that it was configuring a single oracle for two different binary strings. I now realise that each run creates a different oracle!

To try to make sure that I understood it properly, I wrapped the call to circuit() in a loop and returned information from all three wires. Over different runs, I returned sample(), state() and probs() and printed out the results and then repeated all that with one of the post processing Hadamard’s commented out and then both. I compared what I saw to the probability equation on the wikipedia page and now have a much better appreciation of how it works.

There is just one “however”. My assumption is that because shots = 1, each time an observation / sample() occurs, the system “collapses” into one binary sequence or another. However, while I can see (as a result of looking at the third wire) that both the balanced and constant results “process” different binary sequences each pass through the loop, I couldn’t find a way of “trapping” the exact sequence.

Is there anyway, in the case of the (1,1) oracle for example, to satisfy oneself that each of 00,01,10 and 11 are processed and all give |00> ?

(I want to make sure I get the most out of the challenge rather than stopping because the code is working).

Thanks so much for your support!

Simon

Once you have the oracle defined, you could do checks of this type. (Change the bits variable to your liking) :slightly_smiling_face:

    dev = qml.device("default.qubit", wires=3, shots=1)

    @qml.qnode(dev)
    def circuit(bits):
        """
        Args:
            bits (list): Input of the oracle. Could be [0,0], [0,1], [1,0] or [1,1]
        """

        if bit[0] == 1:
            qml.PauliX(wires = 0)
        if bit[1] == 1:
            qml.PauliX(wires = 1)
        
        oracle()  

        return qml.sample(wires=range(3))

    bits = [0,0]
    sample = circuit(bits)
    print(sample)

but the output will not give |00>, that only occurs when you put them all in at the same time. What you can check by hand is if it is constant or balanced.