/// <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)) };
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); }
/// <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."); } }