Exemple #1
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

            int groverIterations;
            int nDatabaseQubits = 10;
            int repeats;

            #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 do not perform any Grover iterates
            groverIterations = 0;

            // Let us repeat more times to collect enough statistics
            repeats = 10000;

            // We define 13 as the marked element. This must be smaller than `databaseSize`

            performDatabaseSearch(sim, nDatabaseQubits, repeats, groverIterations, new QArray <long>()
            {
                13
            });
            Pause();

            #endregion

            #region Single Element Quantum Database Search with the Canon

            // We will perform more Grover iterates to amplify the marked subspace.
            groverIterations = 3;

            // as the probability is higher with quantum search, we need less repeats
            repeats = repeats / 10;

            // We define 13 as the marked element. This must be smaller than `databaseSize`

            performDatabaseSearch(sim, nDatabaseQubits, repeats, groverIterations, new QArray <long>()
            {
                13
            });
            Pause();

            #endregion

            #region Multiple Element Quantum Database Search with the Canon

            groverIterations = 3;

            // We define the marked elements. These must be smaller than `databaseSize`
            QArray <long> markedElements = new QArray <long>()
            {
                0, 15, 48, 62
            };

            // as the probability is higher with multiple input, we need even less repeats
            repeats = repeats / (int)markedElements.Length;

            performDatabaseSearch(sim, nDatabaseQubits, repeats, groverIterations, markedElements);
            Pause();

            #endregion
        }
