예제 #1
0
        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
        }
예제 #2
0
        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
        }