// 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);
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #4
0
 /// <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);
        }