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(); }
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}"); } } } }
/// <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(); }
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 }
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 }
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 }