Skip to content

Commit 2b4623c

Browse files
added setReportedPauli(Chars|StrStyle)
1 parent 3279c45 commit 2b4623c

File tree

8 files changed

+174
-8
lines changed

8 files changed

+174
-8
lines changed

quest/include/debug.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,38 @@ void setMaxNumReportedSigFigs(int numSigFigs);
121121
void setNumReportedNewlines(int numNewlines);
122122

123123

124+
/**
125+
* @notdoced
126+
* @nottested
127+
* @myexample
128+
* ```
129+
PauliStr str = getInlinePauliStr("XYZ", {0,10,20});
130+
reportPauliStr(str);
131+
132+
setReportedPauliChars(".xyz");
133+
reportPauliStr(str);
134+
* ```
135+
*/
136+
void setReportedPauliChars(const char* paulis);
137+
138+
139+
/**
140+
* @notdoced
141+
* @nottested
142+
* @myexample
143+
* ```
144+
PauliStr str = getInlinePauliStr("XYZ", {0,10,20});
145+
146+
setReportedPauliStrStyle(0);
147+
reportPauliStr(str);
148+
149+
setReportedPauliStrStyle(1);
150+
reportPauliStr(str);
151+
* ```
152+
*/
153+
void setReportedPauliStrStyle(int style);
154+
155+
124156
/** @} */
125157

126158

quest/src/api/debug.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,22 @@ void setNumReportedNewlines(int numNewlines) {
155155
}
156156

157157

158+
void setReportedPauliChars(const char* paulis) {
159+
validate_envIsInit(__func__);
160+
validate_numPauliChars(paulis, __func__);
161+
162+
printer_setPauliChars(paulis);
163+
}
164+
165+
166+
void setReportedPauliStrStyle(int flag) {
167+
validate_envIsInit(__func__);
168+
validate_reportedPauliStrStyleFlag(flag, __func__);
169+
170+
printer_setPauliStrFormat(flag);
171+
}
172+
173+
158174

