public void UniqueIndicesTests(Int64 norbitals, Int64[] idx, Int64 uniqueIndices)
        {
            var spinOrbitals = idx.Select(o => new SpinOrbital(norbitals, o));
            var coefficient  = 1.0;
            var fermionTerm  = new FermionTerm(spinOrbitals, coefficient);

            Assert.True(fermionTerm.GetUniqueIndices() == uniqueIndices);
        }
        public void CreateFermionTermTest(bool pass, Int64[] orbitalIdx, Spin[] spinIdx, Double sign)
        {
            var coeff       = 1.0;
            var spinOrbital = orbitalIdx.Zip(spinIdx, (a, b) => new SpinOrbital(a, b));
            var tmp         = new FermionTerm(spinOrbital, coeff);

            Assert.True(tmp.IsInCanonicalOrder());
            Assert.True(tmp.coeff == sign);
        }
        public void ToCanonicalOrderTest(bool pass, Int64 nOrbitals, IEnumerable <Int64> ca, IEnumerable <Int64> idx)
        {
            var tmp      = new FermionTerm(nOrbitals, ca.ToArray(), idx.ToArray(), 1.0);
            var newTerms = tmp.ToCanonicalOrder();

            foreach (var newTerm in newTerms)
            {
                Assert.True(newTerm.IsInCanonicalOrder());
            }
        }
Exemplo n.º 4
0
        // Extracts the JW terms from the Hamiltonian
        // Input: Individual fermionTerm, type of the term, coefficient
        // Output: String describing the term information

        public static String ToJordanWignerPauliTerms(
            FermionTerm fermionTerm,
            TermType.Fermion termType,
            double coeff)
        {
            // Console.WriteLine(fermionTerm.ToString());
            var seq           = fermionTerm.Sequence.Select(o => o.Index).ToArray();
            var string_output = $"{termType.ToString()} | {String.Join(",", seq.Select(p => p.ToString()).ToArray())} | {string.Join(",", fermionTerm.Sequence)} | {coeff.ToString()}";

            // Console.WriteLine(string_output);
            return(string_output);
        }
        public void IsInCanonicalOrderTest(bool pass, Int64 nOrbitals, Int64[] ca, Int64[] idx)
        {
            var tmp = new FermionTerm(nOrbitals, ca, idx, 1.0);

            if (pass)
            {
                Assert.True(tmp.IsInCanonicalOrder());
            }
            else
            {
                Assert.False(tmp.IsInCanonicalOrder());
            }
        }
        public void GetFermionTermTypeTests(Int64 norbitals, Int64[] idx, Int64 type)
        {
            var tmp = new FermionTermType[] { IdentityTermType,
                                              PPTermType,
                                              PQTermType,
                                              PQQPTermType,
                                              PQQRTermType,
                                              PQRSTermType };


            var spinOrbitals    = idx.Select(o => new SpinOrbital(norbitals, o)).ToArray();
            var coefficient     = 1.0;
            var fermionTerm     = new FermionTerm(spinOrbitals, coefficient);
            var fermionTermType = fermionTerm.GetFermionTermType();

            Assert.True(fermionTermType == tmp[type]);
        }