Exemple #2
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 Parity Sampling with the Bernstein–Vazirani Algorithm
            // Consider a function 𝑓(𝑥⃗) on bitstrings 𝑥⃗ = (𝑥₀, …, 𝑥ₙ₋₁) of the
            // form
            //
            //     𝑓(𝑥⃗) ≔ Σᵢ 𝑥ᵢ 𝑟ᵢ
            //
            // where 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁) is an unknown bitstring that determines
            // the parity of 𝑓.

            // The Bernstein–Vazirani algorithm allows determining 𝑟 given a
            // quantum operation that implements
            //
            //     |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.
            //
            // In SimpleAlgorithms.qs, we implement this algorithm as the
            // operation BernsteinVaziraniTestCase. This operation takes an
            // integer whose bits describe 𝑟, then uses those bits to
            // construct an appropriate operation, and finally measures 𝑟.

            // We call that operation here, ensuring that we always get the
            // same value for 𝑟 that we provided as input.

            const int nQubits = 4;
            foreach (var parity in Enumerable.Range(0, 1 << nQubits))
            {
                var measuredParity = BernsteinVaziraniTestCase.Run(sim, nQubits, parity).Result;
                if (measuredParity != parity)
                {
                    throw new Exception($"Measured parity {measuredParity}, but expected {parity}.");
                }
            }

            System.Console.WriteLine("All parities measured successfully!");
            Pause();


            #endregion

            #region Constant versus Balanced Functions with the Deutsch–Josza Algorithm
            // A Boolean function is a function that maps bitstrings to a
            // bit,
            //
            //     𝑓 : {0, 1}^n → {0, 1}.
            //
            // We say that 𝑓 is constant if 𝑓(𝑥⃗) = 𝑓(𝑦⃗) for all bitstrings
            // 𝑥⃗ and 𝑦⃗, and that 𝑓 is balanced if 𝑓 evaluates to true (1) for
            // exactly half of its inputs.

            // If we are given a function 𝑓 as a quantum operation 𝑈 |𝑥〉|𝑦〉
            // = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, and are promised that 𝑓 is either constant or
            // is balanced, then the Deutsch–Josza algorithm decides between
            // these cases with a single application of 𝑈.

            // In SimpleAlgorithms.qs, we implement this algorithm as
            // DeutschJozsaTestCase, following the pattern above.
            // This time, however, we will pass an array to Q# indicating
            // which elements of 𝑓 are marked; that is, should result in true.
            // We check by ensuring that DeutschJozsaTestCase returns true
            // for constant functions and false for balanced functions.
            var balancedTestCase = new QArray <long> {
                1, 2
            };
            if (DeutschJozsaTestCase.Run(sim, 2, balancedTestCase).Result)
            {
                throw new Exception("Measured that test case {1, 2} was constant!");
            }

            var constantTestCase = new QArray <long> {
                0, 1, 2, 3, 4, 5, 6, 7
            };
            if (!DeutschJozsaTestCase.Run(sim, 3, constantTestCase).Result)
            {
                throw new Exception("Measured that test case {0, 1, 2, 3, 4, 5, 6, 7} was balanced!");
            }
            System.Console.WriteLine("Both constant and balanced functions measured successfully!");

            #endregion

            #region Finding Hidden Shifts of Bent Functions with the Roetteler Algorithm
            // Finally, we consider the case of finding a hidden shift 𝑠
            // between two Boolean functions 𝑓(𝑥) and 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).
            // This problem can be solved on a quantum computer with one call
            // to each of 𝑓 and 𝑔 in the special case that both functions are
            // bent; that is, that they are as far from linear as possible.

            // Here, we run the test case HiddenShiftBentCorrelationTestCase
            // defined in the matching Q# source code, and ensure that it
            // correctly finds each hidden shift for a family of bent
            // functions defined by the inner product.
            foreach (var shift in Enumerable.Range(0, 1 << nQubits))
            {
                var measuredShift = HiddenShiftBentCorrelationTestCase.Run(sim, shift, nQubits / 2).Result;
                if (measuredShift != shift)
                {
                    throw new Exception($"Measured shift {measuredShift}, but expected {shift}.");
                }
            }
            System.Console.WriteLine("Measured hidden shifts successfully!");

            #endregion

            System.Console.WriteLine("\n\nPress Enter to exit...\n\n");
            System.Console.ReadLine();
        }
        /// <summary>
        /// Main entry point.
        /// </summary>
        /// <param name="args">
        /// <para>Add the following argument to specify which puzzles to run:</para>
        /// <list type="bullet">
        /// <item><description>`all` or blank : run all puzzles (default)</description></item>
        /// <item><description>`4s4c` : test classic algorthm on a 4slot-4colors puzzle</description></item>
        /// <item><description>`4s4cQ` : test quantum algorthm on a 4slot-4colors puzzle</description></item>
        /// </list>
        /// </param>
        static async Task Main(string[] args)
        {
            using var sim = new QuantumSimulator();

            //var restored = await HelloQ.Run(sim);
            //DEBUG

            /*List<int[]> puzzle6 = new List<int[]>(){
             *  new int[]{0,3,1,2,1,1},
             *  new int[]{0,3,1,2,2,1},
             *  new int[]{0,3,1,2,3,1}
             * };
             * ShowGrid(puzzle6,1);
             * Pause();*/

            //MAIN
            var puzzleToRun = args.Length > 0 ? args[0] : "all";

            //var sim = new QuantumSimulator(throwOnReleasingQubitsNotInZeroState: true);

            MastermindClassic mastermindClassic = new MastermindClassic();

            //MastermindQuantum mastermindQuantum = new MastermindQuantum();

            if (puzzleToRun == "4s4c" || puzzleToRun == "all")
            {
                // Test solving a 4s4c Mastermind puzzle using classical computing
                long[] answer4     = { 1, 2, 3, 0, 4, 0 };
                long[] color4      = { 1, 2, 3, 0 };
                bool   resultFound = false;

                Console.WriteLine("Answer of current trial.");
                ShowGrid(new List <long[]>()
                {
                    answer4
                }, 1);

                List <long[]> puzzle4 = new List <long[]>();
                Console.WriteLine("Solving 4slot-4colors using Classical computing.");
                resultFound = mastermindClassic.Solve(puzzle4, answer4);

                VerifyAndShowResult(resultFound, puzzle4, answer4);
                Console.WriteLine($"Classical Computing used {puzzle4.Count} trials !");
                Console.WriteLine();
            }
            if (puzzleToRun == "4s4cQ" || puzzleToRun == "all")
            {
                // Test solving a 4s4c Mastermind puzzle using quantum computing.
                long[] answer4 = { 1, 2, 3, 0, 4, 0 };
                long[] color4  = { 1, 2, 3, 0 };

                Console.WriteLine("Answer of current trial.");
                ShowGrid(new List <long[]>()
                {
                    answer4
                }, 1);

                Console.WriteLine("Solving 4slot-4colors using Quantum computing.");

                var puzzleArray = new QArray <QArray <long> >();
                foreach (long[] condition in new List <long[]>()
                {
                    answer4
                })
                {
                    puzzleArray.Append(new QArray <long>(condition));
                }
                var(resultFromQuantum, resultFound) = MastermindQuantum.GroversForMastermind.Run(sim, puzzleArray).Result;

                Console.WriteLine("Obtained result from Quantum simulator.");
                long[] answerFromQuantum = { -1, -1, -1, -1 };
                int    index             = 0;
                foreach (long val in resultFromQuantum)
                {
                    answerFromQuantum[index] = val;
                    index++;
                }
                VerifyAndShowResult(resultFound, new List <long[]>()
                {
                    answer4
                }, answerFromQuantum);
                Console.WriteLine();
            }

            if (puzzleToRun == "4s4cQ2" || puzzleToRun == "all")
            {
                // Test solving a 4s4c Mastermind puzzle using quantum computing.
                List <long[]> answer4 = new List <long[]>();

                answer4.Add(new long[] { 1, 1, 1, 2, 2, 10 });
                answer4.Add(new long[] { 1, 1, 2, 1, 2, 10 });
                answer4.Add(new long[] { 1, 2, 1, 1, 2, 10 });

                long[] color4 = { 2, 1, 1, 1 };

                Console.WriteLine("Answer of current trial.");
                ShowGrid(answer4, 1);

                Console.WriteLine("Solving 4slot-4colors using Quantum computing.");

                var puzzleArray = new QArray <QArray <long> >();
                foreach (long[] condition in answer4)
                {
                    puzzleArray.Append(new QArray <long>(condition));
                }
                var(resultFromQuantum, resultFound) = MastermindQuantum.GroversForMastermind.Run(sim, puzzleArray).Result;

                Console.WriteLine("Obtained result from Quantum simulator.");
                long[] answerFromQuantum = { -1, -1, -1, -1 };
                int    index             = 0;
                foreach (long val in resultFromQuantum)
                {
                    answerFromQuantum[index] = val;
                    index++;
                }
                VerifyAndShowResult(resultFound, answer4, answerFromQuantum);
                Console.WriteLine();
            }
            Console.WriteLine("Finished.");
        }
Exemple #4
0
 public bool Equals(QArray <Pauli> x, QArray <Pauli> y)
 {
     return(System.Linq.Enumerable.SequenceEqual(x, y));
 }
