// Checks if any errors occur while building Hamiltonian for both index conventions. public void BuildFermionHamiltonian() { var sourceHamiltonian = new OrbitalIntegralHamiltonian(); sourceHamiltonian.Add(orbitalIntegrals); var targetHamiltonian0 = sourceHamiltonian.ToFermionHamiltonian(IndexConvention.HalfUp); var targetHamiltonian1 = sourceHamiltonian.ToFermionHamiltonian(IndexConvention.UpDown); }
static void SimulateHubbardHamiltonianTest() { ////////////////////////////////////////////////////////////////////////// // Introduction ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // In this example, we will estimate the ground state energy of // 1D Hubbard Hamiltonian using the quantum chemistry library. // The 1D Hubbard model has `n` sites. Let `i` be the site index, // `s` = 1,0 be the spin index, where 0 is up and 1 is down, `t` be the // hopping coefficient, `u` the repulsion coefficient, and aᵢₛ the fermionic // annihilation operator on the fermion indexed by `(i,s)`. The Hamiltonian // of this model is // // H ≔ - t Σᵢ (a†ᵢₛ aᵢ₊₁ₛ + a†ᵢ₊₁ₛ aᵢₛ) + u Σᵢ a†ᵢ₀ a†ᵢ₁ aᵢ₁ aᵢ₀ // // Note that we use closed boundary conditions. #region Building the Hubbard Hamiltonian through orbital integrals var t = 0.2; // hopping coefficient var u = 1.0; // repulsion coefficient var nSites = 6; // number of sites; // Construct Hubbard Hamiltonian var hubbardOrbitalIntegralHamiltonian = new OrbitalIntegralHamiltonian(); foreach (var i in Enumerable.Range(0, nSites)) { hubbardOrbitalIntegralHamiltonian.Add(new OrbitalIntegral(new[] { i, (i + 1) % nSites }, -t)); hubbardOrbitalIntegralHamiltonian.Add(new OrbitalIntegral(new[] { i, i, i, i }, u)); } // Create fermion representation of Hamiltonian // In this case, we use the spin-orbital to integer // indexing convention `x = orbitalIdx + spin * nSites`; as it // minimizes the length of Jordan–Wigner strings var hubbardFermionHamiltonian = hubbardOrbitalIntegralHamiltonian.ToFermionHamiltonian(IndexConvention.HalfUp); #endregion #region Estimating energies by simulating quantum phase estimation // Create Jordan–Wigner representation of Hamiltonian var jordanWignerEncoding = hubbardFermionHamiltonian.ToPauliHamiltonian(); // Create data structure to pass to QSharp. var qSharpData = jordanWignerEncoding.ToQSharpFormat().Pad(); Console.WriteLine($"Estimate Hubbard Hamiltonian energy:"); #endregion }
/// <summary> /// Sample implementation of end-to-end electronic structure problem simulation. /// </summary> /// <param name="filename"></param> public static void SampleWorkflow( string filename, string wavefunctionLabel, IndexConvention indexConvention ) { // Deserialize Broombridge from file. Data broombridge = Deserializers.DeserializeBroombridge(filename); // A single file can contain multiple problem descriptions. Let us pick the first one. var problemData = broombridge.ProblemDescriptions.First(); #region Create electronic structure Hamiltonian // Electronic structure Hamiltonians are usually represented compactly by orbital integrals. Let us construct // such a Hamiltonian from broombridge. OrbitalIntegralHamiltonian orbitalIntegralHamiltonian = problemData.OrbitalIntegralHamiltonian; // We can obtain the full fermion Hamiltonian from the more compact orbital integral representation. // This transformation requires us to pick a convention for converting a spin-orbital index to a single integer. // Let us pick one according to the formula `integer = 2 * orbitalIndex + spinIndex`. FermionHamiltonian fermionHamiltonian = orbitalIntegralHamiltonian.ToFermionHamiltonian(indexConvention); // We target a qubit quantum computer, which requires a Pauli representation of the fermion Hamiltonian. // A number of mappings from fermions to qubits are possible. Let us choose the Jordan–Wigner encoding. PauliHamiltonian pauliHamiltonian = fermionHamiltonian.ToPauliHamiltonian(QubitEncoding.JordanWigner); #endregion #region Create wavefunction Ansatzes // A list of trial wavefunctions can be provided in the Broombridge file. For instance, the wavefunction // may be a single-reference Hartree--Fock state, a multi-reference state, or a unitary coupled-cluster state. // In this case, Broombridge indexes the fermion operators with spin-orbitals instead of integers. Dictionary <string, FermionWavefunction <SpinOrbital> > inputStates = problemData.Wavefunctions ?? new Dictionary <string, FermionWavefunction <SpinOrbital> >(); // If no states are provided, use the Hartree--Fock state. // As fermion operators the fermion Hamiltonian are already indexed by, we now apply the desired // spin-orbital -> integer indexing convention. FermionWavefunction <int> inputState = inputStates.ContainsKey(wavefunctionLabel) ? inputStates[wavefunctionLabel].ToIndexing(indexConvention) : fermionHamiltonian.CreateHartreeFockState(problemData.NElectrons); #endregion #region Pipe to QSharp and simulate // We now convert this Hamiltonian and a selected state to a format that than be passed onto the QSharp component // of the library that implements quantum simulation algorithms. var qSharpHamiltonian = pauliHamiltonian.ToQSharpFormat(); var qSharpWavefunction = inputState.ToQSharpFormat(); var qSharpData = QSharpFormat.Convert.ToQSharpFormat(qSharpHamiltonian, qSharpWavefunction); #endregion }
void NormTerms() { var hamiltonian = new OrbitalIntegralHamiltonian(); hamiltonian.AddRange(orbitalIntegrals.Select(o => (o, o.Coefficient.ToDoubleCoeff()))); var oneNorm = hamiltonian.Norm(); hamiltonian.AddRange(orbitalIntegrals.Select(o => (o, o.Coefficient.ToDoubleCoeff()))); Assert.Equal(oneNorm * 2.0, hamiltonian.Norm()); hamiltonian.AddRange(orbitalIntegrals.Select(o => (o, o.Coefficient.ToDoubleCoeff()))); Assert.Equal(oneNorm * 3.0, hamiltonian.Norm()); hamiltonian.AddRange(orbitalIntegrals.Select(o => (o, o.Coefficient.ToDoubleCoeff()))); Assert.Equal(oneNorm * 4.0, hamiltonian.Norm()); }
static void MakeHamiltonian() { // These orbital integrals are represented using the OrbitalIntegral // data structure. var energyOffset = 0.713776188; var nElectrons = 2; 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(); // 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. var jordanWignerEncoding = fermionHamiltonian.ToPauliHamiltonian(Paulis.QubitEncoding.JordanWigner); // We also need to create an input quantum state to this Hamiltonian. // Let us use the Hartree–Fock state. var fermionWavefunction = fermionHamiltonian.CreateHartreeFockState(nElectrons); // 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); Assert.True(fermionWavefunction.MCFData.Excitations.Keys.Single() .ToIndices().SequenceEqual(new[] { 0, 1 }) ); }
public void MakeHamiltonian() { // We create a `FermionHamiltonian` object to store the terms. var hamiltonian = new OrbitalIntegralHamiltonian( new[] { new OrbitalIntegral(new[] { 0, 1, 2, 3 }, 0.123), new OrbitalIntegral(new[] { 0, 1 }, 0.456) } ) .ToFermionHamiltonian(IndexConvention.UpDown); // We convert this fermion Hamiltonian to a Jordan–Wigner representation. var jordanWignerEncoding = hamiltonian.ToPauliHamiltonian(QubitEncoding.JordanWigner); // We now convert this representation into a format consumable by Q#. var qSharpData = jordanWignerEncoding.ToQSharpFormat(); Assert.Equal(10, hamiltonian.CountTerms()); Assert.Equal(6, jordanWignerEncoding.CountTerms()); }
public void JsonEncoding() { var filename = "Broombridge/broombridge_v0.2.yaml"; Data broombridge = Deserializers.DeserializeBroombridge(filename); var problemData = broombridge.ProblemDescriptions.First(); OrbitalIntegralHamiltonian original = problemData.OrbitalIntegralHamiltonian; var json = JsonConvert.SerializeObject(original); File.WriteAllText("oribital.original.json", json); var serialized = JsonConvert.DeserializeObject <OrbitalIntegralHamiltonian>(json); File.WriteAllText("orbital.serialized.json", JsonConvert.SerializeObject(serialized)); Assert.Equal(original.SystemIndices.Count, serialized.SystemIndices.Count); Assert.Equal(original.Terms.Count, serialized.Terms.Count); Assert.Equal(original.Norm(), serialized.Norm()); Assert.Equal(original.ToString(), serialized.ToString()); }
void CheckTermPresent() { var hamiltonian = new OrbitalIntegralHamiltonian(); var addTerms0 = orbitalIntegrals.Select(o => (o, o.Coefficient.ToDoubleCoeff())).ToList(); hamiltonian.AddRange(addTerms0); // Check that all terms present. foreach (var term in addTerms0) { Assert.Equal(term.Item2, hamiltonian.GetTerm(term.o)); } // Now check that indexing is by value and not by reference. var newTerms0Copy = new[] { new[] { 0, 0 }, new[] { 1, 1 }, new[] { 0, 0, 0, 0 }, new[] { 0, 1, 0, 1 }, new[] { 0, 1, 1, 0 }, new[] { 1, 1, 1, 1 } }.Select(o => new OrbitalIntegral(o, 0.123)); foreach (var term in addTerms0.Zip(newTerms0Copy, (a, b) => (a.Item2.Value, b))) { Assert.Equal(term.Item1, hamiltonian.GetTerm(term.b).Value); } var orb = new OrbitalIntegral(new[] { 0, 1, 1, 0 }, 4.0); Assert.Equal(new[] { 0, 1, 1, 0 }, orb.OrbitalIndices); Assert.Equal(addTerms0[4].o.OrbitalIndices, orb.OrbitalIndices); Debug.WriteLine($"Term type is { orb.TermType.ToString()}"); Debug.WriteLine($"Coefficient is { hamiltonian.Terms[orb.TermType][new OrbitalIntegral(orb.OrbitalIndices, orb.Coefficient)]}"); Debug.WriteLine($"Coefficient is { hamiltonian.Terms[orb.TermType][addTerms0[4].o]}"); Assert.True(0.663472101 == hamiltonian.Terms[orb.TermType][new OrbitalIntegral(orb.OrbitalIndices, orb.Coefficient)]); }
/// <summary> /// Loads a FermionHamiltonian from either a .yaml file with a Broombridge definition, /// or from a ProblemDescription. /// If the fileName is specified, that will be used and the problemDescription will be ignored. /// </summary> public Task <ExecutionResult> Run(string input, IChannel channel) { if (string.IsNullOrWhiteSpace(input)) { channel.Stderr("Please provide the name of a Broombridge file or a problem description to load the fermion Hamiltonian from."); return(Task.FromResult(ExecuteStatus.Error.ToExecutionResult())); } // Identify the ProblemDescription with the hamiltonian from the arguments. var args = JsonConvert.DeserializeObject <Arguments>(input); var problemData = SelectProblemDescription(args); // Electronic structure Hamiltonians are usually represented compactly by orbital integrals. Let us construct // such a Hamiltonian from broombridge. OrbitalIntegralHamiltonian orbitalIntegralHamiltonian = problemData.OrbitalIntegralHamiltonian; // We can obtain the full fermion Hamiltonian from the more compact orbital integral representation. // This transformation requires us to pick a convention for converting a spin-orbital index to a single integer. // Let us pick one according to the formula `integer = 2 * orbitalIndex + spinIndex`. FermionHamiltonian fermionHamiltonian = orbitalIntegralHamiltonian.ToFermionHamiltonian(args.IndexConvention); return(Task.FromResult(fermionHamiltonian.ToExecutionResult())); }
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 MolecularHydrogenTest() { ////////////////////////////////////////////////////////////////////////// // 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), // 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"); #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. // 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); 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 estimate the ground state energy of // 1D Hubbard Hamiltonian using the quantum chemistry library. // The 1D Hubbard model has `n` sites. Let `i` be the site index, // `s` = 1,0 be the spin index, where 0 is up and 1 is down, `t` be the // hopping coefficient, `u` the repulsion coefficient, and aᵢₛ the fermionic // annihilation operator on the fermion indexed by `(i,s)`. The Hamiltonian // of this model is // // H ≔ - t Σᵢ (a†ᵢₛ aᵢ₊₁ₛ + a†ᵢ₊₁ₛ aᵢₛ) + u Σᵢ a†ᵢ₀ a†ᵢ₁ aᵢ₁ aᵢ₀ // // Note that we use closed boundary conditions. #region Building the Hubbard Hamiltonian through orbital integrals var t = 0.2; // hopping coefficient var u = 1.0; // repulsion coefficient var nSites = 6; // number of sites; // Construct Hubbard Hamiltonian var hubbardOrbitalIntegralHamiltonian = new OrbitalIntegralHamiltonian(); foreach (var i in Enumerable.Range(0, nSites)) { hubbardOrbitalIntegralHamiltonian.Add(new OrbitalIntegral(new[] { i, (i + 1) % nSites }, -t)); hubbardOrbitalIntegralHamiltonian.Add(new OrbitalIntegral(new[] { i, i, i, i }, u)); } // Create fermion representation of Hamiltonian // In this case, we use the spin-orbital to integer // indexing convention `x = orbitalIdx + spin * nSites`; as it // minimizes the length of Jordan–Wigner strings var hubbardFermionHamiltonian = hubbardOrbitalIntegralHamiltonian.ToFermionHamiltonian(IndexConvention.HalfUp); #endregion #region Estimating energies by simulating quantum phase estimation // Create Jordan–Wigner representation of Hamiltonian var jordanWignerEncoding = hubbardFermionHamiltonian.ToPauliHamiltonian(); // Create data structure to pass to QSharp. var qSharpData = jordanWignerEncoding.ToQSharpFormat().Pad(); Console.WriteLine($"Estimate Hubbard Hamiltonian energy:"); // Bits of precision in phase estimation. var bits = 7; // Repetitions to find minimum energy. var reps = 5; // Trotter step size var trotterStep = 0.5; using (var qsim = new QuantumSimulator()) { for (int i = 0; i < reps; i++) { // EstimateEnergyByTrotterization // Name should make clear that it does it by trotterized var(phaseEst, energyEst) = GetEnergy.Run(qsim, qSharpData, bits, trotterStep).Result; Console.WriteLine($"Rep #{i}: Energy estimate: {energyEst}; Phase estimate: {phaseEst}"); } } Console.WriteLine("Press Enter to continue..."); if (System.Diagnostics.Debugger.IsAttached) { Console.ReadLine(); } #endregion }
void BuildOrbitalIntegralHamiltonian() { var hamiltonian = new OrbitalIntegralHamiltonian(); hamiltonian.Add(orbitalIntegrals); }
/// <summary> /// Deserializes an FCIDUMP-formatted problem description. /// </summary> /// <param name="reader">A stream for reading FCIDUMP data.</param> /// <returns> /// An electronic structure problem deserialized from the file. /// </returns> public static IEnumerable <ElectronicStructureProblem> Deserialize(TextReader reader) { // FCIDUMP files begin with a FORTRAN-formatted namelist, delimited // by &FCI and &END. We start by extracting that namelist. var allText = reader.ReadToEnd(); var lines = Regex.Split(allText, "\r\n|\r|\n"); if (lines == null) { throw new IOException("Expected a non-empty FCIDUMP file."); } var header = System.String.Join("\n", lines.TakeWhile(line => line.Trim() != "&END")).Trim(); var body = lines !.SkipWhile(line => line.Trim() != "&END").Skip(1).ToList(); // Make sure that the header starts with &FCI, as expected. if (!header.StartsWith("&FCI")) { throw new IOException("FCIDUMP file did not start with \"&FCI\" as expected."); } // Split out the &FCI and &END lines, turn the rest into a dictionary of namelist items. var namelist = Regex.Matches( header .Replace("&FCI", "") .Replace("&END", ""), pattern: "\\s*(?<identifier>\\w+)\\s*=\\s*(?<value>[^=]+),\\s*" ) .ToDictionary( match => match.Groups["identifier"].Value, match => match.Groups["value"].Value ); var hamiltonian = new OrbitalIntegralHamiltonian(); var arrayData = body .Select(line => line.Trim()) .Where(line => line.Length > 0) .Select( line => line.Split(" ", StringSplitOptions.RemoveEmptyEntries) ) .Select( row => ( Double.Parse(row[0]), row[1..].Select(Int32.Parse).Where(idx => idx != 0).ToZeroBasedIndices() ) ); var(coulomb, _) = arrayData.Where(item => item.Item2.Length == 0).Single(); hamiltonian.Add(arrayData .Where(row => row.Item2.Length > 0) .SelectMaybe( row => row.Item2.Length % 2 == 0 ? new OrbitalIntegral( row.Item2, row.Item1, OrbitalIntegral.Convention.Mulliken ).ToCanonicalForm() : null ) .Distinct() ); // The identity term in deserialized Hamiltonians is the sum of the // Coloumb repulsion and the energy offset. Since only the former // exists in FCIDUMP, we set the identity term accordingly. hamiltonian.Add(new OrbitalIntegral(), coulomb); return(new List <ElectronicStructureProblem> { new ElectronicStructureProblem { EnergyOffset = 0.0.WithUnits("hartree"), CoulombRepulsion = coulomb.WithUnits("hartree"), Metadata = new Dictionary <string, object> { ["Comment"] = "Imported from FCIDUMP" }, NElectrons = Int32.Parse(namelist["NELEC"]), NOrbitals = Int32.Parse(namelist["NORB"]), OrbitalIntegralHamiltonian = hamiltonian } }); }
internal static ElectronicStructureProblem DeserializeSingleProblem(string line) { var problem = new ElectronicStructureProblem() { Metadata = new Dictionary <string, object>() }; var regexMiscellaneous = new Regex(@"((info=(?<info>[^\s]*)))"); var regexnuc = new Regex(@"nuc=(?<nuc>-?\s*\d*.\d*)"); var regexPQ = new Regex(@"(^|\s+)(?<p>\d+),(?<q>\d+)\D*=\s*(?<coeff>-?\s*\d*.\d*)e?(?<exponent>-?\d*)"); var regexPQRS = new Regex(@"(^|\s+)(?<p>\d+)\D+(?<q>\d+)\D+(?<r>\d+)\D+(?<s>\d+)\D*=\s*(?<coeff>-?\s*\d*.\d*)e?(?<exponent>-?\d*)"); double coulombRepulsion = 0.0; var fileHIJTerms = new Dictionary <int[], double>(new Extensions.ArrayEqualityComparer <int>()); var fileHIJKLTerms = new Dictionary <int[], double>(new Extensions.ArrayEqualityComparer <int>()); var hamiltonian = new OrbitalIntegralHamiltonian(); var nOrbitals = 0L; Match stringMisc = regexMiscellaneous.Match(line); if (stringMisc.Success) { problem.Metadata["misc_info"] = stringMisc.Groups["info"].ToString(); } Match stringnuc = regexnuc.Match(line); if (stringnuc.Success) { coulombRepulsion = double.Parse(stringnuc.Groups["nuc"].ToString()).ToDoubleCoeff(); hamiltonian.Add(TermType.OrbitalIntegral.Identity, new OrbitalIntegral(), coulombRepulsion); } foreach (Match stringPQ in regexPQ.Matches(line)) { if (stringPQ.Success) { var p = int.Parse(stringPQ.Groups["p"].ToString()); var q = int.Parse(stringPQ.Groups["q"].ToString()); var coeff = double.Parse(stringPQ.Groups["coeff"].ToString()); var exponentString = stringPQ.Groups["exponent"].ToString(); var exponent = 0.0; if (exponentString != "") { exponent = double.Parse(stringPQ.Groups["exponent"].ToString()); } nOrbitals = new long[] { nOrbitals, p + 1, q + 1 }.Max(); var orbitalIntegral = new OrbitalIntegral(new int[] { p, q }, coeff * (10.0).Pow(exponent)); var orbitalIntegralCanonical = orbitalIntegral.ToCanonicalForm(); if (fileHIJTerms.ContainsKey(orbitalIntegralCanonical.OrbitalIndices)) { // Check consistency if (fileHIJTerms[orbitalIntegralCanonical.OrbitalIndices] != orbitalIntegral.Coefficient) { // Consistency check failed. throw new System.NotSupportedException( $"fileHPQTerm Consistency check fail. " + $"Orbital integral {orbitalIntegral} coefficient {orbitalIntegral.Coefficient}" + $"does not match recorded {orbitalIntegralCanonical} coefficient {fileHIJTerms[orbitalIntegral.OrbitalIndices]}."); } else { // Consistency check passed. } } else { fileHIJTerms.Add(orbitalIntegralCanonical.OrbitalIndices, orbitalIntegralCanonical.Coefficient); } } } foreach (Match stringPQRS in regexPQRS.Matches(line)) { if (stringPQRS.Success) { var p = int.Parse(stringPQRS.Groups["p"].ToString()); var q = int.Parse(stringPQRS.Groups["q"].ToString()); var r = int.Parse(stringPQRS.Groups["r"].ToString()); var s = int.Parse(stringPQRS.Groups["s"].ToString()); var coeff = double.Parse(stringPQRS.Groups["coeff"].ToString()); var exponentString = stringPQRS.Groups["exponent"].ToString(); var exponent = 0.0; if (exponentString != "") { exponent = double.Parse(stringPQRS.Groups["exponent"].ToString()); } nOrbitals = new long[] { nOrbitals, p + 1, q + 1, r + 1, s + 1 }.Max(); var orbitalIntegral = new OrbitalIntegral(new int[] { p, q, r, s }, coeff * (10.0).Pow(exponent)); var orbitalIntegralCanonical = orbitalIntegral.ToCanonicalForm(); if (fileHIJKLTerms.ContainsKey(orbitalIntegralCanonical.OrbitalIndices)) { // Check consistency if (fileHIJKLTerms[orbitalIntegralCanonical.OrbitalIndices] != orbitalIntegral.Coefficient) { // Consistency check failed. throw new System.NotSupportedException( $"fileHPQRSTerm Consistency check fail. " + $"Orbital integral {orbitalIntegral.OrbitalIndices} coefficient {orbitalIntegral.Coefficient}" + $"does not match recorded {orbitalIntegralCanonical.OrbitalIndices} coefficient {fileHIJKLTerms[orbitalIntegral.OrbitalIndices]}."); } else { // Consistency check passed. } } else { fileHIJKLTerms.Add(orbitalIntegralCanonical.OrbitalIndices, orbitalIntegralCanonical.Coefficient); } } } hamiltonian.Add(fileHIJTerms.Select(o => new OrbitalIntegral(o.Key, o.Value)).ToList()); hamiltonian.Add(fileHIJKLTerms.Select(o => new OrbitalIntegral(o.Key, o.Value)).ToList()); problem.OrbitalIntegralHamiltonian = hamiltonian; problem.NOrbitals = System.Convert.ToInt32(nOrbitals); problem.CoulombRepulsion = coulombRepulsion.WithUnits("hartree"); return(problem); }
void BuildHamiltonian() { var hamiltonian = new OrbitalIntegralHamiltonian(); hamiltonian.AddRange(orbitalIntegrals.Select(o => (o, o.Coefficient.ToDoubleCoeff()))); }