static void Main(string[] args) { ////////////////////////////////////////////////////////////////////////// // Introduction ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // In this example, we will create a spin-orbital representation of the molecular // Hydrogen Hamiltonian `H`, given overlap coefficients for its one- and // two - electron integrals. // We when perform quantum phase estimation to obtain an estimate of // the molecular Hydrogen ground state energy. #region Building the Hydrogen Hamiltonian through orbital integrals // One of the simplest representations of Hydrogen uses only two // molecular orbitals indexed by `0` and `1`. var nOrbitals = 2; // This representation also has two occupied spin-orbitals. var nElectrons = 2; // The Coulomb repulsion energy between nuclei is var energyOffset = 0.713776188; // One-electron integrals are listed below // <0|H|0> = -1.252477495 // <1|H|1> = -0.475934275 // Two-electron integrals are listed below // <00|H|00> = 0.674493166 // <01|H|01> = 0.181287518 // <01|H|10> = 0.663472101 // <11|H|11> = 0.697398010 // Note that orbitals are assumed to be real. Moreover, indistinguishability // of electrons means that the following integrals are equal. // <PQ|H|RS> = <PR|H|QS> = <SQ|H|RP> = <SR|H|QP> // = <QP|H|SR> = <RP|H|SQ> = <QS|H|PR> = <RS|H|PQ> // Thus it suffices to specify just any one of these terms from each symmetry // group. // These orbital integrals are represented using the OrbitalIntegral // data structure. var orbitalIntegrals = new OrbitalIntegral[] { new OrbitalIntegral(new[] { 0, 0 }, -1.252477495), new OrbitalIntegral(new[] { 1, 1 }, -0.475934275), new OrbitalIntegral(new[] { 0, 0, 0, 0 }, 0.674493166), new OrbitalIntegral(new[] { 0, 1, 0, 1 }, 0.181287518), new OrbitalIntegral(new[] { 0, 1, 1, 0 }, 0.663472101), new OrbitalIntegral(new[] { 1, 1, 1, 1 }, 0.697398010), // Add the identity term new OrbitalIntegral(new int[] { }, energyOffset) }; // We initialize a fermion Hamiltonian data structure and add terms to it var fermionHamiltonian = new OrbitalIntegralHamiltonian(orbitalIntegrals).ToFermionHamiltonian(); // These orbital integral terms are automatically expanded into // spin-orbitals. We may print the Hamiltonian to see verify what it contains. Console.WriteLine("----- Print Hamiltonian"); Console.Write(fermionHamiltonian); Console.WriteLine("----- End Print Hamiltonian \n"); // We also need to create an input quantum state to this Hamiltonian. // Let us use the Hartree–Fock state. var fermionWavefunction = fermionHamiltonian.CreateHartreeFockState(nElectrons); #endregion #region Jordan–Wigner representation // The Jordan–Wigner encoding converts the fermion Hamiltonian, // expressed in terms of Fermionic operators, to a qubit Hamiltonian, // expressed in terms of Pauli matrices. This is an essential step // for simulating our constructed Hamiltonians on a qubit quantum // computer. Console.WriteLine("----- Creating Jordan–Wigner encoding"); var jordanWignerEncoding = fermionHamiltonian.ToPauliHamiltonian(Paulis.QubitEncoding.JordanWigner); Console.WriteLine("----- End Creating Jordan–Wigner encoding \n"); // Print the Jordan–Wigner encoded Hamiltonian to see verify what it contains. Console.WriteLine("----- Print Hamiltonian"); Console.Write(jordanWignerEncoding); Console.WriteLine("----- End Print Hamiltonian \n"); #endregion #region Performing the simulation // We are now ready to run a quantum simulation of molecular Hydrogen. // We will use this to obtain an estimate of its ground state energy. // Here, we make an instance of the simulator used to run our Q# code. using (var qsim = new QuantumSimulator()) { // This Jordan–Wigner data structure also contains a representation // of the Hamiltonian and wavefunction made for consumption by the Q# algorithms. var qSharpHamiltonianData = jordanWignerEncoding.ToQSharpFormat(); var qSharpWavefunctionData = fermionWavefunction.ToQSharpFormat(); var qSharpData = QSharpFormat.Convert.ToQSharpFormat(qSharpHamiltonianData, qSharpWavefunctionData); // We specify the bits of precision desired in the phase estimation // algorithm var bits = 7; // We specify the step-size of the simulated time-evolution var trotterStep = 0.4; // Choose the Trotter integrator order Int64 trotterOrder = 1; // As the quantum algorithm is probabilistic, let us run a few trials. // This may be compared to true value of Console.WriteLine("Exact molecular Hydrogen ground state energy: -1.137260278.\n"); Console.WriteLine("----- Performing quantum energy estimation by Trotter simulation algorithm"); for (int i = 0; i < 5; i++) { // EstimateEnergyByTrotterization // Name should make clear that it does it by trotterized var(phaseEst, energyEst) = GetEnergyByTrotterization.Run(qsim, qSharpData, bits, trotterStep, trotterOrder).Result; Console.WriteLine($"Rep #{i+1}/5: Energy estimate: {energyEst}; Phase estimate: {phaseEst}"); } Console.WriteLine("----- End Performing quantum energy estimation by Trotter simulation algorithm\n"); Console.WriteLine("----- Performing quantum energy estimation by Qubitization simulation algorithm"); for (int i = 0; i < 1; i++) { // EstimateEnergyByTrotterization // Name should make clear that it does it by trotterized var(phaseEst, energyEst) = GetEnergyByQubitization.Run(qsim, qSharpData, bits).Result; Console.WriteLine($"Rep #{i+1}/1: Energy estimate: {energyEst}; Phase estimate: {phaseEst}"); } Console.WriteLine("----- End Performing quantum energy estimation by Qubitization simulation algorithm\n"); } Console.WriteLine("Press Enter to continue..."); if (System.Diagnostics.Debugger.IsAttached) { Console.ReadLine(); } #endregion }
static void Main(string[] args) { ////////////////////////////////////////////////////////////////////////// // Introduction ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // In this example, we will create a spin-orbital representation of the molecular // Hydrogen Hamiltonian `H`, given ovelap coefficients for its one- and // two - electron integrals. // We when perform quantum phase estimation to obtain an estimate of // the molecular Hydrogen ground state energy. #region Building the Hydrogen Hamiltonian through orbital integrals /* * // One of the simplest representations of Hydrogen uses only two * // molecular orbitals indexed by `0` and `1`. * var nOrbitals = 2; * * // This representation also has two occupied spin-orbitals. * var nElectrons = 2; * * // The Coulomb repulsion energy between nuclei is * var energyOffset = 0.713776188; * * // One-electron integrals are listed below * // <0|H|0> = -1.252477495 * // <1|H|1> = -0.475934275 * * // Two-electron integrals are listed below * // <00|H|00> = 0.674493166 * // <01|H|01> = 0.181287518 * // <01|H|10> = 0.663472101 * // <11|H|11> = 0.697398010 * // Note that orbitals are assumed to be real. Moreover, indistinguishability * // of electrons means that the following integrals are equal. * // <PQ|H|RS> = <PR|H|QS> = <SQ|H|RP> = <SR|H|QP> * // = <QP|H|SR> = <RP|H|SQ> = <QS|H|PR> = <RS|H|PQ> * // Thus it sufficies to specify just any one of these terms from each symmetry * // group. * * // These orbital integrals are represented using the OrbitalIntegral * // data structure. * var orbitalIntegrals = new OrbitalIntegral[] * { * new OrbitalIntegral(new[] { 0,0 }, -1.252477495), * new OrbitalIntegral(new[] { 1,1 }, -0.475934275), * new OrbitalIntegral(new[] { 0,0,0,0 }, 0.674493166), * new OrbitalIntegral(new[] { 0,1,0,1 }, 0.181287518), * new OrbitalIntegral(new[] { 0,1,1,0 }, 0.663472101), * new OrbitalIntegral(new[] { 1,1,1,1 }, 0.697398010) * }; * * // We initialize a Fermion Hamiltonian data structure and add terms to it * var hamiltonian = new FermionHamiltonian(); * hamiltonian.NOrbitals = nOrbitals; * hamiltonian.NElectrons = nElectrons; * hamiltonian.EnergyOffset = energyOffset; * hamiltonian.AddFermionTerm(orbitalIntegrals); */ // This is the name of the file we want to load var filename = "h4_sto6g_0.000.yaml"; // var filename = "h2_2_sto6g_1.0au.yaml"; // var filename = "h20_nwchem.yaml"; // This constructs the `FermionHamiltonian` from `Broombridge` format. Console.Write(FermionHamiltonian.LoadFromYAML($@"{filename}")); var hamiltonian = FermionHamiltonian.LoadFromYAML($@"{filename}").Single(); // Note that the `LoadFromYAML` schema returns a list of `FermionHamiltonian` // instances as the file might describe multiple Hamiltonians. // In this example, there is only one Hamiltonian. // So we use `.Single()`, which selects the first element of the list. // These orbital integral terms are automatically expanded into // spin-orbitals. We may print the Hamiltonian to see verify what it contains. Console.WriteLine("----- Print Hamiltonian"); // Console.Write(hamiltonian); Console.WriteLine("----- End Print Hamiltonian \n"); #endregion #region Jordan-Wigner representation // The Jordan-Wigner encoding converts the Fermion Hamiltonian, // expressed in terms of Fermionic operators, to a qubit Hamiltonian, // expressed in terms of Pauli matrices. This is an essential step // for simulating our constructed Hamiltonians on a qubit quantum // computer. Console.WriteLine("----- Creating Jordan-Wigner encoding"); var jordanWignerEncoding = JordanWignerEncoding.Create(hamiltonian); Console.WriteLine("----- End Creating Jordan-Wigner encoding \n"); #endregion #region Performing the simulation // We are now ready to run a quantum simulation of molecular Hydrogen. // We will use this to obtain an estimate of its ground state energy. // Here, we make an instance of the simulator used to run our Q# code. using (var qsim = new QuantumSimulator()) { // This Jordan-Wigner data structure also contains a representation // of the Hamiltonian made for consumption by the Q# algorithms. var state = "|G>"; var qSharpData = jordanWignerEncoding.QSharpData(state); // We specify the bits of precision desired in the phase estimation // algorithm var bits = 7; // We specify the step-size of the simulated time-evolution var trotterStep = 0.4; // Choose the Trotter integrator order Int64 trotterOrder = 1; // As the quantum algorithm is probabilistic, let us run a few trials. // This may be compared to true value of // Console.WriteLine("Exact molecular Hydrogen ground state energy: -1.137260278.\n"); Console.WriteLine("----- Performing quantum energy estimation by Trotter simulation algorithm"); // for (int i = 0; i < 20; i++) // { // // EstimateEnergyByTrotterization // // Name shold make clear that it does it by trotterized // var (phaseEst, energyEst) = GetEnergyByTrotterization.Run(qsim, qSharpData, bits, trotterStep, trotterOrder).Result; // Console.WriteLine($"Rep #{i + 1}/20: Energy estimate: {energyEst}; Phase estimate: {phaseEst}"); // } // Console.WriteLine("----- End Performing quantum energy estimation by Trotter simulation algorithm\n"); // Console.WriteLine("----- Performing quantum energy estimation by Qubitization simulation algorithm"); for (int i = 0; i < 1; i++) { // EstimateEnergyByTrotterization // Name shold make clear that it does it by trotterized var(phaseEst, energyEst) = GetEnergyByQubitization.Run(qsim, qSharpData, bits).Result; Console.WriteLine($"Rep #{i + 1}/1: Energy estimate: {energyEst}; Phase estimate: {phaseEst}"); } // Console.WriteLine("----- End Performing quantum energy estimation by Qubitization simulation algorithm\n"); } Console.WriteLine("Press Enter to continue..."); if (System.Diagnostics.Debugger.IsAttached) { Console.ReadLine(); } #endregion }