Exemple #5
0
        public void TupleBasicConstructor()
        {
            var AssertQubitsCount = new Action <int, IApplyData>((count, t) =>
            {
                var qubits = t.Qubits;
                if (count == 0)
                {
                    Assert.True(qubits == null || qubits?.Where(q => q != null).Count() == 0);
                }
                else
                {
                    Assert.Equal(count, qubits?.Where(q => q != null).Count());
                }
            });

            var q0 = new FreeQubit(0) as Qubit;
            var q1 = new FreeQubit(1) as Qubit;
            var q2 = new FreeQubit(2) as Qubit;

            {
                var actual = new Q(q0);
                Assert.Equal(q0, ((IApplyData)actual).Value);
                AssertQubitsCount(1, actual);
            }
            {
                var actual = new I(32L);
                Assert.Equal(32L, ((IApplyData)actual).Value);
                AssertQubitsCount(0, actual);
            }
            {
                var data   = (2L, Pauli.PauliY, q1, (q0, -7L, null as Qubit));
                var actual = new TupleA(data);
                Assert.Equal(data, ((IApplyData)actual).Value);
                AssertQubitsCount(2, actual);
            }
            {
                var data   = (q1, new TupleB(((2L, 3L), (q1, (4L, (q0, q2)), 3.0))));
                var actual = new TupleC(data);
                Assert.Equal(data, ((IApplyData)actual).Value);
                AssertQubitsCount(4, actual);
            }
            {
                var data   = new QArray <Qubit>(q1, q2, q0, q0, q1);
                var actual = new TupleD(data);
                Assert.Equal((IQArray <Qubit>)data, ((IApplyData)actual).Value);
                AssertQubitsCount(5, actual);
            }
            {
                var data   = (5L, new QArray <Qubit>(q1, q2, q0));
                var actual = new TupleE(data);
                Assert.Equal((data.Item1, (IQArray <Qubit>)data.Item2), ((IApplyData)actual).Value);
                AssertQubitsCount(3, actual);
            }
            {
                var data   = new UnitaryNoOp <(TupleA, TupleD)>();
                var actual = new TupleF(data);
                Assert.Equal(data, ((IApplyData)actual).Value);
                AssertQubitsCount(0, actual);
            }
            {
                var op     = new UnitaryNoOp <(TupleA, TupleD)>();
                var mapper = new Func <(TupleA, TupleD), (IQArray <Qubit>, (TupleA, TupleD))>((_arg) => (new QArray <Qubit>(q1, q2), _arg));
                var data   = op.Controlled.Partial(mapper);
                var actual = new TupleF(data);
                Assert.Equal(data, ((IApplyData)actual).Value);
                AssertQubitsCount(2, actual);
            }
            {
                var data   = (new TupleD(new QArray <Qubit>(q1, q2, q0)), new TupleG());
                var actual = new TupleH(data);
                Assert.Equal(data, ((IApplyData)actual).Value);
                AssertQubitsCount(3, actual);
            }
            {
                var data   = new QArray <(Int64, Qubit)>((1L, q1));
                var actual = new TupleJ(data);
                Assert.Equal((IQArray <(Int64, Qubit)>)data, ((IApplyData)actual).Value);
                AssertQubitsCount(1, actual);
            }
        }
 public override IApplyData __dataIn(QArray <Qubit> data) => data;
 public static System.Threading.Tasks.Task <QArray <Result> > Run(IOperationFactory __m__, QArray <Qubit> register)
 {
     return(__m__.Run <MeasureRegister, QArray <Qubit>, QArray <Result> >(register));
 }
Exemple #8
0
 public static System.Threading.Tasks.Task <Int64> Run(IOperationFactory __m__, QArray <Int64> allLayers)
 {
     return(__m__.Run <ComputeNumWeights, QArray <Int64>, Int64>(allLayers));
 }
Exemple #9
0
 public static System.Threading.Tasks.Task <Int64> Run(IOperationFactory __m__, QArray <Qubit> qs)
 {
     return(__m__.Run <Operation, QArray <Qubit>, Int64>(qs));
 }
Exemple #10
0
 public static System.Threading.Tasks.Task <QArray <Int64> > Run(IOperationFactory __m__, QArray <Qubit> qubit_array)
 {
     return(__m__.Run <ReadQubitArray, QArray <Qubit>, QArray <Int64> >(qubit_array));
 }
Exemple #11
0
 public override IApplyData __dataIn(QArray <Int64> data) => data;
Exemple #12
0
 public static System.Threading.Tasks.Task <QVoid> Run(IOperationFactory __m__, QArray <Qubit> code)
 {
     return(__m__.Run <P2Solution, QArray <Qubit>, QVoid>(code));
 }
Exemple #13
0
 public static System.Threading.Tasks.Task <QVoid> Run(IOperationFactory __m__, QArray <Qubit> qs)
 {
     return(__m__.Run <FredkinGate, QArray <Qubit>, QVoid>(qs));
 }
Exemple #14
0
 public static System.Threading.Tasks.Task <QVoid> Run(IOperationFactory __m__, QArray <Qubit> qs)
 {
     return(__m__.Run <BellStateChange3, QArray <Qubit>, QVoid>(qs));
 }
        private void Wrapper <T>(long count)
        {
            var array = new QArray <T>(new T[count]);

            Assert.Equal(count, array.Length);
        }
