The Quantum Exact Simulation Toolkit v4.1.0
Loading...
Searching...
No Matches
matrices.h
1/** @file
2 * Definitions of all dense and diagonal matrices, their getters and setters,
3 * as well as their reporting utilities. Note that Kraus maps are treated in
4 * a bespoke file (channels.h).
5 *
6 * This file uses extensive preprocessor trickery to achieve overloaded,
7 * platform agnostic, C and C++ compatible, precision agnostic, getters
8 * and setters of complex matrices. All macros herein expand to single-line
9 * definitions, for safety. Some intendedly private functions are necessarily
10 * exposed here to the user, and are prefixed with an underscore.
11 *
12 * Note too that designated initialisers are generally avoided, since while
13 * C99/C11 compatible, they are not explicitly supported by C++14 (only from
14 * C++20) except through compiler extensions
15 *
16 * @author Tyson Jones
17 * @author Richard Meister (aided in design)
18 * @author Erich Essmann (aided in design, patched on MSVC)
19 *
20 * @defgroup matrices Matrices
21 * @ingroup api
22 * @brief Data structures for representing operator matrices.
23 * @{
24 */
25
26#ifndef MATRICES_H
27#define MATRICES_H
28
29#include "quest/include/types.h"
30#include "quest/include/paulis.h"
31
32// C++ gets vector initialiser overloads, whereas C gets a macro
33#ifdef __cplusplus
34 #include <vector>
35#endif
36
37
38
39/*
40 * unlike some other headers, we here intermix the C and C++-only
41 * signatures, grouping them semantically & by their doc groups
42 */
43
44
45
46/**
47 * @defgroup matrices_structs Structs
48 * @brief Data structures for representing operator matrices.
49 * @{
50 */
51
52
53/*
54 * DENSE MATRIX STRUCTS
55 *
56 * which are visible to both C and C++, where qcomp resolves
57 * to the native complex type. These are not de-mangled because
58 * C++ structs are already C compatible.
59 *
60 * The compile-time sized structs have field 'elems', while
61 * dynamic-sized structs have separate 'cpuElems' and
62 * 'gpuElemsFlat', for persistent GPU allocation, and ergo need
63 * syncing. Note 'gpuElemsFlat' is always 1D (hence the name).
64 */
65
66
67/// @notyetdoced
68typedef struct {
69
70 int numQubits;
71 qindex numRows;
72
73 qcomp elems[2][2];
74
75} CompMatr1;
76
77
78/// @notyetdoced
79typedef struct {
80
81 int numQubits;
82 qindex numRows;
83
84 qcomp elems[4][4];
85
86} CompMatr2;
87
88
89/// @notyetdoced
90typedef struct {
91
92 // beware that CompMatr instances are sometimes 'spoofed' inside localiser.cpp,
93 // which will set the fields from other object instances (like a SuperOp). As
94 // such, additional fields to this struct may require updating these spoofers.
95
96 int numQubits;
97 qindex numRows;
98
99 // properties of the matrix (0, 1, or -1 to indicate unknown) which are lazily evaluated,
100 // deferred until a function actually validates them, at which point they are computed
101 // and the flags fixed until the user modifies the matrix (through sync() or setAmps() etc).
102 // flag is stored in heap so even copies of structs are mutable, but pointer is immutable.
103 // otherwise, the field of a user's struct could never be modified because of pass-by-copy.
104 int* isApproxUnitary;
105 int* isApproxHermitian; /// @todo currently unused (relevant to not-yet-implemented calc-expec-val)
106
107 // whether the user has ever synchronised memory to the GPU, which is performed automatically
108 // when calling functions like setCompMatr(), but which requires manual invocation with
109 // syncCompMatr() after manual modification of the cpuElem. Note this can only indicate whether
110 // the matrix has EVER been synced; it cannot be used to detect whether manual modifications
111 // made after an initial sync have been re-synched. This is a heap pointer, as above.
113
114 // 2D CPU memory, which users can manually overwrite like cpuElems[i][j],
115 // but which actually merely aliases the 1D cpuElemsFlat below
116 qcomp** cpuElems;
117
118 // row-major flattened elements of cpuElems, always allocated
119 qcomp* cpuElemsFlat;
120
121 // row-major flattened elems in GPU memory, allocated
122 // only and always in GPU-enabled QuEST environments
123 qcomp* gpuElemsFlat;
124
125} CompMatr;
126
127
128/*
129 * DIAGONAL MATRIX STRUCTS
130 *
131 * with all the same nuances as the CompMatr structs described above.
132 */
133
134
135/// @notyetdoced
136typedef struct {
137
138 int numQubits;
139 qindex numElems;
140
141 qcomp elems[2];
142
143} DiagMatr1;
144
145
146/// @notyetdoced
147typedef struct {
148
149 int numQubits;
150 qindex numElems;
151
152 qcomp elems[4];
153
154} DiagMatr2;
155
156
157/// @notyetdoced
158typedef struct {
159
160 int numQubits;
161 qindex numElems;
162
163 // properties of the matrix (0, 1, or -1 to indicate unknown) which are lazily evaluated,
164 // deferred until a function actually validates them, at which point they are computed
165 // and the flags fixed until the user modifies the matrix (through sync() or setAmps() etc).
166 // flag is stored in heap so even copies of structs are mutable, but pointer is immutable.
167 // otherwise, the field of a user's struct could never be modified because of pass-by-copy.
168 int* isApproxUnitary;
169 int* isApproxHermitian; /// @todo currently unused (relevant to not-yet-implemented calc-expec-val)
170 int* isApproxNonZero; /// @todo currently unused (relevant to not-yet-implemented calc-expec-val)
171 int* isStrictlyNonNegative; /// @todo currently unused (relevant to not-yet-implemented calc-expec-val)
172
173 // whether the user has ever synchronised memory to the GPU, which is performed automatically
174 // when calling functions like setCompMatr(), but which requires manual invocation with
175 // syncCompMatr() after manual modification of the cpuElem. Note this can only indicate whether
176 // the matrix has EVER been synced; it cannot be used to detect whether manual modifications
177 // made after an initial sync have been re-synched. This is a heap pointer, as above.
179
180 // CPU memory; not const, so users can overwrite addresses (e.g. with nullptr)
181 qcomp* cpuElems;
182
183 // GPU memory, allocated only and always in GPU-enabled QuEST environments
184 qcomp* gpuElems;
185
186} DiagMatr;
187
188
189/*
190 * DISTRIBUTED MATRIX STRUCTS
191 */
192
193
194/// @notyetdoced
195typedef struct {
196
197 int numQubits;
198 qindex numElems;
199
200 // unlike other heap-matrices, GPU memory is not always allocated when the QuEST
201 // env is GPU-accelerated; instead, it can be disabled by auto-deployer, or the user
202 int isGpuAccelerated;
203 int isMultithreaded;
204 int isDistributed;
205 qindex numElemsPerNode;
206
207 // properties of the matrix (0, 1, or -1 to indicate unknown) which are lazily evaluated,
208 // deferred until a function actually validates them, at which point they are computed
209 // and the flags fixed until the user modifies the matrix (through sync() or setAmps() etc).
210 // flag is stored in heap so even copies of structs are mutable, but pointer is immutable.
211 // otherwise, the field of a user's struct could never be modified because of pass-by-copy.
212 int* isApproxUnitary;
213 int* isApproxHermitian;
214 int* isApproxNonZero;
215 int* isStrictlyNonNegative;
216
217 // whether the user has ever synchronised memory to the GPU, which is performed automatically
218 // when calling functions like setCompMatr(), but which requires manual invocation with
219 // syncCompMatr() after manual modification of the cpuElem. Note this can only indicate whether
220 // the matrix has EVER been synced; it cannot be used to detect whether manual modifications
221 // made after an initial sync have been re-synched. This is a heap pointer, as above.
222 int* wasGpuSynced;
223
224 // CPU memory; not const, so users can overwrite addresses (e.g. with nullptr)
225 qcomp* cpuElems;
226
227 // GPU memory, allocated only and always in GPU-enabled QuEST environments
228 qcomp* gpuElems;
229
231
232
233/** @} */
234
235
236
237// we define the remaining doc groups in advance, since their signatures are
238// more naturally grouped in an implementation-specific way below. Note the
239// above structs were not doc'd this way (which would be more consistent)
240// because it inexplicably causes Doxygen to duplicate their section at the
241// top-level under Matrices (rather than under Structs). Bizarre! The order
242// of declaration below will match the order shown in the html doc.
243/**
244 * @defgroup matrices_getters Getters
245 * @brief Functions for obtaining fixed-size matrices.
246 *
247 * @defgroup matrices_create Constructors
248 * @brief Functions for creating variable-size matrices.
249 *
250 * @defgroup matrices_destroy Destructors
251 * @brief Functions for destroying existing matrices.
252 *
253 * @defgroup matrices_reporters Reporters
254 * @brief Functions for printing matrices.
255 *
256 * @defgroup matrices_setters Setters
257 * @brief Functions for overwriting the elements of matrices.
258 *
259 * @defgroup matrices_sync Synchronisation
260 * @brief Functions for overwriting a matrix's GPU (VRAM) memory with its CPU (RAM) contents.
261 * @details These functions are only necessary when the user wishes to manually modify the
262 * elements of a matrix (in lieu of using the @ref matrices_setters "Setters"), to
263 * thereafter synchronise the changes to the GPU copy of the channel. These functions
264 * have no effect when running without GPU-acceleration, but remain legal and harmless
265 * to call (to achieve platform agnosticism).
266 */
267
268
269
270/*
271 * FIZED-SIZE MATRIX GETTERS VIA POINTERS
272 *
273 * which are defined here in the header because the 'qcomp' type is interpreted
274 * distinctly by C++ (the backend) and C (user code). The C and C++ ABIs do not
275 * agree on a complex type, so a qcomp (to C; a _Complex, and to C++; a std::complex)
276 * cannot be directly passed between C and C++ compiled binaries; nor can a CompMatr1
277 * struct which unwraps the qcomp[][] array. However, the C and C++ complex types have
278 * identical memory layouts, so pointers to qcomp types can safely be passed between
279 * C and C++ binaries. Ordinarily we leverage this by defining all qcomp-handling API
280 * functions in C++, and defining additional C-only wrappers in wrappers.h, which pass
281 * only pointers to qcomp. Alas, we cannot use this trick here, because the CompMatr1/2
282 * fields are declared 'const'; we cannot modify them through pointers, nor should we
283 * try to address them. Ergo we directly define these functions below (static inline to
284 * avoid symbol duplication), initializing the struct in one line. These functions will be
285 * separately interpreted by the C and C++ compilers, resolving qcomp to their individual
286 * native complex types.
287 *
288 * These functions permit users to pass heap and stack pointers:
289 * - qcomp** ptr = malloc(...); getCompMatr1(ptr);
290 * - qcomp* ptrs[2]; getCompMatr1(ptrs);
291 * in both C and C++. Because of 1D pointer decay, they also permit:
292 * - qcomp* ptr = malloc(...); getDiagMatr1(ptr);
293 * - qcomp arr[2]; getDiagMatr1(arr);
294 */
295
296
297// private validators
298#ifdef __cplusplus
299extern "C" {
300#endif
301
302/// @private
303extern void _validateNewNestedElemsPtrNotNull(qcomp** ptrs, int numQubits, const char* caller);
304
305/// @private
306extern void _validateNewElemsPtrNotNull(qcomp* ptr, const char* caller);
307
308#ifdef __cplusplus
309}
310#endif
311
312
313/** @ingroup matrices_getters
314 * @notyetdoced
315 *
316 * @see
317 * - reportCompMatr1()
318 * - getInlineCompMatr2()
319 * - getDiagMatr1()
320 * - getCompMatr2()
321 * - createCompMatr()
322 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
323 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
324 */
325static inline CompMatr1 getCompMatr1(qcomp** in) {
326 _validateNewNestedElemsPtrNotNull(in, 1, __func__);
327
328 CompMatr1 out;
329
330 out.numQubits = 1;
331 out.numRows = 2;
332 for (int r=0; r<2; r++)
333 for (int c=0; c<2; c++)
334 out.elems[r][c] = in[r][c];
335
336 return out;
337}
338
339
340/** @ingroup matrices_getters
341 * @notyetdoced
342 *
343 * @see
344 * - reportCompMatr2()
345 * - getInlineCompMatr2()
346 * - getDiagMatr2()
347 * - createCompMatr()
348 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
349 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
350 */
351static inline CompMatr2 getCompMatr2(qcomp** in) {
352 _validateNewNestedElemsPtrNotNull(in, 2, __func__);
353
354 CompMatr2 out;
355
356 out.numQubits = 2;
357 out.numRows = 4;
358 for (int r=0; r<4; r++)
359 for (int c=0; c<4; c++)
360 out.elems[r][c] = in[r][c];
361
362 return out;
363}
364
365
366/** @ingroup matrices_getters
367 * @notyetdoced
368 *
369 * @see
370 * - reportDiagMatr1()
371 * - getInlineDiagMatr1()
372 * - getCompMatr1()
373 * - getDiagMatr2()
374 * - createDiagMatr()
375 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
376 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
377 */
378static inline DiagMatr1 getDiagMatr1(qcomp* in) {
379 _validateNewElemsPtrNotNull(in, __func__);
380
381 DiagMatr1 out;
382
383 out.numQubits = 1;
384 out.numElems = 2;
385 for (int i=0; i<2; i++)
386 out.elems[i] = in[i];
387
388 return out;
389}
390
391
392/** @ingroup matrices_getters
393 * @notyetdoced
394 *
395 * @see
396 * - reportDiagMatr2()
397 * - getInlineDiagMatr2()
398 * - getCompMatr2()
399 * - createDiagMatr()
400 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
401 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
402 */
403static inline DiagMatr2 getDiagMatr2(qcomp* in) {
404 _validateNewElemsPtrNotNull(in, __func__);
405
406 DiagMatr2 out;
407
408 out.numQubits = 2;
409 out.numElems = 4;
410 for (int i=0; i<4; i++)
411 out.elems[i] = in[i];
412
413 return out;
414}
415
416
417
418/*
419 * FIZED-SIZE MATRIX GETTERS VIA ARRAYS & VECTORS
420 *
421 * which define additional overloads for arrays, VLAs, C99 temporary arrays,
422 * vectors and vector initialisation lists. This empowers C users to call:
423 * - qcomp arr[2][2]; getCompMatr1(arr);
424 * - int n=2; qcomp arr[n][n]; getCompMatr1(arr);
425 * - getCompMatr1( (qcomp[2][2]) {...} );
426 * and C++ users call:
427 * - qcomp arr[2][2]; getCompMatr1(arr);
428 * - std::vector vec(2); getCompMatr1(vec);
429 * - getCompMatr1( {...} );
430 */
431
432
433// define the array overloads with a distinct name from the base
434// C function - we will alias it with getCompMatr() using Generics
435
436/// @private
437static inline CompMatr1 _getCompMatr1FromArr(qcomp in[2][2]) {
438
439 qcomp* rowPtrs[] = {in[0], in[1]};
440 return getCompMatr1(rowPtrs);
441}
442
443/// @private
444static inline CompMatr2 _getCompMatr2FromArr(qcomp in[4][4]) {
445
446 qcomp* rowPtrs[] = {in[0], in[1], in[2], in[3]};
447 return getCompMatr2(rowPtrs);
448}
449
450
451// no array overloads are necessary for getDiagMatr(), because
452// a 1D array automatically decays to a pointer
453
454
455#ifdef __cplusplus
456
457 // C++ defines overloads which merely wrap _getCompMatr1FromArr(), for fixed-size arrays.
458 // C++ also defines additional std::vector overloads (for convenience, and for inline initialisation).
459 // these are defined in matrices.cpp because they invoke validation (checking vector sizes)
460
461
462 /// @ingroup matrices_getters
463 /// @notyetdoced
464 static inline CompMatr1 getCompMatr1(qcomp in[2][2]) { return _getCompMatr1FromArr(in); }
465
466
467 /// @ingroup matrices_getters
468 /// @notyetdoced
469 static inline CompMatr2 getCompMatr2(qcomp in[4][4]) { return _getCompMatr2FromArr(in); }
470
471
472 /** @ingroup matrices_getters
473 * @notyetdoced
474 * @cpponly
475 *
476 * @see
477 * - reportCompMatr1()
478 * - getInlineCompMatr1()
479 * - getDiagMatr1()
480 * - getCompMatr2()
481 * - createCompMatr()
482 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
483 */
484 CompMatr1 getCompMatr1(std::vector<std::vector<qcomp>> in);
485
486
487 /** @ingroup matrices_getters
488 * @notyetdoced
489 * @cpponly
490 *
491 * @see
492 * - reportCompMatr2()
493 * - getInlineCompMatr2()
494 * - getDiagMatr2()
495 * - createCompMatr()
496 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
497 */
498 CompMatr2 getCompMatr2(std::vector<std::vector<qcomp>> in);
499
500
501 /** @ingroup matrices_getters
502 * @notyetdoced
503 * @cpponly
504 *
505 * @see
506 * - reportDiagMatr1()
507 * - getInlineDiagMatr1()
508 * - getCompMatr1()
509 * - getDiagMatr2()
510 * - createDiagMatr()
511 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
512 */
513 DiagMatr1 getDiagMatr1(std::vector<qcomp> in);
514
515
516 /** @ingroup matrices_getters
517 * @notyetdoced
518 * @cpponly
519 *
520 * @see
521 * - reportDiagMatr2()
522 * - getInlineDiagMatr2()
523 * - getCompMatr2()
524 * - createDiagMatr()
525 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
526 */
527 DiagMatr2 getDiagMatr2(std::vector<qcomp> in);
528
529
530#else
531
532 // C uses C11 Generics to effectively overload getCompMatr1/2 to accept both
533 // pointers (as prior defined) and arrays (wrapping _getCompMatr1FromArr()). Note:
534 // - our macros below accept C99 variadic arguments so that users pass C99
535 // compound literals (e.g. (qcomp[]) {1,2}) in addition to existing ptrs.
536 // they cannot however exclude the (qcomp[]) syntax like C++ users enjoy,
537 // which is why we will subsequently define a getInlineCompMatr1()
538 // - Generics evaluate at compile-time (AFTER preprocessing) so their RHS
539 // expressions are limited; because of this, it is impossible to avoid
540 // defining the _getCompMatr1FromArr() inner functions to avoid exposing them.
541 // - our Generics explicitly check for pointer types (qcomp**), but we use default
542 // to catch all array types (qcomp[][n], or qcomp(*)[] due to automatic Generic
543 // pointer decay in GCC). This makes the code more consistent with our variable-size
544 // CompMatr macros later in this file, which cannot use VLA in Generics at all. It
545 // also avoids the user having to see a Generic compilation error message when they
546 // pass an invalid type.
547 // - Generic expansion does not recurse, hence our macro safely has the same name
548 // (e.g. getCompMatr1) as the inner function, defining a true overload
549 // - we could not have _Generic's 'default' to catch unrecognised types at compile
550 // time to issue a custom message, because we must expand _Generic to a function
551 // rather than a macro; preprocessing is finished by the time _Generic evaluates,
552 // so a macro would always be substituted before compilation and if it contained
553 // a compile-time error, it will always be triggered. A function error however
554 // would compile fine, but the error message would only be triggered at runtime
555 // when the user actually calls getCompMatr1() which is much worse than a slightly
556 // less clear compile-time error! A non-portable solution to this is to use
557 // _Pragma() in the RHS which is evaluated at compile-time (NOT pre-procesing),
558 // e.g. default: _Pragma("GCC error \"arg not allowed\"").
559
560
561 /// @neverdoced
562 #define getCompMatr1(...) \
563 _Generic((__VA_ARGS__), \
564 qcomp** : getCompMatr1, \
565 default : _getCompMatr1FromArr \
566 )((__VA_ARGS__))
567
568
569 /// @neverdoced
570 #define getCompMatr2(...) \
571 _Generic((__VA_ARGS__), \
572 qcomp** : getCompMatr2, \
573 default : _getCompMatr2FromArr \
574 )((__VA_ARGS__))
575
576
577 // note the above macros do not need explicit, separate doxygen
578 // doc because the C++ overloads above it have identical signatures
579
580#endif
581
582
583
584/*
585 * FIXED-SIZE MATRIX GETTERS VIA LITERALS
586 *
587 * which enable C users to give inline 2D array literals without having to use the
588 * compound literal syntax. We expose these macros to C++ too for API consistency.
589 * although C++'s getCompMatr1 vector overload achieves the same thing, and cannot
590 * use C-style temporary arrays.
591 *
592 * These empower C and C++ users to call
593 * - getInlineCompMatr1( {{1,2},{3,4}} )
594 */
595
596
597#ifdef __cplusplus
598
599 // C++ merely invokes the std::vector initialiser overload
600
601 /// @neverdoced
602 #define getInlineCompMatr1(...) \
603 getCompMatr1(__VA_ARGS__)
604
605 /// @neverdoced
606 #define getInlineCompMatr2(...) \
607 getCompMatr2(__VA_ARGS__)
608
609 /// @neverdoced
610 #define getInlineDiagMatr1(...) \
611 getDiagMatr1(__VA_ARGS__)
612
613 /// @neverdoced
614 #define getInlineDiagMatr2(...) \
615 getDiagMatr2(__VA_ARGS__)
616
617#else
618
619 // C adds compound literal syntax to make a temporary array. Helpfully,
620 // explicitly specifying the DiagMatr dimension enables defaulting-to-zero
621
622 /// @neverdoced
623 #define getInlineCompMatr1(...) \
624 _getCompMatr1FromArr((qcomp[2][2]) __VA_ARGS__)
625
626 /// @neverdoced
627 #define getInlineCompMatr2(...) \
628 _getCompMatr2FromArr((qcomp[4][4]) __VA_ARGS__)
629
630 /// @neverdoced
631 #define getInlineDiagMatr1(...) \
632 getDiagMatr1((qcomp[2]) __VA_ARGS__)
633
634 /// @neverdoced
635 #define getInlineDiagMatr2(...) \
636 getDiagMatr2((qcomp[4]) __VA_ARGS__)
637
638#endif
639
640// spoofing above macros as functions to doc
641#if 0
642
643 /** @ingroup matrices_getters
644 * @notyetdoced
645 * @macrodoc
646 *
647 * @see
648 * - reportCompMatr1()
649 * - getInlineDiagMatr1()
650 * - getInlineCompMatr2()
651 * - createCompMatr()
652 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
653 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
654 */
656
657 /** @ingroup matrices_getters
658 * @notyetdoced
659 * @macrodoc
660 *
661 * @see
662 * - reportCompMatr2()
663 * - getInlineDiagMatr2()
664 * - createCompMatr()
665 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
666 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
667 */
669
670 /** @ingroup matrices_getters
671 * @notyetdoced
672 * @macrodoc
673 *
674 * @see
675 * - reportDiagMatr1()
676 * - getInlineCompMatr1()
677 * - getInlineDiagMatr2()
678 * - createDiagMatr()
679 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
680 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
681 */
683
684 /** @ingroup matrices_getters
685 * @notyetdoced
686 * @macrodoc
687 *
688 * @see
689 * - reportDiagMatr2()
690 * - getInlineCompMatr2()
691 * - createDiagMatr()
692 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
693 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
694 */
696
697#endif
698
699
700
701/*
702 * VARIABLE-SIZE MATRIX CONSTRUCTORS, DESTRUCTORS, SYNC
703 */
704
705
706// de-mangle so below are directly callable by C and C++ binary
707#ifdef __cplusplus
708extern "C" {
709#endif
710
711
712 /** @ingroup matrices_create
713 * @notyetdoced
714 *
715 * @see
716 * - setCompMatr()
717 * - syncCompMatr()
718 * - createInlineCompMatr()
719 * - createDiagMatr()
720 * - getCompMatr1()
721 * - getCompMatr2()
722 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
723 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
724 */
725 CompMatr createCompMatr(int numQubits);
726
727
728 /** @ingroup matrices_create
729 * @notyetdoced
730 *
731 * @see
732 * - setDiagMatr()
733 * - syncDiagMatr()
734 * - createInlineDiagMatr()
735 * - createCompMatr()
736 * - getDiagMatr1()
737 * - getDiagMatr2()
738 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
739 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
740 */
741 DiagMatr createDiagMatr(int numQubits);
742
743
744 /** @ingroup matrices_create
745 * @notyetdoced
746 *
747 * @see
748 * - createCustomFullStateDiagMatr()
749 * - setFullStateDiagMatr()
750 * - syncFullStateDiagMatr()
751 * - createDiagMatr()
752 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
753 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
754 */
756
757
758 /** @ingroup matrices_create
759 * @notyetdoced
760 *
761 * @see
762 * - createFullStateDiagMatr()
763 * - setFullStateDiagMatr()
764 * - syncFullStateDiagMatr()
765 * - createDiagMatr()
766 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
767 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
768 */
769 FullStateDiagMatr createCustomFullStateDiagMatr(int numQubits, int useDistrib, int useGpuAccel, int useMultithread);
770
771
772 /// @ingroup matrices_destroy
773 /// @notyetdoced
774 void destroyCompMatr(CompMatr matrix);
775
776
777 /// @ingroup matrices_destroy
778 /// @notyetdoced
779 void destroyDiagMatr(DiagMatr matrix);
780
781
782 /// @ingroup matrices_destroy
783 /// @notyetdoced
785
786
787 /// @ingroup matrices_sync
788 /// @notyetdoced
789 void syncCompMatr(CompMatr matr);
790
791
792 /// @ingroup matrices_sync
793 /// @notyetdoced
794 void syncDiagMatr(DiagMatr matr);
795
796
797 /// @ingroup matrices_sync
798 /// @notyetdoced
800
801
802#ifdef __cplusplus
803}
804#endif
805
806
807
808/*
809 * VARIABLE-SIZE MATRIX SETTERS VIA POINTERS
810 *
811 * These functions permit users to pass heap and stack pointers:
812 * - qcomp** ptr = malloc(...); setCompMatr(m, ptr);
813 * - qcomp* ptrs[8]; setCompMatr(m, ptrs);
814 * in both C and C++. By decay, they also permit arrays to diagonals:
815 * - qcomp* ptr = malloc(...); setDiagMatr(m, ptr);
816 * - qcomp arr[8]; setDiagMatr(m, arr);
817 */
818
819
820// de-mangle so below are directly callable by C and C++ binary
821#ifdef __cplusplus
822extern "C" {
823#endif
824
825
826 /** @ingroup matrices_setters
827 * @notyetdoced
828 *
829 * @see
830 * - setInlineCompMatr()
831 * - reportCompMatr()
832 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
833 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
834 */
835 void setCompMatr(CompMatr matr, qcomp** vals);
836
837
838 /** @ingroup matrices_setters
839 * @notyetdoced
840 *
841 * @see
842 * - setInlineDiagMatr()
843 * - reportDiagMatr()
844 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
845 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
846 */
847 void setDiagMatr(DiagMatr out, qcomp* in);
848
849
850 /** @ingroup matrices_setters
851 * @notyetdoced
852 * @notyettested
853 *
854 * @see
855 * - setInlineFullStateDiagMatr()
856 * - reportFullStateDiagMatr()
857 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) and
858 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
859 */
860 void setFullStateDiagMatr(FullStateDiagMatr out, qindex startInd, qcomp* in, qindex numElems);
861
862
863#ifdef __cplusplus
864}
865#endif
866
867
868
869/*
870 * VARIABLE-SIZE MATRIX SETTERS VIA ARRAYS & VECTORS
871 *
872 * which define additional overloads for arrays, VLAs, vectors and vector initialisation lists.
873 * C users can call:
874 * - qcomp arr[8][8]; setCompMatr(m, arr);
875 * - int n=8; qcomp arr[n][n]; setCompMatr(m, arr);
876 * - setCompMatr(m, (qcomp[8][8]) {{...}});
877 * - inline temporary VLA remains impossible even in C99, however
878 * and C++ users can call:
879 * - int n=8; std::vector vec(n); setCompMatr(m, vec);
880 * - setCompMatr(m, {{...}});
881 */
882
883
884#if defined(__cplusplus)
885
886 // C++ defines vector overloads, permitting inline initialisation
887
888
889 /** @ingroup matrices_setters
890 * @notyetdoced
891 * @cpponly
892 *
893 * @see
894 * - setInlineCompMatr()
895 * - reportCompMatr()
896 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
897 */
898 void setCompMatr(CompMatr out, std::vector<std::vector<qcomp>> in);
899
900
901 /** @ingroup matrices_setters
902 * @notyetdoced
903 * @cpponly
904 *
905 * @see
906 * - setInlineDiagMatr()
907 * - reportDiagMatr()
908 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
909 */
910 void setDiagMatr(DiagMatr out, std::vector<qcomp> in);
911
912
913 /** @ingroup matrices_setters
914 * @notyetdoced
915 * @notyettested
916 * @cpponly
917 *
918 * @see
919 * - setInlineFullStateDiagMatr()
920 * - reportFullStateDiagMatr()
921 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
922 */
923 void setFullStateDiagMatr(FullStateDiagMatr out, qindex startInd, std::vector<qcomp> in);
924
925
926 // C++ cannot accept 2D arrays at all, because it does not support C99 VLA.
927 // It can however accept 1D arrays (which decay to pointers) already to setDiagMatr()
928
929#elif !defined(_MSC_VER)
930
931 // C first defines a bespoke functions receiving C99 VLAs, which we have to define here in
932 // the header becauses the C++ source cannot use VLA, nor should we pass a 2D qcomp array
933 // directly between C and C++ binaries (due to limited interoperability)
934
935
936 // C must validate struct fields before accessing passed 2D arrays to avoid seg-faults
937 /// @private
938 extern void _validateParamsToSetCompMatrFromArr(CompMatr matr);
939
940
941 // static inline to avoid header-symbol duplication
942 /// @private
943 static inline void _setCompMatrFromArr(CompMatr matr, qcomp arr[matr.numRows][matr.numRows]) {
944 _validateParamsToSetCompMatrFromArr(matr);
945
946 // new ptrs array safely fits in stack, since it's sqrt-smaller than user's passed stack array
947 qcomp* ptrs[matr.numRows];
948
949 // collect pointers to each row of arr
950 for (qindex r=0; r<matr.numRows; r++)
951 ptrs[r] = arr[r];
952
953 // array decays to qcomp**, and *FromPtr function re-performs validation (eh)
954 setCompMatr(matr, ptrs); // validation gauranteed to pass
955 }
956
957
958 // C then overloads setCompMatr() to call the above VLA when given arrays, using C11 Generics.
959 // See the doc of getCompMatr1() above for an explanation of Generic, and its nuances
960
961
962 /// @neverdoced
963 #define setCompMatr(matr, ...) \
964 _Generic((__VA_ARGS__), \
965 qcomp** : setCompMatr, \
966 default : _setCompMatrFromArr \
967 )((matr), (__VA_ARGS__))
968
969 // spoofing above macro as functions to doc
970 #if 0
971
972 /** @ingroup matrices_setters
973 * @notyetdoced
974 * @macrodoc
975 * @conly
976 *
977 * @see
978 * - setInlineCompMatr()
979 * - reportCompMatr()
980 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) examples
981 */
982 void setCompMatr(CompMatr matr, qcomp arr[matr.numRows][matr.numRows]);
983
984 #endif
985
986
987 // no need to define bespoke overload for diagonal matrices, because 1D arrays decay to pointers
988
989#else
990
991 // MSVC's C11 does not support C99 VLAs (which the standard left optional, grr!), so
992 // we cannot support 2D-array initialisation of CompMatr at all. This means only the
993 // existing setCompMatr(qcomp**) declared previously is usable by MSVC C users
994
995#endif
996
997
998
999/*
1000 * VARIABLE-SIZE MATRIX SETTERS VIA LITERALS
1001 *
1002 * which enable C users to give inline 2D array literals without having to use the
1003 * VLA compound literal syntax. We expose these macros to C++ too for API consistency,
1004 * although C++'s vector overloads achieve the same thing.
1005 *
1006 * These empower C and C++ users to call e.g.
1007 * - setInlineCompMatr(m, 1, {{1,2},{3,4}})
1008 */
1009
1010
1011#if defined(__cplusplus)
1012
1013 // C++ redirects to vector overloads, passing initialiser lists. The args like 'numQb'
1014 // are superfluous, but needed for consistency with the C API, so we additionally
1015 // validate that they match the struct dimensions (which requires validating the structs).
1016
1017
1018 /** @ingroup matrices_setters
1019 * @notyetdoced
1020 * @cpponly
1021 *
1022 * @see
1023 * - reportCompMatr()
1024 * - createInlineCompMatr()
1025 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
1026 */
1027 void setInlineCompMatr(CompMatr matr, int numQb, std::vector<std::vector<qcomp>> in);
1028
1029
1030 /** @ingroup matrices_setters
1031 * @notyetdoced
1032 * @cpponly
1033 *
1034 * @see
1035 * - reportDiagMatr()
1036 * - createInlineDiagMatr()
1037 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
1038 */
1039 void setInlineDiagMatr(DiagMatr matr, int numQb, std::vector<qcomp> in);
1040
1041
1042 /** @ingroup matrices_setters
1043 * @notyetdoced
1044 * @notyettested
1045 * @cpponly
1046 *
1047 * @see
1048 * - reportFullStateDiagMatr()
1049 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
1050 */
1051 void setInlineFullStateDiagMatr(FullStateDiagMatr matr, qindex startInd, qindex numElems, std::vector<qcomp> in);
1052
1053
1054#elif !defined(_MSC_VER)
1055
1056 // C defines macros which add compound literal syntax so that the user's passed lists
1057 // become compile-time-sized temporary arrays. C99 does not permit inline-initialised
1058 // VLAs, so we cannot have the macro expand to add (qcomp[matr.numRows][matr.numRows])
1059 // in order to preclude passing 'numQb'. We ergo accept and validate 'numQb' macro param.
1060 // We define private inner-functions of a macro, in lieu of writing multiline macros
1061 // using do-while, just to better emulate a function call for users - e.g. they
1062 // can wrap the macro invocations with another function call, etc.
1063
1064
1065 // the C validators check 'numQb' is consistent with the struct, but cannot check the user's passed literal sizes
1066 /// @private
1067 extern void _validateParamsToSetInlineCompMatr(CompMatr matr, int numQb);
1068 /// @private
1069 extern void _validateParamsToSetInlineDiagMatr(DiagMatr matr, int numQb);
1070 /// @private
1071 extern void _validateParamsToSetInlineFullStateDiagMatr(FullStateDiagMatr matr, qindex startInd, qindex numElems);
1072
1073
1074 /// @private
1075 static inline void _setInlineCompMatr(CompMatr matr, int numQb, qcomp elems[1<<numQb][1<<numQb]) {
1076 _validateParamsToSetInlineCompMatr(matr, numQb);
1077 _setCompMatrFromArr(matr, elems); // validation gauranteed to pass
1078 }
1079
1080 /// @private
1081 static inline void _setInlineDiagMatr(DiagMatr matr, int numQb, qcomp elems[1<<numQb]) {
1082 _validateParamsToSetInlineDiagMatr(matr, numQb);
1083 setDiagMatr(matr, elems); // 1D array decays into pointer, validation gauranteed to pass
1084 }
1085
1086 /// @private
1087 static inline void _setInlineFullStateDiagMatr(FullStateDiagMatr matr, qindex startInd, qindex numElems, qcomp elems[numElems]) {
1088 _validateParamsToSetInlineFullStateDiagMatr(matr, startInd, numElems);
1089 setFullStateDiagMatr(matr, startInd, elems, numElems); // 1D array decays into pointer, validation gauranteed to pass
1090 }
1091
1092
1093 // happily, macro arg 'numQb' must be a compile-time constant, so there is no risk of
1094 // unexpectedly re-evaluating user expressions due to its repetition in the macro
1095
1096
1097 /// @neverdoced
1098 #define setInlineCompMatr(matr, numQb, ...) \
1099 _setInlineCompMatr((matr), (numQb), (qcomp[1<<(numQb)][1<<(numQb)]) __VA_ARGS__)
1100
1101 /// @neverdoced
1102 #define setInlineDiagMatr(matr, numQb, ...) \
1103 _setInlineDiagMatr((matr), (numQb), (qcomp[1<<(numQb)]) __VA_ARGS__)
1104
1105 /// @neverdoced
1106 #define setInlineFullStateDiagMatr(matr, startInd, numElems, ...) \
1107 _setInlineFullStateDiagMatr((matr), (startInd), (numElems), (qcomp[(numElems)]) __VA_ARGS__)
1108
1109 // spoofing above macros as functions to doc
1110 #if 0
1111
1112
1113 /** @ingroup matrices_setters
1114 * @notyetdoced
1115 * @macrodoc
1116 *
1117 * @see
1118 * - reportCompMatr()
1119 * - createInlineCompMatr()
1120 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) examples
1121 */
1122 void setInlineCompMatr(CompMatr matr, int numQb, {{ matrix }});
1123
1124
1125 /** @ingroup matrices_setters
1126 * @notyetdoced
1127 * @macrodoc
1128 *
1129 * @see
1130 * - reportDiagMatr()
1131 * - createInlineDiagMatr()
1132 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) examples
1133 */
1134 void setInlineDiagMatr(DiagMatr matr, int numQb, { list });
1135
1136
1137 /** @ingroup matrices_setters
1138 * @notyettested
1139 * @notyetdoced
1140 * @macrodoc
1141 *
1142 * @see
1143 * - reportFullStateDiagMatr()
1144 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) examples
1145 */
1146 void setInlineFullStateDiagMatr(FullStateDiagMatr matr, qindex startInd, qindex numElems, { list });
1147
1148
1149 #endif
1150
1151
1152#else
1153
1154 // MSVC C11 does not support C99 VLAs, so the inner functions above are illegal.
1155 // As such, we must choose to either forego the internal validation (which
1156 // checks that the passed matrix object has been prior created with e.g.
1157 // createDiagMatr), or expand the macro into a do-while which users cannot ergo
1158 // place inside another function call. We opt to preclude the latter, since it
1159 // seems an unlikely use-case (because the function returns void) and will give
1160 // a compile-time error, whereas removing validation could cause silent seg-faults
1161 // when users incorrectly initialise an un-created matrix.
1162
1163 // Note however that because MSVC does not support C99 VLA in C11, such that
1164 // _setCompMatrFromArr() was not defined, so we cannot define setInlineCompMatr();
1165 // MSVC C users simply miss out on this convenience function. Take it up with Bill!
1166
1167 /// @private
1168 extern void _validateParamsToSetInlineDiagMatr(DiagMatr matr, int numQb);
1169 /// @private
1170 extern void _validateParamsToSetInlineFullStateDiagMatr(FullStateDiagMatr matr, qindex startInd, qindex numElems);
1171
1172
1173 /// @neverdoced
1174 #define setInlineDiagMatr(matr, numQb, ...) \
1175 do { \
1176 _validateParamsToSetInlineDiagMatr((matr), (numQb)); \
1177 setDiagMatr((matr), (numQb), (qcomp[1<<(numQb)]) __VA_ARGS__); \
1178 } while (0)
1179
1180
1181 /// @neverdoced
1182 #define setInlineFullStateDiagMatr(matr, startInd, numElems, ...) \
1183 do { \
1184 _validateParamsToSetInlineFullStateDiagMatr((matr), (startInd), (numElems)); \
1185 setFullStateDiagMatr((matr), (startInd), (elems), (numElems)); \
1186 } while (0)
1187
1188
1189 // the above macros are documented in the previous #if branch
1190
1191#endif
1192
1193
1194
1195/*
1196 * VARIABLE-SIZE MATRIX CREATORS VIA LITERALS
1197 *
1198 * which simply combine the create*() and setInline*() functions, for
1199 * user convenience, and to reduce their risk of passing inconsistent params.
1200 * We do not define inline creators for FullStateDiagMatr, since the
1201 * creator automatically decides whether or not to distribute the matrix;
1202 * ergo the user cannot know how many elements to pass in their literal
1203 * (nor should they ever distribute data which fits into a single literal!)
1204 *
1205 * These empower C and C++ users to call e.g.
1206 * - CompMatr m = createInlineCompMatr(1, {{1,2},{3,4}})
1207 */
1208
1209
1210#if defined(__cplusplus)
1211
1212 // C++ accepts vector initialiser lists
1213
1214
1215 /** @ingroup matrices_create
1216 * @notyetdoced
1217 * @cpponly
1218 *
1219 * @see
1220 * - reportCompMatr()
1221 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
1222 */
1223 CompMatr createInlineCompMatr(int numQb, std::vector<std::vector<qcomp>> elems);
1224
1225
1226 /** @ingroup matrices_create
1227 * @notyetdoced
1228 * @cpponly
1229 *
1230 * @see
1231 * - reportDiagMatr()
1232 * - [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.cpp) examples
1233 */
1234 DiagMatr createInlineDiagMatr(int numQb, std::vector<qcomp> elems);
1235
1236
1237#elif !defined(_MSC_VER)
1238
1239 // C defines macros which add compound literal syntax so that the user's passed lists
1240 // become compile-time-sized temporary arrays. We use bespoke validation so that the
1241 // error messages reflect the name of the macro, rather than the inner called functions.
1242 // We define a private inner function per macro, in lieu of writing multiline macros
1243 // using do-while, just to better emulate a function call for users - e.g. they
1244 // can wrap the macro invocation with another function call.
1245
1246
1247 /// @private
1248 extern void _validateParamsToCreateInlineCompMatr(int numQb);
1249 /// @private
1250 extern void _validateParamsToCreateInlineDiagMatr(int numQb);
1251
1252
1253 /// @private
1254 static inline CompMatr _createInlineCompMatr(int numQb, qcomp elems[1<<numQb][1<<numQb]) {
1255 _validateParamsToCreateInlineCompMatr(numQb);
1256 CompMatr out = createCompMatr(numQb); // malloc failures will report 'createCompMatr', rather than 'inline' version. Alas!
1257 _setCompMatrFromArr(out, elems);
1258 return out;
1259 }
1260
1261 /// @private
1262 static inline DiagMatr _createInlineDiagMatr(int numQb, qcomp elems[1<<numQb]) {
1263 _validateParamsToCreateInlineDiagMatr(numQb);
1264 DiagMatr out = createDiagMatr(numQb); // malloc failures will report 'createCompMatr', rather than 'inline' version. Alas!
1265 setDiagMatr(out, elems); // 1D array decays to ptr
1266 return out;
1267 }
1268
1269
1270 /// @neverdoced
1271 #define createInlineCompMatr(numQb, ...) \
1272 _createInlineCompMatr((numQb), (qcomp[1<<(numQb)][1<<(numQb)]) __VA_ARGS__)
1273
1274 /// @neverdoced
1275 #define createInlineDiagMatr(numQb, ...) \
1276 _createInlineDiagMatr((numQb), (qcomp[1<<(numQb)]) __VA_ARGS__)
1277
1278 // spoofing above macros as functions to doc
1279 #if 0
1280
1281
1282 /** @ingroup matrices_create
1283 * @notyetdoced
1284 * @macrodoc
1285 *
1286 * @see
1287 * - reportCompMatr()
1288 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) examples
1289 */
1290 CompMatr createInlineCompMatr(int numQb, {{ matrix }});
1291
1292
1293 /** @ingroup matrices_create
1294 * @notyetdoced
1295 * @macrodoc
1296 *
1297 * @see
1298 * - reportDiagMatr()
1299 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/initialising_matrices.c) examples
1300 */
1301 DiagMatr createInlineDiagMatr(int numQb, { list });
1302
1303
1304 #endif
1305
1306#else
1307
1308 // MSVC's C11 does not support C99 VLA, so we cannot use the above inner functions.
1309 // The nuisance of trying to create, modify then return a matrix instance using
1310 // MSVC-specific preprocessors is too annoying, so Windows C users miss out! :(
1311
1312#endif
1313
1314
1315
1316/*
1317 * SPECIAL CREATORS AND SETTERS
1318 */
1319
1320
1321#ifdef __cplusplus
1322extern "C" {
1323#endif
1324
1325
1326 /// @todo
1327 /// add std::vector<int> overloads for C++ users for the
1328 /// below functions (missed during original overload work)
1329
1330
1331 /// @ingroup matrices_setters
1332 /// @notyetdoced
1333 /// @notyettested
1334 void setDiagMatrFromMultiVarFunc(DiagMatr out, qcomp (*func)(qindex*), int* numQubitsPerVar, int numVars, int areSigned);
1335
1336
1337 /// @ingroup matrices_setters
1338 /// @notyetdoced
1339 /// @notyettested
1340 void setDiagMatrFromMultiDimLists(DiagMatr out, void* lists, int* numQubitsPerDim, int numDims);
1341
1342
1343 /// @ingroup matrices_create
1344 /// @notyetdoced
1345 /// @notyettested
1347
1348
1349 /// @ingroup matrices_setters
1350 /// @notyetdoced
1351 /// @notyettested
1353
1354
1355 /// @ingroup matrices_setters
1356 /// @notyetdoced
1357 /// @notyettested
1358 void setFullStateDiagMatrFromMultiVarFunc(FullStateDiagMatr out, qcomp (*func)(qindex*), int* numQubitsPerVar, int numVars, int areSigned);
1359
1360
1361 /// @ingroup matrices_setters
1362 /// @notyetdoced
1363 /// @notyettested
1364 void setFullStateDiagMatrFromMultiDimLists(FullStateDiagMatr out, void* lists, int* numQubitsPerDim, int numDims);
1365
1366
1367#ifdef __cplusplus
1368}
1369#endif
1370
1371
1372
1373/*
1374 * MATRIX REPORTERS
1375 */
1376
1377
1378// de-mangle so below are directly callable by C binary
1379#ifdef __cplusplus
1380extern "C" {
1381#endif
1382
1383
1384 /** @ingroup matrices_reporters
1385 * @notyetdoced
1386 * @notyettested
1387 *
1388 * @see
1389 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_matrices.c) and
1390 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_matrices.cpp) examples
1391 */
1392 void reportCompMatr1(CompMatr1 matrix);
1393
1394
1395 /** @ingroup matrices_reporters
1396 * @notyetdoced
1397 * @notyettested
1398 *
1399 * @see
1400 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_matrices.c) and
1401 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_matrices.cpp) examples
1402 */
1403 void reportCompMatr2(CompMatr2 matrix);
1404
1405
1406 /** @ingroup matrices_reporters
1407 * @notyetdoced
1408 * @notyettested
1409 *
1410 * @see
1411 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_matrices.c) and
1412 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_matrices.cpp) examples
1413 */
1414 void reportCompMatr(CompMatr matrix);
1415
1416
1417 /** @ingroup matrices_reporters
1418 * @notyetdoced
1419 * @notyettested
1420 *
1421 * @see
1422 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_matrices.c) and
1423 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_matrices.cpp) examples
1424 */
1425 void reportDiagMatr1(DiagMatr1 matrix);
1426
1427
1428 /** @ingroup matrices_reporters
1429 * @notyetdoced
1430 * @notyettested
1431 *
1432 * @see
1433 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_matrices.c) and
1434 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_matrices.cpp) examples
1435 */
1436 void reportDiagMatr2(DiagMatr2 matrix);
1437
1438
1439 /// @ingroup matrices_reporters
1440 /// @notyetdoced
1441 /// @notyettested
1442 void reportDiagMatr(DiagMatr matrix);
1443
1444
1445 /** @ingroup matrices_reporters
1446 * @notyetdoced
1447 * @notyettested
1448 *
1449 * @see
1450 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_matrices.c) and
1451 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_matrices.cpp) examples
1452 */
1454
1455
1456#ifdef __cplusplus
1457}
1458#endif
1459
1460
1461
1462#endif // MATRICES_H
1463
1464/** @} */ // (end file-wide doxygen defgroup)
FullStateDiagMatr createCustomFullStateDiagMatr(int numQubits, int useDistrib, int useGpuAccel, int useMultithread)
Definition matrices.cpp:316
DiagMatr createInlineDiagMatr(int numQb, std::vector< qcomp > elems)
FullStateDiagMatr createFullStateDiagMatr(int numQubits)
Definition matrices.cpp:321
CompMatr createInlineCompMatr(int numQb, std::vector< std::vector< qcomp > > elems)
CompMatr createCompMatr(int numQubits)
Definition matrices.cpp:211
DiagMatr createDiagMatr(int numQubits)
Definition matrices.cpp:246
FullStateDiagMatr createFullStateDiagMatrFromPauliStrSum(PauliStrSum in)
Definition matrices.cpp:652
void destroyDiagMatr(DiagMatr matrix)
Definition matrices.cpp:397
void destroyFullStateDiagMatr(FullStateDiagMatr matrix)
Definition matrices.cpp:398
void destroyCompMatr(CompMatr matrix)
Definition matrices.cpp:396
static CompMatr2 getCompMatr2(qcomp **in)
Definition matrices.h:351
static CompMatr1 getCompMatr1(qcomp **in)
Definition matrices.h:325
static DiagMatr2 getDiagMatr2(qcomp *in)
Definition matrices.h:403
CompMatr1 getInlineCompMatr1({{ matrix }})
CompMatr2 getInlineCompMatr2({{ matrix }})
DiagMatr2 getInlineDiagMatr2({ list })
static DiagMatr1 getDiagMatr1(qcomp *in)
Definition matrices.h:378
DiagMatr1 getInlineDiagMatr1({ list })
void reportCompMatr2(CompMatr2 matrix)
Definition matrices.cpp:779
void reportDiagMatr1(DiagMatr1 matrix)
Definition matrices.cpp:781
void reportCompMatr(CompMatr matrix)
Definition matrices.cpp:780
void reportDiagMatr2(DiagMatr2 matrix)
Definition matrices.cpp:782
void reportCompMatr1(CompMatr1 matrix)
Definition matrices.cpp:778
void reportDiagMatr(DiagMatr matrix)
Definition matrices.cpp:783
void reportFullStateDiagMatr(FullStateDiagMatr matr)
Definition matrices.cpp:784
void setInlineDiagMatr(DiagMatr matr, int numQb, std::vector< qcomp > in)
void setFullStateDiagMatrFromMultiDimLists(FullStateDiagMatr out, void *lists, int *numQubitsPerDim, int numDims)
Definition matrices.cpp:724
void setDiagMatrFromMultiDimLists(DiagMatr out, void *lists, int *numQubitsPerDim, int numDims)
Definition matrices.cpp:702
void setFullStateDiagMatrFromMultiVarFunc(FullStateDiagMatr out, qcomp(*func)(qindex *), int *numQubitsPerVar, int numVars, int areSigned)
Definition matrices.cpp:688
void setInlineCompMatr(CompMatr matr, int numQb, std::vector< std::vector< qcomp > > in)
void setDiagMatr(DiagMatr out, qcomp *in)
Definition matrices.cpp:429
void setCompMatr(CompMatr matr, qcomp **vals)
Definition matrices.cpp:421
void setFullStateDiagMatr(FullStateDiagMatr out, qindex startInd, qcomp *in, qindex numElems)
Definition matrices.cpp:441
void setDiagMatrFromMultiVarFunc(DiagMatr out, qcomp(*func)(qindex *), int *numQubitsPerVar, int numVars, int areSigned)
Definition matrices.cpp:668
void setFullStateDiagMatrFromPauliStrSum(FullStateDiagMatr out, PauliStrSum in)
Definition matrices.cpp:635
void setInlineFullStateDiagMatr(FullStateDiagMatr matr, qindex startInd, qindex numElems, std::vector< qcomp > in)
void syncFullStateDiagMatr(FullStateDiagMatr matr)
Definition matrices.cpp:373
void syncDiagMatr(DiagMatr matr)
Definition matrices.cpp:372
void syncCompMatr(CompMatr matr)
Definition matrices.cpp:371
int * wasGpuSynced
Definition matrices.h:112
int * isApproxNonZero
Definition matrices.h:170
int * isStrictlyNonNegative
Definition matrices.h:171
int * wasGpuSynced
Definition matrices.h:178