Esempio n. 1
0
        static void Main(string[] args)
        {
            var sim = new QuantumSimulator(throwOnReleasingQubitsNotInZeroState: true);

            Console.Write("Enter the number of bits in the system (Less than 6):\n");
            var nDatabaseQubits = int.Parse(Console.ReadLine());

            if (nDatabaseQubits > 6)
            {
                Console.WriteLine("Input greater than 6. Value defaulted to 6.");
                nDatabaseQubits = 6;
            }
            Console.Write($"N: {nDatabaseQubits}");
            var databaseSize = Math.Pow(2.0, nDatabaseQubits);
            var nIterations  = (int)Math.Floor(Math.PI * 1 / (Math.Asin(Math.Sqrt(1 / databaseSize))) / 4);

            var queries = nIterations * 2 + 1;

            var classicalSuccessProbability = 1.0 / databaseSize;
            var quantumSuccessProbability   = Math.Pow(Math.Sin((2.0 * (double)nIterations + 1.0) * Math.Asin(1.0 / Math.Sqrt(databaseSize))), 2.0);
            var repeats      = 100;
            var successCount = 0;

            Console.Write(
                $"\n\nQuantum search for marked element in database.\n" +
                $"  Database size: {databaseSize}.\n" +
                $"  Classical success probability: {classicalSuccessProbability}\n" +
                $"  Quantum success probability: {quantumSuccessProbability}\n\n");



            foreach (var idxAttempt in Enumerable.Range(0, repeats))
            {
                var task = ApplyQuantumSearch.Run(sim, nIterations, nDatabaseQubits);

                var data = task.Result;

                var markedQubit      = data.Item1;
                var databaseRegister = data.Item2.ToArray();

                successCount += markedQubit == Result.One ? 1 : 0;

                if ((idxAttempt + 1) % 10 == 0)
                {
                    var empiricalSuccessProbability = Math.Round((double)successCount / ((double)idxAttempt + 1), 3);

                    var speedupFactor = Math.Round(empiricalSuccessProbability / classicalSuccessProbability / (double)queries, 3);

                    Console.Write(
                        $"Attempt {idxAttempt+1}. " +
                        $"Success: {markedQubit},  " +
                        $"Probability: {empiricalSuccessProbability} " +
                        $"Speedup: {speedupFactor} " +
                        $"Found database index {string.Join(", ", databaseRegister.Select(x => x.ToString()).ToArray())} \n");
                }
            }

            System.Console.WriteLine("\n\nPress any key to continue...\n");
            System.Console.ReadKey();
        }
