The Quantum Exact Simulation Toolkit v4.2.0
Loading...
Searching...
No Matches
operations.h
1/** @file
2 * API signatures for effecting mostly physical and/or trace
3 * preserving operators, such as unitaries, gates and
4 * measurements, upon Quregs which are instantiated as both
5 * statevectors or density matrices. This excludes Trotterised
6 * gadgets and evolutions (exposed instead in trotterisation.h),
7 * functions to pre- or post-multiply operators upon density
8 * matrices (multiplication.h) and decoherence channels
9 * (decoherence.h).
10 *
11 * @author Tyson Jones
12 * @author Diogo Pratas Maia (non-unitary Pauli gadget)
13 *
14 * @defgroup operations Operations
15 * @ingroup api
16 * @brief Functions for effecting standard operators upon Quregs.
17 * @{
18 */
19
20#ifndef OPERATIONS_H
21#define OPERATIONS_H
22
23#include "quest/include/qureg.h"
24#include "quest/include/paulis.h"
25#include "quest/include/matrices.h"
26#include "quest/include/channels.h"
27
28#ifdef __cplusplus
29 #include <vector>
30#endif
31
32
33
34/*
35 * unlike some other headers, we here intermix the C and C++-only
36 * signatures, grouping them semantically & by their doc groups
37 */
38
39
40
41/**
42 * @defgroup op_compmatr1 CompMatr1
43 * @brief Functions for applying general one-qubit dense matrices, as CompMatr1.
44 * @{
45 */
46
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52
53/** Applies a general one-qubit dense unitary @p matrix to the specified @p target
54 * qubit of @p qureg.
55 *
56 * @diagram
57 * @dot
58digraph {
59 rankdir=LR;
60 node [fontsize=10, fontname="Menlo"];
61 edge [dir=none];
62
63 wireL [shape=plaintext, label="target"];
64 wireR [shape=plaintext, label=""];
65 gate [shape=box, label="matrix"];
66
67 wireL -> gate -> wireR
68}
69 * @enddot
70 *
71 * @formulae
72 *
73 * Let @f$ \hat{U} = @f$ @p matrix, @f$ t = @f$ @p target, and let @f$\hat{U}_t@f$
74 * notate operating @f$\hat{U}@f$ upon the @f$ t @f$-th qubit among@f$ N @f$, i.e.
75 * @f[
76 \hat{U}_t \equiv \id^{N-t} \otimes \hat{U} \otimes \id^{t-1}.
77 * @f]
78 * Then,
79 * - When @p qureg is a statevector @f$ \svpsi @f$, this function effects
80 * @f[
81 \svpsi \rightarrow \hat{U}_t \, \svpsi.
82 * @f]
83 * - When @p qureg is a density matrix @f$\dmrho@f$, this function effects
84 * @f[
85 \dmrho \rightarrow \hat{U}_t \, \dmrho \, {\hat{U}_t}^\dagger.
86 * @f]
87 *
88 * @constraints
89 *
90 * - Unitarity of @f$ \hat{U} = @f$ @p matrix requires that
91 * @f$ \hat{U} \hat{U}^\dagger = \id @f$. Validation will check that @p matrix is
92 * approximately unitary via
93 * @f[
94 \max\limits_{ij} \Big|\left(\hat{U} \hat{U}^\dagger - \id\right)_{ij}\Big|^2 \le \valeps
95 * @f]
96 * where the validation epsilon @f$ \valeps @f$ can be adjusted with setValidationEpsilon().
97 *
98 * @myexample
99 * ```
100 Qureg qureg = createQureg(5);
101
102 CompMatr1 matrix = getInlineCompMatr1({
103 {-1i/sqrt(2), 1i/sqrt(2)},
104 {(1i-1)/2, (1i-1)/2}
105 });
106
107 applyCompMatr1(qureg, 2, matrix);
108 * ```
109 *
110 * @param[in,out] qureg the state to modify.
111 * @param[in] target the index of the target qubit.
112 * @param[in] matrix the Z-basis unitary matrix to effect.
113 * @throws @validationerror
114 * - if @p qureg or @p matrix are uninitialised.
115 * - if @p matrix is not approximately unitary.
116 * - if @p target is an invalid qubit index.
117 * @see
118 * - getCompMatr1()
119 * - getInlineCompMatr1()
120 * - leftapplyCompMatr1()
121 * - rightapplyCompMatr1()
122 * - applyControlledCompMatr1()
123 * - applyCompMatr2()
124 * - applyCompMatr()
125 * @author Tyson Jones
126 */
127void applyCompMatr1(Qureg qureg, int target, CompMatr1 matrix);
128
129
130/** Applies a singly-controlled one-qubit dense unitary @p matrix to the specified
131 * @p target qubit of @p qureg.
132 *
133 * @diagram
134 * @dot
135digraph {
136 rankdir=LR;
137 node [fontsize=10, fontname="Menlo"];
138 edge [dir=none];
139
140 topWireL [shape=plaintext, label="control"];
141 topWireR [shape=plaintext, label=""];
142 ctrl [shape=circle, label="", width=.12, style=filled, fillcolor=black];
143
144 topWireL -> ctrl -> topWireR;
145
146 botWireL [shape=plaintext, label="target"];
147 botWireR [shape=plaintext, label=""];
148 gate [shape=box, label="matrix"];
149
150 botWireL -> gate -> botWireR;
151 ctrl -> gate;
152
153 {rank=same; topWireL; botWireL};
154 {rank=same; ctrl; gate};
155 {rank=same; topWireR; botWireR};
156}
157 * @enddot
158 *
159 * @formulae
160 *
161 * Let @f$ \hat{U} = @f$ @p matrix, @f$ t = @f$ @p target, @f$ c = @f$ @p control,
162 * and let @f$\hat{O}_q@f$ denote an operator upon the @f$q@f$-th qubit.
163 * This function effects operator
164 * @f[
165 C_c[\hat{U}_t] = \ketbra{0}{0}_c \otimes \id_t + \ketbra{1}{1}_c \otimes \hat{U}_t,
166 * @f]
167 * where @f$\hat{U}@f$ is effected upon basis states for which qubit @f$c@f$ has value `1`.
168 * For illustration, when @p control=0 and @p target=1, this function would effect
169 * @f[
170 C_1[\hat{U}_0] \equiv
171 \begin{pmatrix}
172 1 \\ & 1 \\ & & u_{00} & u_{01} \\ & & u_{10} & u_{11}
173 \end{pmatrix}.
174 * @f]
175 *
176 * This operation can be performed upon statevectors and density matrices.
177 *
178 * - When @p qureg is a statevector @f$ \svpsi @f$, this function effects
179 * @f[
180 \svpsi \rightarrow C_c[\hat{U}_t] \, \svpsi.
181 * @f]
182 * - When @p qureg is a density matrix @f$\dmrho@f$, this function effects
183 * @f[
184 \dmrho \rightarrow C_c[\hat{U}_t] \, \dmrho \, {C_c[\hat{U}_t]}^\dagger.
185 * @f]
186 *
187 * @constraints
188 *
189 * - Unitarity of @f$ \hat{U} = @f$ @p matrix requires that
190 * @f$ \hat{U} \hat{U}^\dagger = \id @f$. Validation will check that @p matrix is
191 * approximately unitary via
192 * @f[
193 \max\limits_{ij} \Big|\left(\hat{U} \hat{U}^\dagger - \id\right)_{ij}\Big|^2 \le \valeps
194 * @f]
195 * where the validation epsilon @f$ \valeps @f$ can be adjusted with setValidationEpsilon().
196 *
197 * @equivalences
198 *
199 * - This function is faster than, but mathematically equivalent to, initialising a two-qubit
200 * matrix (CompMatr2) to the @f$C_1[\hat{U}_0]@f$ matrix above, and calling applyCompMatr2():
201 * ```
202 CompMatr2 m = getInlineCompMatr2({
203 {1,0,0,0},
204 {0,1,0,0},
205 {0,0,u00,u01},
206 {0,0,u10,u11}});
207
208 applyCompMatr2(qureg, target, control);
209 * ```
210 *
211 * @myexample
212 * ```
213 Qureg qureg = createQureg(5);
214
215 CompMatr1 matrix = getInlineCompMatr1({
216 {-1i/sqrt(2), 1i/sqrt(2)},
217 {(1i-1)/2, (1i-1)/2}
218 });
219
220 // C_0[U_2]
221 applyControlledCompMatr1(qureg, 0, 2, matrix);
222 * ```
223
224 * @param[in,out] qureg the state to modify.
225 * @param[in] control the index of the control qubit.
226 * @param[in] target the index of the target qubit.
227 * @param[in] matrix the Z-basis unitary matrix to effect.
228 * @throws @validationerror
229 * - if @p qureg or @p matrix are uninitialised.
230 * - if @p matrix is not approximately unitary.
231 * - if @p control or @p target are an invalid qubit index.
232 * - if @p control and @p target overlap.
233 * @see
234 * - applyMultiControlledCompMatr1()
235 * - applyMultiStateControlledCompMatr1()
236 * @author Tyson Jones
237 */
238void applyControlledCompMatr1(Qureg qureg, int control, int target, CompMatr1 matrix);
239
240
241/** @notyetdoced
242 *
243 * Applies a multiply-controlled one-qubit dense unitary @p matrix to the specified
244 * @p target qubit of @p qureg.
245 *
246 * @diagram
247 * @dot
248digraph {
249 rankdir=LR;
250 node [fontsize=10, fontname="Menlo"];
251 edge [dir=none];
252
253 trailingCtrl [shape=plaintext, label="..."];
254
255 topWireL [shape=plaintext, label="controls[1]"];
256 topWireR [shape=plaintext, label=""];
257 topCtrl [shape=circle, label="", width=.12, style=filled, fillcolor=black];
258
259 topWireL -> topCtrl -> topWireR;
260
261 midWireL [shape=plaintext, label="controls[0]"];
262 midWireR [shape=plaintext, label=""];
263 midCtrl [shape=circle, label="", width=.12, style=filled, fillcolor=black];
264
265 midWireL -> midCtrl -> midWireR;
266
267 botWireL [shape=plaintext, label="target"];
268 botWireR [shape=plaintext, label=""];
269 gate [shape=box, label="matrix"];
270
271 botWireL -> gate -> botWireR;
272 trailingCtrl -> topCtrl -> midCtrl -> gate;
273
274 {rank=same; topWireL; midWireL; botWireL};
275 {rank=same; trailingCtrl; topCtrl; midCtrl; gate};
276 {rank=same; topWireR; midWireR; botWireR};
277}
278 * @enddot
279 *
280 * @formulae
281 *
282 * Let @f$ \vec{c} = @f$ @p controls, @f$ t = @f$ @p target, and @f$ \hat{U} = @f$ @p matrix.
283 * This functions effects operator
284 *
285 * @f[
286 C_{\vec{c}}[\hat{U}_t]
287 * @f]
288 *
289 * which is equivalent to applying @f$ \hat{U}_t @f$ upon only the computational basis states for which
290 * all control qubits are in the @f$ \ket{1} @f$ state.
291 *
292 * Precisely, let @f$n = 2^{|\vec{c}|}-1@f$. Then
293 * @f[
294 C_{\vec{c}}[\hat{U}_t] = \sum\limits_{i=0}^{n-1} \ketbra{i}{i}_{\vec{c}} \otimes \hat{\id}_t
295 + \ketbra{n}{n}_{\vec{c}} \otimes \hat{U}_t
296 * @f]
297 *
298 * @see
299 * - applyCompMatr1()
300 */
301void applyMultiControlledCompMatr1(Qureg qureg, int* controls, int numControls, int target, CompMatr1 matrix);
302
303
304/** @notyetdoced
305 *
306 * Applies an arbitrarily-controlled one-qubit dense unitary @p matrix to the specified
307 * @p target qubit of @p qureg, conditioned upon the @p controls being in the given @p states.
308 *
309 * @diagram
310 * @dot
311digraph {
312 rankdir=LR;
313 node [fontsize=10, fontname="Menlo"];
314 edge [dir=none];
315
316 trailingCtrl [shape=plaintext, label="..."];
317
318 topWireL [shape=plaintext, label="controls[1]"];
319 topWireR [shape=plaintext, label=""];
320 topCtrl [shape=circle, label="", width=.12, style=filled, fillcolor=black];
321
322 topWireL -> topCtrl -> topWireR;
323
324 midWireL [shape=plaintext, label="controls[0]"];
325 midWireR [shape=plaintext, label=""];
326 midCtrl [shape=circle, label="", width=.12, style=filled, fillcolor=white];
327
328 midWireL -> midCtrl -> midWireR;
329
330 botWireL [shape=plaintext, label="target"];
331 botWireR [shape=plaintext, label=""];
332 gate [shape=box, label="matrix"];
333
334 botWireL -> gate -> botWireR;
335 trailingCtrl -> topCtrl -> midCtrl -> gate;
336
337 {rank=same; topWireL; midWireL; botWireL};
338 {rank=same; trailingCtrl; topCtrl; midCtrl; gate};
339 {rank=same; topWireR; midWireR; botWireR};
340}
341 * @enddot
342 *
343 * @see
344 * - applyCompMatr1()
345 */
346void applyMultiStateControlledCompMatr1(Qureg qureg, int* controls, int* states, int numControls, int target, CompMatr1 matrix);
347
348
349// end de-mangler
350#ifdef __cplusplus
351}
352#endif
353
354#ifdef __cplusplus
355
356
357/// @notyettested
358/// @notyetvalidated
359/// @notyetdoced
360/// @cppvectoroverload
361/// @see applyMultiControlledCompMatr1()
362void applyMultiControlledCompMatr1(Qureg qureg, std::vector<int> controls, int target, CompMatr1 matrix);
363
364
365/// @notyettested
366/// @notyetvalidated
367/// @notyetdoced
368/// @cppvectoroverload
369/// @see applyMultiStateControlledCompMatr1()
370void applyMultiStateControlledCompMatr1(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target, CompMatr1 matrix);
371
372
373#endif // __cplusplus
374
375/** @} */
376
377
378
379/**
380 * @defgroup op_compmatr2 CompMatr2
381 * @brief Functions for applying general two-qubit dense matrices, as CompMatr2.
382 * @{
383 */
384
385
386#ifdef __cplusplus
387extern "C" {
388#endif
389
390
391/** @notyetdoced
392 *
393 * Applies a general two-qubit dense unitary @p matrix to qubits @p target1 and
394 * @p target2 (treated as increasing significance) of @p qureg.
395 *
396 * @diagram
397 * @dot
398digraph {
399 layout=neato;
400 rankdir=LR;
401 node [fontsize=10, fontname="Menlo"];
402 edge [dir=none];
403
404 topWireL [shape=plaintext, pos="0,0!", label="target2"];
405 topWireR [shape=plaintext, pos="2.5,0!", label=""];
406
407 botWireL [shape=plaintext, pos="0,.5!", label="target1"];
408 botWireR [shape=plaintext, pos="2.5,.5!", label=""];
409
410 gate [shape=rectangle, label="matrix", style=filled, fillcolor=white, height=1, pos="1.25,.25!"];
411
412 topWireL -> topWireR;
413 botWireL -> botWireR;
414}
415 * @enddot
416 *
417 * @see
418 * - applyCompMatr1()
419 * - leftapplyCompMatr2()
420 * - rightapplyCompMatr2()
421 */
422void applyCompMatr2(Qureg qureg, int target1, int target2, CompMatr2 matrix);
423
424
425/** @notyetdoced
426 *
427 * Applies a singly-controlled two-qubit dense unitary @p matrix to qubits
428 * @p target1 and @p target2 (treated as increasing significance) of @p qureg.
429 *
430 * @diagram
431 * @dot
432digraph {
433 layout=neato;
434 rankdir=LR;
435 node [fontsize=10, fontname="Menlo"];
436 edge [dir=none];
437
438 topWireL [shape=plaintext, pos="0,1!", label="control"];
439 topWireR [shape=plaintext, pos="2.5,1!", label=""];
440
441 midWireL [shape=plaintext, pos="0,0.5!", label="target2"];
442 midWireR [shape=plaintext, pos="2.5,0.5!", label=""];
443
444 botWireL [shape=plaintext, pos="0,0!", label="target1"];
445 botWireR [shape=plaintext, pos="2.5,0!", label=""];
446
447 gate [shape=rectangle, label="matrix", style=filled, fillcolor=white, height=1, pos="1.25,0.25!"];
448 ctrl [shape=circle, label="", width=.12, style=filled, fillcolor=black, pos="1.25,1!"];
449
450 topWireL -> ctrl -> topWireR;
451 midWireL -> midWireR;
452 botWireL -> botWireR;
453 ctrl -> gate;
454}
455 * @enddot
456 *
457 * @see
458 * - applyCompMatr2()
459 */
460void applyControlledCompMatr2(Qureg qureg, int control, int target1, int target2, CompMatr2 matr);
461
462
463/** @notyetdoced
464 *
465 * Applies a multiply-controlled two-qubit dense unitary @p matrix to qubits
466 * @p target1 and @p target2 (treated as increasing significance) of @p qureg.
467 *
468 * @diagram
469 * @dot
470digraph {
471 layout=neato;
472 rankdir=LR;
473 node [fontsize=10, fontname="Menlo"];
474 edge [dir=none];
475
476 tippytopWireL [shape=plaintext, pos="0,1.5!", label="controls[1]"];
477 tippytopWireR [shape=plaintext, pos="2.5,1.5!", label=""];
478
479 topWireL [shape=plaintext, pos="0,1!", label="controls[0]"];
480 topWireR [shape=plaintext, pos="2.5,1!", label=""];
481
482 midWireL [shape=plaintext, pos="0,0.5!", label="target2"];
483 midWireR [shape=plaintext, pos="2.5,0.5!", label=""];
484
485 botWireL [shape=plaintext, pos="0,0!", label="target1"];
486 botWireR [shape=plaintext, pos="2.5,0!", label=""];
487
488 gate [shape=rectangle, label="matrix", style=filled, fillcolor=white, height=1, pos="1.25,0.25!"];
489 ctrl1 [shape=circle, label="", width=.12, style=filled, fillcolor=black, pos="1.25,1!"];
490 ctrl2 [shape=circle, label="", width=.12, style=filled, fillcolor=black, pos="1.25,1.5!"];
491 trailingCtrl [shape=plaintext, label="...", pos="1.25,2!"];
492
493 tippytopWireL -> ctrl2 -> tippytopWireR;
494 topWireL -> ctrl1 -> topWireR;
495 midWireL -> midWireR;
496 botWireL -> botWireR;
497 trailingCtrl -> ctrl2 -> ctrl1 -> gate;
498}
499 * @enddot
500 *
501 * @see
502 * - applyCompMatr2()
503 */
504void applyMultiControlledCompMatr2(Qureg qureg, int* controls, int numControls, int target1, int target2, CompMatr2 matr);
505
506
507/** @notyetdoced
508 *
509 * Applies an arbitrarily-controlled two-qubit dense unitary @p matrix to qubits
510 * @p target1 and @p target2 (treated as increasing significance) of @p qureg,
511 * conditioned upon the @p controls being in the given @p states.
512 *
513 * @diagram
514 * @dot
515digraph {
516 layout=neato;
517 rankdir=LR;
518 node [fontsize=10, fontname="Menlo"];
519 edge [dir=none];
520
521 tippytopWireL [shape=plaintext, pos="0,1.5!", label="controls[1]"];
522 tippytopWireR [shape=plaintext, pos="2.5,1.5!", label=""];
523
524 topWireL [shape=plaintext, pos="0,1!", label="controls[0]"];
525 topWireR [shape=plaintext, pos="2.5,1!", label=""];
526
527 midWireL [shape=plaintext, pos="0,0.5!", label="target2"];
528 midWireR [shape=plaintext, pos="2.5,0.5!", label=""];
529
530 botWireL [shape=plaintext, pos="0,0!", label="target1"];
531 botWireR [shape=plaintext, pos="2.5,0!", label=""];
532
533 gate [shape=rectangle, label="matrix", style=filled, fillcolor=white, height=1, pos="1.25,0.25!"];
534 ctrl1 [shape=circle, label="", width=.12, style=filled, fillcolor=white, pos="1.25,1!"];
535 ctrl2 [shape=circle, label="", width=.12, style=filled, fillcolor=black, pos="1.25,1.5!"];
536 trailingCtrl [shape=plaintext, label="...", pos="1.25,2!"];
537
538 tippytopWireL -> ctrl2 -> tippytopWireR;
539 topWireL -> ctrl1 -> topWireR;
540 midWireL -> midWireR;
541 botWireL -> botWireR;
542 trailingCtrl -> ctrl2 -> ctrl1 -> gate;
543}
544 * @enddot
545 *
546 * @see
547 * - applyCompMatr2()
548 * - applyMultiStateControlledCompMatr1()
549 */
550void applyMultiStateControlledCompMatr2(Qureg qureg, int* controls, int* states, int numControls, int target1, int target2, CompMatr2 matr);
551
552
553// end de-mangler
554#ifdef __cplusplus
555}
556#endif
557
558#ifdef __cplusplus
559
560
561/// @notyettested
562/// @notyetvalidated
563/// @notyetdoced
564/// @cppvectoroverload
565/// @see applyMultiControlledCompMatr2()
566void applyMultiControlledCompMatr2(Qureg qureg, std::vector<int> controls, int target1, int target2, CompMatr2 matr);
567
568
569/// @notyettested
570/// @notyetvalidated
571/// @notyetdoced
572/// @cppvectoroverload
573/// @see applyMultiStateControlledCompMatr2()
574void applyMultiStateControlledCompMatr2(Qureg qureg, std::vector<int> controls, std::vector<int> states, int numControls, int target1, int target2, CompMatr2 matr);
575
576
577#endif // __cplusplus
578
579/** @} */
580
581
582
583/**
584 * @defgroup op_compmatr CompMatr
585 * @brief Functions for applying general many-target dense matrices, as CompMatr.
586 * @{
587 */
588
589
590#ifdef __cplusplus
591extern "C" {
592#endif
593
594
595/** @notyetdoced
596 *
597 * @formulae
598 *
599 * Let @f$ M = @f$ @p matrix.
600 * The qubits within @p targets are treated to be ordered least to most significant with respect
601 * to @f$ M @f$. That is, if @f$ M @f$ was hypothetically separable single-qubit matrices
602 * @f[
603 M \equiv \dots \otimes C \otimes B \otimes A
604 * @f]
605 * then this function would effect
606 * @f[
607 \hat{M}_{\text{targets}} \equiv A_{\text{targets}[0]} \cdot B_{\text{targets}[1]} \cdot C_{\text{targets}[2]} \cdot \dots
608 * @f]
609 *
610 * @see
611 * - applyCompMatr1()
612 * - leftapplyCompMatr()
613 * - rightapplyCompMatr()
614 */
615void applyCompMatr(Qureg qureg, int* targets, int numTargets, CompMatr matr);
616
617
618/// @notyetdoced
619/// @see
620/// - applyControlledCompMatr1()
621void applyControlledCompMatr(Qureg qureg, int control, int* targets, int numTargets, CompMatr matr);
622
623
624/// @notyetdoced
625/// @see
626/// - applyMultiControlledCompMatr1()
627void applyMultiControlledCompMatr(Qureg qureg, int* controls, int numControls, int* targets, int numTargets, CompMatr matr);
628
629
630/// @notyetdoced
631/// @see
632/// - applyMultiStateControlledCompMatr1()
633void applyMultiStateControlledCompMatr(Qureg qureg, int* controls, int* states, int numControls, int* targets, int numTargets, CompMatr matr);
634
635
636// end de-mangler
637#ifdef __cplusplus
638}
639#endif
640
641#ifdef __cplusplus
642
643
644/// @notyettested
645/// @notyetvalidated
646/// @notyetdoced
647/// @cppvectoroverload
648/// @see applyCompMatr()
649void applyCompMatr(Qureg qureg, std::vector<int> targets, CompMatr matr);
650
651
652/// @notyettested
653/// @notyetvalidated
654/// @notyetdoced
655/// @cppvectoroverload
656/// @see applyControlledCompMatr()
657void applyControlledCompMatr(Qureg qureg, int control, std::vector<int> targets, CompMatr matr);
658
659
660/// @notyettested
661/// @notyetvalidated
662/// @notyetdoced
663/// @cppvectoroverload
664/// @see applyMultiControlledCompMatr()
665void applyMultiControlledCompMatr(Qureg qureg, std::vector<int> controls, std::vector<int> targets, CompMatr matr);
666
667
668/// @notyettested
669/// @notyetvalidated
670/// @notyetdoced
671/// @cppvectoroverload
672/// @see applyMultiStateControlledCompMatr()
673void applyMultiStateControlledCompMatr(Qureg qureg, std::vector<int> controls, std::vector<int> states, std::vector<int> targets, CompMatr matr);
674
675
676#endif // __cplusplus
677
678/** @} */
679
680
681
682/**
683 * @defgroup op_diagmatr1 DiagMatr1
684 * @brief Functions for applying general one-qubit diagonal matrices, as DiagMatr1.
685 * @{
686 */
687
688
689#ifdef __cplusplus
690extern "C" {
691#endif
692
693
694/** @notyetdoced
695 * @see
696 * - applyCompMatr1()
697 * - leftapplyCompMatr2()
698 * - rightapplyCompMatr2()
699 */
700void applyDiagMatr1(Qureg qureg, int target, DiagMatr1 matr);
701
702
703/// @notyetdoced
704/// @see applyControlledCompMatr1()
705void applyControlledDiagMatr1(Qureg qureg, int control, int target, DiagMatr1 matr);
706
707
708/// @notyetdoced
709/// @see applyMultiControlledCompMatr1()
710void applyMultiControlledDiagMatr1(Qureg qureg, int* controls, int numControls, int target, DiagMatr1 matr);
711
712
713/// @notyetdoced
714/// @see applyMultiStateControlledCompMatr1()
715void applyMultiStateControlledDiagMatr1(Qureg qureg, int* controls, int* states, int numControls, int target, DiagMatr1 matr);
716
717
718// end de-mangler
719#ifdef __cplusplus
720}
721#endif
722
723#ifdef __cplusplus
724
725
726/// @notyettested
727/// @notyetvalidated
728/// @notyetdoced
729/// @cppvectoroverload
730/// @see applyMultiControlledDiagMatr1()
731void applyMultiControlledDiagMatr1(Qureg qureg, std::vector<int> controls, int target, DiagMatr1 matr);
732
733
734/// @notyettested
735/// @notyetvalidated
736/// @notyetdoced
737/// @cppvectoroverload
738/// @see applyMultiStateControlledDiagMatr1()
739void applyMultiStateControlledDiagMatr1(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target, DiagMatr1 matr);
740
741
742#endif // __cplusplus
743
744/** @} */
745
746
747
748/**
749 * @defgroup op_diagmatr2 DiagMatr2
750 * @brief Functions for applying general two-qubit diagonal matrices, as DiagMatr2.
751 * @{
752 */
753
754
755#ifdef __cplusplus
756extern "C" {
757#endif
758
759
760/// @notyetdoced
761/// @see applyCompMatr1()
762void applyDiagMatr2(Qureg qureg, int target1, int target2, DiagMatr2 matr);
763
764
765/// @notyetdoced
766/// @see applyControlledCompMatr1()
767void applyControlledDiagMatr2(Qureg qureg, int control, int target1, int target2, DiagMatr2 matr);
768
769
770/// @notyetdoced
771/// @see applyMultiControlledCompMatr1()
772void applyMultiControlledDiagMatr2(Qureg qureg, int* controls, int numControls, int target1, int target2, DiagMatr2 matr);
773
774
775/// @notyetdoced
776/// @see applyMultiStateControlledCompMatr1()
777void applyMultiStateControlledDiagMatr2(Qureg qureg, int* controls, int* states, int numControls, int target1, int target2, DiagMatr2 matr);
778
779
780// end de-mangler
781#ifdef __cplusplus
782}
783#endif
784
785#ifdef __cplusplus
786
787
788/// @notyettested
789/// @notyetvalidated
790/// @notyetdoced
791/// @cppvectoroverload
792/// @see applyMultiControlledDiagMatr2()
793void applyMultiControlledDiagMatr2(Qureg qureg, std::vector<int> controls, int target1, int target2, DiagMatr2 matr);
794
795
796/// @notyettested
797/// @notyetvalidated
798/// @notyetdoced
799/// @cppvectoroverload
800/// @see applyMultiStateControlledDiagMatr2()
801void applyMultiStateControlledDiagMatr2(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target1, int target2, DiagMatr2 matr);
802
803
804#endif // __cplusplus
805
806/** @} */
807
808
809
810/**
811 * @defgroup op_diagmatr DiagMatr
812 * @brief Functions for applying general many-qubit diagonal matrices, as DiagMatr.
813 * @{
814 */
815
816
817#ifdef __cplusplus
818extern "C" {
819#endif
820
821
822/// @notyetdoced
823/// @see applyCompMatr1()
824void applyDiagMatr(Qureg qureg, int* targets, int numTargets, DiagMatr matrix);
825
826
827/// @notyetdoced
828/// @see applyControlledCompMatr1()
829void applyControlledDiagMatr(Qureg qureg, int control, int* targets, int numTargets, DiagMatr matrix);
830
831
832/// @notyetdoced
833/// @see applyMultiControlledCompMatr1()
834void applyMultiControlledDiagMatr(Qureg qureg, int* controls, int numControls, int* targets, int numTargets, DiagMatr matrix);
835
836
837/// @notyetdoced
838/// @see applyMultiStateControlledCompMatr1()
839void applyMultiStateControlledDiagMatr(Qureg qureg, int* controls, int* states, int numControls, int* targets, int numTargets, DiagMatr matrix);
840
841
842/** @notyetdoced
843 *
844 * @formulae
845 *
846 * This function is equivalent to applyDiagMatr() except that @p matrix is raised to the given @p exponent.
847 */
848void applyDiagMatrPower(Qureg qureg, int* targets, int numTargets, DiagMatr matrix, qcomp exponent);
849
850
851/// @notyetdoced
852/// @see
853/// - applyDiagMatrPower()
854/// - applyControlledCompMatr1()
855void applyControlledDiagMatrPower(Qureg qureg, int control, int* targets, int numTargets, DiagMatr matrix, qcomp exponent);
856
857
858/// @notyetdoced
859/// @see
860/// - applyDiagMatrPower()
861/// - applyMultiControlledCompMatr1()
862void applyMultiControlledDiagMatrPower(Qureg qureg, int* controls, int numControls, int* targets, int numTargets, DiagMatr matrix, qcomp exponent);
863
864
865/// @notyetdoced
866/// @see
867/// - applyDiagMatrPower()
868/// - applyMultiStateControlledCompMatr1()
869void applyMultiStateControlledDiagMatrPower(Qureg qureg, int* controls, int* states, int numControls, int* targets, int numTargets, DiagMatr matrix, qcomp exponent);
870
871
872// end de-mangler
873#ifdef __cplusplus
874}
875#endif
876
877#ifdef __cplusplus
878
879
880/// @notyettested
881/// @notyetvalidated
882/// @notyetdoced
883/// @cppvectoroverload
884/// @see applyDiagMatr()
885void applyDiagMatr(Qureg qureg, std::vector<int> targets, DiagMatr matrix);
886
887
888/// @notyettested
889/// @notyetvalidated
890/// @notyetdoced
891/// @cppvectoroverload
892/// @see applyControlledDiagMatr()
893void applyControlledDiagMatr(Qureg qureg, int control, std::vector<int> targets, DiagMatr matrix);
894
895
896/// @notyettested
897/// @notyetvalidated
898/// @notyetdoced
899/// @cppvectoroverload
900/// @see applyMultiControlledDiagMatr()
901void applyMultiControlledDiagMatr(Qureg qureg, std::vector<int> controls, std::vector<int> targets, DiagMatr matrix);
902
903
904/// @notyettested
905/// @notyetvalidated
906/// @notyetdoced
907/// @cppvectoroverload
908/// @see applyMultiStateControlledDiagMatr()
909void applyMultiStateControlledDiagMatr(Qureg qureg, std::vector<int> controls, std::vector<int> states, std::vector<int> targets, DiagMatr matrix);
910
911
912/// @notyettested
913/// @notyetvalidated
914/// @notyetdoced
915/// @cppvectoroverload
916/// @see applyDiagMatrPower()
917void applyDiagMatrPower(Qureg qureg, std::vector<int> targets, DiagMatr matrix, qcomp exponent);
918
919
920/// @notyettested
921/// @notyetvalidated
922/// @notyetdoced
923/// @cppvectoroverload
924/// @see applyControlledDiagMatrPower()
925void applyControlledDiagMatrPower(Qureg qureg, int control, std::vector<int> targets, DiagMatr matrix, qcomp exponent);
926
927
928/// @notyettested
929/// @notyetvalidated
930/// @notyetdoced
931/// @cppvectoroverload
932/// @see applyMultiControlledDiagMatrPower()
933void applyMultiControlledDiagMatrPower(Qureg qureg, std::vector<int> controls, std::vector<int> targets, DiagMatr matrix, qcomp exponent);
934
935
936/// @notyettested
937/// @notyetvalidated
938/// @notyetdoced
939/// @cppvectoroverload
940/// @see applyMultiStateControlledDiagMatrPower()
941void applyMultiStateControlledDiagMatrPower(Qureg qureg, std::vector<int> controls, std::vector<int> states, std::vector<int> targets, DiagMatr matrix, qcomp exponent);
942
943
944#endif // __cplusplus
945
946/** @} */
947
948
949
950/**
951 * @defgroup op_fullstatediagmatr FullStateDiagMatr
952 * @brief Functions for applying general all-qubit diagonal matrices, as FullStateDiagMatr.
953 * @{
954 */
955
956
957#ifdef __cplusplus
958extern "C" {
959#endif
960
961
962/// @notyetdoced
963/// @notyetvalidated
965
966
967/// @notyetdoced
968/// @notyetvalidated
969/// @see
970/// - applyDiagMatrPower
971void applyFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qcomp exponent);
972
973
974// end de-mangler
975#ifdef __cplusplus
976}
977#endif
978
979
980/** @} */
981
982
983
984/**
985 * @defgroup op_fixed Fixed
986 * @brief Functions for applying the one-qubit S, T and Hadamard gates.
987 * @{
988 */
989
990
991#ifdef __cplusplus
992extern "C" {
993#endif
994
995
996/// @notyetdoced
997void applyS(Qureg qureg, int target);
998
999
1000/// @notyetdoced
1001void applyControlledS(Qureg qureg, int control, int target);
1002
1003
1004/// @notyetdoced
1005void applyMultiControlledS(Qureg qureg, int* controls, int numControls, int target);
1006
1007
1008/// @notyetdoced
1009/// @see applyMultiStateControlledCompMatr1()
1010void applyMultiStateControlledS(Qureg qureg, int* controls, int* states, int numControls, int target);
1011
1012
1013/// @notyetdoced
1014void applyT(Qureg qureg, int target);
1015
1016
1017/// @notyetdoced
1018void applyControlledT(Qureg qureg, int control, int target);
1019
1020
1021/// @notyetdoced
1022void applyMultiControlledT(Qureg qureg, int* controls, int numControls, int target);
1023
1024
1025/// @notyetdoced
1026/// @see applyMultiStateControlledCompMatr1()
1027void applyMultiStateControlledT(Qureg qureg, int* controls, int* states, int numControls, int target);
1028
1029
1030/// @notyetdoced
1031void applyHadamard(Qureg qureg, int target);
1032
1033
1034/// @notyetdoced
1035void applyControlledHadamard(Qureg qureg, int control, int target);
1036
1037
1038/// @notyetdoced
1039void applyMultiControlledHadamard(Qureg qureg, int* controls, int numControls, int target);
1040
1041
1042/// @notyetdoced
1043/// @see applyMultiStateControlledCompMatr1()
1044void applyMultiStateControlledHadamard(Qureg qureg, int* controls, int* states, int numControls, int target);
1045
1046
1047// end de-mangler
1048#ifdef __cplusplus
1049}
1050#endif
1051
1052#ifdef __cplusplus
1053
1054
1055/// @notyettested
1056/// @notyetvalidated
1057/// @notyetdoced
1058/// @cppvectoroverload
1059/// @see applyMultiControlledS()
1060void applyMultiControlledS(Qureg qureg, std::vector<int> controls, int target);
1061
1062
1063/// @notyettested
1064/// @notyetvalidated
1065/// @notyetdoced
1066/// @cppvectoroverload
1067/// @see applyMultiStateControlledS()
1068void applyMultiStateControlledS(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target);
1069
1070
1071/// @notyettested
1072/// @notyetvalidated
1073/// @notyetdoced
1074/// @cppvectoroverload
1075/// @see applyMultiControlledT()
1076void applyMultiControlledT(Qureg qureg, std::vector<int> controls, int target);
1077
1078
1079/// @notyettested
1080/// @notyetvalidated
1081/// @notyetdoced
1082/// @cppvectoroverload
1083/// @see applyMultiStateControlledT()
1084void applyMultiStateControlledT(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target);
1085
1086
1087/// @notyettested
1088/// @notyetvalidated
1089/// @notyetdoced
1090/// @cppvectoroverload
1091/// @see applyMultiControlledHadamard()
1092void applyMultiControlledHadamard(Qureg qureg, std::vector<int> controls, int target);
1093
1094
1095/// @notyettested
1096/// @notyetvalidated
1097/// @notyetdoced
1098/// @cppvectoroverload
1099/// @see applyMultiStateControlledHadamard()
1100void applyMultiStateControlledHadamard(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target);
1101
1102
1103#endif // __cplusplus
1104
1105/** @} */
1106
1107
1108
1109/**
1110 * @defgroup op_swap Swap
1111 * @brief Functions for applying the two-qubit SWAP and related gates.
1112 * @{
1113 */
1114
1115
1116#ifdef __cplusplus
1117extern "C" {
1118#endif
1119
1120
1121/** Applies a SWAP gate between @p qubit1 and @p qubit2 of @p qureg.
1122 *
1123 * @diagram
1124 * @dot
1125digraph {
1126 rankdir=LR;
1127 layout=neato;
1128 node [fontsize=10, fontname="Menlo"];
1129 edge [dir=none];
1130
1131 topWireL [shape=plaintext, label="qubit2", pos="0,.5!"];
1132 topWireM [shape=point, label="", width=0, pos=".75,.5!"];
1133 topWireR [shape=plaintext, label="", pos="1.5,.5!"];
1134
1135 botWireL [shape=plaintext, label="qubit1", pos="0,0!"];
1136 botWireM [shape=point, label="", width=0, pos=".75,0!"];
1137 botWireR [shape=plaintext, label="", pos="1.5,0!"];
1138
1139 topWireL -> topWireR;
1140 botWireL -> botWireR;
1141 botWireM -> topWireM;
1142
1143 topX [shape=plaintext, label="✕", pos=".75,.5!", fontsize=15];
1144 botX [shape=plaintext, label="✕", pos=".75,0!", fontsize=15];
1145}
1146 * @enddot
1147 *
1148 * @notyetdoced
1149 */
1150void applySwap(Qureg qureg, int qubit1, int qubit2);
1151
1152
1153/// @notyetdoced
1154void applyControlledSwap(Qureg qureg, int control, int qubit1, int qubit2);
1155
1156
1157/// @notyetdoced
1158void applyMultiControlledSwap(Qureg qureg, int* controls, int numControls, int qubit1, int qubit2);
1159
1160
1161/// @notyetdoced
1162/// @see applyMultiStateControlledCompMatr1()
1163void applyMultiStateControlledSwap(Qureg qureg, int* controls, int* states, int numControls, int qubit1, int qubit2);
1164
1165
1166/// @notyetdoced
1167void applySqrtSwap(Qureg qureg, int qubit1, int qubit2);
1168
1169
1170/// @notyetdoced
1171void applyControlledSqrtSwap(Qureg qureg, int control, int qubit1, int qubit2);
1172
1173
1174/// @notyetdoced
1175void applyMultiControlledSqrtSwap(Qureg qureg, int* controls, int numControls, int qubit1, int qubit2);
1176
1177
1178/// @notyetdoced
1179/// @see applyMultiStateControlledCompMatr1()
1180void applyMultiStateControlledSqrtSwap(Qureg qureg, int* controls, int* states, int numControls, int qubit1, int qubit2);
1181
1182
1183// end de-mangler
1184#ifdef __cplusplus
1185}
1186#endif
1187
1188#ifdef __cplusplus
1189
1190
1191/// @notyettested
1192/// @notyetvalidated
1193/// @notyetdoced
1194/// @cppvectoroverload
1195/// @see applyMultiControlledSwap()
1196void applyMultiControlledSwap(Qureg qureg, std::vector<int> controls, int qubit1, int qubit2);
1197
1198
1199/// @notyettested
1200/// @notyetvalidated
1201/// @notyetdoced
1202/// @cppvectoroverload
1203/// @see applyMultiStateControlledSwap()
1204void applyMultiStateControlledSwap(Qureg qureg, std::vector<int> controls, std::vector<int> states, int qubit1, int qubit2);
1205
1206
1207/// @notyettested
1208/// @notyetvalidated
1209/// @notyetdoced
1210/// @cppvectoroverload
1211/// @see applyMultiControlledSqrtSwap()
1212void applyMultiControlledSqrtSwap(Qureg qureg, std::vector<int> controls, int qubit1, int qubit2);
1213
1214
1215/// @notyettested
1216/// @notyetvalidated
1217/// @notyetdoced
1218/// @cppvectoroverload
1219/// @see applyMultiStateControlledSqrtSwap()
1220void applyMultiStateControlledSqrtSwap(Qureg qureg, std::vector<int> controls, std::vector<int> states, int numControls, int qubit1, int qubit2);
1221
1222
1223#endif // __cplusplus
1224
1225/** @} */
1226
1227
1228
1229/**
1230 * @defgroup op_pauli Pauli
1231 * @brief Functions for applying the individual one-qubit Pauli operators.
1232 * @{
1233 */
1234
1235
1236#ifdef __cplusplus
1237extern "C" {
1238#endif
1239
1240
1241/// @notyetdoced
1242void applyPauliX(Qureg qureg, int target);
1243
1244
1245/// @notyetdoced
1246void applyPauliY(Qureg qureg, int target);
1247
1248
1249/// @notyetdoced
1250void applyPauliZ(Qureg qureg, int target);
1251
1252
1253/// @notyetdoced
1254void applyControlledPauliX(Qureg qureg, int control, int target);
1255
1256
1257/// @notyetdoced
1258void applyControlledPauliY(Qureg qureg, int control, int target);
1259
1260
1261/// @notyetdoced
1262void applyControlledPauliZ(Qureg qureg, int control, int target);
1263
1264
1265/// @notyetdoced
1266void applyMultiControlledPauliX(Qureg qureg, int* controls, int numControls, int target);
1267
1268
1269/// @notyetdoced
1270void applyMultiControlledPauliY(Qureg qureg, int* controls, int numControls, int target);
1271
1272
1273/// @notyetdoced
1274void applyMultiControlledPauliZ(Qureg qureg, int* controls, int numControls, int target);
1275
1276
1277/// @notyetdoced
1278/// @see applyMultiStateControlledCompMatr1()
1279void applyMultiStateControlledPauliX(Qureg qureg, int* controls, int* states, int numControls, int target);
1280
1281
1282/// @notyetdoced
1283/// @see applyMultiStateControlledCompMatr1()
1284void applyMultiStateControlledPauliY(Qureg qureg, int* controls, int* states, int numControls, int target);
1285
1286
1287/// @notyetdoced
1288/// @see applyMultiStateControlledCompMatr1()
1289void applyMultiStateControlledPauliZ(Qureg qureg, int* controls, int* states, int numControls, int target);
1290
1291
1292// end de-mangler
1293#ifdef __cplusplus
1294}
1295#endif
1296
1297#ifdef __cplusplus
1298
1299
1300/// @notyettested
1301/// @notyetvalidated
1302/// @notyetdoced
1303/// @cppvectoroverload
1304/// @see applyMultiControlledPauliX()
1305void applyMultiControlledPauliX(Qureg qureg, std::vector<int> controls, int target);
1306
1307
1308/// @notyettested
1309/// @notyetvalidated
1310/// @notyetdoced
1311/// @cppvectoroverload
1312/// @see applyMultiControlledPauliY()
1313void applyMultiControlledPauliY(Qureg qureg, std::vector<int> controls, int target);
1314
1315
1316/// @notyettested
1317/// @notyetvalidated
1318/// @notyetdoced
1319/// @cppvectoroverload
1320/// @see applyMultiControlledPauliZ()
1321void applyMultiControlledPauliZ(Qureg qureg, std::vector<int> controls, int target);
1322
1323
1324/// @notyettested
1325/// @notyetvalidated
1326/// @notyetdoced
1327/// @cppvectoroverload
1328/// @see applyMultiStateControlledPauliX()
1329void applyMultiStateControlledPauliX(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target);
1330
1331
1332/// @notyettested
1333/// @notyetvalidated
1334/// @notyetdoced
1335/// @cppvectoroverload
1336/// @see applyMultiStateControlledPauliY()
1337void applyMultiStateControlledPauliY(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target);
1338
1339
1340/// @notyettested
1341/// @notyetvalidated
1342/// @notyetdoced
1343/// @cppvectoroverload
1344/// @see applyMultiStateControlledPauliZ()
1345void applyMultiStateControlledPauliZ(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target);
1346
1347
1348#endif // __cplusplus
1349
1350/** @} */
1351
1352
1353
1354/**
1355 * @defgroup op_paulistr PauliStr
1356 * @brief Functions for applying a tensor product of Pauli operators, as a PauliStr
1357 * @{
1358 */
1359
1360
1361#ifdef __cplusplus
1362extern "C" {
1363#endif
1364
1365
1366/// @notyetdoced
1367void applyPauliStr(Qureg qureg, PauliStr str);
1368
1369
1370/// @notyetdoced
1371void applyControlledPauliStr(Qureg qureg, int control, PauliStr str);
1372
1373
1374/// @notyetdoced
1375void applyMultiControlledPauliStr(Qureg qureg, int* controls, int numControls, PauliStr str);
1376
1377
1378/// @notyetdoced
1379/// @see applyMultiStateControlledCompMatr1()
1380void applyMultiStateControlledPauliStr(Qureg qureg, int* controls, int* states, int numControls, PauliStr str);
1381
1382
1383// end de-mangler
1384#ifdef __cplusplus
1385}
1386#endif
1387
1388#ifdef __cplusplus
1389
1390
1391/// @notyettested
1392/// @notyetvalidated
1393/// @notyetdoced
1394/// @cppvectoroverload
1395/// @see applyMultiControlledPauliStr()
1396void applyMultiControlledPauliStr(Qureg qureg, std::vector<int> controls, PauliStr str);
1397
1398
1399/// @notyettested
1400/// @notyetvalidated
1401/// @notyetdoced
1402/// @cppvectoroverload
1403/// @see applyMultiStateControlledPauliStr()
1404void applyMultiStateControlledPauliStr(Qureg qureg, std::vector<int> controls, std::vector<int> states, PauliStr str);
1405
1406
1407#endif // __cplusplus
1408
1409/** @} */
1410
1411
1412
1413/**
1414 * @defgroup op_rotation Rotations
1415 * @brief Functions for applying one-qubit rotations around Pauli and arbitrary axis.
1416 * @{
1417 */
1418
1419
1420#ifdef __cplusplus
1421extern "C" {
1422#endif
1423
1424
1425/** @notyetdoced
1426 *
1427 * @formulae
1428 *
1429 * Let @f$ \theta = @f$ @p angle.
1430 * This function effects unitary
1431 * @f[
1432 \hat{R}_{x}(\theta)
1433 =
1434 \exp \left(
1435 - \iu \frac{\theta}{2}
1436 \hat{\sigma}_x
1437 \right)
1438 * @f]
1439 * upon the @p target qubit, where @f$ \hat{\sigma}_x @f$ is the Pauli X matrix.
1440 *
1441 * @equivalences
1442 *
1443 * - This function is entirely equivalent to calling applyPauliGadget() with a single-site PauliStr.
1444 * ```
1445 applyPauliGadget(qureg, getInlinePauliStr("X", {target}), angle);
1446 * ```
1447 * - This function is faster than, but otherwise equivalent to, invoking applyRotateAroundAxis()
1448 * with an axis vector equal to the X-axis.
1449 * ```
1450 applyRotateAroundAxis(qureg, target, qreal angle, 1,0,0);
1451 * ```
1452 * - This function is faster than, but otherwise equivalent to, effecting @f$ \hat{R}_{x}(\theta) @f$ as a CompMatr1.
1453 * ```
1454 qcomp c = cos(angle/2);
1455 qcomp s = sin(angle/2) * (-1.i);
1456 CompMatr1 matr = getInlineCompMatr1({{c, s}, {s, c}});
1457 applyCompMatr1(qureg, target, matr);
1458 * ```
1459 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
1460 */
1461void applyRotateX(Qureg qureg, int target, qreal angle);
1462
1463
1464/** @notyetdoced
1465 *
1466 * @formulae
1467 *
1468 * Let @f$ \theta = @f$ @p angle.
1469 * This function effects unitary
1470 * @f[
1471 \hat{R}_{y}(\theta)
1472 =
1473 \exp \left(
1474 - \iu \frac{\theta}{2}
1475 \hat{\sigma}_y
1476 \right)
1477 * @f]
1478 * upon the @p target qubit, where @f$ \hat{\sigma}_y @f$ is the Pauli Y matrix.
1479 *
1480 * @equivalences
1481 *
1482 * - This function is entirely equivalent to calling applyPauliGadget() with a single-site PauliStr.
1483 * ```
1484 applyPauliGadget(qureg, getInlinePauliStr("Y", {target}), angle);
1485 * ```
1486 * - This function is faster than, but otherwise equivalent to, invoking applyRotateAroundAxis()
1487 * with an axis vector equal to the Y-axis.
1488 * ```
1489 applyRotateAroundAxis(qureg, target, qreal angle, 0,1,0);
1490 * ```
1491 * - This function is faster than, but otherwise equivalent to, effecting @f$ \hat{R}_{y}(\theta) @f$ as a CompMatr1.
1492 * ```
1493 qcomp c = cos(angle/2);
1494 qcomp s = sin(angle/2);
1495 CompMatr1 matr = getInlineCompMatr1({{c, -s}, {s, c}});
1496 applyCompMatr1(qureg, target, matr);
1497 * ```
1498 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
1499 */
1500void applyRotateY(Qureg qureg, int target, qreal angle);
1501
1502
1503/** @notyetdoced
1504 *
1505 * @formulae
1506 *
1507 * Let @f$ \theta = @f$ @p angle.
1508 * This function effects unitary
1509 * @f[
1510 \hat{R}_{z}(\theta)
1511 =
1512 \exp \left(
1513 - \iu \frac{\theta}{2}
1514 \hat{\sigma}_z
1515 \right)
1516 * @f]
1517 * upon the @p target qubit, where @f$ \hat{\sigma}_z @f$ is the Pauli Z matrix.
1518 *
1519 * @equivalences
1520 *
1521 * - This function is entirely equivalent to calling applyPauliGadget() with a single-site PauliStr.
1522 * ```
1523 applyPauliGadget(qureg, getInlinePauliStr("Z", {target}), angle);
1524 * ```
1525 * - This function is faster than, but otherwise equivalent to, invoking applyRotateAroundAxis()
1526 * with an axis vector equal to the Z-axis.
1527 * ```
1528 applyRotateAroundAxis(qureg, target, qreal angle, 0,0,1);
1529 * ```
1530 * - This function is faster than, but otherwise equivalent to, effecting @f$ \hat{R}_{z}(\theta) @f$ as a DiagMatr1.
1531 * ```
1532 qcomp a = cexp(- angle / 2 * 1.i);
1533 qcomp b = cexp( angle / 2 * 1.i);
1534 DiagMatr1 matr = getInlineDiagMatr1({a, b});
1535 applyDiagMatr1(qureg, target, matr);
1536 * ```
1537 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
1538 */
1539void applyRotateZ(Qureg qureg, int target, qreal angle);
1540
1541
1542/// @notyetdoced
1543void applyControlledRotateX(Qureg qureg, int control, int target, qreal angle);
1544
1545
1546/// @notyetdoced
1547void applyControlledRotateY(Qureg qureg, int control, int target, qreal angle);
1548
1549
1550/// @notyetdoced
1551void applyControlledRotateZ(Qureg qureg, int control, int target, qreal angle);
1552
1553
1554/// @notyetdoced
1555void applyMultiControlledRotateX(Qureg qureg, int* controls, int numControls, int target, qreal angle);
1556
1557
1558/// @notyetdoced
1559void applyMultiControlledRotateY(Qureg qureg, int* controls, int numControls, int target, qreal angle);
1560
1561
1562/// @notyetdoced
1563void applyMultiControlledRotateZ(Qureg qureg, int* controls, int numControls, int target, qreal angle);
1564
1565
1566/// @notyetdoced
1567/// @see
1568/// - applyRotateX()
1569/// - applyMultiStateControlledCompMatr1()
1570void applyMultiStateControlledRotateX(Qureg qureg, int* controls, int* states, int numControls, int target, qreal angle);
1571
1572
1573/// @notyetdoced
1574/// @see
1575/// - applyRotateY()
1576/// - applyMultiStateControlledCompMatr1()
1577void applyMultiStateControlledRotateY(Qureg qureg, int* controls, int* states, int numControls, int target, qreal angle);
1578
1579
1580/// @notyetdoced
1581/// @see
1582/// - applyRotateZ()
1583/// - applyMultiStateControlledCompMatr1()
1584void applyMultiStateControlledRotateZ(Qureg qureg, int* controls, int* states, int numControls, int target, qreal angle);
1585
1586
1587/** @notyetdoced
1588 *
1589 * @formulae
1590 *
1591 * Let @f$ \theta = @f$ @p angle and @f$ \vec{n} = ( @f$ @p axisX, @p axisY, @p axisZ @f$ ) @f$,
1592 * with corresponding unit vector @f$ \bar{n} @f$.
1593 * Further, let @f$ \vec{\sigma} = (\hat{\sigma}_x, \hat{\sigma}_y, \hat{\sigma}_z) @f$ denote a vector of the Pauli matrices.
1594 *
1595 * This function effects unitary
1596 * @f[
1597 \hat{R}_{\bar{n}}(\theta)
1598 =
1599 \exp \left(
1600 - \iu \frac{\theta}{2}
1601 \bar{n} \cdot \vec{\sigma}
1602 \right)
1603 * @f]
1604 * upon the target qubit. Explicitly,
1605 * @f[
1606 \hat{R}_{\bar{n}}(\theta)
1607 \equiv
1608 \begin{pmatrix}
1609 \cos\left( \frac{\theta}{2} \right) - \iu \, \bar{n}_z \sin\left( \frac{\theta}{2} \right)
1610 &
1611 - \, (\bar{n}_y + \bar{n}_x \, \iu ) \sin\left( \frac{\theta}{2} \right)
1612 \\
1613 (\bar{n}_y - \bar{n}_x \, \iu ) \sin\left( \frac{\theta}{2} \right)
1614 &
1615 \cos\left( \frac{\theta}{2} \right) + \iu \, \bar{n}_z \sin\left( \frac{\theta}{2} \right)
1616 \end{pmatrix}
1617 * @f]
1618 * where
1619 * @f[
1620 \bar{n}_i
1621 =
1622 \frac{\vec{n}_i}{\| \vec{n} \|_2}
1623 =
1624 \frac{\vec{n}_i}{ \sqrt{ {\vec{n}_x}^2 + {\vec{n}_y}^2 + {\vec{n}_z}^2 } }.
1625 * @f]
1626 *
1627 * @equivalences
1628 *
1629 * - Assuming @f$ \| \vec{n} \|_2 \ne 0 @f$, this function is agnostic to the normalisation
1630 * of the axis vector.
1631 * ```
1632 applyRotateAroundAxis(qureg, target, angle, x, y, z);
1633 applyRotateAroundAxis(qureg, target, angle, 5*x,5*y,5*z); // equivalent
1634 * ```
1635 * - This function is entirely equivalent to preparing @f$ \hat{R}_{\bar{n}}(\theta) @f$
1636 * as a CompMatr1 and effecting it upon the state via applyCompMatr1().
1637 * - This function is both more accurate and efficient than equivalently instantiating a
1638 * three-term PauliStrSum @f$ \hat{H} = \bar{n} \cdot \vec{\sigma}@f$ and effecting
1639 * @f$ \exp \left(\iu \alpha \hat{H} \right) @f$ via applyTrotterizedPauliStrSumGadget()
1640 * with @f$ \alpha = - \theta/2 @f$ and very many repetitions.
1641 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
1642 */
1643void applyRotateAroundAxis(Qureg qureg, int target, qreal angle, qreal axisX, qreal axisY, qreal axisZ);
1644
1645
1646/// @notyetdoced
1647void applyControlledRotateAroundAxis(Qureg qureg, int ctrl, int targ, qreal angle, qreal axisX, qreal axisY, qreal axisZ);
1648
1649
1650/// @notyetdoced
1651void applyMultiControlledRotateAroundAxis(Qureg qureg, int* ctrls, int numCtrls, int targ, qreal angle, qreal axisX, qreal axisY, qreal axisZ);
1652
1653
1654/// @notyetdoced
1655/// @see
1656/// - applyRotateAroundAxis()
1657/// - applyMultiStateControlledCompMatr1()
1658void applyMultiStateControlledRotateAroundAxis(Qureg qureg, int* ctrls, int* states, int numCtrls, int targ, qreal angle, qreal axisX, qreal axisY, qreal axisZ);
1659
1660
1661// end de-mangler
1662#ifdef __cplusplus
1663}
1664#endif
1665
1666#ifdef __cplusplus
1667
1668
1669/// @notyettested
1670/// @notyetvalidated
1671/// @notyetdoced
1672/// @cppvectoroverload
1673/// @see applyMultiControlledRotateX()
1674void applyMultiControlledRotateX(Qureg qureg, std::vector<int> controls, int target, qreal angle);
1675
1676
1677/// @notyettested
1678/// @notyetvalidated
1679/// @notyetdoced
1680/// @cppvectoroverload
1681/// @see applyMultiControlledRotateY()
1682void applyMultiControlledRotateY(Qureg qureg, std::vector<int> controls, int target, qreal angle);
1683
1684
1685/// @notyettested
1686/// @notyetvalidated
1687/// @notyetdoced
1688/// @cppvectoroverload
1689/// @see applyMultiControlledRotateZ()
1690void applyMultiControlledRotateZ(Qureg qureg, std::vector<int> controls, int target, qreal angle);
1691
1692
1693/// @notyettested
1694/// @notyetvalidated
1695/// @notyetdoced
1696/// @cppvectoroverload
1697/// @see applyMultiStateControlledRotateX()
1698void applyMultiStateControlledRotateX(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target, qreal angle);
1699
1700
1701/// @notyettested
1702/// @notyetvalidated
1703/// @notyetdoced
1704/// @cppvectoroverload
1705/// @see applyMultiStateControlledRotateY()
1706void applyMultiStateControlledRotateY(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target, qreal angle);
1707
1708
1709/// @notyettested
1710/// @notyetvalidated
1711/// @notyetdoced
1712/// @cppvectoroverload
1713/// @see applyMultiStateControlledRotateZ()
1714void applyMultiStateControlledRotateZ(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target, qreal angle);
1715
1716
1717/// @notyettested
1718/// @notyetvalidated
1719/// @notyetdoced
1720/// @cppvectoroverload
1721/// @see applyMultiControlledRotateAroundAxis()
1722void applyMultiControlledRotateAroundAxis(Qureg qureg, std::vector<int> ctrls, int targ, qreal angle, qreal axisX, qreal axisY, qreal axisZ);
1723
1724
1725/// @notyettested
1726/// @notyetvalidated
1727/// @notyetdoced
1728/// @cppvectoroverload
1729/// @see applyMultiStateControlledRotateAroundAxis()
1730void applyMultiStateControlledRotateAroundAxis(Qureg qureg, std::vector<int> ctrls, std::vector<int> states, int targ, qreal angle, qreal axisX, qreal axisY, qreal axisZ);
1731
1732
1733#endif // __cplusplus
1734
1735/** @} */
1736
1737
1738
1739/**
1740 * @defgroup op_pauligadget PauliStr gadgets
1741 * @brief Functions for applying many-qubit rotations around arbitrary PauliStr.
1742 * @{
1743 */
1744
1745
1746#ifdef __cplusplus
1747extern "C" {
1748#endif
1749
1750
1751/** @notyetdoced
1752 *
1753 * @formulae
1754 *
1755 * Let @f$ \hat{\sigma} = @f$ @p str and @f$ \theta = @f$ @p angle.
1756 *
1757 * This function effects unitary
1758 * @f[
1759 R_{\hat{\sigma}}(\theta) = \exp \left( - \iu \, \frac{\theta}{2} \, \hat{\sigma} \right),
1760 * @f]
1761 * which affects only the qubits for which @f$ \hat{\sigma} @f$ is not the identity
1762 * Pauli. As such, this effects a multi-qubit rotation around an arbitrary Pauli string.
1763 *
1764 * @equivalences
1765 *
1766 * - Because @f$ R_{\hat{\sigma}}(\theta) @f$ satisfies
1767 * @f[
1768 R_{\hat{\sigma}}(\theta) \equiv
1769 \cos\left( \frac{\theta}{2} \right) \, \id
1770 - \iu \sin\left( \frac{\theta}{2} \right) \, \hat{\sigma},
1771 * @f]
1772 * this function is equivalent to (but much faster than) effecting @f$ \hat{\sigma} @f$
1773 * upon a clone which is subsequently combined.
1774 * ```
1775 // prepare |temp> = str |qureg>
1776 Qureg temp = createCloneQureg(qureg);
1777 applyPauliStr(temp, str);
1778
1779 // set |qureg> = cos(theta/2) |qureg> - i sin(theta/2) str |qureg>
1780 qcomp coeffs[] = {cos(theta/2), -1i * sin(theta/2)};
1781 Qureg quregs[] = {qureg, temp};
1782 setQuregToWeightedSum(qureg, coeffs, quregs, 2);
1783 * ```
1784 * - When @p str contains only @f$ \hat{Z} @f$ or @f$ \id @f$ Paulis, this function will
1785 * automatically invoke applyPhaseGadget() which leverages an optimised implementation.
1786 * - When @p str contains only @f$ \id @f$ Paulis, this function merely effects a change
1787 * of global phase upon statevectors of @f$ -\theta/2 @f$, leaving density matrices
1788 * unchanged.
1789 * ```
1790 qcomp factor = cexp(- theta / 2 * 1.i);
1791 setQuregToWeightedSum(qureg, &factor, &qureg, 1);
1792 * ```
1793 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
1794 *
1795 * @myexample
1796 * ```
1797 Qureg qureg = createQureg(10);
1798 qreal theta = 3.14;
1799
1800 // verbosely
1801 int numPaulis = 4;
1802 char* paulis = "XYIZ";
1803 int targets[] = {0,1,5,7};
1804 PauliStr str = getPauliStr(paulis, targets, numPaulis);
1805 applyPauliGadget(qureg, str, angle);
1806
1807 // concisely
1808 applyPauliGadget(qureg, getInlinePauliStr("XYZ",{0,1,7}), theta);
1809 * ```
1810 *
1811 * @see
1812 * - applyNonUnitaryPauliGadget()
1813 */
1814void applyPauliGadget(Qureg qureg, PauliStr str, qreal angle);
1815
1816
1817/** @notyetdoced
1818 *
1819 * This function generalises applyPauliGadget() to accept a complex angle.
1820 */
1821void applyNonUnitaryPauliGadget(Qureg qureg, PauliStr str, qcomp angle);
1822
1823
1824/// @notyetdoced
1825void applyControlledPauliGadget(Qureg qureg, int control, PauliStr str, qreal angle);
1826
1827
1828/// @notyetdoced
1829void applyMultiControlledPauliGadget(Qureg qureg, int* controls, int numControls, PauliStr str, qreal angle);
1830
1831
1832/// @notyetdoced
1833/// @see
1834/// - applyPauliGadget()
1835/// - applyMultiStateControlledCompMatr1()
1836void applyMultiStateControlledPauliGadget(Qureg qureg, int* controls, int* states, int numControls, PauliStr str, qreal angle);
1837
1838
1839// end de-mangler
1840#ifdef __cplusplus
1841}
1842#endif
1843
1844#ifdef __cplusplus
1845
1846
1847/// @notyettested
1848/// @notyetvalidated
1849/// @notyetdoced
1850/// @cppvectoroverload
1851/// @see applyMultiControlledPauliGadget()
1852void applyMultiControlledPauliGadget(Qureg qureg, std::vector<int> controls, PauliStr str, qreal angle);
1853
1854
1855/// @notyettested
1856/// @notyetvalidated
1857/// @notyetdoced
1858/// @cppvectoroverload
1859/// @see applyMultiStateControlledPauliGadget()
1860void applyMultiStateControlledPauliGadget(Qureg qureg, std::vector<int> controls, std::vector<int> states, PauliStr str, qreal angle);
1861
1862
1863#endif // __cplusplus
1864
1865/** @} */
1866
1867
1868
1869/**
1870 * @defgroup op_phasegadget Phase gates
1871 * @brief Functions for applying many-qubit rotations around Pauli Z axis, and phase flips and shifts.
1872 * @{
1873 */
1874
1875
1876#ifdef __cplusplus
1877extern "C" {
1878#endif
1879
1880
1881/** @notyetdoced
1882 *
1883 * @formulae
1884 *
1885 * Let @f$ \vec{t} = @f$ @p targets and @f$ \theta = @f$ @p angle.
1886 *
1887 * This function effects diagonal unitary
1888 * @f[
1889 R_{\hat{Z}}(\theta) = \exp \left( - \iu \, \frac{\theta}{2} \, \bigotimes_{t \,\in\, \vec{t}} \hat{Z}_t \right).
1890 * @f]
1891 *
1892 * @equivalences
1893 *
1894 * - This function is equivalent to calling applyPauliGadget() with a PauliStr containing only @f$ \hat{Z} @f$ and @f$ \id @f$.
1895 * This latter function will actually automatically invoke applyPhaseGadget() which has an optimised implementation.
1896 * - This function is equivalent to, albeit much faster than, preparing a DiagMatr with @f$ \pm 1 @f$ elements (depending upon
1897 * the parity of the targeted set bits) and effecting it with applyDiagMatr().
1898 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
1899 */
1900void applyPhaseGadget(Qureg qureg, int* targets, int numTargets, qreal angle);
1901
1902
1903/// @notyetdoced
1904void applyControlledPhaseGadget(Qureg qureg, int control, int* targets, int numTargets, qreal angle);
1905
1906
1907/// @notyetdoced
1908void applyMultiControlledPhaseGadget(Qureg qureg, int* controls, int numControls, int* targets, int numTargets, qreal angle);
1909
1910
1911/// @notyetdoced
1912/// @see
1913/// - applyPhaseGadget()
1914/// - applyMultiStateControlledCompMatr1()
1915void applyMultiStateControlledPhaseGadget(Qureg qureg, int* controls, int* states, int numControls, int* targets, int numTargets, qreal angle);
1916
1917
1918/** @notyetdoced
1919 *
1920 * This function is a mere alias of applyPauliZ(), meaningfully differing only for many targets.
1921 */
1922void applyPhaseFlip(Qureg qureg, int target);
1923
1924
1925/** @notyetdoced
1926 *
1927 * @formulae
1928 *
1929 * Let @f$ \theta = @f$ @p angle. This function effects diagonal unitary
1930 *
1931 * @f[
1932 \hat{U}(\theta) = \begin{pmatrix} 1 & 0 \\ 0 & e^{\iu \theta} \end{pmatrix}
1933 * @f]
1934 * upon the @p target qubit.
1935 *
1936 * @equivalences
1937 *
1938 * - This function is equivalent to, albeit much faster than, a Z-axis rotation with
1939 * an adjustment to the global phase (which is redundant upon density matrices).
1940 * @f[
1941 * \hat{U}(\theta) \equiv \hat{R}_z(\theta) \cdot e^{\iu \frac{\theta}{2}} \hat{\id}
1942 * @f]
1943 * ```
1944 applyRotateZ(qureg, target, angle);
1945 applyPauliGadget(qureg, getPauliStr("I"), angle); // global phase
1946 * ```
1947 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
1948 */
1949void applyPhaseShift(Qureg qureg, int target, qreal angle);
1950
1951
1952/** @notyetdoced
1953 *
1954 * Applies a two-qubit phase flip upon qubits @p target1 and @p target2 of @p qureg.
1955 *
1956 * @formulae
1957 *
1958 * This function flips the sign of all computational basis states for which
1959 * the targeted qubits are in state @f$ \ket{1}\ket{1} @f$. This is equivalent
1960 * to the diagonal unitary
1961 *
1962 * @f[
1963 \hat{U}(\theta) = \begin{pmatrix} 1 \\ & 1 \\ & & 1 \\ & & & -1 \end{pmatrix},
1964 * @f]
1965 * effected upon the target qubits.
1966 *
1967 * @diagram
1968 * @dot
1969digraph {
1970 rankdir=LR;
1971 layout=neato;
1972 node [fontsize=10, fontname="Menlo"];
1973 edge [dir=none];
1974
1975 topWireL [shape=plaintext, label="target1", pos="0,.5!"];
1976 topWireM [shape=point, label="", width=.1, pos=".75,.5!"]
1977 topWireR [shape=plaintext, label="", pos="1.5,.5!"];
1978
1979 botWireL [shape=plaintext, label="target2", pos="0,0!"];
1980 botWireM [shape=point, label="", width=.1, pos=".75,0!"];
1981 botWireR [shape=plaintext, label="", pos="1.5,0!"];
1982
1983 topWireL -> topWireR;
1984 botWireL -> botWireR;
1985 botWireM -> topWireM;
1986}
1987 * @enddot
1988 *
1989 * @equivalences
1990 *
1991 * - The target qubits are interchangeable, ergo
1992 * ```
1993 applyTwoQubitPhaseFlip(qureg, target1, target2);
1994 applyTwoQubitPhaseFlip(qureg, target2, target1); // equivalent
1995 * ```
1996 * - This function is entirely equivalent to a controlled Pauli-Z unitary (or a hypothetical
1997 * controlled variant of applyPhaseFlip()) with either target qubit substituted for the control qubit.
1998 * ```
1999 applyControlledPauliZ(qureg, target1, target2);
2000 * ```
2001 * - This function is faster and more accurate than, but otherwise equivalent to, a two-qubit phase shift
2002 * with angle @f$ = \pi @f$.
2003 * ```
2004 applyTwoQubitPhaseShift(qureg, target1, target2, 3.141592653); // approx equiv
2005 * ```
2006 */
2007void applyTwoQubitPhaseFlip(Qureg qureg, int target1, int target2);
2008
2009
2010/** @notyetdoced
2011 *
2012 * Applies a two-qubit phase shift upon qubits @p target1 and @p target2 of @p qureg.
2013 *
2014 * @formulae
2015 *
2016 * Let @f$ \theta = @f$ @p angle.
2017 * This function multiplies factor @f$ e^{\iu \theta} @f$ upon all computational basis states
2018 * for which the targeted qubits are in state @f$ \ket{1}\ket{1} @f$. This is equivalent
2019 * to the diagonal unitary
2020 *
2021 * @f[
2022 \hat{U}(\theta) = \begin{pmatrix} 1 \\ & 1 \\ & & 1 \\ & & & e^{\iu \theta} \end{pmatrix},
2023 * @f]
2024 * effected upon the target qubits.
2025 *
2026 * @diagram
2027 * @dot
2028digraph {
2029 rankdir=LR;
2030 layout=neato;
2031 node [fontsize=10, fontname="Menlo"];
2032 edge [dir=none];
2033
2034 topWireL [shape=plaintext, label="target1", pos="0,.5!"];
2035 topWireM [shape=point, label="", width=.1, pos=".75,.5!"]
2036 topWireR [shape=plaintext, label="", pos="1.5,.5!"];
2037
2038 botWireL [shape=plaintext, label="target2", pos="0,0!"];
2039 botWireM [shape=point, label="", width=.1, pos=".75,0!"];
2040 botWireR [shape=plaintext, label="", pos="1.5,0!"];
2041
2042 topWireL -> topWireR;
2043 botWireL -> botWireR;
2044 botWireM -> topWireM;
2045
2046 angle [shape=plaintext, label="θ", pos=".85,-.2!"];
2047}
2048 * @enddot
2049 *
2050 * @equivalences
2051 *
2052 * - The target qubits are interchangeable, ergo
2053 * ```
2054 applyTwoQubitPhaseShift(qureg, target1, target2, angle);
2055 applyTwoQubitPhaseShift(qureg, target2, target1, angle); // equivalent
2056 * ```
2057 * - This function is equivalent to a controlled variant of applyPhaseShift(), treating
2058 * either target qubit as the control qubit.
2059 * - This function generalises applyTwoQubitPhaseFlip() to arbitrary changes in phase.
2060 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
2061 */
2062void applyTwoQubitPhaseShift(Qureg qureg, int target1, int target2, qreal angle);
2063
2064
2065/** @notyetdoced
2066 *
2067 * @formulae
2068 *
2069 * This function flips the sign of all computational basis states for which
2070 * the targeted qubits are all in state @f$ \ket{1} @f$. This is equivalent
2071 * to the diagonal unitary
2072 * @f[
2073 \hat{U}(\theta) = \begin{pmatrix} 1 \\ & \ddots \\ & & 1 \\ & & & -1 \end{pmatrix},
2074 * @f]
2075 * effected upon the target qubits.
2076 *
2077 * @equivalences
2078 *
2079 * - The ordering of @p targets has no affect on the effected operation.
2080 * - This function is entirely equivalent to a multi-controlled Pauli-Z unitary (or a hypothetical
2081 * many-controlled variant of applyPhaseFlip()) with all but one arbitrary target qubit becoming
2082 * control qubits.
2083 * ```
2084 applyMultiControlledPauliZ(qureg, targets, numTargets-1, targets[0]);
2085 * ```
2086 * - This function is faster and more accurate than, but otherwise equivalent to, a multi-qubit phase shift
2087 * with angle @f$ = \pi @f$.
2088 * ```
2089 applyMultiQubitPhaseShift(qureg, targets, numTargets, 3.141592653); // approx equiv
2090 * ```
2091 */
2092void applyMultiQubitPhaseFlip(Qureg qureg, int* targets, int numTargets);
2093
2094
2095/** @notyetdoced
2096 *
2097 * @formulae
2098 *
2099 * Let @f$ \theta = @f$ @p angle.
2100 * This function multiplies factor @f$ e^{\iu \theta} @f$ upon all computational basis states
2101 * for which all targeted qubits are in state @f$ \ket{1} @f$. This is equivalent
2102 * to the diagonal unitary
2103 * @f[
2104 \hat{U}(\theta) = \begin{pmatrix} 1 \\ & \ddots \\ & & 1 \\ & & & e^{\iu \theta} \end{pmatrix},
2105 * @f]
2106 * effected upon the target qubits.
2107 *
2108 * @diagram
2109 * @dot
2110digraph {
2111 rankdir=LR;
2112 layout=neato;
2113 node [fontsize=10, fontname="Menlo"];
2114 edge [dir=none];
2115
2116 topWireL [shape=plaintext, label="target1", pos="0,.5!"];
2117 topWireM [shape=point, label="", width=.1, pos=".75,.5!"]
2118 topWireR [shape=plaintext, label="", pos="1.5,.5!"];
2119
2120 botWireL [shape=plaintext, label="target2", pos="0,0!"];
2121 botWireM [shape=point, label="", width=.1, pos=".75,0!"];
2122 botWireR [shape=plaintext, label="", pos="1.5,0!"];
2123
2124 topWireL -> topWireR;
2125 botWireL -> botWireR;
2126 botWireM -> topWireM;
2127
2128 angle [shape=plaintext, label="θ", pos=".85,-.2!"];
2129}
2130 * @enddot
2131 *
2132 * @equivalences
2133 *
2134 * - The ordering of @p targets has no affect on the effected operation.
2135 * - This function is equivalent to a multi-controlled variant of applyPhaseShift(), treating all
2136 * but one arbitrary target qubit as control qubits.
2137 * - This function generalises applyMultiQubitPhaseFlip() to arbitrary changes in phase.
2138 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
2139 */
2140void applyMultiQubitPhaseShift(Qureg qureg, int* targets, int numTargets, qreal angle);
2141
2142
2143// end de-mangler
2144#ifdef __cplusplus
2145}
2146#endif
2147
2148#ifdef __cplusplus
2149
2150
2151/// @notyettested
2152/// @notyetvalidated
2153/// @notyetdoced
2154/// @cppvectoroverload
2155/// @see applyPhaseGadget()
2156void applyPhaseGadget(Qureg qureg, std::vector<int> targets, qreal angle);
2157
2158
2159/// @notyettested
2160/// @notyetvalidated
2161/// @notyetdoced
2162/// @cppvectoroverload
2163/// @see applyControlledPhaseGadget()
2164void applyControlledPhaseGadget(Qureg qureg, int control, std::vector<int> targets, qreal angle);
2165
2166
2167/// @notyettested
2168/// @notyetvalidated
2169/// @notyetdoced
2170/// @cppvectoroverload
2171/// @see applyMultiControlledPhaseGadget()
2172void applyMultiControlledPhaseGadget(Qureg qureg, std::vector<int> controls, std::vector<int> targets, qreal angle);
2173
2174
2175/// @notyettested
2176/// @notyetvalidated
2177/// @notyetdoced
2178/// @cppvectoroverload
2179/// @see applyMultiStateControlledPhaseGadget()
2180void applyMultiStateControlledPhaseGadget(Qureg qureg, std::vector<int> controls, std::vector<int> states, std::vector<int> targets, qreal angle);
2181
2182
2183/// @notyettested
2184/// @notyetvalidated
2185/// @notyetdoced
2186/// @cppvectoroverload
2187/// @see applyMultiQubitPhaseFlip()
2188void applyMultiQubitPhaseFlip(Qureg qureg, std::vector<int> targets);
2189
2190
2191/// @notyettested
2192/// @notyetvalidated
2193/// @notyetdoced
2194/// @cppvectoroverload
2195/// @see applyMultiQubitPhaseShift()
2196void applyMultiQubitPhaseShift(Qureg qureg, std::vector<int> targets, qreal angle);
2197
2198
2199#endif // __cplusplus
2200
2201/** @} */
2202
2203
2204
2205/**
2206 * @defgroup op_nots Many-not gates
2207 * @brief Functions for effecting many-qubit NOT gates
2208 * @{
2209 */
2210
2211
2212#ifdef __cplusplus
2213extern "C" {
2214#endif
2215
2216
2217/// @notyetdoced
2218void applyMultiQubitNot(Qureg qureg, int* targets, int numTargets);
2219
2220
2221/// @notyetdoced
2222void applyControlledMultiQubitNot(Qureg qureg, int control, int* targets, int numTargets);
2223
2224
2225/// @notyetdoced
2226void applyMultiControlledMultiQubitNot(Qureg qureg, int* controls, int numControls, int* targets, int numTargets);
2227
2228
2229/// @notyetdoced
2230/// @see
2231/// - applyMultiStateControlledCompMatr1()
2232void applyMultiStateControlledMultiQubitNot(Qureg qureg, int* controls, int* states, int numControls, int* targets, int numTargets);
2233
2234
2235// end de-mangler
2236#ifdef __cplusplus
2237}
2238#endif
2239
2240#ifdef __cplusplus
2241
2242
2243/// @notyettested
2244/// @notyetvalidated
2245/// @notyetdoced
2246/// @cppvectoroverload
2247/// @see applyMultiQubitNot()
2248void applyMultiQubitNot(Qureg qureg, std::vector<int> targets);
2249
2250
2251/// @notyettested
2252/// @notyetvalidated
2253/// @notyetdoced
2254/// @cppvectoroverload
2255/// @see applyControlledMultiQubitNot()
2256void applyControlledMultiQubitNot(Qureg qureg, int control, std::vector<int> targets);
2257
2258
2259/// @notyettested
2260/// @notyetvalidated
2261/// @notyetdoced
2262/// @cppvectoroverload
2263/// @see applyMultiControlledMultiQubitNot()
2264void applyMultiControlledMultiQubitNot(Qureg qureg, std::vector<int> controls, std::vector<int> targets);
2265
2266
2267/// @notyettested
2268/// @notyetvalidated
2269/// @notyetdoced
2270/// @cppvectoroverload
2271/// @see applyMultiStateControlledMultiQubitNot()
2272void applyMultiStateControlledMultiQubitNot(Qureg qureg, std::vector<int> controls, std::vector<int> states, std::vector<int> targets);
2273
2274
2275#endif // __cplusplus
2276
2277/** @} */
2278
2279
2280
2281/**
2282 * @defgroup op_measurement Measurements
2283 * @brief Functions for effecting destructive measurements.
2284 * @{
2285 */
2286
2287
2288#ifdef __cplusplus
2289extern "C" {
2290#endif
2291
2292
2293/// @notyetdoced
2294/// @notyetvalidated
2295int applyQubitMeasurement(Qureg qureg, int target);
2296
2297
2298/// @notyetdoced
2299/// @notyetvalidated
2300int applyQubitMeasurementAndGetProb(Qureg qureg, int target, qreal* probability);
2301
2302
2303/// @notyetdoced
2304/// @notyetvalidated
2305qreal applyForcedQubitMeasurement(Qureg qureg, int target, int outcome);
2306
2307
2308/// @notyetdoced
2309/// @notyetvalidated
2310qindex applyMultiQubitMeasurement(Qureg qureg, int* qubits, int numQubits);
2311
2312
2313/// @notyetdoced
2314/// @notyetvalidated
2315qindex applyMultiQubitMeasurementAndGetProb(Qureg qureg, int* qubits, int numQubits, qreal* probability);
2316
2317
2318/// @notyetdoced
2319/// @notyetvalidated
2320qreal applyForcedMultiQubitMeasurement(Qureg qureg, int* qubits, int* outcomes, int numQubits);
2321
2322
2323// end de-mangler
2324#ifdef __cplusplus
2325}
2326#endif
2327
2328#ifdef __cplusplus
2329
2330
2331/// @notyettested
2332/// @notyetvalidated
2333/// @notyetdoced
2334/// @cppvectoroverload
2335/// @see applyMultiQubitMeasurementAndGetProb()
2336qindex applyMultiQubitMeasurementAndGetProb(Qureg qureg, std::vector<int> qubits, qreal* probability);
2337
2338
2339/// @notyettested
2340/// @notyetvalidated
2341/// @notyetdoced
2342/// @cppvectoroverload
2343/// @see applyForcedMultiQubitMeasurement()
2344qreal applyForcedMultiQubitMeasurement(Qureg qureg, std::vector<int> qubits, std::vector<int> outcomes);
2345
2346
2347#endif // __cplusplus
2348
2349/** @} */
2350
2351
2352
2353/**
2354 * @defgroup op_projectors Projectors
2355 * @brief Functions for effecting projectors which break the state normalisation.
2356 * @{
2357 */
2358
2359
2360#ifdef __cplusplus
2361extern "C" {
2362#endif
2363
2364
2365/// @notyetdoced
2366/// @notyetvalidated
2367void applyQubitProjector(Qureg qureg, int target, int outcome);
2368
2369
2370/// @notyetdoced
2371/// @notyetvalidated
2372void applyMultiQubitProjector(Qureg qureg, int* qubits, int* outcomes, int numQubits);
2373
2374
2375// end de-mangler
2376#ifdef __cplusplus
2377}
2378#endif
2379
2380#ifdef __cplusplus
2381
2382
2383/// @notyettested
2384/// @notyetvalidated
2385/// @notyetdoced
2386/// @cppvectoroverload
2387/// @see applyMultiQubitProjector()
2388void applyMultiQubitProjector(Qureg qureg, std::vector<int> qubits, std::vector<int> outcomes);
2389
2390
2391#endif // __cplusplus
2392
2393/** @} */
2394
2395
2396
2397/**
2398 * @defgroup op_qft QFT
2399 * @brief Functions for applying the Quantum Fourier Transform.
2400 * @{
2401 */
2402
2403
2404#ifdef __cplusplus
2405extern "C" {
2406#endif
2407
2408
2409/// @notyetdoced
2410/// @notyetvalidated
2411void applyQuantumFourierTransform(Qureg qureg, int* targets, int numTargets);
2412
2413
2414/// @notyetdoced
2415/// @notyetvalidated
2417
2418
2419// end de-mangler
2420#ifdef __cplusplus
2421}
2422#endif
2423
2424#ifdef __cplusplus
2425
2426
2427/// @notyettested
2428/// @notyetvalidated
2429/// @notyetdoced
2430/// @cppvectoroverload
2431/// @see applyQuantumFourierTransform()
2432void applyQuantumFourierTransform(Qureg qureg, std::vector<int> targets);
2433
2434
2435#endif // __cplusplus
2436
2437/** @} */
2438
2439
2440
2441#endif // OPERATIONS_H
2442
2443/** @} */ // (end file-wide doxygen defgroup)
void applyCompMatr1(Qureg qureg, int target, CompMatr1 matrix)
void applyMultiControlledCompMatr1(Qureg qureg, int *controls, int numControls, int target, CompMatr1 matrix)
void applyControlledCompMatr1(Qureg qureg, int control, int target, CompMatr1 matrix)
void applyMultiStateControlledCompMatr1(Qureg qureg, int *controls, int *states, int numControls, int target, CompMatr1 matrix)
void applyMultiStateControlledCompMatr2(Qureg qureg, int *controls, int *states, int numControls, int target1, int target2, CompMatr2 matr)
void applyMultiControlledCompMatr2(Qureg qureg, int *controls, int numControls, int target1, int target2, CompMatr2 matr)
void applyCompMatr2(Qureg qureg, int target1, int target2, CompMatr2 matrix)
void applyControlledCompMatr2(Qureg qureg, int control, int target1, int target2, CompMatr2 matr)
void applyMultiStateControlledCompMatr(Qureg qureg, int *controls, int *states, int numControls, int *targets, int numTargets, CompMatr matr)
void applyMultiControlledCompMatr(Qureg qureg, int *controls, int numControls, int *targets, int numTargets, CompMatr matr)
void applyControlledCompMatr(Qureg qureg, int control, int *targets, int numTargets, CompMatr matr)
void applyCompMatr(Qureg qureg, int *targets, int numTargets, CompMatr matr)
void applyControlledDiagMatr1(Qureg qureg, int control, int target, DiagMatr1 matr)
void applyDiagMatr1(Qureg qureg, int target, DiagMatr1 matr)
void applyMultiStateControlledDiagMatr1(Qureg qureg, int *controls, int *states, int numControls, int target, DiagMatr1 matr)
void applyMultiControlledDiagMatr1(Qureg qureg, int *controls, int numControls, int target, DiagMatr1 matr)
void applyMultiStateControlledDiagMatr2(Qureg qureg, int *controls, int *states, int numControls, int target1, int target2, DiagMatr2 matr)
void applyMultiControlledDiagMatr2(Qureg qureg, int *controls, int numControls, int target1, int target2, DiagMatr2 matr)
void applyDiagMatr2(Qureg qureg, int target1, int target2, DiagMatr2 matr)
void applyControlledDiagMatr2(Qureg qureg, int control, int target1, int target2, DiagMatr2 matr)
void applyDiagMatr(Qureg qureg, int *targets, int numTargets, DiagMatr matrix)
void applyMultiControlledDiagMatrPower(Qureg qureg, int *controls, int numControls, int *targets, int numTargets, DiagMatr matrix, qcomp exponent)
void applyMultiStateControlledDiagMatrPower(Qureg qureg, int *controls, int *states, int numControls, int *targets, int numTargets, DiagMatr matrix, qcomp exponent)
void applyDiagMatrPower(Qureg qureg, int *targets, int numTargets, DiagMatr matrix, qcomp exponent)
void applyControlledDiagMatr(Qureg qureg, int control, int *targets, int numTargets, DiagMatr matrix)
void applyMultiControlledDiagMatr(Qureg qureg, int *controls, int numControls, int *targets, int numTargets, DiagMatr matrix)
void applyControlledDiagMatrPower(Qureg qureg, int control, int *targets, int numTargets, DiagMatr matrix, qcomp exponent)
void applyMultiStateControlledDiagMatr(Qureg qureg, int *controls, int *states, int numControls, int *targets, int numTargets, DiagMatr matrix)
void applyControlledT(Qureg qureg, int control, int target)
void applyControlledS(Qureg qureg, int control, int target)
void applyMultiStateControlledHadamard(Qureg qureg, int *controls, int *states, int numControls, int target)
void applyMultiControlledHadamard(Qureg qureg, int *controls, int numControls, int target)
void applyS(Qureg qureg, int target)
void applyMultiControlledT(Qureg qureg, int *controls, int numControls, int target)
void applyMultiControlledS(Qureg qureg, int *controls, int numControls, int target)
void applyT(Qureg qureg, int target)
void applyMultiStateControlledS(Qureg qureg, int *controls, int *states, int numControls, int target)
void applyHadamard(Qureg qureg, int target)
void applyControlledHadamard(Qureg qureg, int control, int target)
void applyMultiStateControlledT(Qureg qureg, int *controls, int *states, int numControls, int target)
void applyFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matrix)
void applyFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qcomp exponent)
qreal applyForcedQubitMeasurement(Qureg qureg, int target, int outcome)
qindex applyMultiQubitMeasurement(Qureg qureg, int *qubits, int numQubits)
int applyQubitMeasurement(Qureg qureg, int target)
qreal applyForcedMultiQubitMeasurement(Qureg qureg, int *qubits, int *outcomes, int numQubits)
qindex applyMultiQubitMeasurementAndGetProb(Qureg qureg, int *qubits, int numQubits, qreal *probability)
int applyQubitMeasurementAndGetProb(Qureg qureg, int target, qreal *probability)
void applyMultiStateControlledMultiQubitNot(Qureg qureg, int *controls, int *states, int numControls, int *targets, int numTargets)
void applyMultiControlledMultiQubitNot(Qureg qureg, int *controls, int numControls, int *targets, int numTargets)
void applyMultiQubitNot(Qureg qureg, int *targets, int numTargets)
void applyControlledMultiQubitNot(Qureg qureg, int control, int *targets, int numTargets)
void applyMultiControlledPauliZ(Qureg qureg, int *controls, int numControls, int target)
void applyPauliX(Qureg qureg, int target)
void applyControlledPauliX(Qureg qureg, int control, int target)
void applyMultiStateControlledPauliY(Qureg qureg, int *controls, int *states, int numControls, int target)
void applyMultiControlledPauliY(Qureg qureg, int *controls, int numControls, int target)
void applyControlledPauliZ(Qureg qureg, int control, int target)
void applyMultiControlledPauliX(Qureg qureg, int *controls, int numControls, int target)
void applyPauliZ(Qureg qureg, int target)
void applyMultiStateControlledPauliZ(Qureg qureg, int *controls, int *states, int numControls, int target)
void applyPauliY(Qureg qureg, int target)
void applyControlledPauliY(Qureg qureg, int control, int target)
void applyMultiStateControlledPauliX(Qureg qureg, int *controls, int *states, int numControls, int target)
void applyMultiControlledPauliGadget(Qureg qureg, int *controls, int numControls, PauliStr str, qreal angle)
void applyControlledPauliGadget(Qureg qureg, int control, PauliStr str, qreal angle)
void applyMultiStateControlledPauliGadget(Qureg qureg, int *controls, int *states, int numControls, PauliStr str, qreal angle)
void applyNonUnitaryPauliGadget(Qureg qureg, PauliStr str, qcomp angle)
void applyPauliGadget(Qureg qureg, PauliStr str, qreal angle)
void applyMultiControlledPauliStr(Qureg qureg, int *controls, int numControls, PauliStr str)
void applyPauliStr(Qureg qureg, PauliStr str)
void applyMultiStateControlledPauliStr(Qureg qureg, int *controls, int *states, int numControls, PauliStr str)
void applyControlledPauliStr(Qureg qureg, int control, PauliStr str)
void applyControlledPhaseGadget(Qureg qureg, int control, int *targets, int numTargets, qreal angle)
void applyMultiControlledPhaseGadget(Qureg qureg, int *controls, int numControls, int *targets, int numTargets, qreal angle)
void applyMultiQubitPhaseShift(Qureg qureg, int *targets, int numTargets, qreal angle)
void applyTwoQubitPhaseShift(Qureg qureg, int target1, int target2, qreal angle)
void applyTwoQubitPhaseFlip(Qureg qureg, int target1, int target2)
void applyMultiStateControlledPhaseGadget(Qureg qureg, int *controls, int *states, int numControls, int *targets, int numTargets, qreal angle)
void applyPhaseShift(Qureg qureg, int target, qreal angle)
void applyPhaseFlip(Qureg qureg, int target)
void applyMultiQubitPhaseFlip(Qureg qureg, int *targets, int numTargets)
void applyPhaseGadget(Qureg qureg, int *targets, int numTargets, qreal angle)
void applyMultiQubitProjector(Qureg qureg, int *qubits, int *outcomes, int numQubits)
void applyQubitProjector(Qureg qureg, int target, int outcome)
void applyFullQuantumFourierTransform(Qureg qureg)
void applyQuantumFourierTransform(Qureg qureg, int *targets, int numTargets)
void applyMultiStateControlledRotateY(Qureg qureg, int *controls, int *states, int numControls, int target, qreal angle)
void applyControlledRotateZ(Qureg qureg, int control, int target, qreal angle)
void applyMultiControlledRotateX(Qureg qureg, int *controls, int numControls, int target, qreal angle)
void applyMultiStateControlledRotateX(Qureg qureg, int *controls, int *states, int numControls, int target, qreal angle)
void applyMultiControlledRotateZ(Qureg qureg, int *controls, int numControls, int target, qreal angle)
void applyMultiStateControlledRotateZ(Qureg qureg, int *controls, int *states, int numControls, int target, qreal angle)
void applyRotateZ(Qureg qureg, int target, qreal angle)
void applyMultiStateControlledRotateAroundAxis(Qureg qureg, int *ctrls, int *states, int numCtrls, int targ, qreal angle, qreal axisX, qreal axisY, qreal axisZ)
void applyControlledRotateX(Qureg qureg, int control, int target, qreal angle)
void applyRotateY(Qureg qureg, int target, qreal angle)
void applyRotateX(Qureg qureg, int target, qreal angle)
void applyRotateAroundAxis(Qureg qureg, int target, qreal angle, qreal axisX, qreal axisY, qreal axisZ)
void applyMultiControlledRotateAroundAxis(Qureg qureg, int *ctrls, int numCtrls, int targ, qreal angle, qreal axisX, qreal axisY, qreal axisZ)
void applyMultiControlledRotateY(Qureg qureg, int *controls, int numControls, int target, qreal angle)
void applyControlledRotateAroundAxis(Qureg qureg, int ctrl, int targ, qreal angle, qreal axisX, qreal axisY, qreal axisZ)
void applyControlledRotateY(Qureg qureg, int control, int target, qreal angle)
void applyMultiControlledSwap(Qureg qureg, int *controls, int numControls, int qubit1, int qubit2)
void applyControlledSwap(Qureg qureg, int control, int qubit1, int qubit2)
void applyMultiStateControlledSwap(Qureg qureg, int *controls, int *states, int numControls, int qubit1, int qubit2)
void applySwap(Qureg qureg, int qubit1, int qubit2)
void applyControlledSqrtSwap(Qureg qureg, int control, int qubit1, int qubit2)
void applySqrtSwap(Qureg qureg, int qubit1, int qubit2)
void applyMultiControlledSqrtSwap(Qureg qureg, int *controls, int numControls, int qubit1, int qubit2)
void applyMultiStateControlledSqrtSwap(Qureg qureg, int *controls, int *states, int numControls, int qubit1, int qubit2)
Definition qureg.h:49