public static (Double, Int64, JWOptimizedHTerms) ToQSharpFormat(this PauliHamiltonian pauliHamiltonian) { var energyOffset = 0.0; if (pauliHamiltonian.Terms.ContainsKey(TermType.PauliTerm.Identity)) { energyOffset = pauliHamiltonian.Terms[TermType.PauliTerm.Identity].Values.First().Value.First(); } var nSpinOrbitals = pauliHamiltonian.SystemIndices.Max() + 1; var hZ = CreateHTermList(pauliHamiltonian, TermType.PauliTerm.Z); var hZZ = CreateHTermList(pauliHamiltonian, TermType.PauliTerm.ZZ); var hPQ = CreateHTermList(pauliHamiltonian, TermType.PauliTerm.PQ); var hPQQR = CreateHTermList(pauliHamiltonian, TermType.PauliTerm.PQQR); var hv0123 = CreateHTermList(pauliHamiltonian, TermType.PauliTerm.v01234); var hPQandPQQR = hPQ.Concat(hPQQR).ToList(); // Sort terms into desired order. hZ.Sort(new HTermIndexIComparer()); hZZ.Sort(new HTermIndexIComparer()); hPQandPQQR.Sort(new HPQandPQQRIComparer()); hv0123.Sort(new HTermIndexIComparer()); return( energyOffset, nSpinOrbitals, new JWOptimizedHTerms(( new QArray <HTerm>(hZ), new QArray <HTerm>(hZZ), new QArray <HTerm>(hPQandPQQR), new QArray <HTerm>(hv0123))) ); }
internal static List <HTerm> CreateHTermList(PauliHamiltonian pauliHamiltonian, TermType.PauliTerm term) { if (pauliHamiltonian.Terms.ContainsKey(term)) { return(pauliHamiltonian.Terms[term].Select(o => FromPauliTerm(o.Key, o.Value)).ToList()); } else { return(new List <HTerm>()); } }
/// <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 }
public async Task <ExecutionResult> Run(string input, IChannel channel) { var args = JsonConvert.DeserializeObject <Arguments>(input); // 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 = args.Hamiltonian.ToPauliHamiltonian(QubitEncoding.JordanWigner); // 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 = args.Wavefunction.ToQSharpFormat(); var qSharpData = Microsoft.Quantum.Chemistry.QSharpFormat.Convert.ToQSharpFormat(qSharpHamiltonian, qSharpWavefunction); return(qSharpData.ToExecutionResult()); }
// Creates the typical JordanWignerEncodingData given the JSON input + the index of the interaction to use // Input: full JSON, index of interaction to use // Output: JordanWignerEncodingData to use with Q# public static JordanWignerEncodingData ConvertOneToJWED( JObject OptimizedHamiltonian, int index ) { // begin initial converstion to Q# files PauliHamiltonian hamiltonianQSharpFormat = CallQSharpPipeline(OptimizedHamiltonian, index); var inputState = CreateJWInputState(OptimizedHamiltonian); // convert to refined Q# format var pauliHamiltonianQSharpFormat = hamiltonianQSharpFormat.ToQSharpFormat(); var(energyOffset, trash, trash2) = pauliHamiltonianQSharpFormat; return(QSharpFormat.Convert.ToQSharpFormat(pauliHamiltonianQSharpFormat, inputState)); }
// Converts JSON to data format with existing Q# pipeline // Input: JSON file // Output: PauliHamiltonian for later use in Q# pipeline public static PauliHamiltonian CallQSharpPipeline( JObject OptimizedHamiltonian, int index ) { // make Hamiltonian to be output var hamiltonian = new PauliHamiltonian(); // Pull the interactions from a specific round var interactionList = OptimizedHamiltonian["terms"]["interactions"][index]; // make the conversion function Func <FermionTerm, TermType.Fermion, double, IEnumerable <(PauliTerm, PauliTermValue)> > conversion = (fermionTerm, termType, coeff) => (fermionTerm.ToJordanWignerPauliTerms(termType, coeff)); // pull the interactions and parse them into the PauliHamiltonian format foreach (var interaction in interactionList) { var(term, type, coeffData) = ConvertToFermionFormat(interaction); hamiltonian.AddRange(conversion(term, type, coeffData)); // if ((string)interaction["type"] == "Identity") // { // // We need to still add the term if it's an identity term // hamiltonian. // } else { // var (term, type, coeff) = ConvertToFermionFormat(interaction); // hamiltonian.AddRange(conversion(term, type, coeff)); // } } // assume that the indices are simply an ascending 0-indexed list List <int> indices = new List <int>(); for (int i = 0; i < interactionList.Count(); i++) { indices.Add(i); } hamiltonian.SystemIndices = new HashSet <int>(indices); // hamiltonian.SystemIndices = new HashSet<int>(sourceHamiltonian.SystemIndices.ToList()); return(hamiltonian); }
/// <summary> /// Method for constructing a Pauli Hamiltonian from a fermion Hamiltonina. /// </summary> /// <param name="sourceHamiltonian">Input orbital integral Hamiltonian.</param> /// <param name="encoding">Identifies how the terms should be encoded on the qubits.</param> /// <returns>Fermion Hamiltonian constructed from orbital integrals.</returns> public static PauliHamiltonian ToPauliHamiltonian( this FermionHamiltonian sourceHamiltonian, QubitEncoding encoding = QubitEncoding.JordanWigner) { var nFermions = sourceHamiltonian.SystemIndices.Max() + 1; var hamiltonian = new PauliHamiltonian(); Func <FermionTerm, TermType.Fermion, double, IEnumerable <(PauliTerm, PauliTermValue)> > conversion = (fermionTerm, termType, coeff) => (fermionTerm.ToJordanWignerPauliTerms(termType, coeff)); foreach (var termType in sourceHamiltonian.Terms) { foreach (var term in termType.Value) { hamiltonian.AddRange(conversion(term.Key, termType.Key, term.Value.Value)); } } // Create a copy of fermion indices hash set. hamiltonian.SystemIndices = new HashSet <int>(sourceHamiltonian.SystemIndices.ToList()); return(hamiltonian); }