Exemple #16
0
        /// <summary>
        /// Runs Simon's Algorithm on the provided function, finding the secret bit string
        /// that it contains.
        /// </summary>
        /// <param name="Description">A human-readable description of this test</param>
        /// <param name="FunctionToTest">The type of the class representing the Q# function to
        /// evaluate using the algorithm</param>
        /// <param name="InputSize">The number of bits that the function expects for its
        /// input and output</param>
        /// <param name="DesiredSuccessChance">A number representing what chance you want the
        /// algorithm to have of solving the problem. A higher chance means potentially
        /// more iterations. This must be at least 0.5, and less than 1.0.</param>
        /// <returns>
        /// The secret string S for the provided function.
        /// </returns>
        private bool[] RunTest(
            string Description,
            ICallable FunctionToTest,
            int InputSize,
            double DesiredSuccessChance)
        {
            if (DesiredSuccessChance <= 0.5 ||
                DesiredSuccessChance >= 1)
            {
                Assert.True(false, $"{nameof(DesiredSuccessChance)} must be at least " +
                            $"0.5 and less than 1.");
            }

            // The chance of failure is 1 / 2^T, where T is the number of extra
            // rounds to run. This just gets that value based on the desired chance
            // of success.
            double t           = Math.Log(1.0 / (1 - DesiredSuccessChance), 2);
            int    extraRounds = (int)Math.Ceiling(t); // Round up

            // This set will contain the input bit strings returned by the quantum
            // step of the algorithm.
            List <IList <bool> > validInputs = new List <IList <bool> >();

            HandleTestLogMessage($"Running Simon's algorithm on test [{Description}] " +
                                 $"with up to {InputSize + extraRounds} iterations.");

            bool foundEnoughStrings = false;

            for (int i = 0; i < InputSize + extraRounds; i++)
            {
                // Get a new candidate input string from the quantum part of the algorithm
                IReadOnlyList <bool> inputString = SimonQuantumStep.Run(Simulator, FunctionToTest, InputSize).Result;
                string message = $"Found input {PrintBitString(inputString)}... ";

                // If it's linearly independent with the strings found so far, add it to the list
                bool wasValid = MatrixMath.CheckLinearIndependence(inputString, validInputs);
                if (wasValid)
                {
                    message += "valid, added it to the collection.";
                }
                else
                {
                    message += "not linearly independent, ignoring it.";
                }
                HandleTestLogMessage(message);

                // If we have enough strings, we're done.
                if (validInputs.Count == InputSize - 1)
                {
                    foundEnoughStrings = true;
                    break;
                }
            }

            if (!foundEnoughStrings)
            {
                Assert.True(false, $"Didn't find enough independent inputs. Found {validInputs.Count}, but " +
                            $"this problem required {InputSize - 1}. Try again, or use a higher success chance.");
            }

            // Add one more linearly-independent string to the list so we have N total equations,
            // and get the right-hand-side vector that represents the solution to each equation.
            IList <bool> rightHandSide = MatrixMath.CompleteMatrix(validInputs);

            // Now we have enough strings to figure out what the secret is!
            IList <bool> secretString = MatrixMath.SolveMatrix(validInputs, rightHandSide);

            HandleTestLogMessage($"Matrix solved, secret = {PrintBitString(secretString)}");

            // If this secret is correct, then f(0) should equal f(S). Run them both and compare them to
            // verify the input. If the output values differ, then that means this function isn't 2-to-1
            // and thus S = 0.
            bool[]               zeros        = new bool[InputSize];
            QArray <bool>        zeroInput    = new QArray <bool>(zeros);
            QArray <bool>        secretInput  = new QArray <bool>(secretString);
            IReadOnlyList <bool> zeroOutput   = RunFunctionInClassicalMode.Run(Simulator, FunctionToTest, zeroInput).Result;
            IReadOnlyList <bool> secretOutput = RunFunctionInClassicalMode.Run(Simulator, FunctionToTest, secretInput).Result;

            if (zeroOutput.SequenceEqual(secretOutput))
            {
                return(secretString.ToArray());
            }
            else
            {
                HandleTestLogMessage("Secret string doesn't provide the same output as all zeros, so this function " +
                                     "isn't actually 2-to-1. Secret must be all zeros.");
                return(zeros);
            }
        }
Exemple #17
0
 public static System.Threading.Tasks.Task <QVoid> Run(IOperationFactory __m__, QArray <Qubit> qubits)
 {
     return(__m__.Run <ControlledX, QArray <Qubit>, QVoid>(qubits));
 }