Exemplo n.º 7
0
        // Produce a format of fermions to be used in the typical Q# pathway
        // Input: JObject containing the JSON
        // Output: Fermion data to be used immediately in the pipeline
        public static (FermionTerm, TermType.Fermion, double) ConvertToFermionFormat(
            JToken interaction
            )
        {
            // extract only the fermionic interactions
            string type  = (string)interaction["type"];
            var    angle = (double)interaction["angle"];
            var    p     = -1;
            var    q     = -1;
            var    r     = -1;
            var    s     = -1;

            TermType.Fermion termType;

            // create the new ladder sequence
            var ladderSpins = interaction["targets"].ToObject <int[]>();
            var pqrsSorted  = ladderSpins.ToList();

            pqrsSorted.Sort();

            switch (type)
            {
            case "Identity":
                termType    = TermType.Fermion.Identity;
                ladderSpins = new int[0];
                break;

            case "PP":
                termType = TermType.Fermion.PP;
                break;

            case "PQ":
                termType = TermType.Fermion.PQ;
                break;

            case "PQQP":
                termType       = TermType.Fermion.PQQP;
                p              = pqrsSorted[0];
                q              = pqrsSorted[2];
                ladderSpins[0] = p;
                ladderSpins[1] = q;
                ladderSpins[2] = q;
                ladderSpins[3] = p;
                break;

            case "PQQR":
                termType = TermType.Fermion.PQQR;
                // Console.WriteLine("[{0}]", string.Join(", ", ladderSpins));
                // Console.WriteLine($"{angle}");

                // Console.WriteLine("-------------------");
                // Console.WriteLine($"PQQR values: {ladderSpins[0]}, {ladderSpins[1]}, {ladderSpins[2]}, {ladderSpins[3]} | {angle}");

                p = -1;
                q = -1;
                r = -1;

                // PROBLEM: if you swap the ladderspins, the internal data format will try to move it
                // into a way it understands. HOWEVER, this causes two problems:
                // - the term has been reordered without your knowledge, into a form you're not sure of
                // - the coefficient induced by this swap is not recorded BY THE ACTUAL TRANSFORMATION
                // so, I avoided the more rigorous transformation by simply avoiding our main problem,
                // where p > q. This code checks for that and swaps p,q if so.
                // it also assumes we're in some combo of qprq or pqrq
                if (ladderSpins[0] == ladderSpins[3])
                {
                    // QPRQ
                    if (ladderSpins[1] > ladderSpins[2])
                    {
                        var temp = ladderSpins[1];
                        ladderSpins[1] = ladderSpins[2];
                        ladderSpins[2] = temp;
                    }
                }
                else if (ladderSpins[1] == ladderSpins[3])
                {
                    // PQRQ
                    if (ladderSpins[0] > ladderSpins[2])
                    {
                        var temp = ladderSpins[2];
                        ladderSpins[2] = ladderSpins[0];
                        ladderSpins[0] = temp;
                    }
                }
                else if (ladderSpins[1] == ladderSpins[2])
                {
                    // PQQR
                    if (ladderSpins[0] > ladderSpins[3])
                    {
                        var temp = ladderSpins[3];
                        ladderSpins[3] = ladderSpins[0];
                        ladderSpins[0] = temp;
                    }
                }

                // if (ladderSpins[0] == ladderSpins[1])
                // {
                //     // we are in QQPR, need to see if P, R should be switched
                //     p = ladderSpins[2];
                //     q = ladderSpins[0];
                //     r = ladderSpins[3];
                //     Console.WriteLine("---------QQPR");
                //     ladderSpins[0] = p;
                //     ladderSpins[1] = q;
                //     ladderSpins[2] = q;
                //     ladderSpins[3] = r;
                // } else if (ladderSpins[0] == ladderSpins[2])
                // {
                //     // we are in QPQR
                //     p = ladderSpins[1];
                //     q = ladderSpins[0];
                //     r = ladderSpins[3];
                //     angle = angle * -1.0; // FLAG
                //     Console.WriteLine("---------QPQR");
                // } else if (ladderSpins[0] == ladderSpins[3])
                // {
                //     // we are in QPRQ
                //     p = ladderSpins[1];
                //     q = ladderSpins[0];
                //     r = ladderSpins[2];
                //     Console.WriteLine("---------QPRQ");
                // }
                // else
                // if (ladderSpins[1] == ladderSpins[2])
                // {
                //     // we are in PQQR
                //     p = ladderSpins[0];
                //     q = ladderSpins[1];
                //     r = ladderSpins[3];
                //     Console.WriteLine("---------PQQR");
                // }
                // else
                // if (ladderSpins[1] == ladderSpins[3])
                // {
                //     // we are in pqrq
                //     p = ladderSpins[0];
                //     q = ladderSpins[1];
                //     r = ladderSpins[2];
                //     angle = angle * -1.0;
                //     Console.WriteLine("---------PQRQ");
                //     ladderSpins[0] = p;
                //     ladderSpins[1] = q;
                //     ladderSpins[2] = q;
                //     ladderSpins[3] = r;
                // }
                // else if (ladderSpins[2] == ladderSpins[3])
                // {
                //     // we are in prqq
                //     p = ladderSpins[0];
                //     q = ladderSpins[2];
                //     r = ladderSpins[1];
                //     Console.WriteLine("---------PRQQ");
                //     ladderSpins[0] = p;
                //     ladderSpins[1] = q;
                //     ladderSpins[2] = q;
                //     ladderSpins[3] = r;
                // }
                // else
                // {
                //     Console.WriteLine("Unknown PQQR Permutation");
                // }

                // // rename the terms now
                // if (p < r)
                // {
                //     ladderSpins[0] = p;
                //     ladderSpins[3] = r;
                // }
                // else
                // {
                //     ladderSpins[0] = r;
                //     ladderSpins[3] = p;
                //     angle = angle * -1.0;
                // }

                // // Console.WriteLine(angle);

                // ladderSpins[1] = q;
                // ladderSpins[2] = q;
                // Console.WriteLine($"PQQR values: {ladderSpins[0]}, {ladderSpins[1]}, {ladderSpins[2]}, {ladderSpins[3]} | {angle}");
                break;

            case "PQRS":
                termType = TermType.Fermion.PQRS;

                // find the new PQRS (p'q'r's') and their corresponding original indices
                p = pqrsSorted[0];
                q = pqrsSorted[1];
                r = pqrsSorted[2];
                s = pqrsSorted[3];

                var pIndex = Array.IndexOf(ladderSpins, p);
                var qIndex = Array.IndexOf(ladderSpins, q);
                var rIndex = Array.IndexOf(ladderSpins, r);
                var sIndex = Array.IndexOf(ladderSpins, s);

                // // if the index is 0, 1, then that coefficient is creation
                // // if the index is 2, 3, then that coefficient is annihilation

                // Console.WriteLine($"{pIndex}, {qIndex}, {rIndex}, {sIndex}");
                // Console.WriteLine($"values: {p}, {q}, {r}, {s}");
                // Console.WriteLine($"values: {ladderSpins[0]}, {ladderSpins[1]}, {ladderSpins[2]}, {ladderSpins[3]} | {angle}");

                // set the leading sign coefficients
                var zSign = 0.0;
                if ((qIndex + sIndex == 1) || (qIndex + sIndex == 5))
                {
                    // we have two annihilation / creation
                    zSign = -1.0;
                }
                else
                {
                    // we could have pr (2) to qs (4)
                    zSign = 1.0;
                }
                int[] orderingArray = { pIndex, qIndex, rIndex, sIndex };
                var   swapCoeff     = RecursivelyIdentifyDeterminant(orderingArray.ToArray());

                // identify which Q# pipeline to use
                if ((pIndex + qIndex == 1) || (pIndex + qIndex == 5))
                {
                    // XXYY / YYXX are negative; pqsr pipeline
                    ladderSpins[0] = p;
                    ladderSpins[1] = q;
                    ladderSpins[2] = s;
                    ladderSpins[3] = r;
                }
                else if ((qIndex + sIndex == 1) || (qIndex + sIndex == 5))
                {
                    // XYXY / YXYX are negative; prsq pipeline
                    ladderSpins[0] = p;
                    ladderSpins[1] = r;
                    ladderSpins[2] = s;
                    ladderSpins[3] = q;
                }
                else if ((qIndex + rIndex == 1) || (qIndex + rIndex == 5))
                {
                    // XYYX / YXXY are negative; psrq pipeline
                    ladderSpins[0] = p;
                    ladderSpins[1] = s;
                    ladderSpins[2] = r;
                    ladderSpins[3] = q;
                }
                else
                {
                    throw new System.NotImplementedException();
                }

                // apply final corrections
                // Console.WriteLine($"z: {zSign}, {swapCoeff}, {angle}");
                angle = -1.0 * zSign * swapCoeff * angle;

                // Console.WriteLine($"values: {ladderSpins[0]}, {ladderSpins[1]}, {ladderSpins[2]}, {ladderSpins[3]} | {angle}");
                break;

            default:
                throw new System.NotImplementedException();
            }

            var         ladderSeq     = ladderSpins.ToLadderSequence();
            FermionTerm convertedTerm = new FermionTerm(ladderSeq);

            // Console.WriteLine($"{termType} | {convertedTerm} | {angle}");
            // // Console.WriteLine($"{convertedTerm.Sequence}");
            // Console.WriteLine("[{0}]", string.Join(", ", convertedTerm.Sequence));
            // Console.WriteLine(convertedTerm.Coefficient);

            // IMPORTANT: MAKE SURE TO KEEP THE convertedTerm.Coefficient, as it corrects for internal manipulation
            return(convertedTerm, termType, angle *convertedTerm.Coefficient);
        }