Esempio n. 2
0
        static void Main(string[] args)
        {
            using (var qsim = new QuantumSimulator())
            {
                //データベースのサイズ(databaseSize)Nに対する
                //必要な量子ビット数(nDatabaseQubits)n. N=2^n
                var nDatabaseQubits = 6;
                var databaseSize    = Math.Pow(2.0, nDatabaseQubits);

                //振幅増幅を繰り返す回数k。
                //確率をほぼ1にするためには PI/4*Sqrt(N)-1/2なので、N=2^6なら6回程度必要。
                var nIterations = 3;

                // データベースに対する問い合わせ数
                var queries = nIterations * 2 + 1;

                // 期待される確率を計算して、実際の結果と比較する
                // 古典アルゴリズムでの確率は、N個から1つ探す確率なので
                var classicalSuccessProbability = 1.0 / databaseSize;
                // Groverアルゴリズムでの確率sin^2[(2*k+1)θ]。ただしsinθ=Sqrt(1/N)
                var quantumSuccessProbability = Math.Pow(Math.Sin((2.0 * (double)nIterations + 1.0) * Math.Asin(1.0 / Math.Sqrt(databaseSize))), 2.0);
                // 一連の測定を繰り返す回数
                var repeats = 100;
                // 探索がうまく行った回数
                var successCount = 0;

                Console.Write(
                    $@"
  Quantum search for marked element in database.
  データベースのサイズ: {databaseSize}
  古典アルゴリズムでの確率: {classicalSuccessProbability}
  1回当たりの問い合わせ数: {queries}
  量子アルゴリズムでの確率: {quantumSuccessProbability}

");

                foreach (var idxAttempt in Enumerable.Range(0, repeats))
                {
                    //必要なパラメーターを渡してQ#のコードを実行
                    // GetAwaiter().GetResult() はC#のasync/await構文
                    // var () = ... という書き方はタプル構文を参照してください
                    var(markedQubit, databaseRegister) = ApplyQuantumSearch.Run(qsim, nIterations, nDatabaseQubits).GetAwaiter().GetResult();

                    // 探索に成功していればカウントアップ
                    successCount += markedQubit == Result.One ? 1 : 0;

                    // 10回ごとに結果を表示する (10回ごとに特に意味はない)
                    if ((idxAttempt + 1) % 10 == 0)
                    {
                        // 成功した割合を表示
                        var empiricalSuccessProbability = Math.Round((double)successCount / ((double)idxAttempt + 1), 3);

                        // 古典アルゴリズムよりどけだけよかったか(割合の比)
                        var speedupFactor = Math.Round(empiricalSuccessProbability / classicalSuccessProbability / (double)queries, 3);

                        Console.WriteLine($"試行回数 {idxAttempt}. 成功: {markedQubit}, 確率: {empiricalSuccessProbability} 高速化比: {speedupFactor} 検出したインデックス {databaseRegister}");
                    }
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// The aim of this program is to find out the maximum |11…1> in the
        /// n-qubits domain with grover algorithm speeding up.
        /// </summary>
        static void Main(string[] args)
        {
            var sim = new QuantumSimulator(throwOnReleasingQubitsNotInZeroState: true);

            // Quantum Database Search with Manual Oracle Definitions

            // N = 2^n
            var nDatabaseQubits = 6;
            var databaseSize    = (int)Math.Pow(2.0, nDatabaseQubits);

            double overallProbability  = 0.0;
            double overallIteration    = 0.0;
            double overallAcceleration = 0.0;

            double overallMutationSuccess      = 0.0;
            double overallMutationAcceleration = 0.0;
            int    totalMutation = 0;

            int caseNum = 50;

            foreach (var cs in Enumerable.Range(0, caseNum))
            {
                // We define the marked elements. These must be smaller than `databaseSize`
                //var markedElements = new long[] { 255, 250, 251, 254, 234 };
                var         markedElements = new long[] { };
                List <long> Elements       = markedElements.ToList();

                //Generate some random integers for grover to find
                Random rnd = new Random();
                //At least one individual is marked
                int ranLength = rnd.Next(1, (int)Math.Sqrt(databaseSize));
                foreach (var i in Enumerable.Range(0, ranLength))
                {
                    int ranNum = rnd.Next(0, databaseSize);
                    Elements.Add(ranNum);
                }

                markedElements = Elements.ToArray();

                var nMarkedElements = markedElements.Length;

                // Grover iteration times to amplify the marked subspace
                // Note that the domain is 64 and the solution to this
                // problem can only be one, so the number of iterations
                // is (π/4)(√N/1)
                var nIterations = Statics(databaseSize, nMarkedElements);

                // Number of queries to database oracle.
                var queries = nIterations * 2 + 1;

                var quantumSuccessProbability = Math.Pow(Math.Sin((2.0 * (double)nIterations + 1.0) * Math.Asin(1.0 / Math.Sqrt(databaseSize))), 2.0);
                int iterationsTest            = (int)((Math.PI / 2.0 / (Math.Asin(Math.Sqrt(nMarkedElements) / Math.Sqrt(databaseSize))) - 1) / 2.0) + 1;

                var repeats = 50;

                Console.Write(
                    $"Marked elements: {string.Join(",", markedElements.Select(x => x.ToString()).ToArray())}" +
                    $" Initial iteration: {iterationsTest}" +
                    $" Iterations: {nIterations}" +
                    //$" Theoretical probability: {quantumSuccessProbability}\n\n" +
                    "\n");

                //Perform mutaion or not
                var mutate = 1;
                //Record the maximun probability of find a result and its corresponding iteration number
                var maxProbability          = 0.0;
                var correspondingIterations = 0;
                //More iteration numbers can be tested in the following line
                foreach (var iterAttempt in Enumerable.Range(1, nIterations + (int)Math.Sqrt(nIterations)))
                {
                    Console.WriteLine($"-------------------No.{iterAttempt} iteration attempt in No.{cs+1} case test-------------------");
                    var probsWithoutMutation = 0.0;
                    for (int mutation = 0; mutation <= mutate; mutation++)
                    {
                        var successCount = 0;
                        //This loop controls whether mutation should be performed or not
                        foreach (var idxAttempt in Enumerable.Range(0, repeats))
                        {
                            //Which qubit should perform Hadamard transformation
                            var         H     = new long[] { };
                            List <long> HList = H.ToList();
                            //Which qubit should flip
                            var         X     = new long[] { };
                            List <long> XList = X.ToList();
                            //Which qubit should control
                            var         CNOTLeft     = new long[] { };
                            List <long> CNOTLeftList = CNOTLeft.ToList();
                            //Which qubit should be controlled to flip
                            var         CNOTRight     = new long[] { };
                            List <long> CNOTRightList = CNOTRight.ToList();

                            //Note: the number of Hize is yet to reconsider
                            //int HSize = rnd.Next((int)Math.Sqrt(databaseSize), databaseSize / 2);
                            int HSize = rnd.Next(0, (int)Math.Sqrt(databaseSize));
                            foreach (var idxRan in Enumerable.Range(0, HSize))
                            {
                                HList.Add(rnd.Next(0, nDatabaseQubits));
                            }
                            H = HList.ToArray();

                            //Not working
                            int XSize = rnd.Next(0, (int)Math.Sqrt(databaseSize));
                            foreach (var idxRan in Enumerable.Range(0, XSize))
                            {
                                XList.Add(rnd.Next(0, nDatabaseQubits));
                            }
                            X = XList.ToArray();

                            //Note: the number of CNOTSize is yet to reconsider
                            int CNOTSize = rnd.Next(databaseSize / 2, databaseSize);
                            foreach (var idxRan in Enumerable.Range(0, CNOTSize))
                            {
                                CNOTLeftList.Add(rnd.Next(0, nDatabaseQubits));
                                CNOTRightList.Add(rnd.Next(0, nDatabaseQubits));
                            }
                            CNOTLeft  = CNOTLeftList.ToArray();
                            CNOTRight = CNOTRightList.ToArray();

                            var task = ApplyQuantumSearch.Run(sim, new QArray <long>(markedElements), iterAttempt, nDatabaseQubits,
                                                              new QArray <long>(H), new QArray <long>(X), new QArray <long>(CNOTLeft), new QArray <long>(CNOTRight), mutation);

                            //Extract the marked qubit and the database register
                            var data             = task.Result;
                            var markedQubit      = data.Item1;
                            var databaseRegister = data.Item2;
                            //var resultTest = data.Item3 == Result.One ? 1 : 0;

                            //If the returned marked qubit is One,
                            //that means the grover search succeed.
                            successCount += markedQubit == Result.One ? 1 : 0;
                        }

                        var Probability = Math.Round((double)successCount / ((double)repeats), 5);
                        if (mutation == 0)
                        {
                            Console.WriteLine("Random initial State");
                            probsWithoutMutation = Probability;
                        }
                        else
                        {
                            Console.WriteLine("With Mutation");
                        }
                        if (Probability > maxProbability && mutation == 0)
                        {
                            maxProbability          = Probability;
                            correspondingIterations = iterAttempt;
                        }
                        else if (mutation == 1 && Probability > probsWithoutMutation)
                        {
                            overallMutationSuccess++;
                            overallMutationAcceleration += (Probability - probsWithoutMutation);
                        }
                        Console.WriteLine("Iterations: " + iterAttempt + " Probability: " + Probability);
                    }
                    totalMutation++;
                }
                double acclerationRate = (double)(nIterations > iterationsTest ? nIterations : iterationsTest) / correspondingIterations;
                Console.WriteLine("\nIterations: " + correspondingIterations + " Probability: " + maxProbability + " Accleration Rate: " + acclerationRate);
                Console.WriteLine("Total mutation: " + totalMutation + " Overall mutation success: " + overallMutationSuccess);
                Console.WriteLine("Contemporary Mutation Success: " + overallMutationSuccess / totalMutation + " and Mutation Acceleration : " + overallMutationAcceleration / overallMutationSuccess + "\n");
                overallIteration    += correspondingIterations;
                overallProbability  += maxProbability;
                overallAcceleration += acclerationRate;
            }
            Console.WriteLine("Overall probability: " + overallProbability / caseNum + " iterations: " + overallIteration / caseNum + " Acceleration Rate: " + overallAcceleration / caseNum);
            Pause();
        }
Esempio n. 4
0
        static void Main(string[] args)
        {
            #region Simulator Setup

            // We begin by defining a quantum simulator to be our target
            // machine.
            var sim = new QuantumSimulator(throwOnReleasingQubitsNotInZeroState: true);

            #endregion

            #region Random (Classical) Database Search

            // Let us investigate the success probability of classical random search.
            // This corresponds to the case where we only prepare the start state, and
            // do not perform any Grover iterations to amplify the marked subspace
            var nIterations = 0;

            // We now define the size `N` = 2^n of the database to search in terms of
            // number of qubits `n`
            var nDatabaseQubits = 6;

            // 2^6 = 64
            var databaseSize = Math.Pow(2.0, nDatabaseQubits);

            // We now execute the classical random search.
            // Repeat 1000 times to collect enough data.
            var repeats      = 1000;
            var successCount = 0;

            Console.Write(
                $"Classical random search for marked element in database (no Grover iterations).\n" +
                $"  Database size: {databaseSize}\n" +
                $"  Looking for marked element: One One One One One One\n\n");



            foreach (var idxAttempt in Enumerable.Range(0, repeats))
            {
                // Each operation has a static method called Run which takes a simulator as
                // an argument, along with all the arguments defined by the operation itself.
                var task = ApplyQuantumSearch.Run(sim, nIterations, nDatabaseQubits);

                // We extract the return value of the operation by getting the Results property.
                var data = task.Result;

                // Extract the marked qubit state
                var markedQubit      = data.Item1;
                var databaseRegister = data.Item2.ToArray();

                successCount += markedQubit == Result.One ? 1 : 0;

                // Print the results of the search every 100 attempts
                if ((idxAttempt + 1) % 100 == 0)
                {
                    var success = false;

                    if (markedQubit == Result.One)
                    {
                        success = true;
                    }

                    Console.Write(
                        $"Attempt: {idxAttempt}. " +
                        $"Success: {success}. " +
                        $"Probability: {Math.Round((double)successCount / ((double)idxAttempt + 1), 3)}. " +
                        $"Found database index: {string.Join(", ", databaseRegister.Select(x => x.ToString()).ToArray())} \n");
                }
            }
            Console.Write($"\nTotal success count over {repeats} attempts: {successCount}.\n");

            #endregion

            #region Quantum Database Search

            // Let us investigate the success probability of the quantum search.

            // Wedefine the size `N` = 2^n of the database to searched in terms of
            // number of qubits `n`.
            nDatabaseQubits = 6;
            databaseSize    = Math.Pow(2.0, nDatabaseQubits);

            // We now perform Grover iterates to amplify the marked subspace.
            nIterations = 3;

            // Number of queries to database oracle.
            var queries = nIterations * 2 + 1;

            // We now execute the quantum search.
            repeats      = 1000;
            successCount = 0;

            Console.Write(
                $"\nQuantum search for marked element in database. Number of Grover iterations: {nIterations}\n" +
                $"  Database size: {databaseSize}\n" +
                $"  Looking for marked element: One One One One One One\n\n");



            foreach (var idxAttempt in Enumerable.Range(0, repeats))
            {
                // Each operation has a static method called Run which takes a simulator as
                // an argument, along with all the arguments defined by the operation itself.
                var task = ApplyQuantumSearch.Run(sim, nIterations, nDatabaseQubits);

                // We extract the return value of the operation by getting the Results property.
                var data = task.Result;

                // Extract the marked qubit state
                var markedQubit      = data.Item1;
                var databaseRegister = data.Item2.ToArray();

                successCount += markedQubit == Result.One ? 1 : 0;

                // Print the results of the search every 10 attemps
                if ((idxAttempt + 1) % 100 == 0)
                {
                    var success = false;

                    if (markedQubit == Result.One)
                    {
                        success = true;
                    }

                    Console.Write(
                        $"Attempt: {idxAttempt}. " +
                        $"Success: {success}.  " +
                        $"Found database index: {string.Join(", ", databaseRegister.Select(x => x.ToString()).ToArray())} \n");
                }
            }

            Console.Write($"\nTotal success count over {repeats} attempts: {successCount}.\n");

            Console.WriteLine("\nPress any key to exit.\n");
            Console.ReadKey();

            #endregion
        }
Esempio n. 5
0
        static void Main(string[] args)
        {
            #region Setup

            // We begin by defining a quantum simulator to be our target
            // machine.
            var sim = new QuantumSimulator(throwOnReleasingQubitsNotInZeroState: true);

            #endregion

            #region Random Database Search with Manual Oracle Definitions

            // Let us investigate the success probability of classical random search.
            // This corresponds to the case where we only prepare the start state, and
            // do not perform any Grover iterates to amplify the marked subspace.
            var nIterations = 0;

            // We now define the size `N` = 2^n of the database to searched in terms of
            // number of qubits `n`.
            var nDatabaseQubits = 3;
            var databaseSize    = Math.Pow(2.0, nDatabaseQubits);

            // We now execute the classical random search and verify that the success
            // probability matches the classical result of 1/N. Let us repeat 100
            // times to collect enough statistics.
            var classicalSuccessProbability = 1.0 / databaseSize;
            var repeats      = 3;
            var successCount = 0;

/*
 *          Console.Write(
 *              $"Classical random search for marked element in database.\n" +
 *              $"  Database size: {databaseSize}.\n" +
 *              $"  Success probability:  {classicalSuccessProbability}\n\n");
 *
 *
 *
 *          foreach (var idxAttempt in Enumerable.Range(0, repeats))
 *          {
 *              // Each operation has a static method called Run which takes a simulator as
 *              // an argument, along with all the arguments defined by the operation itself.
 *              var task = ApplyQuantumSearch.Run(sim, nIterations, nDatabaseQubits);
 *
 *              // We extract the return value of the operation by getting the Results property.
 *              var data = task.Result;
 *
 *              // Extract the marked qubit state
 *              var markedQubit = data.Item1;
 *              var databaseRegister = data.Item2.ToArray();
 *
 *              successCount += markedQubit == Result.One ? 1 : 0;
 *
 *              // Print the results of the search every 100 attemps
 *              //if ((idxAttempt + 1) % 1 == 0)
 *              if(markedQubit == Result.One)
 *              {
 *
 *                  Console.Write(
 *                      $"Attempt {idxAttempt}. " +
 *                      $"Success: {markedQubit},  " +
 *                      $"Probability: {Math.Round((double)successCount / ((double)idxAttempt + 1),3)} " +
 *                      $"Found database index {string.Join(", ", databaseRegister.Select(x => x.ToString()).ToArray())} \n");
 *              }
 *          }
 *          Console.Write("Total Success = " + successCount);
 *          Pause();
 */
            #endregion


            #region Quantum Database Search with Manual Oracle Definitions

            // Let us investigate the success probability of the quantum search.

            // Wedefine the size `N` = 2^n of the database to searched in terms of
            // number of qubits `n`.
            nDatabaseQubits = 6;
            databaseSize    = Math.Pow(2.0, nDatabaseQubits);

            // We now perform Grover iterates to amplify the marked subspace.
            nIterations = 3;

            // Number of queries to database oracle.
            var queries = nIterations * 2 + 1;

            // We now execute the quantum search and verify that the success
            // probability matches the theoretical prediction.
            classicalSuccessProbability = 1.0 / databaseSize;
            var quantumSuccessProbability = Math.Pow(Math.Sin((2.0 * (double)nIterations + 1.0) * Math.Asin(1.0 / Math.Sqrt(databaseSize))), 2.0);
            repeats      = 8;
            successCount = 0;
            Console.Write("Searching in 6 bit Register - 2^6=64");
            Console.Write(
                $"\n\n  Quantum search for marked element (63 - (1,1,1,1,1,1))in database. \n" +
                $"  Database size: {databaseSize}.\n" +
                $"  Classical success probability: {classicalSuccessProbability}\n" +
                // $"  Queries per search: {queries} \n" +
                $"  No of Iterations = {repeats}.\n" +
                $"  Quantum success probability: {quantumSuccessProbability}\n\n");



            foreach (var idxAttempt in Enumerable.Range(0, repeats))
            {
                // Each operation has a static method called Run which takes a simulator as
                // an argument, along with all the arguments defined by the operation itself.
                var task = ApplyQuantumSearch.Run(sim, nIterations, nDatabaseQubits);

                // We extract the return value of the operation by getting the Results property.
                var data = task.Result;

                // Extract the marked qubit state
                var markedQubit      = data.Item1;
                var databaseRegister = data.Item2.ToArray();

                successCount += markedQubit == Result.One ? 1 : 0;

                // Print the results of the search every 10 attemps
                //if ((idxAttempt + 1) % 10 == 0)
                //if (markedQubit == Result.One )
                {
                    var empiricalSuccessProbability = Math.Round((double)successCount / ((double)idxAttempt + 1), 3);

                    // This is how much faster the quantum algorithm performs on average
                    // over the classical search.
                    var speedupFactor = Math.Round(empiricalSuccessProbability / classicalSuccessProbability / (double)queries, 3);

                    Console.Write(
                        $"Attempt {idxAttempt+1}. " +
                        $"Success: {markedQubit},  " +
                        $"Probability: {empiricalSuccessProbability} " +
                        // $"Speedup: {speedupFactor} " +
                        $"Found database index {string.Join(", ", databaseRegister.Select(x => x.ToString()).ToArray())} \n");
                }
            }
            Console.Write("\n\nTotal Success = " + successCount);
            Pause();

            #endregion


            #region Multiple Element Quantum Database Search with the Canon

            // Let us investigate the success probability of the quantum search with multiple
            // marked elements.

            // We define the size `N` = 2^n of the database to searched in terms of
            // number of qubits `n`.
            nDatabaseQubits = 8;
            databaseSize    = Math.Pow(2.0, nDatabaseQubits);

            // We define the marked elements. These must be smaller than `databaseSize`
            //Microsoft.Quantum.Simulation.Core.QArray<long>[]
            Console.Write("\nEnter the no to find below 256:");
            long xart = 0;
            try
            {
                xart = Convert.ToInt64(Console.ReadLine());
            }
            catch (Exception)
            {
                Console.Write("Since no input given, randomly taking 84\n\n");
                xart = 84;
            }

            QArray <long> markedElements = new QArray <long>()
            {
                xart
            };
            var nMarkedElements = markedElements.Length;



            // We now perform Grover iterates to amplify the marked subspace.
            nIterations = 3;

            // Number of queries to database oracle.
            queries = nIterations * 2 + 1;

            // We now execute the quantum search and verify that the success
            // probability matches the theoretical prediction.
            classicalSuccessProbability = (double)(nMarkedElements) / databaseSize;
            quantumSuccessProbability   = Math.Pow(Math.Sin((2.0 * (double)nIterations + 1.0) * Math.Asin(Math.Sqrt(nMarkedElements) / Math.Sqrt(databaseSize))), 2.0);
            repeats      = 16;
            successCount = 0;

            Console.Write(
                $"\n\nQuantum search for marked element in database.\n" +
                $"  Database size: {databaseSize}.\n" +
                $"  Marked elements: {string.Join(",", markedElements.Select(x => x.ToString()).ToArray())}\n" +
                $"  Classical success probability: {classicalSuccessProbability}\n" +
                // $"  Queries per search: {queries} \n" +
                $"  Quantum success probability: {quantumSuccessProbability}\n\n");


            //Pause();
            foreach (var idxAttempt in Enumerable.Range(0, repeats))
            {
                //Console.Write(idxAttempt); // Bharath Code
                // Each operation has a static method called Run which takes a simulator as
                // an argument, along with all the arguments defined by the operation itself.
                var task = ApplyGroverSearch.Run(sim, markedElements, nIterations, nDatabaseQubits);

                // We extract the return value of the operation by getting the Results property.
                var data = task.Result;

                // Extract the marked qubit state
                var markedQubit      = data.Item1;
                var databaseRegister = data.Item2;

                successCount += markedQubit == Result.One ? 1 : 0;

                // Print the results of the search every 1 attemps
                //if ((idxAttempt + 1) % 1 == 0)
                //if (markedQubit == Result.One)

                {
                    var empiricalSuccessProbability = Math.Round((double)successCount / ((double)idxAttempt + 1), 3);

                    // This is how much faster the quantum algorithm performs on average
                    // over the classical search.
                    var speedupFactor = Math.Round(empiricalSuccessProbability / classicalSuccessProbability / (double)queries, 3);

                    Console.Write(
                        $"Attempt {idxAttempt+1}. " +
                        $"Success: {markedQubit},  " +
                        $"Probability: {empiricalSuccessProbability} " +
                        //  $"Speedup: {speedupFactor} " +
                        $"Found database index {databaseRegister} \n");
                }
            }
            Console.Write("\n\nTotal Success = " + successCount);
            Pause();


            #endregion
            /* */
        }
        static void Main(string[] args)
        {
            #region Setup

            // We begin by defining a quantum simulator to be our target
            // machine.
            var sim = new QuantumSimulator(throwOnReleasingQubitsNotInZeroState: true);

            #endregion

            #region Quantum Database Search with Manual Oracle Definitions

            // Let us investigate the success probability of the quantum search.

            // Wedefine the size `N` = 2^n of the database to searched in terms of
            // number of qubits `n`.
            var nDatabaseQubits = 6;
            var databaseSize    = Math.Pow(2.0, nDatabaseQubits);

            // We now perform Grover iterates to amplify the marked subspace.
            var nIterations = 3;

            // Number of queries to database oracle.
            var queries = nIterations * 2 + 1;

            // We now execute the quantum search and verify that the success
            // probability matches the theoretical prediction.
            var classicalSuccessProbability = 1.0 / databaseSize;
            var quantumSuccessProbability   = Math.Pow(Math.Sin((2.0 * (double)nIterations + 1.0) * Math.Asin(1.0 / Math.Sqrt(databaseSize))), 2.0);
            var repeats       = 100;
            var numberSuccess = 0;
            var numberTotal   = 0;

            foreach (var idxAttempt in Enumerable.Range(0, repeats))
            {
                // Each operation has a static method called Run which takes a simulator as
                // an argument, along with all the arguments defined by the operation itself.
                var task = ApplyQuantumSearch.Run(sim, nIterations, nDatabaseQubits);

                // We extract the return value of the operation by getting the Results property.
                var data = task.Result;

                // Extract the marked qubit state
                var markedQubit      = data.Item1;
                var databaseRegister = data.Item2.ToArray();
                var isSuccess        = true;

                foreach (var elt in databaseRegister)
                {
                    if (elt.ToString() == "Zero")
                    {
                        isSuccess = false;
                    }
                }

                if (isSuccess)
                {
                    numberSuccess += 1;
                }

                Console.Write("Output of Grover's search in binary\n");
                Console.Write(string.Join(", ", databaseRegister) + "\n");

                numberTotal += 1;

                Console.WriteLine("Statistics so far...");
                Console.WriteLine($"Total number of attempts = {numberTotal}");
                Console.WriteLine($"Total number of successes = {numberSuccess}");

                Pause();
            }

            // Pause();

            #endregion
        }
Esempio n. 7
0
        static void Main(string[] args)
        {
            #region Setup

            // We begin by defining a quantum simulator to be our target
            // machine.
            var sim = new QuantumSimulator(throwOnReleasingQubitsNotInZeroState: true);

            #endregion

            #region Random Database Search with Manual Oracle Definitions

            // Let us investigate the success probability of classical random search.
            // This corresponds to the case where we only prepare the start state, and
            // do not perform any Grover iterates to amplify the marked subspace.
            var nIterations = 0;

            // We now define the size `N` = 2^n of the database to searched in terms of
            // number of qubits `n`.
            var nDatabaseQubits = 3;
            var databaseSize    = Pow(2.0, nDatabaseQubits);

            // We now execute the classical random search and verify that the success
            // probability matches the classical result of 1/N. Let us repeat 100
            // times to collect enough statistics.
            var classicalSuccessProbability = 1.0 / databaseSize;
            var repeats      = 1000;
            var successCount = 0;

            Console.Write(
                $"Classical random search for marked element in database.\n" +
                $"  Database size: {databaseSize}.\n" +
                $"  Success probability:  {classicalSuccessProbability}\n\n");



            foreach (var idxAttempt in Enumerable.Range(0, repeats))
            {
                // Each operation has a static method called Run which takes a simulator as
                // an argument, along with all the arguments defined by the operation itself.
                var task = ApplyQuantumSearch.Run(sim, nIterations, nDatabaseQubits);

                // We extract the return value of the operation by getting the Results property.
                var data = task.Result;

                // Extract the marked qubit state
                var markedQubit      = data.Item1;
                var databaseRegister = data.Item2.ToArray();

                successCount += markedQubit == Result.One ? 1 : 0;

                // Print the results of the search every 100 attempts
                if ((idxAttempt + 1) % 100 == 0)
                {
                    Console.Write(
                        $"Attempt {idxAttempt}. " +
                        $"Success: {markedQubit},  " +
                        $"Probability: {Round((double)successCount / ((double)idxAttempt + 1),3)} " +
                        $"Found database index {string.Join(", ", databaseRegister.Select(x => x.ToString()).ToArray())} \n");
                }
            }

            Pause();

            #endregion


            #region Quantum Database Search with Manual Oracle Definitions

            // Let us investigate the success probability of the quantum search.

            // We define the size `N` = 2^n of the database to searched in terms of
            // number of qubits `n`.
            nDatabaseQubits = 6;
            databaseSize    = Pow(2.0, nDatabaseQubits);

            // We now perform Grover iterates to amplify the marked subspace.
            nIterations = 3;

            // Number of queries to database oracle.
            var queries = nIterations * 2 + 1;

            // We now execute the quantum search and verify that the success
            // probability matches the theoretical prediction.
            classicalSuccessProbability = 1.0 / databaseSize;
            var quantumSuccessProbability = Pow(Sin((2.0 * (double)nIterations + 1.0) * Asin(1.0 / Sqrt(databaseSize))), 2.0);
            repeats      = 100;
            successCount = 0;

            Console.Write(
                $"\n\nQuantum search for marked element in database.\n" +
                $"  Database size: {databaseSize}.\n" +
                $"  Classical success probability: {classicalSuccessProbability}\n" +
                $"  Queries per search: {queries} \n" +
                $"  Quantum success probability: {quantumSuccessProbability}\n\n");



            foreach (var idxAttempt in Enumerable.Range(0, repeats))
            {
                // Each operation has a static method called Run which takes a simulator as
                // an argument, along with all the arguments defined by the operation itself.
                var task = ApplyQuantumSearch.Run(sim, nIterations, nDatabaseQubits);

                // We extract the return value of the operation by getting the Results property.
                var data = task.Result;

                // Extract the marked qubit state
                var markedQubit      = data.Item1;
                var databaseRegister = data.Item2.ToArray();

                successCount += markedQubit == Result.One ? 1 : 0;

                // Print the results of the search every 10 attempts
                if ((idxAttempt + 1) % 10 == 0)
                {
                    var empiricalSuccessProbability = Round((double)successCount / ((double)idxAttempt + 1), 3);

                    // This is how much faster the quantum algorithm performs on average
                    // over the classical search.
                    var speedupFactor = Round(empiricalSuccessProbability / classicalSuccessProbability / (double)queries, 3);

                    Console.Write(
                        $"Attempt {idxAttempt}. " +
                        $"Success: {markedQubit},  " +
                        $"Probability: {empiricalSuccessProbability} " +
                        $"Speedup: {speedupFactor} " +
                        $"Found database index {string.Join(", ", databaseRegister.Select(x => x.ToString()).ToArray())} \n");
                }
            }

            Pause();

            #endregion


            #region Multiple Element Quantum Database Search with the Canon

            // Let us investigate the success probability of the quantum search with multiple
            // marked elements.

            // We define the size `N` = 2^n of the database to searched in terms of
            // number of qubits `n`.
            nDatabaseQubits = 8;
            databaseSize    = Pow(2.0, nDatabaseQubits);

            // We define the marked elements. These must be smaller than `databaseSize`.
            var markedElements  = new long[] { 0, 39, 101, 234 };
            var nMarkedElements = markedElements.Length;



            // We now perform Grover iterates to amplify the marked subspace.
            nIterations = 3;

            // Number of queries to database oracle.
            queries = nIterations * 2 + 1;

            // We now execute the quantum search and verify that the success
            // probability matches the theoretical prediction.
            classicalSuccessProbability = (double)(nMarkedElements) / databaseSize;
            quantumSuccessProbability   = Pow(Sin((2.0 * (double)nIterations + 1.0) * Asin(Sqrt(nMarkedElements) / Sqrt(databaseSize))), 2.0);
            repeats      = 10;
            successCount = 0;

            Console.Write(
                $"\n\nQuantum search for marked element in database.\n" +
                $"  Database size: {databaseSize}.\n" +
                $"  Marked elements: {string.Join(",", markedElements.Select(x => x.ToString()).ToArray())}" +
                $"  Classical success probability: {classicalSuccessProbability}\n" +
                $"  Queries per search: {queries} \n" +
                $"  Quantum success probability: {quantumSuccessProbability}\n\n");



            foreach (var idxAttempt in Enumerable.Range(0, repeats))
            {
                // Each operation has a static method called Run which takes a simulator as
                // an argument, along with all the arguments defined by the operation itself.
                var task = ApplyGroverSearch.Run(sim, new QArray <long>(markedElements), nIterations, nDatabaseQubits);

                // We extract the return value of the operation by getting the Results property.
                var data = task.Result;

                // Extract the marked qubit state
                var markedQubit      = data.Item1;
                var databaseRegister = data.Item2;

                successCount += markedQubit == Result.One ? 1 : 0;

                // Print the results of the search every 1 attempt
                if ((idxAttempt + 1) % 1 == 0)
                {
                    var empiricalSuccessProbability = Round((double)successCount / ((double)idxAttempt + 1), 3);

                    // This is how much faster the quantum algorithm performs on average
                    // over the classical search.
                    var speedupFactor = Round(empiricalSuccessProbability / classicalSuccessProbability / (double)queries, 3);

                    Console.Write(
                        $"Attempt {idxAttempt}. " +
                        $"Success: {markedQubit},  " +
                        $"Probability: {empiricalSuccessProbability} " +
                        $"Speedup: {speedupFactor} " +
                        $"Found database index {databaseRegister} \n");
                }
            }

            Pause();

            #endregion
        }