Exemple #18
0
        static async Task Main()
        {
            // We start by loading the training and validation data from our JSON
            // data file.
            var data = await LoadData("data.json");

            // We then define the classifier parameters where we want to start our
            // training iterations from. Since gradient descent is good at finding
            // local optima, it's helpful to have a variety of different starting
            // points.
            var parameterStartingPoints = new []
            {
                new [] { 0.060057, 3.00522, 2.03083, 0.63527, 1.03771, 1.27881, 4.10186, 5.34396 },
                new [] { 0.586514, 3.371623, 0.860791, 2.92517, 1.14616, 2.99776, 2.26505, 5.62137 },
                new [] { 1.69704, 1.13912, 2.3595, 4.037552, 1.63698, 1.27549, 0.328671, 0.302282 },
                new [] { 5.21662, 6.04363, 0.224184, 1.53913, 1.64524, 4.79508, 1.49742, 1.5455 }
            };

            // Convert samples to Q# form.
            var samples = new QArray <QArray <double> >(data.TrainingData.Features.Select(vector => new QArray <double>(vector)));

            // Once we have the data loaded and have initialized our target machine,
            // we can then use that target machine to train a QCC classifier.
            var(optimizedParameters, optimizedBias, nMisses) = parameterStartingPoints
                                                               // We can use parallel LINQ (PLINQ) to convert the IEnumerable
                                                               // over starting points into a parallelized query.
                                                               .AsParallel()
                                                               // By default, PLINQ may or may not actually run our query in
                                                               // parallel, depending on the capabilities of your machine.
                                                               // We can force PLINQ to actually parallelize, however, by using
                                                               // the WithExecutionMode method.
                                                               .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
                                                               // Many of the same LINQ methods are defined for PLINQ queries
                                                               // as well as IEnumerable objects, so we can go on and run
                                                               // the training loop in parallel by selecting on the start point.
                                                               .Select(
                (startPoint, idxStartPoint) =>
            {
                // Since we want each start point to run on its own
                // instance of the full-state simulator, we create a new
                // instance here, using C# 8's "using var" syntax to
                // ensure that the simulator is deallocated once
                // training is complete for this start point.
                using var targetMachine = new QuantumSimulator();

                // We attach a tag to log output so that we can tell
                // each training job's messages apart.
                // To do so, we disable the default output to the console
                // and attach our own event with the index of the
                // starting point that generated each message.
                targetMachine.DisableLogToConsole();
                targetMachine.OnLog += message =>
                                       Console.WriteLine($"[{idxStartPoint}] {message}");

                // Finally, we can call the Q# entry point with the
                // samples, their labels, and our given start point.
                return(TrainHalfMoonModelAtStartPoint.Run(
                           targetMachine,
                           samples,
                           new QArray <long>(data.TrainingData.Labels),
                           new QArray <double>(startPoint)
                           ).Result);
            }
                )
                                                               // We can then gather the results back into a sequential
                                                               // (IEnumerable) collection.
                                                               .AsSequential()
                                                               // Finally, we want to minimize over the number of misses,
                                                               // returning the corresponding sequential classifier model.
                                                               // In this case, we use a handy extension method defined below
                                                               // to perform the minimization.
                                                               .MinBy(result => result.Item3);

            // After training, we can use the validation data to test the accuracy
            // of our new classifier.
            using var targetMachine = new QuantumSimulator();
            var missRate = await ValidateHalfMoonModel.Run(
                targetMachine,
                new QArray <QArray <double> >(data.ValidationData.Features.Select(vector => new QArray <double>(vector))),
                new QArray <long>(data.ValidationData.Labels),
                optimizedParameters,
                optimizedBias
                );

            System.Console.WriteLine($"Observed {100 * missRate:F2}% misclassifications.");
        }
 public override IApplyData __dataOut(QArray <Result> data) => data;
Exemple #20
0
        static void Main(string[] args)
        {
            // Prompts user whether to run naive eigensolver (QE)
            // or variational eigensolver (VQE)
            // QE will use the ground state provided in Broombridge file (FILENAME, see below)
            // VQE will give the user the option to use the ground state from Broombridge
            // as initial conditions, if not the initial conditions are all zero
            Console.Write("Run QE or VQE? ");
            String runString = Console.ReadLine();

            #region Parameters of Operation
            // filename of the molecule to be emulated
            var FILENAME = "h20_nwchem.yaml";

            // suggested state to include in JW Terms
            var STATE = "|G>";

            // the margin of error to use when approximating the expected value
            // note - our current code currently maxes the number of runs to 50
            // this is to prevent an exponential number of runs required given
            // an arbitrary small margin of error
            // if you'd like to change this parameter, feel free to edit the repeat/until loop
            // in the "FindExpectedValue" method
            var MOE = 0.1;

            #endregion

            #region Creating the Hamiltonian and JW Terms

            // create the first hamiltonian from the YAML File
            var hamiltonian = FermionHamiltonian.LoadFromYAML($@"{FILENAME}").First();

            // convert the hamiltonian into it's JW Encoding
            var JWEncoding = JordanWignerEncoding.Create(hamiltonian);

            // JW encoding data to be passed to Q#
            var data = JWEncoding.QSharpData(STATE);

            #endregion
            #region Hybrid Quantum/Classical accelerator

            // Communicate to the user the choice of eigensolver
            if (runString.Equals("VQE"))
            {
                Console.WriteLine("----- Begin VQE Setup");
            }
            else
            {
                Console.WriteLine("----- Begin QE Simulation");
            }

            using (var qsim = new QuantumSimulator())
            {
                // Block to run VQE
                if (runString.Equals("VQE"))
                {
                    string useGroundState;

                    // we begin by asking whether to use the YAML suggested ground or an ansatz
                    Console.Write("Use ground state? (yes or no): ");
                    useGroundState = Console.ReadLine();

                    // extract parameters for use below
                    var statePrepData = data.Item3;
                    var N             = statePrepData.Length;

                    // We'd like to have a method to create an input state given parameters
                    // method to convert optimized parameters, i.e. the
                    // coefficients of the creation/annihilation operators
                    // to JordanWignerInputStates that can be run in the
                    // simulation defined in Q#
                    double convertDoubleArrToJWInputStateArr(double[] x)
                    {
                        var JWInputStateArr = new QArray <JordanWignerInputState>();

                        for (int i = 0; i < N; i++)
                        {
                            var currJWInputState = statePrepData[i];
                            var positions        = currJWInputState.Item2; // registers to apply coefficients
                            JWInputStateArr.Add(new JordanWignerInputState(((x[i], 0.0), positions)));
                        }
                        return(Simulate_Variational.Run(qsim, data, MOE, JWInputStateArr).Result);
                    }

                    // wrapper function which feeds parameters to be optimized to minimize
                    // the output of the simulation of the molecule defined in FILENAME
                    Func <double[], double> Simulate_Wrapper = (double[] x) => convertDoubleArrToJWInputStateArr(x);

                    // create new Nelder-Mead solver on the simulation of the molecule
                    var solver = new NelderMead((int)N, Simulate_Wrapper);

                    // create initial condition vector
                    var initialConds = new double[N];
                    for (int i = 0; i < N; i++)
                    {
                        if (useGroundState.Equals("yes"))
                        {
                            var currJWInputState = statePrepData[i];
                            var groundStateGuess = currJWInputState.Item1;
                            initialConds[i] = groundStateGuess.Item1;
                        }
                        else
                        {
                            initialConds[i] = 0.0;
                        }
                    }

                    Console.WriteLine("----Beginning computational simulation----");

                    // Now, we can minimize it with:
                    bool success = solver.Minimize(initialConds);

                    // And get the solution vector using
                    double[] solution = solver.Solution;

                    // The minimum at this location would be:
                    double minimum = solver.Value;

                    // Communicate VQE results to the user
                    // success indicates wheter the solution converged
                    // solution is the vector of coefficients for the creation/annihilation
                    // operators defined in positions (defined in convertDoubleArrToJWInputStateArr)
                    // minimum is the value of the minimum energy found by VQE
                    Console.WriteLine($"Solution converged: {success}");
                    Console.WriteLine("The solution is: " + String.Join(" ", solution));
                    Console.WriteLine($"The minimum is: {minimum}");
                }
                else
                { // Run QE 5 times
                    Console.WriteLine(Simulate.Run(qsim, data, MOE, 5).Result);
                }
            }
            #endregion
        }
