The Quantum Exact Simulation Toolkit v4.3.0
Loading...
Searching...
No Matches
paulis.h
1/** @file
2 * Definitions of PauliStr and PauliStrSum,
3 * their initialisers, and reporting utilities.
4 *
5 * @author Tyson Jones
6 *
7 * @defgroup paulis Paulis
8 * @ingroup api
9 * @brief Data structures for representing Pauli strings and their weighted sums.
10 * @{
11 */
12
13#ifndef PAULIS_H
14#define PAULIS_H
15
16#include "quest/include/precision.h"
17#include "quest/include/types.h"
18
19// C++ gets string and vector initialiser overloads
20#ifdef __cplusplus
21 #include <string>
22 #include <vector>
23#endif
24
25
26
27/*
28 * unlike some other headers, we here intermix the C and C++-only
29 * signatures, grouping them semantically & by their doc groups
30 */
31
32
33
34/*
35 * PAULI STRUCTS
36 *
37 * which are visible to both C and C++, and don't require demangling.
38 * PauliStr contain only stack primitives, while PauliStrSum
39 * contains dynamic heap pointers. Notice that PauliStr has non-const
40 * members, because users will typically store large collections of
41 * them (like in a PauliStrSum) so we wish to retain copy overwriting.
42 */
43
44
45/**
46 * @defgroup paulis_structs Structs
47 * @brief Data structures for representing tensors and weighted sums of Pauli operators
48 * @{
49 */
50
51
52/// @notyetdoced
53typedef struct {
54
55 // represent Pauli strings as base-4 numerals, split into their
56 // upper and lower halves (as max-bit unsigned integers). This
57 // imposes a strict upperbound on the number of stored Paulis.
58 PAULI_MASK_TYPE lowPaulis;
59 PAULI_MASK_TYPE highPaulis;
60
61} PauliStr;
62
63
64/// @notyetdoced
65typedef struct {
66
67 qindex numTerms;
68
69 // numTerms-sized collection of Pauli strings and their
70 // coefficients, stored in heap memory.
71 PauliStr* strings;
72 qcomp* coeffs;
73
74 // whether the sum constitutes a Hermitian operator (0, 1, or -1 to indicate unknown),
75 // which is lazily evaluated when a function validates Hermiticity them. The flag is
76 // stored in heap so even copies of structs are mutable, but the pointer is immutable;
77 // otherwise, the field of a user's struct could never be modified because of pass-by-copy.
78 int* isApproxHermitian;
79
81
82
83/** @} */
84
85
86
87// we define the remaining doc groups in advance, since their signatures are
88// more naturally grouped in an implementation-specific way below. Note the
89// above structs were not doc'd this way (which would be more consistent)
90// because it inexplicably causes Doxygen to duplicate their section at the
91// top-level under Paulis (rather than under Structs). Bizarre! The order
92// of declaration below will match the order shown in the html doc.
93/**
94 * @defgroup paulis_create Constructors
95 * @brief Functions for creating and initialising Pauli data structures.
96 *
97 * @defgroup paulis_destroy Destructors
98 * @brief Functions for destroying existing Pauli data structures.
99 *
100 * @defgroup paulis_reporters Reporters
101 * @brief Functions for printing Pauli data structures.
102 *
103 * @defgroup paulis_setters Setters
104 * @brief Functions for modifying existing Pauli data structures.
105 */
106
107
108
109/*
110 * PAULI STRING CREATION
111 */
112
113
114// base method is C and C++ compatible
115#ifdef __cplusplus
116extern "C" {
117#endif
118
119 /** @ingroup paulis_create
120 * @notyetdoced
121 *
122 * @see
123 * - reportPauliStr()
124 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) or
125 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
126 */
127 PauliStr getPauliStr(const char* paulis, int* indices, int numPaulis);
128
129#ifdef __cplusplus
130}
131#endif
132
133
134#ifdef __cplusplus
135
136 // C++ users can access the above C method, along with direct overloads
137 // to accept integers (in lieu of chars), natural C++ string types
138 // (like literals), and C++ vector types for brevity. Furthermore, C++
139 // gets an overload which accepts only a string (no additional args)
140 // which is used internally by parsers, and exposed for user-convenience.
141 // note that C++ does NOT get an overload where the pauli codes (integers) are
142 // passed as a vector; this is because integer literal initialiser lists like
143 // {0,3,1} are valid std::string instances, causing overload ambiguity. Blegh!
144
145
146 /** @ingroup paulis_create
147 * @notyetdoced
148 *
149 * @see
150 * - reportPauliStr()
151 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) or
152 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
153 */
154 PauliStr getPauliStr(int* paulis, int* indices, int numPaulis);
155
156
157 /** @ingroup paulis_create
158 * @notyetdoced
159 * @cpponly
160 *
161 * @see
162 * - getPauliStr()
163 * - reportPauliStr()
164 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
165 */
166 PauliStr getPauliStr(std::string paulis, int* indices, int numPaulis);
167
168
169 /** @ingroup paulis_create
170 * @notyetdoced
171 * @cpponly
172 *
173 * @see
174 * - reportPauliStr()
175 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
176 */
177 PauliStr getPauliStr(std::string paulis, std::vector<int> indices);
178
179
180 /** @ingroup paulis_create
181 * @notyetdoced
182 * @cpponly
183 *
184 * @see
185 * - reportPauliStr()
186 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
187 */
188 PauliStr getPauliStr(std::string paulis);
189
190
191 // never needs to be doc'd
192 /// @private
193 /// @neverdoced
194 #define getInlinePauliStr(str, ...) \
195 getPauliStr(str, __VA_ARGS__)
196
197
198#else
199
200 // C supports passing a char array or string literal with a specified number of Paulis,
201 // or an overload accepting ints, achieved using a C11 _Generic. C also gets an inline
202 // macro which exploits the compile-time size of a string literal, and enables array
203 // literals without the C99 inline temporary array syntax; we further give the array
204 // an explici size (instead of just (int[])) to gaurantee it contains at leasts as
205 // many elements as claimed, avoiding seg-faults if the user provides too few indices
206
207
208 /// @ingroup paulis_create
209 /// @private
210 PauliStr _getPauliStrFromInts(int* paulis, int* indices, int numPaulis);
211
212
213 // documented above (identical signatures to C)
214 /// @neverdoced
215 #define getPauliStr(paulis, ...) \
216 _Generic((paulis), \
217 int* : _getPauliStrFromInts, \
218 default : getPauliStr \
219 )(paulis, __VA_ARGS__)
220
221
222 // documented below
223 /// @neverdoced
224 #define getInlinePauliStr(str, ...) \
225 getPauliStr((str), (int[sizeof(str)-1]) __VA_ARGS__, sizeof(str)-1)
226
227 // spoofing above macro as function to doc
228 #if 0
229
230 /** @ingroup paulis_create
231 * @notyetdoced
232 * @macrodoc
233 *
234 * @see
235 * - reportPauliStr()
236 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) and
237 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp)examples
238 */
239 PauliStr getInlinePauliStr(const char* paulis, { list });
240
241 #endif
242
243
244#endif
245
246
247
248/*
249 * PAULI STRING SUM CREATION
250 */
251
252
253// base methods are C and C++ compatible
254#ifdef __cplusplus
255extern "C" {
256#endif
257
258
259 /** @ingroup paulis_create
260 * @notyetdoced
261 *
262 * @see
263 * - reportPauliStrSum()
264 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) or
265 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
266 */
267 PauliStrSum createPauliStrSum(PauliStr* strings, qcomp* coeffs, qindex numTerms);
268
269
270 /** @ingroup paulis_create
271 * @notyetdoced
272 *
273 * @see
274 * - reportPauliStrSum()
275 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) or
276 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
277 */
278 PauliStrSum createInlinePauliStrSum(const char* str);
279
280
281 /** @ingroup paulis_create
282 * @notyetdoced
283 *
284 * @see
285 * - reportPauliStrSum()
286 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) or
287 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
288 */
290
291
292 /** @ingroup paulis_create
293 * @notyetdoced
294 *
295 * @see
296 * - reportPauliStrSum()
297 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) or
298 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
299 */
301
302
303#ifdef __cplusplus
304}
305#endif
306
307
308// C++ users get additional overloads
309#ifdef __cplusplus
310
311
312 /** @ingroup paulis_create
313 * @notyetdoced
314 * @cpponly
315 *
316 * @see
317 * - createPauliStrSum()
318 * - reportPauliStrSum()
319 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
320 */
321 PauliStrSum createPauliStrSum(std::vector<PauliStr> strings, std::vector<qcomp> coeffs);
322
323
324 /** @ingroup paulis_create
325 * @notyetdoced
326 * @cpponly
327 *
328 * @see
329 * - createInlinePauliStrSum()
330 * - reportPauliStrSum()
331 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
332 */
333 PauliStrSum createInlinePauliStrSum(std::string str);
334
335
336 /** @ingroup paulis_create
337 * @notyetdoced
338 * @cpponly
339 *
340 * @see
341 * - createPauliStrSumFromFile()
342 * - reportPauliStrSum()
343 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
344 */
346
347
348 /** @ingroup paulis_create
349 * @notyetdoced
350 * @cpponly
351 *
352 * @see
353 * - createPauliStrSumFromReversedFile()
354 * - reportPauliStrSum()
355 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
356 */
358
359
360#endif
361
362
363
364/*
365 * PAULI STRING SUM DESTRUCTION
366 */
367
368
369// enable invocation by both C and C++ binaries
370#ifdef __cplusplus
371extern "C" {
372#endif
373
374
375 /// @ingroup paulis_destroy
376 /// @notyetdoced
378
379
380// end de-mangler
381#ifdef __cplusplus
382}
383#endif
384
385
386
387/*
388 * REPORTERS
389 */
390
391// enable invocation by both C and C++ binaries
392#ifdef __cplusplus
393extern "C" {
394#endif
395
396
397 /** @ingroup paulis_reporters
398 * @notyetdoced
399 * @notyettested
400 *
401 * @see
402 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_paulis.c) or
403 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_paulis.cpp) examples
404 */
405 void reportPauliStr(PauliStr str);
406
407
408 /** @ingroup paulis_reporters
409 * @notyetdoced
410 * @notyettested
411 *
412 * @see
413 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_paulis.c) or
414 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_paulis.cpp) examples
415 */
417
418
419// end de-mangler
420#ifdef __cplusplus
421}
422#endif
423
424
425
426/*
427 * SETTERS
428 */
429
430// enable invocation by both C and C++ binaries
431#ifdef __cplusplus
432extern "C" {
433#endif
434
435
436 /** @ingroup paulis_setters
437 *
438 * Reorders the terms within a @p sum of weighted Pauli strings
439 * so that the Pauli strings are ordered lexicographically.
440 *
441 * @formulae
442 *
443 * Let @f$ H = @f$ @p sum, satisfying
444 * @f[
445 H = \sum\limits_j c_j \, \hat{\sigma}_j
446 * @f]
447 * where @f$ c_j @f$ is the coefficient of the @f$ j @f$-th PauliStr @f$ \hat{\sigma}_j @f$.
448 *
449 * This function applies the permutation @f$ \pi @f$ to @f$ H @f$, whereby
450 * @f[
451 H = \sum\limits_j c_{\pi(j)} \, \hat{\sigma}_{\pi(j)}
452 * @f]
453 * such that
454 * @f[
455 * \hat{\sigma}_{\pi(i)} <_{lex} \hat{\sigma}_{\pi(j)} \ \forall \ \pi(i) < \pi(j).
456 * @f]
457 *
458 *
459 * @param[in,out] sum a weighted sum of Pauli strings to reorder.
460 *
461 * @throws @validationerror
462 * - if @p sum is not initialised.
463 *
464 * @see
465 * - sortPauliStrSumMagnitude()
466 * @author Vasco Ferreira
467 */
469
470
471 /** @ingroup paulis_setters
472 *
473 * Reorders the terms within a @p sum of weighted Pauli strings such that
474 * coefficients are ordered with decreasing magnitude.
475 *
476 * @formulae
477 *
478 * Let @f$ H = @f$ @p sum, satisfying
479 * @f[
480 H = \sum\limits_j c_j \, \hat{\sigma}_j
481 * @f]
482 * where @f$ c_j @f$ is the coefficient of the @f$ j @f$-th PauliStr @f$ \hat{\sigma}_j @f$.
483 *
484 * This function applies the permutation @f$ \pi @f$ to @f$ H @f$ such that
485 * @f[
486 * |c_{\pi(i)}| > |c_{\pi(j)}| \, \forall \, \pi(i) < \pi(j).
487 * @f]
488 *
489 * @param[in,out] sum a weighted sum of Pauli strings to reorder.
490 *
491 * @throws @validationerror
492 * - if @p sum is not initialised.
493 *
494 * @see
495 * - sortPauliStrSumLexicographic()
496 *
497 * @author Vasco Ferreira
498 */
500
501
502// end de-mangler
503#ifdef __cplusplus
504}
505#endif
506
507
508
509#endif // PAULIS_H
510
511/** @} */ // (end file-wide doxygen defgroup)
PauliStr getInlinePauliStr(const char *paulis, { list })
PauliStrSum createPauliStrSumFromFile(const char *fn)
Definition paulis.cpp:211
PauliStrSum createPauliStrSum(PauliStr *strings, qcomp *coeffs, qindex numTerms)
Definition paulis.cpp:166
PauliStrSum createInlinePauliStrSum(const char *str)
Definition paulis.cpp:198
PauliStrSum createPauliStrSumFromReversedFile(const char *fn)
Definition paulis.cpp:228
PauliStr getPauliStr(const char *paulis, int *indices, int numPaulis)
Definition paulis.cpp:76
void destroyPauliStrSum(PauliStrSum sum)
Definition paulis.cpp:251
void reportPauliStrSum(PauliStrSum str)
Definition paulis.cpp:279
void reportPauliStr(PauliStr str)
Definition paulis.cpp:264
void sortPauliStrSumLexicographic(PauliStrSum sum)
Definition paulis.cpp:310
void sortPauliStrSumMagnitude(PauliStrSum sum)
Definition paulis.cpp:324
long long unsigned int PAULI_MASK_TYPE
Definition precision.h:69