3
$\begingroup$

I have this program derived from Microsoft Quantum Katas for counting (see here):

namespace Quantum.Sample
{
    open Microsoft.Quantum.Primitive;
    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Extensions.Convert;
    open Microsoft.Quantum.Extensions.Math;

    operation SprinklerAnc (queryRegister:  Qubit[],  target : Qubit,ancilla: Qubit[]) : Unit {
        body (...) {
            X(queryRegister[2]);
            X(queryRegister[3]);
            X(queryRegister[4]);
            X(queryRegister[5]);
            X(queryRegister[6]);
            X(ancilla[0]);
            X(ancilla[1]);
            X(ancilla[2]);

            CCNOT(queryRegister[0],queryRegister[1],ancilla[0]);
            CCNOT(queryRegister[1],queryRegister[2],ancilla[1]);
            CCNOT(queryRegister[0],queryRegister[2],ancilla[2]);
            (Controlled X)([ancilla[0],ancilla[1],ancilla[2],queryRegister[3],queryRegister[4],queryRegister[5],queryRegister[6]],target);
            CCNOT(queryRegister[0],queryRegister[2],ancilla[2]);
            CCNOT(queryRegister[1],queryRegister[2],ancilla[1]);
            CCNOT(queryRegister[0],queryRegister[1],ancilla[0]);

            X(ancilla[2]);
            X(ancilla[1]);
            X(ancilla[0]);
                        X(queryRegister[2]);
            X(queryRegister[6]);
            X(queryRegister[5]);
            X(queryRegister[4]);
            X(queryRegister[3]);


        }
        adjoint invert;
        controlled auto;
        controlled adjoint auto;
    }           
    operation OracleConverterImpl (markingOracle : ((Qubit[], Qubit) => Unit : Adjoint, Controlled), register : Qubit[]) : Unit {

        body (...) {
            using (target = Qubit()) {
                // Put the target into the |-⟩ state
                X(target);
                H(target);

                // Apply the marking oracle; since the target is in the |-⟩ state,
                // flipping the target if the register satisfies the oracle condition will apply a -1 factor to the state
                markingOracle(register, target);

                // Put the target back into |0⟩ so we can return it
                H(target);
                X(target);
            }
        }

        adjoint invert;
        controlled auto;
        adjoint controlled auto;
    }

    operation HadamardTransform (register : Qubit[]) : Unit {

        body (...) {
            //ApplyToEachA(H, register);

            // ApplyToEach is a library routine that is equivalent to the following code:
             let nQubits = Length(register);
             for (idxQubit in 0..nQubits - 1) {
                 H(register[idxQubit]);
             }
        }

        adjoint invert;
        controlled auto;
        controlled adjoint auto;
    }
    operation Oracle_ArbitraryPattern (queryRegister : Qubit[], target : Qubit, pattern : Bool[]) : Unit {

        body (...) {
            (ControlledOnBitString(pattern, X))(queryRegister, target);
        }

        adjoint invert;
        controlled auto;
        controlled adjoint auto;

    }   

    // Task 2.2. Conditional phase flip
    operation ConditionalPhaseFlip (register : Qubit[]) : Unit {

        body (...) {
            // Define a marking oracle which detects an all zero state
            let allZerosOracle = Oracle_ArbitraryPattern(_, _, new Bool[Length(register)]);

            // Convert it into a phase-flip oracle and apply it
            let flipOracle = OracleConverter(allZerosOracle);
            flipOracle(register);
        }

        adjoint self;
        controlled  auto;

        controlled adjoint auto;

    }



    // Task 2.3. The Grover iteration
    operation GroverIteration (register : Qubit[], oracle : (Qubit[] => Unit :   Adjoint, Controlled)) : Unit {

        body (...) {
            oracle(register);
            HadamardTransform(register);
            ConditionalPhaseFlip(register);
            HadamardTransform(register);
        }

        adjoint invert;
              controlled auto;
        controlled adjoint auto;
    }    
    function OracleConverter (markingOracle : ((Qubit[], Qubit) => Unit : Adjoint, Controlled)) : (Qubit[] => Unit : Adjoint, Controlled) {
        return OracleConverterImpl(markingOracle, _);
    }

    operation UnitaryPowerImpl (U : (Qubit[] => Unit : Adjoint, Controlled), power : Int, q : Qubit[]) : Unit {
        body (...) {
            for (i in 1..power) {
                U(q);
            }
        }
        adjoint auto;
        controlled auto;
        controlled adjoint auto;
    }

    operation QPE() : Double {
        mutable phase = -1.0;
        let n=8;
                       using ((reg,phaseRegister,ancilla)=(Qubit[7 ], Qubit[n],Qubit[3]))
                       {
        // Construct a phase estimation oracle from the unitary
                         let phaseOracle = OracleConverter(SprinklerAnc(_,_,ancilla));

        let oracle = DiscreteOracle(UnitaryPowerImpl(GroverIteration(_, phaseOracle), _, _));

              //  let markingOracle = Sprinkler(_, _);

        // Allocate qubits to hold the eigenstate of U and the phase in a big endian register 

            let phaseRegisterBE = BigEndian(phaseRegister);
            // Prepare the eigenstate of U
                HadamardTransform(reg);

            // Call library
            QuantumPhaseEstimation(oracle, reg, phaseRegisterBE);
            // Read out the phase
            set phase = ToDouble(MeasureIntegerBE(phaseRegisterBE)) / ToDouble(1 <<< (n));

            ResetAll(reg);
            ResetAll(phaseRegister);
        }
        let angle = PI()*phase;
        let res = 128.0 *(1.0- PowD(Sin(angle),2.0));

        return res;
    }



}

with driver (see this):

using System;

using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;

namespace Quantum.Sample
{
    class Driver
    {
        static void Main(string[] args)
        {
            using (var qsim = new QuantumSimulator())
            {
                for (int i = 0; i < 100; i++)
                {
                    var res = QPE.Run(qsim).Result;
                    System.Console.WriteLine($"Res:{res}");
                }
            }
        }
    }
}

It should count the solutions of the 3 bits formula (not reg[0] or reg[2]) and (not reg[1] or reg[2]) and (not reg[0] or not reg[1]) This formula has 4 solutions. I consider an extended formula with 7 bits that is true when the first three bit satisfy the above formula and the other four bits are at 0. The extended formula this has 4 solutions as well but I can increase easily the number of solutions by excluding variables from the formula. I compute the phase $\phi$ with the linked program, then I compute $\theta/2$ as $2\pi\phi/2=\pi\phi$ Now the number of solutions should be $$128\sin(\theta/2)^2$$ right? I get the correct number of solutions if I compute $$128(1-\sin(\theta/2)^2)$$ It's as if the formula is negated but I can't find where the negation is. This same formula with GroverSearch from Microsoft Quantum Katas returns correct solutions.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.