Exemple #21
0
 public override IApplyData __dataOut(QArray <QArray <Int64> > data) => data;
Exemple #22
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
            /* */
        }
Exemple #23
0
 public int GetHashCode(QArray <Pauli> obj)
 {
     return(Utils.ObservableToString(obj).GetHashCode());
 }
        static void Main(string[] args)
        {
            #region Basic Definitions

            // We start by loading the simulator that we will use to run our Q# operations.
            var qsim = new QuantumSimulator();

            // In all the following, we use this coefficient for coupling to the transverse
            // field.
            var hxCoeff = 1.0;

            // As we are using a Trotter–Suzuki decomposition as our simulation algorithm,
            // we will need to pick a timestep for the simulation, and the order of the
            // integrator. The optimal timestep needs to be determined empirically, and
            // we find that the following choice works well enough.
            var trotterStepSize = 0.05;
            var trotterOrder    = 2;

            // Let us now simulate time-evolution by interpolating between the initial
            // Hamiltonian with the |+〉 product state as the ground state, and the target
            // Hamiltonian. For the uniform Ising model, the ground state of the target
            // Hamiltonian should have all spins pointing in the same direction. If we
            // interpolate between these Hamiltonians slowly enough, the initial ground
            // state will continuously deform into the ground state of the target
            // Hamiltonian

            // Let now interpolate between these Hamiltonians more slowly.
            var adiabaticTime = 500.0;

            #endregion

            #region Ising model simulations

            var penalty      = 20.0;
            var segmentCosts = new double[] { 4.70, 9.09, 9.03, 5.70, 8.02, 1.71 };
            var numQubits    = 6;

            // The phase estimation algorithm requires us to choose the duration of time-
            // evolution in the oracle it calls, and the bits of precision to which we
            // estimate the phase. Note that the error of the energy estimate is typically
            // rescaled by 1 / `qpeStepSize`
            var qpeStepSize    = 0.1;
            var nBitsPrecision = 10;

            var linearTerm    = segmentCosts.Select(c => 4.0 * penalty - 0.5 * c).ToArray();
            var quadraticTerm = new double[numQubits * numQubits].Select((c, i) => i == 2 || i == 9 || i == 29 ? penalty : 2.0 * penalty).ToArray();

            var hZFinal  = new QArray <Double>(linearTerm);
            var jZZFinal = new QArray <Double>(quadraticTerm);
            CalculateCache(quadraticTerm, linearTerm, segmentCosts);

            Console.WriteLine("\nIsing model parameters:");
            Console.WriteLine(
                $"\t{numQubits} sites\n" +
                $"\t{hxCoeff} transverse field coefficient\n" +
                $"\t{adiabaticTime} time-interval of interpolation\n" +
                $"\t{trotterStepSize} simulation time step \n" +
                $"\t{trotterOrder} order of integrator\n");

            // Let us use this opportunity to test the adiabatic evolution as written using
            // more library functions.
            for (int rep = 0; rep < 10; rep++)
            {
                var data = GeneralIsingAdiabaticAndMeasureBuiltIn.Run(qsim,
                                                                      numQubits, hxCoeff, hZFinal, jZZFinal,
                                                                      adiabaticTime, trotterStepSize, trotterOrder,
                                                                      qpeStepSize, nBitsPrecision).Result;

                var measuredState = data.ToArray().Select(x => x.ToString() == "Zero" ? "0" : "1");

                Console.Write($"State: {string.Join("", measuredState)} \n");

                var expectationValues = CalculateExpectationValuesFromFile("..\\..\\..\\QubitsDump.txt", numQubits);

                Console.WriteLine($"Energy after evolution: {expectationValues.Item1}\nExpected Costs: {expectationValues.Item2}\nCosts for measured state: {CalculateCostForStateCache(measuredState.Select(q => q.Equals("1")).ToArray(), segmentCosts)}");
            }

            Console.WriteLine("Press Enter to continue...");
            Console.ReadLine();

            #endregion
        }
Exemple #25
0
 /// <summary>
 /// Removes PauliI terms from observable and corresponding qubits from qubits.
 /// Returns the observable description that is equivalent to the original one, but has no PauliI terms
 /// </summary>
 public static void PruneObservable(IQArray <Pauli> observable, IQArray <Qubit> qubits, out QArray <Pauli> prunedObservable, out QArray <Qubit> prunedQubits)
 {
     Debug.Assert(observable != null);
     Debug.Assert(qubits != null);
     Debug.Assert(observable.Length == qubits.Length);
     prunedObservable = new QArray <Pauli>(PrunedSequence(observable, Pauli.PauliI, observable));
     prunedQubits     = new QArray <Qubit>(PrunedSequence(observable, Pauli.PauliI, qubits));
 }
