Example #1
0
        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)))
                );
        }
Example #2
0
 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>());
     }
 }
Example #3
0
        /// <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());
        }
Example #5
0
        // 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));
        }
Example #6
0
        // 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);
        }