The Quantum Exact Simulation Toolkit v4.0.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/// @notdoced
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/// @notdoced
65typedef struct {
66
67 qindex numTerms;
68
69 // arbitrarily-sized collection of Pauli strings and their
70 // coefficients are 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
104
105
106/*
107 * PAULI STRING CREATION
108 */
109
110
111// base method is C and C++ compatible
112#ifdef __cplusplus
113extern "C" {
114#endif
115
116 /// @ingroup paulis_create
117 /// @notdoced
118 PauliStr getPauliStr(const char* paulis, int* indices, int numPaulis);
119
120#ifdef __cplusplus
121}
122#endif
123
124
125#ifdef __cplusplus
126
127 // C++ users can access the above C method, along with direct overloads
128 // to accept integers (in lieu of chars), natural C++ string types
129 // (like literals), and C++ vector types for brevity. Furthermore, C++
130 // gets an overload which accepts only a string (no additional args)
131 // which is used internally by parsers, and exposed for user-convenience.
132 // note that C++ does NOT get an overload where the pauli codes (integers) are
133 // passed as a vector; this is because integer literal initialiser lists like
134 // {0,3,1} are valid std::string instances, causing overload ambiguity. Blegh!
135
136
137 /// @ingroup paulis_create
138 /// @notdoced
139 PauliStr getPauliStr(int* paulis, int* indices, int numPaulis);
140
141
142 /// @ingroup paulis_create
143 /// @notdoced
144 /// @cpponly
145 PauliStr getPauliStr(std::string paulis, int* indices, int numPaulis);
146
147
148 /// @ingroup paulis_create
149 /// @notdoced
150 /// @cpponly
151 PauliStr getPauliStr(std::string paulis, std::vector<int> indices);
152
153
154 /// @ingroup paulis_create
155 /// @notdoced
156 /// @cpponly
157 PauliStr getPauliStr(std::string paulis);
158
159
160 // never needs to be doc'd
161 /// @private
162 /// @neverdoced
163 #define getInlinePauliStr(str, ...) \
164 getPauliStr(str, __VA_ARGS__)
165
166
167#else
168
169 // C supports passing a char array or string literal with a specified number of Paulis,
170 // or an overload accepting ints, achieved using a C11 _Generic. C also gets an inline
171 // macro which exploits the compile-time size of a string literal, and enables array
172 // literals without the C99 inline temporary array syntax; we further give the array
173 // an explici size (instead of just (int[])) to gaurantee it contains at leasts as
174 // many elements as claimed, avoiding seg-faults if the user provides too few indices
175
176
177 /// @ingroup paulis_create
178 /// @private
179 PauliStr _getPauliStrFromInts(int* paulis, int* indices, int numPaulis);
180
181
182 // documented above (identical signatures to C)
183 /// @neverdoced
184 #define getPauliStr(paulis, ...) \
185 _Generic((paulis), \
186 int* : _getPauliStrFromInts, \
187 default : getPauliStr \
188 )(paulis, __VA_ARGS__)
189
190
191 // documented below
192 /// @neverdoced
193 #define getInlinePauliStr(str, ...) \
194 getPauliStr((str), (int[sizeof(str)-1]) __VA_ARGS__, sizeof(str)-1)
195
196 // spoofing above macro as function to doc
197 #if 0
198
199 /// @ingroup paulis_create
200 /// @notdoced
201 /// @macrodoc
202 PauliStr getInlinePauliStr(const char* paulis, { list });
203
204 #endif
205
206
207#endif
208
209
210
211/*
212 * PAULI STRING SUM CREATION
213 */
214
215
216// base methods are C and C++ compatible
217#ifdef __cplusplus
218extern "C" {
219#endif
220
221
222 /// @ingroup paulis_create
223 /// @notdoced
224 PauliStrSum createPauliStrSum(PauliStr* strings, qcomp* coeffs, qindex numTerms);
225
226
227 /// @ingroup paulis_create
228 /// @notdoced
229 PauliStrSum createInlinePauliStrSum(const char* str);
230
231
232 /// @ingroup paulis_create
233 /// @notdoced
235
236
237 /// @ingroup paulis_create
238 /// @notdoced
240
241
242#ifdef __cplusplus
243}
244#endif
245
246
247// C++ users get additional overloads
248#ifdef __cplusplus
249
250
251 /// @ingroup paulis_create
252 /// @notdoced
253 /// @cpponly
254 PauliStrSum createPauliStrSum(std::vector<PauliStr> strings, std::vector<qcomp> coeffs);
255
256
257 /// @ingroup paulis_create
258 /// @notdoced
259 /// @cpponly
261
262
263 /// @ingroup paulis_create
264 /// @notdoced
265 /// @cpponly
267
268
269 /// @ingroup paulis_create
270 /// @notdoced
271 /// @cpponly
273
274
275#endif
276
277
278
279/*
280 * PAULI STRING SUM DESTRUCTION
281 */
282
283
284// enable invocation by both C and C++ binaries
285#ifdef __cplusplus
286extern "C" {
287#endif
288
289
290 /// @ingroup paulis_destroy
291 /// @notdoced
293
294
295// end de-mangler
296#ifdef __cplusplus
297}
298#endif
299
300
301
302/*
303 * REPORTERS
304 */
305
306// enable invocation by both C and C++ binaries
307#ifdef __cplusplus
308extern "C" {
309#endif
310
311
312 /// @ingroup paulis_reporters
313 /// @notdoced
314 /// @nottested
315 void reportPauliStr(PauliStr str);
316
317 /// @ingroup paulis_reporters
318 /// @notdoced
319 /// @nottested
321
322
323// end de-mangler
324#ifdef __cplusplus
325}
326#endif
327
328
329
330#endif // PAULIS_H
331
332/** @} */ // (end file-wide doxygen defgroup)
PauliStr getInlinePauliStr(const char *paulis, { list })
PauliStrSum createPauliStrSumFromFile(const char *fn)
Definition paulis.cpp:431
PauliStrSum createPauliStrSum(PauliStr *strings, qcomp *coeffs, qindex numTerms)
Definition paulis.cpp:385
PauliStrSum createInlinePauliStrSum(const char *str)
Definition paulis.cpp:418
PauliStrSum createPauliStrSumFromReversedFile(const char *fn)
Definition paulis.cpp:448
PauliStr getPauliStr(const char *paulis, int *indices, int numPaulis)
Definition paulis.cpp:296
void destroyPauliStrSum(PauliStrSum sum)
Definition paulis.cpp:471
void reportPauliStrSum(PauliStrSum str)
Definition paulis.cpp:495
void reportPauliStr(PauliStr str)
Definition paulis.cpp:484
long long unsigned int PAULI_MASK_TYPE
Definition precision.h:69