Exemple #26
0
        static void Main(string[] args)
        {
            Console.Write("Run QE or VQE? ");
            String runString = Console.ReadLine();

            #region Parameters of Operation
            // filename of the molecule to be emulated

            // var FILENAME = "h2_2_sto6g_1.0au.yaml";
            // var FILENAME = "h4_sto6g_0.000.yaml";
            var FILENAME = "h20_nwchem.yaml";

            // use this state provided in the YAML.
            var STATE = "|G>";

            // the margin of error to use when approximating the expected value
            var MOE = 0.1;

            // precision to iterate over with the state preparation gate
            // the number of trials is directly proportional to this constant's inverse
            // the gate will be applying a transform of the form (2 pi i \phi) where \phi
            // varies by the precision specified below
            var ANGULAR_PRECISION = 0.01;

            Console.WriteLine($"STATE: {STATE} | MOE: {MOE} | PRECISION: {ANGULAR_PRECISION}");

            #endregion

            #region Creating the Hamiltonian and JW Terms

            // create the first hamiltonian from the YAML File
            var hamiltonian = FermionHamiltonian.LoadFromYAML($@"{FILENAME}").First();

            // convert the hamiltonian into it's JW Encoding
            var JWEncoding = JordanWignerEncoding.Create(hamiltonian);

            var data = JWEncoding.QSharpData(STATE);

            #endregion
            #region Hybrid Quantum/Classical accelerator
            // Feed created state and hamiltonian terms to VQE
            if (runString.Equals("VQE"))
            {
                Console.WriteLine("----- Begin VQE Simulation");
            }
            else
            {
                Console.WriteLine("----- Begin QE Simulation");
            }

            using (var qsim = new QuantumSimulator())
            {
                if (runString.Equals("VQE"))
                {
                    string useGroundState;
                    Console.Write("Use ground state? (yes or no): ");
                    useGroundState = Console.ReadLine();

                    var statePrepData = data.Item3; // statePrep data
                    var N             = statePrepData.Length;

                    double convertDoubleArrToJWInputStateArr(double[] x)
                    {
                        var JWInputStateArr = new QArray <JordanWignerInputState>();

                        for (int i = 0; i < N; i++)
                        {
                            var currJWInputState = statePrepData[i];
                            var positions        = currJWInputState.Item2;
                            JWInputStateArr.Add(new JordanWignerInputState(((x[i], 0.0), positions)));
                        }
                        return(Simulate_Variational.Run(qsim, data, 1.0, MOE, JWInputStateArr).Result);
                    }

                    Func <double[], double> Simulate_Wrapper = (double[] x) => convertDoubleArrToJWInputStateArr(x);

                    var solver = new NelderMead((int)N, Simulate_Wrapper);

                    // create initial condition vector
                    var initialConds = new double[N];
                    for (int i = 0; i < N; i++)
                    {
                        if (useGroundState.Equals("yes"))
                        {
                            var currJWInputState = statePrepData[i];
                            var groundStateGuess = currJWInputState.Item1;
                            initialConds[i] = groundStateGuess.Item1;
                        }
                        else
                        {
                            initialConds[i] = 0.0;
                        }
                    }

                    // Now, we can minimize it with:
                    bool success = solver.Minimize(initialConds);

                    // And get the solution vector using
                    double[] solution = solver.Solution;

                    // The minimum at this location would be:
                    double minimum = solver.Value;

                    Console.WriteLine($"Solution converged: {success}");
                    Console.WriteLine("The solution is: " + String.Join(" ", solution));
                    Console.WriteLine($"The minimum is: {minimum}");
                }
                else
                {
                    Console.WriteLine(Simulate.Run(qsim, data, 1.0, MOE).Result);
                }
            }
            #endregion
            #region Classical update scheme
            // Determine how to update the starting state using classical methods
            #endregion
        }
 public override void Apply(QArray <Qubit> qubits)
 {
     _sim._qubitsAllocated -= qubits.Length;
     base.Apply(qubits);
 }
        public void ArraySharing()
        {
            // Basic copy-on-write
            var array1 = new QArray <long>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
            var array2 = new QArray <long>(array1);

            Assert.Equal(2, array1[2]);
            Assert.Equal(2, array2[2]);
            array1.Modify(2, 12);
            Assert.Equal(12, array1[2]);
            Assert.Equal(2, array2[2]);
            array2.Modify(2, 22);
            Assert.Equal(12, array1[2]);
            Assert.Equal(22, array2[2]);

            // Arrays of arrays
            array1 = new QArray <long>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
            array2 = new QArray <long>(array1);
            var arrayArray1 = new QArray <QArray <long> >(array1, array2); // in generated C# code, QArray<IQArray<long>> is used
            var arrayArray2 = new QArray <QArray <long> >(arrayArray1);

            Assert.Equal(2, arrayArray1[0][2]);
            Assert.Equal(2, arrayArray1[1][2]);
            arrayArray1.Modify(0, arrayArray1[0].Modify(2, 12));
            Assert.Equal(12, arrayArray1[0][2]);
            Assert.Equal(2, arrayArray1[1][2]);
            Assert.Equal(12, array1[2]);
            arrayArray1.Modify(1, arrayArray1[1].Modify(2, 22));
            Assert.Equal(12, arrayArray1[0][2]);
            Assert.Equal(22, arrayArray1[1][2]);
            Assert.Equal(12, array1[2]);
            Assert.Equal(22, array2[2]);

            // Copy-on-write with slices
            var r        = new QRange(1, 2, 10);
            var array3   = array2.Slice(r);
            var expected = new QArray <long>(1, 3, 5, 7, 9);

            Assert.Equal(expected, array3);
            array3.Modify(0, 11);
            Assert.Equal(1, array2[1]);
            Assert.Equal(11, array3[0]);

            // Mixing slicing and joining
            array2 = new QArray <long>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
            var expected2 = new QArray <long>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

            r      = new QRange(1, 2, 10);
            array3 = array2.Slice(r);
            var array4 = new QArray <long>(11, 13);
            var array5 = QArray <long> .Add(array3, array4);

            var expected3 = new QArray <long>(1, 3, 5, 7, 9);
            var expected4 = new QArray <long>(11, 13);
            var expected5 = new QArray <long>(1, 3, 5, 7, 9, 11, 13);

            Assert.Equal(expected2, array2);
            Assert.Equal(expected3, array3);
            Assert.Equal(expected4, array4);
            Assert.Equal(expected5, array5);

            // Self-joining
            array1 = new QArray <long>(0, 1, 2);
            array2 = new QArray <long>(QArray <long> .Add(array1, array1));
            var expected1 = new QArray <long>(0, 1, 2);

            expected2 = new QArray <long>(0, 1, 2, 0, 1, 2);
            Assert.Equal(expected1, array1);
            Assert.Equal(expected2, array2);
            array1.Modify(0, 10);
            Assert.Equal(10, array1[0]);
            Assert.Equal(0, array2[0]);
        }
