Ejemplo n.º 1
0
 /// <summary>
 /// Concatenates two Fermion terms.
 /// </summary>
 /// <param name="left">Left Fermion term `x`</param>
 /// <param name="right">Right Fermion term  `y`</param>
 /// <returns>Returns new <see cref="FermionTerm"/> `xy` where coefficients and
 /// Fermion operators are multipled together.</returns>
 public FermionTerm Concatenate(FermionTerm left, FermionTerm right)
 {
     return(new FermionTerm(
                left.CreationAnnihilationIndices.Concat(right.CreationAnnihilationIndices).ToArray(),
                left.SpinOrbitalIndices.Concat(right.SpinOrbitalIndices).ToArray(),
                left.coeff * right.coeff
                ));
 }
 /// <summary>
 /// Method for adding a <see cref="FermionTerm"/> of type <see cref="FermionTermType"/>
 /// to a <see cref="FermionHamiltonian"/>.
 /// </summary>
 /// <param name="termType">Type of fermion term to be added.</param>
 /// <param name="term">Fermion term to be added.</param>
 public void AddFermionTerm(FermionTermType termType, FermionTerm term)
 {
     if (!FermionTerms.ContainsKey(termType))
     {
         FermionTerms.Add(termType, new List <FermionTerm>());
     }
     FermionTerms[termType].Add(term);
 }
        /// <summary>
        /// Method for adding a <see cref="FermionTerm"/> of type <see cref="FermionTermType"/>
        /// to a <see cref="FermionHamiltonian"/>.
        /// </summary>
        /// <param name="termType">Type of fermion term to be added.</param>
        /// <param name="fermionIdxArray">indices of Fermion term to be added.</param>
        public void AddFermionTerm(FermionTermType termType, Int64[] fermionIdxArray, Double coefficient)
        {
            if (!FermionTerms.ContainsKey(termType))
            {
                FermionTerms.Add(termType, new List <FermionTerm>());
            }
            var conjugateArray = termType.GetConjugateSequence();
            var fermionTerm    = new FermionTerm(
                nOrbitals: NOrbitals,
                caArray: conjugateArray,
                fermionIdxArray: fermionIdxArray,
                coeffIn: coefficient
                );

            AddFermionTerm(termType, fermionTerm);
        }
        /// <summary>
        /// This approximates the Hamiltonian ground state by a greedy algorithm
        /// that minimizes only the PP term energies. If there are no PP terms,
        /// states will be occupied in lexicographic order.
        /// </summary>
        /// <returns>
        /// Greedy trial state for minimizing Hamiltonian diagonal one-electron energy.
        /// </returns>
        public InputState GreedyStatePreparation()
        {
            var label = "Greedy";

            (Double, Double)coeff = (1.0, 0.0);
            var conjugate = Enumerable.Range(0, (int)NElectrons).Select(o => (Int64)1).ToArray();

            if (FermionTerms.ContainsKey(PPTermType))
            {
                var hPPTermSortedByCoeff = FermionTerms[PPTermType];
                var spinOrbitals         = hPPTermSortedByCoeff.OrderBy(o => o.coeff).Select(o => o.SpinOrbitalIndices.First()).Take((int)NElectrons).ToArray();
                var fermionTerm          = new FermionTerm(conjugate, spinOrbitals, 1.0);
                fermionTerm.ToSpinOrbitalCanonicalOrder();
                fermionTerm.coeff = 1.0;

                var superposition = new((Double, Double), FermionTerm)[] {
Ejemplo n.º 5
0
 public bool Equals(FermionTerm x)
 {
     if (ReferenceEquals(null, x))
     {
         return(false);
     }
     else if (ReferenceEquals(this, x))
     {
         return(true);
     }
     else if (GetType() != x.GetType())
     {
         return(false);
     }
     else
     {
         return(this == x);
     }
 }
 /// <summary>
 /// Method for adding a <see cref="FermionTerm"/>
 /// to a <see cref="FermionHamiltonian"/>.
 /// </summary>
 /// <param name="term">Fermion term to be added.</param>
 public void AddFermionTerm(FermionTerm term)
 {
     AddFermionTerm(term.GetFermionTermType(), term);
 }
Ejemplo n.º 7
0
        /// <summary>
        ///  Converts a <c>FermionTerm</c> to canonical order. This generates
        ///  new terms and modifies the coefficient as needed.
        /// </summary>
        public List <FermionTerm> ToCanonicalOrder()
        {
            // Step 1: anti-commute creation to the left.
            // Step 2: sort to canonical order

            var TmpTerms = new Stack <FermionTerm>();
            var NewTerms = new List <FermionTerm>();

            TmpTerms.Push(this);

            // Anti-commutes creation and annihilation operators to canonical order
            // and creates new terms if spin-orbital indices match.
            while (TmpTerms.Any())
            {
                var tmpTerm = TmpTerms.Pop();
                if (tmpTerm.IsInNormalOrder())
                {
                    NewTerms.Add(tmpTerm);
                }
                else
                {
                    // Anticommute creation and annihilation operators.
                    for (int i = 0; i < tmpTerm.CreationAnnihilationIndices.Count() - 1; i++)
                    {
                        if (tmpTerm.CreationAnnihilationIndices.ElementAt(i) < tmpTerm.CreationAnnihilationIndices.ElementAt(i + 1))
                        {
                            var antiCommutedCreationAnnihilationIndices = tmpTerm.CreationAnnihilationIndices.ToList();
                            var antiCommutedSpinOrbitalIndices          = tmpTerm.SpinOrbitalIndices.ToList();
                            // Swap the two elements and flip sign of the coefficient.
                            antiCommutedCreationAnnihilationIndices[i + 1] = tmpTerm.CreationAnnihilationIndices.ElementAt(i);
                            antiCommutedCreationAnnihilationIndices[i]     = tmpTerm.CreationAnnihilationIndices.ElementAt(i + 1);
                            antiCommutedSpinOrbitalIndices[i + 1]          = tmpTerm.SpinOrbitalIndices.ElementAt(i);
                            antiCommutedSpinOrbitalIndices[i] = tmpTerm.SpinOrbitalIndices.ElementAt(i + 1);

                            var antiCommutedTerm = new FermionTerm(antiCommutedCreationAnnihilationIndices.ToArray(), antiCommutedSpinOrbitalIndices.ToArray(), -1.0 * tmpTerm.coeff);

                            TmpTerms.Push(antiCommutedTerm);

                            // If the two elements have the same spin orbital index, generate a new term.
                            if (antiCommutedSpinOrbitalIndices.ElementAt(i).Equals(antiCommutedSpinOrbitalIndices.ElementAt(i + 1)))
                            {
                                var newCreationAnnihilationIndices = antiCommutedCreationAnnihilationIndices.ToList();
                                var newSpinOrbitalIndices          = antiCommutedSpinOrbitalIndices.ToList();
                                newCreationAnnihilationIndices.RemoveRange(i, 2);
                                newSpinOrbitalIndices.RemoveRange(i, 2);

                                var newTerm = new FermionTerm(newCreationAnnihilationIndices.ToArray(), newSpinOrbitalIndices.ToArray(), tmpTerm.coeff);

                                TmpTerms.Push(newTerm);
                            }
                            break;
                        }
                    }
                }
            }

            // Anti-commutes spin-orbital indices to canonical order
            // and changes the sign of the coefficient as necessay.
            for (int idx = 0; idx < NewTerms.Count(); idx++)
            {
                var tmp = NewTerms[idx];
                tmp.ToSpinOrbitalCanonicalOrder();
                NewTerms[idx] = tmp;
            }
            return(NewTerms);
        }