The Quantum Exact Simulation Toolkit v4.1.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 // 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 * @notyetdoced
118 *
119 * @see
120 * - reportPauliStr()
121 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) or
122 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
123 */
124 PauliStr getPauliStr(const char* paulis, int* indices, int numPaulis);
125
126#ifdef __cplusplus
127}
128#endif
129
130
131#ifdef __cplusplus
132
133 // C++ users can access the above C method, along with direct overloads
134 // to accept integers (in lieu of chars), natural C++ string types
135 // (like literals), and C++ vector types for brevity. Furthermore, C++
136 // gets an overload which accepts only a string (no additional args)
137 // which is used internally by parsers, and exposed for user-convenience.
138 // note that C++ does NOT get an overload where the pauli codes (integers) are
139 // passed as a vector; this is because integer literal initialiser lists like
140 // {0,3,1} are valid std::string instances, causing overload ambiguity. Blegh!
141
142
143 /** @ingroup paulis_create
144 * @notyetdoced
145 *
146 * @see
147 * - reportPauliStr()
148 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) or
149 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
150 */
151 PauliStr getPauliStr(int* paulis, int* indices, int numPaulis);
152
153
154 /** @ingroup paulis_create
155 * @notyetdoced
156 * @cpponly
157 *
158 * @see
159 * - getPauliStr()
160 * - reportPauliStr()
161 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
162 */
163 PauliStr getPauliStr(std::string paulis, int* indices, int numPaulis);
164
165
166 /** @ingroup paulis_create
167 * @notyetdoced
168 * @cpponly
169 *
170 * @see
171 * - reportPauliStr()
172 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
173 */
174 PauliStr getPauliStr(std::string paulis, std::vector<int> indices);
175
176
177 /** @ingroup paulis_create
178 * @notyetdoced
179 * @cpponly
180 *
181 * @see
182 * - reportPauliStr()
183 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
184 */
185 PauliStr getPauliStr(std::string paulis);
186
187
188 // never needs to be doc'd
189 /// @private
190 /// @neverdoced
191 #define getInlinePauliStr(str, ...) \
192 getPauliStr(str, __VA_ARGS__)
193
194
195#else
196
197 // C supports passing a char array or string literal with a specified number of Paulis,
198 // or an overload accepting ints, achieved using a C11 _Generic. C also gets an inline
199 // macro which exploits the compile-time size of a string literal, and enables array
200 // literals without the C99 inline temporary array syntax; we further give the array
201 // an explici size (instead of just (int[])) to gaurantee it contains at leasts as
202 // many elements as claimed, avoiding seg-faults if the user provides too few indices
203
204
205 /// @ingroup paulis_create
206 /// @private
207 PauliStr _getPauliStrFromInts(int* paulis, int* indices, int numPaulis);
208
209
210 // documented above (identical signatures to C)
211 /// @neverdoced
212 #define getPauliStr(paulis, ...) \
213 _Generic((paulis), \
214 int* : _getPauliStrFromInts, \
215 default : getPauliStr \
216 )(paulis, __VA_ARGS__)
217
218
219 // documented below
220 /// @neverdoced
221 #define getInlinePauliStr(str, ...) \
222 getPauliStr((str), (int[sizeof(str)-1]) __VA_ARGS__, sizeof(str)-1)
223
224 // spoofing above macro as function to doc
225 #if 0
226
227 /** @ingroup paulis_create
228 * @notyetdoced
229 * @macrodoc
230 *
231 * @see
232 * - reportPauliStr()
233 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) and
234 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp)examples
235 */
236 PauliStr getInlinePauliStr(const char* paulis, { list });
237
238 #endif
239
240
241#endif
242
243
244
245/*
246 * PAULI STRING SUM CREATION
247 */
248
249
250// base methods are C and C++ compatible
251#ifdef __cplusplus
252extern "C" {
253#endif
254
255
256 /** @ingroup paulis_create
257 * @notyetdoced
258 *
259 * @see
260 * - reportPauliStrSum()
261 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) or
262 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
263 */
264 PauliStrSum createPauliStrSum(PauliStr* strings, qcomp* coeffs, qindex numTerms);
265
266
267 /** @ingroup paulis_create
268 * @notyetdoced
269 *
270 * @see
271 * - reportPauliStrSum()
272 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) or
273 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
274 */
275 PauliStrSum createInlinePauliStrSum(const char* str);
276
277
278 /** @ingroup paulis_create
279 * @notyetdoced
280 *
281 * @see
282 * - reportPauliStrSum()
283 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) or
284 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
285 */
287
288
289 /** @ingroup paulis_create
290 * @notyetdoced
291 *
292 * @see
293 * - reportPauliStrSum()
294 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.c) or
295 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
296 */
298
299
300#ifdef __cplusplus
301}
302#endif
303
304
305// C++ users get additional overloads
306#ifdef __cplusplus
307
308
309 /** @ingroup paulis_create
310 * @notyetdoced
311 * @cpponly
312 *
313 * @see
314 * - createPauliStrSum()
315 * - reportPauliStrSum()
316 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
317 */
318 PauliStrSum createPauliStrSum(std::vector<PauliStr> strings, std::vector<qcomp> coeffs);
319
320
321 /** @ingroup paulis_create
322 * @notyetdoced
323 * @cpponly
324 *
325 * @see
326 * - createInlinePauliStrSum()
327 * - reportPauliStrSum()
328 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
329 */
331
332
333 /** @ingroup paulis_create
334 * @notyetdoced
335 * @cpponly
336 *
337 * @see
338 * - createPauliStrSumFromFile()
339 * - reportPauliStrSum()
340 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
341 */
343
344
345 /** @ingroup paulis_create
346 * @notyetdoced
347 * @cpponly
348 *
349 * @see
350 * - createPauliStrSumFromReversedFile()
351 * - reportPauliStrSum()
352 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_paulis.cpp) examples
353 */
355
356
357#endif
358
359
360
361/*
362 * PAULI STRING SUM DESTRUCTION
363 */
364
365
366// enable invocation by both C and C++ binaries
367#ifdef __cplusplus
368extern "C" {
369#endif
370
371
372 /// @ingroup paulis_destroy
373 /// @notyetdoced
375
376
377// end de-mangler
378#ifdef __cplusplus
379}
380#endif
381
382
383
384/*
385 * REPORTERS
386 */
387
388// enable invocation by both C and C++ binaries
389#ifdef __cplusplus
390extern "C" {
391#endif
392
393
394 /** @ingroup paulis_reporters
395 * @notyetdoced
396 * @notyettested
397 *
398 * @see
399 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_paulis.c) or
400 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_paulis.cpp) examples
401 */
402 void reportPauliStr(PauliStr str);
403
404
405 /** @ingroup paulis_reporters
406 * @notyetdoced
407 * @notyettested
408 *
409 * @see
410 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_paulis.c) or
411 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_paulis.cpp) examples
412 */
414
415
416// end de-mangler
417#ifdef __cplusplus
418}
419#endif
420
421
422
423#endif // PAULIS_H
424
425/** @} */ // (end file-wide doxygen defgroup)
PauliStr getInlinePauliStr(const char *paulis, { list })
PauliStrSum createPauliStrSumFromFile(const char *fn)
Definition paulis.cpp:441
PauliStrSum createPauliStrSum(PauliStr *strings, qcomp *coeffs, qindex numTerms)
Definition paulis.cpp:396
PauliStrSum createInlinePauliStrSum(const char *str)
Definition paulis.cpp:428
PauliStrSum createPauliStrSumFromReversedFile(const char *fn)
Definition paulis.cpp:458
PauliStr getPauliStr(const char *paulis, int *indices, int numPaulis)
Definition paulis.cpp:306
void destroyPauliStrSum(PauliStrSum sum)
Definition paulis.cpp:481
void reportPauliStrSum(PauliStrSum str)
Definition paulis.cpp:505
void reportPauliStr(PauliStr str)
Definition paulis.cpp:494
long long unsigned int PAULI_MASK_TYPE
Definition precision.h:69