Exemple #29
0
        static void Main(string[] args)
        {
            using (var qsim = new QuantumSimulator())
            {
                Client Alice = new Client();
                Client Bob   = new Client();
                Console.WriteLine("Creating Secret Basis Measurement Pattern Between Alice and Bob...");

                IQArray <bool> AlicePattern = new QArray <bool>();
                IQArray <bool> BobPattern   = new QArray <bool>();
                //create secret pattern
                (AlicePattern, BobPattern)     = createBasisMeasurementPatternFromSender.Run(qsim).Result;
                Alice.basisMeassurementPattern = AlicePattern.ToArray();
                Bob.basisMeassurementPattern   = BobPattern.ToArray();
                Console.WriteLine("Representing Alice Pattern");
                Alice.representPattern();

                Console.WriteLine("Representing Bob Pattern");
                Bob.representPattern();
                Console.WriteLine("Both Patterns Should Match");

                Console.WriteLine("Now And Bob Share Secret Pattern!, Alice want to send Bob a secret message using BMP");
                Console.WriteLine("Suggest any message!");

                Alice.message = Console.ReadLine();
                Alice.convertMessageToBitString();
                //running the basis code
                Alice.encode();
                Bob.decode(Alice.encodedMessage);
                Random rnd = new Random();
                int    r   = 0;
                for (int k = 0; k < (Alice.messageInBits.Length / 8); ++k)
                {
                    r = rnd.Next(1, 13);
                    if (k % 2 == 1)
                    {
                        Console.WriteLine("after sending the " + k + "th character the controller pair of qubits entangled with  Bob measuered in 1 the pattern become");
                        for (int l = 0; l < 8; l++)
                        {
                            if (Alice.basisMeassurementPattern[l] == true)
                            {
                                Alice.basisMeassurementPattern[l] = false;
                            }
                            else
                            {
                                Alice.basisMeassurementPattern[l] = true;
                            }
                            Bob.basisMeassurementPattern[l] = Alice.basisMeassurementPattern[l];
                        }
                        Console.WriteLine("new pattern for Alice and Bob!");
                        Alice.representPattern();
                        Bob.representPattern();
                    }
                }

                if (r % 2 == 1)
                {
                    //flipp
                    Console.Out.Write("The pattern will be flipped");
                }

                Console.WriteLine("Decoded Message From Bob Is");
                Console.WriteLine(Bob.decodedMessage);
                HelloQ.Run(qsim).Wait();
                var estimator = new ResourcesEstimator();
                //System.Console.WriteLine(estimator.ToTSV());
                System.Console.WriteLine("Press any key to continue...");
                Console.ReadKey();
            }
        }
Exemple #30
0
        static void performDatabaseSearch(
            QuantumSimulator sim,
            int nDatabaseQubits,
            int repeats,
            int groverIterations,
            QArray <long> markedElements)
        {
            // We define the size `N` = 2^n of the database to searched in terms of number of qubits `n`.
            long databaseSize = (long)Math.Pow(2.0, nDatabaseQubits);

            long nMarkedElements = markedElements.Length;

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

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


            if (groverIterations > 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" +
                    $"  Oracle queries per search: {queries} \n" +
                    $"  Quantum success probability: {quantumSuccessProbability}\n\n");
            }
            else
            {
                Console.Write(
                    $"\n\nClassical 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\n");
            }


            foreach (var idxAttempt in Enumerable.Range(1, repeats + 1))
            {
                // 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, groverIterations, 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 10 sample results of the attempts
                if (idxAttempt % (repeats / 10) == 0)
                {
                    var empiricalSuccessProbability = Math.Round((double)successCount / ((double)idxAttempt + 1), 5);

                    // 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}: " +
                        ((markedQubit == Result.One) ? "Success. " : "Fail. ") +
                        $"Found database index {databaseRegister} \n");

                    if (groverIterations > 0)
                    {
                        Console.Write(
                            $"Up to now success frequency: {empiricalSuccessProbability}" +
                            $" => Speedup: {speedupFactor}\n\n");
                    }
                    else
                    {
                        Console.Write(
                            $"Up to now success frequency: {empiricalSuccessProbability}\n\n");
                    }
                }
            }
        }