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()); } }
// 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]); }
// 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); }