// Parses MCF wavefunction. internal static SparseMultiCFWavefunction <SpinOrbital> ToSparseMultiCFWavefunction(List <List <string> > superposition) { var outputState = new SparseMultiCFWavefunction <SpinOrbital>(); // Todo: modify broombridge to have explicit reference state. foreach (var element in superposition) { // First item is the amplitude. double amplitude = double.Parse(element.First().ToString(), System.Globalization.CultureInfo.InvariantCulture); // Second to Second-last are fermion operators. IEnumerable <LadderOperator <SpinOrbital> > operators = element .Take(element.Count() - 1) .Skip(1) .Select(o => V0_1.ParsePolishNotation(o.ToString())); var ladderSequence = new LadderSequence <SpinOrbital>(operators); // Sort operators to index order. IEnumerable <IndexOrderedSequence <SpinOrbital> > sortedOperators = ladderSequence.ToIndexOrder(); // Only select the shortest term with no repeated indices. IndexOrderedSequence <SpinOrbital> sortedOperator = sortedOperators.ToList().OrderBy(o => o.UniqueIndices()).First(); outputState.Set(sortedOperator, new Complex(amplitude, 0.0)); } return(outputState); }
/// <summary> /// Populates the Unitary coupled-cluster wavefunction with all possible spin-preserving exitations /// from occupied orbitals to virtual orbitals. /// </summary> /// <param name="occupiedSpinOrbitals">Occupied orbitals that annihilation operators act on.</param> /// <param name="nOrbitals">Number of orbitals.</param> public static UnitaryCCWavefunction <SpinOrbital> CreateAllUCCSDSingletExcitations(this IEnumerable <SpinOrbital> occupiedSpinOrbitals, int nOrbitals) { // Create list of unoccupied spin-orbitals var virtualOrbitals = Enumerable.Range(0, nOrbitals).Select(x => new SpinOrbital(x, Spin.u)) .Concat(Enumerable.Range(0, nOrbitals).Select(x => new SpinOrbital(x, Spin.d))) .Except(occupiedSpinOrbitals); var outputState = new UnitaryCCWavefunction <SpinOrbital>() { Reference = new SingleCFWavefunction <SpinOrbital>(occupiedSpinOrbitals) }; // Populate singles excitations. foreach (var occupiedIdx in occupiedSpinOrbitals) { foreach (var virtualIdx in virtualOrbitals) { if (occupiedIdx.Spin == virtualIdx.Spin) { var term = new IndexOrderedSequence <SpinOrbital>(new[] { virtualIdx, occupiedIdx }.ToLadderSequence()); outputState.Set(term, new Complex()); } } } // Populate doubles excitations. foreach (var occupiedIdx0 in occupiedSpinOrbitals) { foreach (var occupiedIdx1 in occupiedSpinOrbitals) { // Only loop over distinct pairs of occupied spin orbitals if (occupiedIdx0.ToInt() < occupiedIdx1.ToInt()) { foreach (var virtualIdx0 in virtualOrbitals) { foreach (var virtualIdx1 in virtualOrbitals) { // Only loop over distinct pairs of occupied spin orbitals if (virtualIdx0.ToInt() < virtualIdx1.ToInt()) { if (virtualIdx0.Spin + virtualIdx1.Spin == occupiedIdx0.Spin + occupiedIdx1.Spin) { var term = new IndexOrderedSequence <SpinOrbital>(new[] { virtualIdx1, virtualIdx0, occupiedIdx1, occupiedIdx0 }.ToLadderSequence()); outputState.Set(term, new Complex()); } } } } } } } return(outputState); }
// Parses UCC wavefunction. internal static UnitaryCCWavefunction <SpinOrbital> ToUnitaryCCWavefunction(ClusterOperator clusterOperator) { var outputState = new UnitaryCCWavefunction <SpinOrbital>(); var oneBodyTerms = clusterOperator.OneBodyAmplitudes ?? new List <List <string> >(); var twoBodyTerms = clusterOperator.TwoBodyAmplitudes ?? new List <List <string> >(); foreach (var element in oneBodyTerms.Concat(twoBodyTerms)) { // First item is the amplitude. double amplitude = double.Parse(element.First().ToString(), System.Globalization.CultureInfo.InvariantCulture); // Second to last are fermion operators. IEnumerable <LadderOperator <SpinOrbital> > operators = element .Skip(1) .Select(o => V0_1.ParsePolishNotation(o.ToString())); var ladderSequence = new LadderSequence <SpinOrbital>(operators); // Terms are assumed to be in normal order. var sortedOperator = new IndexOrderedSequence <SpinOrbital>(operators); outputState.Set(sortedOperator, new Complex(amplitude, 0.0)); } var reference = new List <List <string> >() { clusterOperator.Reference }; outputState.Reference = new SingleCFWavefunction <SpinOrbital>( ToSparseMultiCFWavefunction(reference).Excitations.Single().Key.ToIndices() ); return(outputState); }
/// <summary> /// Set a term of the wavefunction. /// </summary> /// <param name="term">Index to term to set amplitude of.</param> /// <param name="amplitude">Relative amplitude of term.</param> public void Set(IndexOrderedSequence <TIndex> term, Complex amplitude) { Excitations[term] = amplitude * (double)term.Coefficient; term.Coefficient = 1; }
/// <summary> /// Translate initial state specified by a <see cref="FermionTerm"/> acting on /// the vacuum state to a format consumable by Q# /// </summary> /// <param name="term">Sequence of creation operations acting on vacuum state.</param> /// <param name="complexCoeff">coefficient of term.</param> /// <param name="checkAnnihilation">If true, throws an exception if annihilation operators act on the vacuum state.</param> /// <returns>Q# description of initial state</returns> public static JordanWignerInputState InitialStatePrep(System.Numerics.Complex complexCoeff, IndexOrderedSequence <int> term, bool checkAnnihilation) { // Place input in canonical order. var termCanonical = term; if (checkAnnihilation) { // There must be no annihilation operators the presence of // any of the in normal order destroys the vacuum state. if (termCanonical.Sequence.Where(o => o.Type == RaisingLowering.d).Count() > 0) { throw new System.ArgumentException("Initial state cannot contain annihilation operators acting on the vacuum state."); } } // There must be no duplicate creation operators. if (termCanonical.Sequence.Distinct().Count() != termCanonical.Sequence.Count()) { throw new System.ArgumentException("Initial state cannot contain duplicate creation operators with the same index."); } // Rescale input complex coefficient by fermion term coefficient, // including any sign changes. (double, double)complexOut = (complexCoeff.Real, complexCoeff.Imaginary); QArray <Int64> indices = new QArray <Int64>(term.Sequence.Select(o => (Int64)o.Index)); var state = new JordanWignerInputState((complexOut, indices)); return(state); }