Ejemplo n.º 1
0
        /// <summary>
        /// Converts the raw problem description in V0_2 Broombridge into
        /// in internal data format.
        /// </summary>
        /// <param name="problem">Problem description to be converted</param>
        /// <returns>The internal problem description data structure.</returns>
        public static ProblemDescription ProcessRawProblemDescription(Broombridge.V0_2.ProblemDescription problem)
        {
            var problemDescription = new ProblemDescription
            {
                EnergyOffset = problem.EnergyOffset.Value + problem.CoulombRepulsion.Value,
                NElectrons   = problem.NElectrons,
                NOrbitals    = problem.NOrbitals,
                OrbitalIntegralHamiltonian = V0_2.ToOrbitalIntegralHamiltonian(problem),
                Wavefunctions = new Dictionary <string, FermionWavefunction <SpinOrbital> >()
            };

            foreach (var initialState in problem.InitialStates)
            {
                var finalState = new FermionWavefunction <SpinOrbital>();

                var(method, energy, outputState) = V0_2.ToWavefunction(initialState);

                var setMethod = V0_2.ParseInitialStateMethod(initialState.Method);
                var setEnergy = energy;

                if (setMethod == StateType.SparseMultiConfigurational)
                {
                    var mcfData = (SparseMultiCFWavefunction <SpinOrbital>)outputState;

                    finalState = new FermionWavefunction <SpinOrbital>(
                        mcfData.Excitations
                        .Select(o => (
                                    o.Key.ToIndices().ToArray(),
                                    o.Value.Real
                                    )));
                }
                else if (setMethod == StateType.UnitaryCoupledCluster)
                {
                    var uccData = (UnitaryCCWavefunction <SpinOrbital>)outputState;

                    var reference = uccData.Reference;

                    var excitations = uccData.Excitations;

                    finalState = new FermionWavefunction <SpinOrbital>(
                        reference.ToIndices(),
                        excitations
                        .Select(o => (
                                    o.Key.ToIndices().ToArray(),
                                    o.Value.Real
                                    ))
                        );
                }
                else
                {
                    throw new System.ArgumentException($"Wavefunction type {setMethod} not recognized");
                }

                finalState.Method = setMethod;
                finalState.Energy = setEnergy;

                problemDescription.Wavefunctions.Add(initialState.Label, finalState);
            }
            return(problemDescription);
        }
        public static JordanWignerEncodingData GetQSharpData(string filename, string wavefunctionLabel, Config configuration)
        {
            using var reader = File.OpenText(filename);
            var broombridge = BroombridgeSerializer.Deserialize(reader).First();

            var orbHam = broombridge.OrbitalIntegralHamiltonian;

            var ferHam = orbHam.ToFermionHamiltonian(configuration.UseIndexConvention);

            var pauHam = ferHam.ToPauliHamiltonian();

            var hamiltonian = pauHam.ToQSharpFormat();

            var inputStates = broombridge.InitialStates ?? 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> wavefunction = inputStates.ContainsKey(wavefunctionLabel)
                ? inputStates[wavefunctionLabel].ToIndexing(configuration.UseIndexConvention)
                : ferHam.CreateHartreeFockState(broombridge.NElectrons);

            var qSharpData = Microsoft.Quantum.Chemistry.QSharpFormat.Convert.ToQSharpFormat(hamiltonian, wavefunction.ToQSharpFormat());

            return(qSharpData);
        }
 /// <summary>
 /// Converts spin-orbital indices to integer indices
 /// </summary>
 /// <param name="wavefunction">A fermionic wavefunction whose spin-orbital indices are to be converted.</param>
 /// <param name="indexConvention">The convention for mapping spin-orbitals to indices to be used in converting the spin-orbital indices of <paramref name="wavefunction" />.</param>
 /// <returns>
 /// A fermion wavefunction where spin-orbitals are indexed by integers
 /// according to the chosen indexing scheme.
 /// </returns>
 public static FermionWavefunction <int> ToIndexing(this FermionWavefunction <SpinOrbital> wavefunction, IndexConvention indexConvention)
 => new FermionWavefunction <int>()
 {
     Method  = wavefunction.Method,
     Energy  = wavefunction.Energy,
     SCFData = wavefunction.SCFData.SelectIndex <int>((x) => x.ToInt(indexConvention)),
     MCFData = wavefunction.MCFData.SelectIndex <int>((x) => x.ToInt(indexConvention)),
     UCCData = wavefunction.UCCData.SelectIndex <int>((x) => x.ToInt(indexConvention))
 };
Ejemplo n.º 4
0
        static void MakeSingleReferenceState()
        {
            // Create a list of indices of the creation operators
            var indices = new[] { 1, 2, 6 };

            // Convert the list of indices to a `FermionWavefunction` object.
            var wavefunction = new FermionWavefunction <int>(indices);

            Assert.Equal(StateType.SparseMultiConfigurational, wavefunction.Method);
        }
Ejemplo n.º 5
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
        }
        /// <summary>
        /// Translate initial state to a format consumable by Q#.
        /// </summary>
        /// <param name="inputState">Initial state</param>
        /// <returns>Initial state in Q# format.</returns>
        public static (Int64, QArray <JordanWignerInputState>) ToQSharpFormat(this FermionWavefunction <int> inputState)
        {
            //return (0, new QArray<JordanWignerInputState>());

            if (inputState.Method == StateType.SparseMultiConfigurational)
            {
                return((int)inputState.Method, InitialStateSparseMultiConfigural(inputState.MCFData));
            }
            else if (inputState.Method == StateType.UnitaryCoupledCluster)
            {
                return((int)inputState.Method, InitialStateUnitaryCoupledCluster(inputState.UCCData));
            }
            else
            {
                throw new ArgumentException($"Selected quantum state {inputState.Method.ToString("G")} not recognized.");
            }
        }