Skip to content

Commit

Permalink
added GetPauliString overload
Browse files Browse the repository at this point in the history
whereby users can specify both the target qubits and the number of final Paulis simultaneously. This enables users to (e.g.) specify an 8x8 matrix encoding the Paulis upon qubits {2,4,7}, and request output strings acting on 20 qubits.
  • Loading branch information
TysonRayJones committed Apr 1, 2024
1 parent 286802e commit 82ef4a3
Show file tree
Hide file tree
Showing 3 changed files with 2,159 additions and 2,828 deletions.
52 changes: 34 additions & 18 deletions Link/QuESTlink.m
Original file line number Diff line number Diff line change
Expand Up @@ -430,9 +430,10 @@ The sum of the expected values of the (potentially unnormalised) state-vectors o
GetPauliString[index] returns the basis Pauli string corresponding to the given index, where the returned Pauli operator targeting 0 is informed by the least significant bit(s) of the index.
GetPauliString[digits] specifies the Pauli product via the base-4 digits of its index, where the rightmost digit is the least significant.
GetPauliString[address] opens or downloads the file at address (a string, of a file location or URL), and interprets it as a list of coefficients and Pauli codes. Each line of the file is assumed a separate Pauli tensor with format {coeff code1 code2 ... codeN} (excluding braces) where the codes are in {0,1,2,3} (indicating a I, X, Y, Z), for an N-qubit Pauli string, and are given in order of increasing significance (zero qubit left). Each line must have N+1 terms, which includes the initial real decimal coefficient. For an example, see \"https://qtechtheory.org/hamil_6qbLiH.txt\".
GetPauliString[..., numQubits] overrides the inferred number of qubits, introducing additional Id operators upon un-targeted qubits (unless explicitly removed with \"RemoveIds\"->False).
GetPauliString[..., {targets}] specifies a list of qubits which the returned Pauli string should target (in the given order), instead of the default targets {0, 1, 2, ...}.
GetPauliString accepts optional argument \"RemoveIds\" -> True or False (default Automatic) which when True, retains otherwise removed Id operators so that the returned string has an explicit Pauli operator acting upon every qubit."
GetPauliString[..., numPaulis] forces the output to contain the given number of Pauli operators, introducing additional Id operators upon un-targeted qubits (unless explicitly removed with \"RemoveIds\"->True).
GetPauliString[..., {targets}] specifies a list of qubits which the returned Pauli string should target (in the given order), instead of the default targets {0, 1, 2, ...}. Targeted Ids are retained.
GetPauliString[..., {targets}, numPaulis] (in either order) specifies the targets, and thereafter pads the output with Ids to achieve the specified number of Pauli operators.
GetPauliString accepts optional argument \"RemoveIds\" -> True or False (default Automatic) which when True, retains otherwise removed Id operators."
GetPauliString::error = "`1`"

GetPauliStringRetargeted::usage = "GetPauliStringRetargeted[string, rules] returns the given Pauli string but with its target qubits modified as per the given rules. The rules can be anything accepted by ReplaceAll.
Expand Down Expand Up @@ -1562,30 +1563,45 @@ The probability of the forced measurement outcome (as if it were hypothetically
getPauliStringFromDigits[{digits}, numPaulis, shouldRemovePauliStringIds[numPaulis, opts]]]

(* optionally remap the returned Pauli string to a custom set of targets *)
GetPauliString[obj:(_String|_?MatrixQ|_Integer|{__Integer}), OrderlessPatternSequence[targs:{___Integer}, nQb:optionalNumQbPatt], opts___] :=
GetPauliString[obj:(_String|_?MatrixQ|_Integer|{__Integer}), OrderlessPatternSequence[targs:{___Integer}, numPaulis:optionalNumQbPatt], opts:OptionsPattern[]] :=
Module[
{pauliStr, numQbInStr, map},
{pauliStr, map, retargStr, numQbInStr, remIds, untargs, padIds},

(* validate options, and choose whether to remove Ids *)
remIds = Check[OptionValue @ "RemoveIds", Return @ $Failed] /. Automatic -> False;

(* partially validate targs *)
If[ Not @ AllTrue[targs, NonNegative] || Not @ DuplicateFreeQ[targs],
Message[GetPauliString::error, "The list of target qubits must be non-negative and unique."];
Return @ $Failed
];
Message[GetPauliString::error, "Target qubits must be list of unique, non-negative and integers."];
Return @ $Failed];

(* produce Pauli string with indices from 0, every term is Length[targs]-operators. *)
pauliStr = Check[GetPauliString[obj, Length[targs], "RemoveIds"->False], Return @ $Failed];

(* produce Pauli string with indices from 0, possibly enlarged by nQb *)
pauliStr = Check[GetPauliString[obj, nQb, opts], Return @ $Failed];
numQbInStr = getNumQubitsInPauliString[pauliStr];
(* modify the Pauli string to the users target qubits; may contain Ids, but is NOT necessarily full-length. E.g. X7 Id5 Z3 *)
map = MapThread[Rule, {Range @ Length @ targs -1, targs}];
retargStr = GetPauliStringRetargeted[pauliStr, map];

(* require user gave precisely the right number of targets *)
If[ Length[targs] =!= numQbInStr,
(* validate optional forced numPaulis equals or exceeds num in retargStr *)
numQbInStr = 1 + Max[targs];
If[Length@{numPaulis}>0 && numPaulis < numQbInStr,
Message[GetPauliString::error,
"A different number of target qubits was given (" <> ToString@Length@targs <>
") than exists in the Pauli string (" <> ToString@numQbInStr <> ")."];
"The requested number of Pauli operators (" <> ToString[numPaulis] <> ") cannot be fewer than " <>
"the number in the targeted Pauli string (" <> ToString[numQbInStr] <> ")."];
Return @ $Failed];

(* modify the Pauli string to the users target qubits *)
map = MapThread[Rule, {Range[numQbInStr]-1, targs}];
GetPauliStringRetargeted[pauliStr, map]
(* if numPaulis specified, add additional Ids at all untargeted *)
If[Length@{numPaulis}>0 && (numPaulis>Length[targs]) && Not[remIds],
untargs = Complement[Range@numPaulis-1, targs];
padIds = Product[Subscript[Id,t], {t,untargs}];
retargStr = Expand[padIds * retargStr, pauliOpPatt]];

(* optionally remove Ids, but keep standalone Id terms *)
If[remIds, retargStr = retargStr //.
Verbatim[Times][OrderlessPatternSequence[c___, p:pauliOpPatt, Subscript[Id,_]]] :> c p];

(* return *)
retargStr
]

GetPauliString[___] := invalidArgError[GetPauliString]
Expand Down

0 comments on commit 82ef4a3

Please sign in to comment.