Search code examples
c#fftcomplex-numbersq#qubit

Why does the quantum estimator say i don't use any qubits in Q#?


In short terms, I'm trying to implement in Q# the NonUniform Discrete Fourier Transform.

I've managed to do it bug-free in a classical manner(no quantum gates nor qubits used) yet the resource estimator says that no quantum resources used. This makes me tend to believe that Q# in the back-end, even though I have an Operation type function, does not make use of any quantum specific operations. So I'm trying now to take it step-by-step and load my data into qubits (I'm thinking) then make use of any potential useful gates.

Problem is my data consists of 2 arrays consisting of Double numbers representing the real and imaginary parts of complex numbers. I might need to redesign this into an array of straight-up complex values int the future.

But in essence, the problem is how can I load a complex number in one or more qubits such that i can then do some processing over it and obtain some results?

I'm not too keen on sharing my code as the algorithm is something that wasn't attempted before; but small bits of code and especially further clarifications I am willing to provide.


Solution

  • If I understand your description correctly, the resources estimator provided with the Quantum Development Kit accurately reported that your operation did not use any qubits or quantum instructions. This is because the qubits used by a Q# operation are precisely those used explicitly with using or borrowing statements, plus those used by any other operations called.

    For instance, if you're writing a teleportation operation in Q#, you might do like the following:

    operation PrepareEntangledPair(left : Qubit, right : Qubit) : Unit {
        body (...) {
            H(left);
            CNOT(left, right);
        }
    
        adjoint auto;
    }
    
    operation ApplyCorrection(here : Qubit, msg : Qubit, there : Qubit) : Unit {
        if (M(msg) == One)  { Z(there); }
        if (M(here) == One) { X(there); }
    }
    
    operation TeleportMessage(msg : Qubit, there : Qubit) : Unit {
        using (here = Qubit()) {
            // Create some entanglement that we can use to send our message.
            PrepareEntangledPair(here, there);
    
            // Move our message into the entangled pair by using a Bell
            // measurement.
            Adjoint PrepareEntangledPair(msg, here);
    
            // Measure out the entanglement.
            ApplyCorrection(here, msg, there);
    
            // Reset our "here" qubit before releasing it.
            Reset(here);
        }
    }
    
    operation TeleportClassicalFlag() : Unit {
        using ((msg, there) = (Qubit(), Qubit())) {
            X(msg);
            TeleportMessage(msg, there);
            ApplyToEach(Reset, [msg, there]);
        }
    }
    

    Running the resources estimator on this reports that three qubits were used (two by TeleportClassicalFlag directly, and one by TeleportMessage, which was called by TeleportClassicalFlag):

    enter image description here

    Classical logic, by contrast, always remains classical. This is designed to make it easy to mix classical and quantum logic, such as in implementing iterative phase estimation algorithms. In the above example, the if statements and == operators used in ApplyCorrection are used to describe the classical parts of the teleportation algorithm.