159175
/*
160176
* GPU CACHE

quest/src/api/paulis.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,8 @@ PauliStr getPauliStr(int* paulis, int* indices, int numPaulis) {
327327
// validation ensures never causes stack overflow
328328
char pauliChars[MAX_NUM_PAULIS_PER_STR + 1]; // +1 for null-terminal
329329

330-
// made a char array from the pauli codes
330+
// make a char array from the pauli codes, using an arbitrary
331+
// choice of the Pauli characters accepted by the API (like IXYZ)
331332
for (int i=0; i<numPaulis; i++)
332333
pauliChars[i] = "IXYZ"[paulis[i]];
333334

quest/src/core/printer.cpp

Lines changed: 92 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ const int SET_SPACE_BETWEEN_KET_AND_RANK = 2;
6363
// must be kept as single char; use numbers above to change spacing
6464
const char TABLE_SPACE_CHAR = '.';
6565
const char MATRIX_SPACE_CHAR = ' ';
66+
const char PAULI_SPACE_CHAR = ' ';
6667

6768
// should not contain newline
6869
const string LABEL_SUFFIX = ":";
@@ -137,6 +138,32 @@ int printer_getNumTrailingNewlines() {
137138
}
138139

139140

141+
// user specified characters to represent Pauli operators
142+
143+
string global_pauliChars = "IXYZ";
144+
145+
void printer_setPauliChars(string newChars) {
146+
147+
global_pauliChars = newChars;
148+
}
149+
150+
151+
// user specified Pauli string format
152+
153+
int global_pauliStrFormatFlag = 0;
154+
155+
void printer_setPauliStrFormat(int flag) {
156+
157+
/// @todo
158+
/// this could be changed to an enum, even though the
159+
/// API will likely always receive an int (for C and
160+
/// C++ agnosticism and simplicity - I hate polluting
161+
/// an API with custom types and constants!).
162+
163+
global_pauliStrFormatFlag = flag;
164+
}
165+
166+
140167

141168
/*
142169
* TYPE NAME STRINGS
@@ -1236,27 +1263,85 @@ extern int paulis_getIndOfLefmostNonIdentityPauli(PauliStr str);
12361263
extern int paulis_getIndOfLefmostNonIdentityPauli(PauliStr* strings, qindex numStrings);
12371264

12381265

1239-
string getPauliStrAsString(PauliStr str, int maxNumQubits) {
1266+
string getPauliStrAsAllQubitsString(PauliStr str, int numPaulis) {
12401267

1241-
string labels = "IXYZ";
1268+
// avoid repeated allocations in below string concatenation
1269+
string out = "";
1270+
out.reserve(numPaulis);
12421271

12431272
// ugly but adequate - like me (call me)
1244-
string out = "";
1245-
for (int i=maxNumQubits-1; i>=0; i--)
1246-
out += labels[paulis_getPauliAt(str, i)];
1273+
for (int i=numPaulis-1; i>=0; i--) {
1274+
int code = paulis_getPauliAt(str, i); // 0123
1275+
out += global_pauliChars[code]; // IXYZ unless user-overriden
1276+
}
12471277

12481278
return out;
12491279
}
12501280

12511281

1282+
string getPauliStrAsIndexString(PauliStr str, int numPaulis) {
1283+
1284+
string out = "";
1285+
1286+
// prematurely optimise (hehe) by avoiding repeated allocations
1287+
// induced by below string concatenation, since we can bound the
1288+
// string length; each Pauli is 1 char, each index is max 2 digits
1289+
// (<64) and each inter-Pauli space is 1 char, so <=4 chars per Pauli.
1290+
int maxLen = numPaulis * 4; // <= 256 always
1291+
out.reserve(maxLen);
1292+
1293+
for (int i=0; i<numPaulis; i++) {
1294+
int code = paulis_getPauliAt(str, i);
1295+
1296+
// don't report identities
1297+
if (code == 0)
1298+
continue;
1299+
1300+
// e.g. X12
1301+
out += global_pauliChars[code] + toStr(i) + PAULI_SPACE_CHAR;
1302+
}
1303+
1304+
// out includes a trailing PAULI_SPACE_CHAR which is fine,
1305+
// since nothing else is ever post-printed on the same line
1306+
return out;
1307+
}
1308+
1309+
1310+
string getPauliStrAsString(PauliStr str, int numPauliChars=0) {
1311+
1312+
// numPauliChars (only used by all-qubits reporting format)
1313+
// allows the caller to pad the printed PauliStr with left I,
1314+
// useful when reporting a truncated PauliStrSum to ensure
1315+
// the top and bottom partitions are aligned and equal width.
1316+
// When not passed, it defaults to minimum padding
1317+
if (numPauliChars == 0)
1318+
numPauliChars = 1 + paulis_getIndOfLefmostNonIdentityPauli(str);
1319+
1320+
/// @todo
1321+
/// to be absolutely pedantic/defensively-designed, we should
1322+
/// assert numPauliChars >= 1+paulis_getIndOfLefmostNonIdentityPauli
1323+
/// to ensure a bug never occludes a PauliStr. Very low priority!
1324+
1325+
switch(global_pauliStrFormatFlag) {
1326+
case 0: return getPauliStrAsAllQubitsString(str, numPauliChars);
1327+
case 1: return getPauliStrAsIndexString(str, numPauliChars);
1328+
}
1329+
1330+
/// @todo
1331+
/// to be defensively-designed, we should throw a runtime error
1332+
/// here because global_pauliStrFormatFlag was mutilated. This is
1333+
/// a very low priority; so we just return a suspicious string!
1334+
return "(PauliStr stringifying failed - please alert the QuEST devs)";
1335+
}
1336+
1337+
12521338
void print_elemsWithoutNewline(PauliStr str, string indent) {
12531339

12541340
// only root node ever prints
12551341
if (!comm_isRootNode())
12561342
return;
12571343

1258-
int numPaulis = 1 + paulis_getIndOfLefmostNonIdentityPauli(str);
1259-
cout << indent << getPauliStrAsString(str, numPaulis);
1344+
cout << indent << getPauliStrAsString(str);
12601345

12611346
// beware that NO trailing newlines are printed so subsequent
12621347
// calls (without calling print_newlines()) will run-on

quest/src/core/printer.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ void printer_setNumTrailingNewlines(int numNewlines);
4242

4343
int printer_getNumTrailingNewlines();
4444

45+
void printer_setPauliChars(string newChars);
46+
47+
void printer_setPauliStrFormat(int flag);
48+
4549

4650

4751
/*

quest/src/core/validation.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ namespace report {
134134
string INSUFFICIENT_NUM_REPORTED_NEWLINES =
135135
"The number of trailing newlines (set by setNumReportedNewlines()) is zero which is not permitted when calling multi-line reporters.";
136136

137+
string INVALID_NUM_NEW_PAULI_CHARS =
138+
"Given an invalid number of Pauli characters. Must specify precisely four to respectively replace IXYZ.";
139+
140+
string INVALID_REPORTED_PAULI_STR_STYLE_FLAG =
141+
"Given an unrecognised style flag (${FLAG}). Legal flags are 0 and 1.";
142+
137143

138144
/*
139145
* QUREG CREATION
@@ -1433,6 +1439,21 @@ void validate_numReportedNewlinesAboveZero(const char* caller) {
14331439
assertThat(printer_getNumTrailingNewlines() > 0, report::INSUFFICIENT_NUM_REPORTED_NEWLINES, caller);
14341440
}
14351441

1442+
void validate_numPauliChars(const char* paulis, const char* caller) {
1443+
1444+
// check position of terminal char, else default to numChars=5 (illegal)
1445+
int numChars = 0;
1446+
for (int i=0; i<5 && paulis[i] != '\0'; i++)
1447+
numChars++;
1448+
1449+
assertThat(numChars==4, report::INVALID_NUM_NEW_PAULI_CHARS, caller);
1450+
}
1451+
1452+
void validate_reportedPauliStrStyleFlag(int flag, const char* caller) {
1453+
1454+
assertThat(flag==0 || flag==1, report::INVALID_REPORTED_PAULI_STR_STYLE_FLAG, {{"${FLAG}",flag}}, caller);
1455+
}
1456+
14361457

14371458

14381459
/*

quest/src/core/validation.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ void validate_newNumReportedNewlines(int numNewlines, const char* caller);
103103

104104
void validate_numReportedNewlinesAboveZero(const char* caller);
105105

106+
void validate_numPauliChars(const char* paulis, const char* caller);
107+
108+
void validate_reportedPauliStrStyleFlag(int flag, const char* caller);
109+
106110

107111

108112
/*

tests/unit/debug.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,3 +750,6 @@ void setMaxNumReportedItems(qindex numRows, qindex numCols);
750750

751751
void getEnvironmentString(char str[200]);
752752

753+
void setReportedPauliChars(const char* paulis);
754+
755+
void setReportedPauliStrStyle(int style);

0 commit comments

Comments
 (0)