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 }
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 }
static void Main(string[] args) { #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); // Console.WriteLine("----- Print Hamiltonian"); // Console.Write(hamiltonian); // Console.WriteLine("----- End Print Hamiltonian \n"); #endregion #region Hybrid Quantum/Classical accelerator // Feed created state and hamiltonian terms to VQE Console.WriteLine("----- Begin VQE Simulation"); //var N = 10; // number of qubits, calculate from data??? //var oneReal = (1.0, 0.0); //var inputCoeffs = new ComplexPolar[N]; //for (int i = 0; i < Length(inputCoeffs) - 1; i++) // { // inputCoeffs[i] = oneReal; // } ResourcesEstimator estimator = new ResourcesEstimator(); Simulate.Run(estimator, data, 1.0, MOE).Wait(); //Aux.Run(estimator).Wait(); var configCNOT = new QCTraceSimulatorConfiguration(); configCNOT.useDepthCounter = true; configCNOT.gateTimes[PrimitiveOperationsGroups.CNOT] = 1.0; configCNOT.gateTimes[PrimitiveOperationsGroups.Measure] = 0.0; configCNOT.gateTimes[PrimitiveOperationsGroups.QubitClifford] = 0.0; configCNOT.gateTimes[PrimitiveOperationsGroups.R] = 0.0; configCNOT.gateTimes[PrimitiveOperationsGroups.T] = 0.0; var traceSimCNOT = new QCTraceSimulator(configCNOT); Simulate.Run(traceSimCNOT, data, 1.0, MOE).Wait(); double cnotDepth = traceSimCNOT.GetMetric <Simulate>(DepthCounter.Metrics.Depth); var configT = new QCTraceSimulatorConfiguration(); configT.useDepthCounter = true; configT.gateTimes[PrimitiveOperationsGroups.CNOT] = 0.0; configT.gateTimes[PrimitiveOperationsGroups.Measure] = 0.0; configT.gateTimes[PrimitiveOperationsGroups.QubitClifford] = 0.0; configT.gateTimes[PrimitiveOperationsGroups.R] = 0.0; configT.gateTimes[PrimitiveOperationsGroups.T] = 1.0; var traceSimT = new QCTraceSimulator(configT); Simulate.Run(traceSimT, data, 1.0, MOE).Wait(); double tDepth = traceSimT.GetMetric <Simulate>(DepthCounter.Metrics.Depth); var configClifford = new QCTraceSimulatorConfiguration(); configClifford.useDepthCounter = true; configClifford.gateTimes[PrimitiveOperationsGroups.CNOT] = 0.0; configClifford.gateTimes[PrimitiveOperationsGroups.Measure] = 0.0; configClifford.gateTimes[PrimitiveOperationsGroups.QubitClifford] = 1.0; configClifford.gateTimes[PrimitiveOperationsGroups.R] = 0.0; configClifford.gateTimes[PrimitiveOperationsGroups.T] = 0.0; var traceSimClifford = new QCTraceSimulator(configClifford); Simulate.Run(traceSimClifford, data, 1.0, MOE).Wait(); double cliffordDepth = traceSimClifford.GetMetric <Simulate>(DepthCounter.Metrics.Depth); Console.WriteLine(estimator.ToTSV()); Console.WriteLine($"CNOT depth is {cnotDepth}"); Console.WriteLine($"T depth is {tDepth}"); Console.WriteLine($"Clifford depth is {cliffordDepth}"); #endregion #region Classical update scheme // Determine how to update the starting state using classical methods #endregion }
static void Main(string[] args) { #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); // Console.WriteLine("----- Print Hamiltonian"); // Console.Write(hamiltonian); // Console.WriteLine("----- End Print Hamiltonian \n"); #endregion #region Convert Q# Hamiltonian #endregion #region Hybrid Quantum/Classical accelerator // Feed created state and hamiltonian terms to VQE Console.WriteLine("----- Begin VQE Simulation"); //var N = 10; // number of qubits, calculate from data??? //var oneReal = (1.0, 0.0); //var inputCoeffs = new ComplexPolar[N]; //for (int i = 0; i < Length(inputCoeffs) - 1; i++) // { // inputCoeffs[i] = oneReal; // } using (var qsim = new QuantumSimulator()) { // Simulate.Run(qsim).Wait(); // Console.WriteLine(arbitrary_test.Run(qsim, data).Result); 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 }