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 }
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."); }
public bool Equals(QArray <Pauli> x, QArray <Pauli> y) { return(System.Linq.Enumerable.SequenceEqual(x, y)); }
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)); }
public static System.Threading.Tasks.Task <Int64> Run(IOperationFactory __m__, QArray <Int64> allLayers) { return(__m__.Run <ComputeNumWeights, QArray <Int64>, Int64>(allLayers)); }
public static System.Threading.Tasks.Task <Int64> Run(IOperationFactory __m__, QArray <Qubit> qs) { return(__m__.Run <Operation, QArray <Qubit>, Int64>(qs)); }
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)); }
public override IApplyData __dataIn(QArray <Int64> data) => data;
public static System.Threading.Tasks.Task <QVoid> Run(IOperationFactory __m__, QArray <Qubit> code) { return(__m__.Run <P2Solution, QArray <Qubit>, QVoid>(code)); }
public static System.Threading.Tasks.Task <QVoid> Run(IOperationFactory __m__, QArray <Qubit> qs) { return(__m__.Run <FredkinGate, QArray <Qubit>, QVoid>(qs)); }
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); }
/// <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); } }
public static System.Threading.Tasks.Task <QVoid> Run(IOperationFactory __m__, QArray <Qubit> qubits) { return(__m__.Run <ControlledX, QArray <Qubit>, QVoid>(qubits)); }
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;
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 }
public override IApplyData __dataOut(QArray <QArray <Int64> > data) => data;
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 /* */ }
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 }
/// <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)); }
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]); }
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(); } }
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"); } } } }