The Quantum Exact Simulation Toolkit v4.3.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#include <stdbool.h>
29
30#ifdef __cplusplus
31 #include <vector>
32#endif
33
34
35
36/*
37 * unlike some other headers, we here intermix the C and C++-only
38 * signatures, grouping them semantically & by their doc groups
39 */
40
41
42
43/**
44 * @defgroup op_compmatr1 CompMatr1
45 * @brief Functions for applying general one-qubit dense matrices, as CompMatr1.
46 * @{
47 */
48
49
50#ifdef __cplusplus
51extern "C" {
52#endif
53
54
55/** Applies a general one-qubit dense unitary @p matrix to the specified @p target
56 * qubit of @p qureg.
57 *
58 * @diagram
59 * @dot
60digraph {
61 rankdir=LR;
62 node [fontsize=10, fontname="Menlo"];
63 edge [dir=none];
64
65 wireL [shape=plaintext, label="target"];
66 wireR [shape=plaintext, label=""];
67 gate [shape=box, label="matrix"];
68
69 wireL -> gate -> wireR
70}
71 * @enddot
72 *
73 * @formulae
74 *
75 * Let @f$ \hat{U} = @f$ @p matrix, @f$ t = @f$ @p target, and let @f$\hat{U}_t@f$
76 * notate operating @f$\hat{U}@f$ upon the @f$ t @f$-th qubit among@f$ N @f$, i.e.
77 * @f[
78 \hat{U}_t \equiv \id^{N-t} \otimes \hat{U} \otimes \id^{t-1}.
79 * @f]
80 * Then,
81 * - When @p qureg is a statevector @f$ \svpsi @f$, this function effects
82 * @f[
83 \svpsi \rightarrow \hat{U}_t \, \svpsi.
84 * @f]
85 * - When @p qureg is a density matrix @f$\dmrho@f$, this function effects
86 * @f[
87 \dmrho \rightarrow \hat{U}_t \, \dmrho \, {\hat{U}_t}^\dagger.
88 * @f]
89 *
90 * @constraints
91 *
92 * - Unitarity of @f$ \hat{U} = @f$ @p matrix requires that
93 * @f$ \hat{U} \hat{U}^\dagger = \id @f$. Validation will check that @p matrix is
94 * approximately unitary via
95 * @f[
96 \max\limits_{ij} \Big|\left(\hat{U} \hat{U}^\dagger - \id\right)_{ij}\Big|^2 \le \valeps
97 * @f]
98 * where the validation epsilon @f$ \valeps @f$ can be adjusted with setQuESTValidationEpsilon().
99 *
100 * @myexample
101 *
102 * ```
103 Qureg qureg = createQureg(5);
104
105 CompMatr1 matrix = getInlineCompMatr1({
106 {-1i/sqrt(2), 1i/sqrt(2)},
107 {(1i-1)/2, (1i-1)/2}
108 });
109
110 applyCompMatr1(qureg, 2, matrix);
111 * ```
112 *
113 * @param[in,out] qureg the state to modify.
114 * @param[in] target the index of the target qubit.
115 * @param[in] matrix the Z-basis unitary matrix to effect.
116 * @throws @validationerror
117 * - if @p qureg or @p matrix are uninitialised.
118 * - if @p matrix is not approximately unitary.
119 * - if @p target is an invalid qubit index.
120 * @see
121 * - getCompMatr1()
122 * - getInlineCompMatr1()
123 * - leftapplyCompMatr1()
124 * - rightapplyCompMatr1()
125 * - applyControlledCompMatr1()
126 * - applyCompMatr2()
127 * - applyCompMatr()
128 * @author Tyson Jones
129 */
130void applyCompMatr1(Qureg qureg, int target, CompMatr1 matrix);
131
132
133/** Applies a singly-controlled one-qubit dense unitary @p matrix to the specified
134 * @p target qubit of @p qureg.
135 *
136 * @diagram
137 * @dot
138digraph {
139 rankdir=LR;
140 node [fontsize=10, fontname="Menlo"];
141 edge [dir=none];
142
143 topWireL [shape=plaintext, label="control"];
144 topWireR [shape=plaintext, label=""];
145 ctrl [shape=circle, label="", width=.12, style=filled, fillcolor=black];
146
147 topWireL -> ctrl -> topWireR;
148
149 botWireL [shape=plaintext, label="target"];
150 botWireR [shape=plaintext, label=""];
151 gate [shape=box, label="matrix"];
152
153 botWireL -> gate -> botWireR;
154 ctrl -> gate;
155
156 {rank=same; topWireL; botWireL};
157 {rank=same; ctrl; gate};
158 {rank=same; topWireR; botWireR};
159}
160 * @enddot
161 *
162 * @formulae
163 *
164 * Let @f$ \hat{U} = @f$ @p matrix, @f$ t = @f$ @p target, @f$ c = @f$ @p control,
165 * and let @f$\hat{O}_q@f$ denote an operator upon the @f$q@f$-th qubit.
166 * This function effects operator
167 * @f[
168 C_c[\hat{U}_t] = \ketbra{0}{0}_c \otimes \id_t + \ketbra{1}{1}_c \otimes \hat{U}_t,
169 * @f]
170 * where @f$\hat{U}@f$ is effected upon basis states for which qubit @f$c@f$ has value `1`.
171 * For illustration, when @p control=0 and @p target=1, this function would effect
172 * @f[
173 C_1[\hat{U}_0] \equiv
174 \begin{pmatrix}
175 1 \\ & 1 \\ & & u_{00} & u_{01} \\ & & u_{10} & u_{11}
176 \end{pmatrix}.
177 * @f]
178 *
179 * This operation can be performed upon statevectors and density matrices.
180 *
181 * - When @p qureg is a statevector @f$ \svpsi @f$, this function effects
182 * @f[
183 \svpsi \rightarrow C_c[\hat{U}_t] \, \svpsi.
184 * @f]
185 * - When @p qureg is a density matrix @f$\dmrho@f$, this function effects
186 * @f[
187 \dmrho \rightarrow C_c[\hat{U}_t] \, \dmrho \, {C_c[\hat{U}_t]}^\dagger.
188 * @f]
189 *
190 * The amplitudes which _are_ modified, are done so in an identical fashion as in applyCompMatr1().
191 *
192 * @constraints
193 *
194 * - Unitarity of @f$ \hat{U} = @f$ @p matrix requires that
195 * @f$ \hat{U} \hat{U}^\dagger = \id @f$. Validation will check that @p matrix is
196 * approximately unitary via
197 * @f[
198 \max\limits_{ij} \Big|\left(\hat{U} \hat{U}^\dagger - \id\right)_{ij}\Big|^2 \le \valeps
199 * @f]
200 * where the validation epsilon @f$ \valeps @f$ can be adjusted with setQuESTValidationEpsilon().
201 *
202 * @equivalences
203 *
204 * - This function is faster than, but mathematically equivalent to, initialising a two-qubit
205 * matrix (CompMatr2) to the @f$C_1[\hat{U}_0]@f$ matrix above, and calling applyCompMatr2(),
206 * passing @p control as the most significant target.
207 * ```
208 CompMatr2 m = getInlineCompMatr2({
209 {1,0,0,0},
210 {0,1,0,0},
211 {0,0,u00,u01},
212 {0,0,u10,u11}});
213
214 applyCompMatr2(qureg, target, control, m);
215 * ```
216 *
217 * @myexample
218 *
219 * ```
220 Qureg qureg = createQureg(5);
221
222 CompMatr1 matrix = getInlineCompMatr1({
223 {-1i/sqrt(2), 1i/sqrt(2)},
224 {(1i-1)/2, (1i-1)/2}
225 });
226
227 // C_0[U_2]
228 applyControlledCompMatr1(qureg, 0, 2, matrix);
229 * ```
230
231 * @param[in,out] qureg the state to modify.
232 * @param[in] control the index of the control qubit.
233 * @param[in] target the index of the target qubit.
234 * @param[in] matrix the Z-basis unitary matrix to effect.
235 * @throws @validationerror
236 * - if @p qureg or @p matrix are uninitialised.
237 * - if @p matrix is not approximately unitary.
238 * - if @p control or @p target are an invalid qubit index.
239 * - if @p control and @p target are equal.
240 * @see
241 * - applyCompMatr1()
242 * - applyMultiControlledCompMatr1()
243 * - applyMultiStateControlledCompMatr1()
244 * @author Tyson Jones
245 */
246void applyControlledCompMatr1(Qureg qureg, int control, int target, CompMatr1 matrix);
247
248
249/** Applies a multiply-controlled one-qubit dense unitary @p matrix to the specified
250 * @p target qubit of @p qureg.
251 *
252 * @diagram
253 * @dot
254digraph {
255 rankdir=LR;
256 node [fontsize=10, fontname="Menlo"];
257 edge [dir=none];
258
259 trailingCtrl [shape=plaintext, label="..."];
260
261 topWireL [shape=plaintext, label="controls[1]"];
262 topWireR [shape=plaintext, label=""];
263 topCtrl [shape=circle, label="", width=.12, style=filled, fillcolor=black];
264
265 topWireL -> topCtrl -> topWireR;
266
267 midWireL [shape=plaintext, label="controls[0]"];
268 midWireR [shape=plaintext, label=""];
269 midCtrl [shape=circle, label="", width=.12, style=filled, fillcolor=black];
270
271 midWireL -> midCtrl -> midWireR;
272
273 botWireL [shape=plaintext, label="target"];
274 botWireR [shape=plaintext, label=""];
275 gate [shape=box, label="matrix"];
276
277 botWireL -> gate -> botWireR;
278 trailingCtrl -> topCtrl -> midCtrl -> gate;
279
280 {rank=same; topWireL; midWireL; botWireL};
281 {rank=same; trailingCtrl; topCtrl; midCtrl; gate};
282 {rank=same; topWireR; midWireR; botWireR};
283}
284 * @enddot
285 *
286 * @formulae
287 *
288 * Let @f$ \vec{c} = @f$ @p controls, @f$ t = @f$ @p target, and @f$ \hat{U} = @f$ @p matrix.
289 * This functions effects operator
290 *
291 * @f[
292 C_{\vec{c}}[\hat{U}_t]
293 * @f]
294 *
295 * which is equivalent to applying @f$ \hat{U}_t @f$ upon only the computational basis states for which
296 * all control qubits are in the @f$ \ket{1} @f$ state.
297 *
298 * Precisely, let @f$n = 2^{|\vec{c}|}-1@f$. Then
299 * @f[
300 C_{\vec{c}}[\hat{U}_t] = \sum\limits_{i=0}^{n-1} \ketbra{i}{i}_{\vec{c}} \otimes \hat{\id}_t
301 + \ketbra{n}{n}_{\vec{c}} \otimes \hat{U}_t
302 * @f]
303 *
304 * The amplitudes which _are_ modified, are done so in an identical fashion as in applyCompMatr1().
305 *
306 * @param[in,out] qureg the state to modify.
307 * @param[in] controls a list of control qubits.
308 * @param[in] numControls the length of @p controls.
309 * @param[in] target the target qubit.
310 * @param[in] matrix the Z-basis unitary matrix to effect.
311 * @throws @validationerror
312 * - if @p qureg or @p matrix are uninitialised.
313 * - if @p matrix is not approximately unitary.
314 * - if @p target or any element of @p controls are an invalid qubit index.
315 * - if @p controls contains duplicates, or includes @p target.
316 * - if @p numControls is negative.
317 * @see
318 * - applyCompMatr1()
319 * - applyMultiStateControlledCompMatr1()
320 * @author Tyson Jones
321 */
322void applyMultiControlledCompMatr1(Qureg qureg, int* controls, int numControls, int target, CompMatr1 matrix);
323
324
325/** Applies an arbitrarily-controlled one-qubit dense unitary @p matrix to the specified
326 * @p target qubit of @p qureg, conditioned upon the @p controls being in the corresponding @p states.
327 *
328 * @diagram
329 * @dot
330digraph {
331 rankdir=LR;
332 node [fontsize=10, fontname="Menlo"];
333 edge [dir=none];
334
335 trailingCtrl [shape=plaintext, label="..."];
336
337 topWireL [shape=plaintext, label="controls[1]"];
338 topWireR [shape=plaintext, label=""];
339 topCtrl [shape=circle, label="", width=.12, style=filled, fillcolor=black];
340
341 topWireL -> topCtrl -> topWireR;
342
343 midWireL [shape=plaintext, label="controls[0]"];
344 midWireR [shape=plaintext, label=""];
345 midCtrl [shape=circle, label="", width=.12, style=filled, fillcolor=white];
346
347 midWireL -> midCtrl -> midWireR;
348
349 botWireL [shape=plaintext, label="target"];
350 botWireR [shape=plaintext, label=""];
351 gate [shape=box, label="matrix"];
352
353 botWireL -> gate -> botWireR;
354 trailingCtrl -> topCtrl -> midCtrl -> gate;
355
356 {rank=same; topWireL; midWireL; botWireL};
357 {rank=same; trailingCtrl; topCtrl; midCtrl; gate};
358 {rank=same; topWireR; midWireR; botWireR};
359}
360 * @enddot
361 *
362 * @formulae
363 *
364 * Let @f$ \vec{c} = @f$ @p controls, @f$ t = @f$ @p target, @f$ \hat{U} = @f$ @p matrix and
365 * @f$n = 2^{|\vec{c}|}-1@f$. Let @f$ \ket{s}_{\vec{c}} @f$ be the computational substate formed by
366 * the qubits in @p controls being in the corresponding @p states.
367 *
368 * This function applies the operator
369 *
370 * @f[
371 \sum\limits_{i=0, i \ne s}^{n} \ketbra{i}{i}_{\vec{c}} \otimes \hat{\id}_t
372 + \ketbra{s}{s}_{\vec{c}} \otimes \hat{U}_t
373 * @f]
374 *
375 * The amplitudes which _are_ modified, are done so in an identical fashion as in applyCompMatr1().
376 *
377 * @equivalences
378 *
379 * - This function is faster than, but mathematically equivalent to, applying a Pauli @c X
380 * upon every zero-controlled qubit, applying the matrix with all one-controls, then undoing
381 * the flipped qubits.
382 * ```cpp
383 for (int i=0; i<numControls; i++)
384 if (states[i] == 0)
385 applyPauliX(qureg, controls[i]);
386
387 applyMultiControlledCompMatr1(qureg, controls, numControls, target, matrix);
388
389 for (int i=0; i<numControls; i++)
390 if (states[i] == 0)
391 applyPauliX(qureg, controls[i]);
392 * ```
393 *
394 * @param[in,out] qureg the state to modify.
395 * @param[in] controls a list of control qubits.
396 * @param[in] states a list of corresponding qubit states (each, @c 0 or @c 1).
397 * @param[in] numControls the length of @p controls and @p states.
398 * @param[in] target the target qubit.
399 * @param[in] matrix the Z-basis unitary matrix to effect.
400 * @throws @validationerror
401 * - if @p qureg or @p matrix are uninitialised.
402 * - if @p matrix is not approximately unitary.
403 * - if @p target or any element of @p controls are an invalid qubit index.
404 * - if @p controls contains duplicates, or includes @p target.
405 * - if @p numControls is negative.
406 * - if @p states contains any element besides @c 0 or @c 1.
407 * @see
408 * - applyCompMatr1()
409 * @author Tyson Jones
410 */
411void applyMultiStateControlledCompMatr1(Qureg qureg, int* controls, int* states, int numControls, int target, CompMatr1 matrix);
412
413
414// end de-mangler
415#ifdef __cplusplus
416}
417#endif
418
419#ifdef __cplusplus
420
421
422/// @notyettested
423/// @notyetvalidated
424/// @notyetdoced
425/// @cppvectoroverload
426/// @see applyMultiControlledCompMatr1()
427void applyMultiControlledCompMatr1(Qureg qureg, std::vector<int> controls, int target, CompMatr1 matrix);
428
429
430/// @notyettested
431/// @notyetvalidated
432/// @notyetdoced
433/// @cppvectoroverload
434/// @see applyMultiStateControlledCompMatr1()
435void applyMultiStateControlledCompMatr1(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target, CompMatr1 matrix);
436
437
438#endif // __cplusplus
439
440/** @} */
441
442
443
444/**
445 * @defgroup op_compmatr2 CompMatr2
446 * @brief Functions for applying general two-qubit dense matrices, as CompMatr2.
447 * @{
448 */
449
450
451#ifdef __cplusplus
452extern "C" {
453#endif
454
455
456/** @notyetdoced
457 *
458 * Applies a general two-qubit dense unitary @p matrix to qubits @p target1 and
459 * @p target2 (treated as increasing significance) of @p qureg.
460 *
461 * @diagram
462 * @dot
463digraph {
464 layout=neato;
465 rankdir=LR;
466 node [fontsize=10, fontname="Menlo"];
467 edge [dir=none];
468
469 topWireL [shape=plaintext, pos="0,0!", label="target2"];
470 topWireR [shape=plaintext, pos="2.5,0!", label=""];
471
472 botWireL [shape=plaintext, pos="0,.5!", label="target1"];
473 botWireR [shape=plaintext, pos="2.5,.5!", label=""];
474
475 gate [shape=rectangle, label="matrix", style=filled, fillcolor=white, height=1, pos="1.25,.25!"];
476
477 topWireL -> topWireR;
478 botWireL -> botWireR;
479}
480 * @enddot
481 *
482 * @see
483 * - applyCompMatr1()
484 * - leftapplyCompMatr2()
485 * - rightapplyCompMatr2()
486 * @author Tyson Jones
487 */
488void applyCompMatr2(Qureg qureg, int target1, int target2, CompMatr2 matrix);
489
490
491/** @notyetdoced
492 *
493 * Applies a singly-controlled two-qubit dense unitary @p matrix to qubits
494 * @p target1 and @p target2 (treated as increasing significance) of @p qureg.
495 *
496 * > - See applyCompMatr2() for information about the base operation.
497 * > - See applyControlledCompMatr1() for information about the @p control qubit.
498 *
499 * @diagram
500 * @dot
501digraph {
502 layout=neato;
503 rankdir=LR;
504 node [fontsize=10, fontname="Menlo"];
505 edge [dir=none];
506
507 topWireL [shape=plaintext, pos="0,1!", label="control"];
508 topWireR [shape=plaintext, pos="2.5,1!", label=""];
509
510 midWireL [shape=plaintext, pos="0,0.5!", label="target2"];
511 midWireR [shape=plaintext, pos="2.5,0.5!", label=""];
512
513 botWireL [shape=plaintext, pos="0,0!", label="target1"];
514 botWireR [shape=plaintext, pos="2.5,0!", label=""];
515
516 gate [shape=rectangle, label="matrix", style=filled, fillcolor=white, height=1, pos="1.25,0.25!"];
517 ctrl [shape=circle, label="", width=.12, style=filled, fillcolor=black, pos="1.25,1!"];
518
519 topWireL -> ctrl -> topWireR;
520 midWireL -> midWireR;
521 botWireL -> botWireR;
522 ctrl -> gate;
523}
524 * @enddot
525 *
526 * @see
527 * - applyCompMatr2()
528 * @author Tyson Jones
529 */
530void applyControlledCompMatr2(Qureg qureg, int control, int target1, int target2, CompMatr2 matrix);
531
532
533/** @notyetdoced
534 *
535 * Applies a multiply-controlled two-qubit dense unitary @p matrix to qubits
536 * @p target1 and @p target2 (treated as increasing significance) of @p qureg.
537 *
538 * > - See applyCompMatr2() for information about @p target1, @p target2 and @p matrix.
539 * > - See applyMultiControlledCompMatr1() for information about @p controls.
540 *
541 * @diagram
542 * @dot
543digraph {
544 layout=neato;
545 rankdir=LR;
546 node [fontsize=10, fontname="Menlo"];
547 edge [dir=none];
548
549 tippytopWireL [shape=plaintext, pos="0,1.5!", label="controls[1]"];
550 tippytopWireR [shape=plaintext, pos="2.5,1.5!", label=""];
551
552 topWireL [shape=plaintext, pos="0,1!", label="controls[0]"];
553 topWireR [shape=plaintext, pos="2.5,1!", label=""];
554
555 midWireL [shape=plaintext, pos="0,0.5!", label="target2"];
556 midWireR [shape=plaintext, pos="2.5,0.5!", label=""];
557
558 botWireL [shape=plaintext, pos="0,0!", label="target1"];
559 botWireR [shape=plaintext, pos="2.5,0!", label=""];
560
561 gate [shape=rectangle, label="matrix", style=filled, fillcolor=white, height=1, pos="1.25,0.25!"];
562 ctrl1 [shape=circle, label="", width=.12, style=filled, fillcolor=black, pos="1.25,1!"];
563 ctrl2 [shape=circle, label="", width=.12, style=filled, fillcolor=black, pos="1.25,1.5!"];
564 trailingCtrl [shape=plaintext, label="...", pos="1.25,2!"];
565
566 tippytopWireL -> ctrl2 -> tippytopWireR;
567 topWireL -> ctrl1 -> topWireR;
568 midWireL -> midWireR;
569 botWireL -> botWireR;
570 trailingCtrl -> ctrl2 -> ctrl1 -> gate;
571}
572 * @enddot
573 *
574 * @see
575 * - applyCompMatr2()
576 */
577void applyMultiControlledCompMatr2(Qureg qureg, int* controls, int numControls, int target1, int target2, CompMatr2 matrix);
578
579
580/** @notyetdoced
581 *
582 * Applies an arbitrarily-controlled two-qubit dense unitary @p matrix to qubits
583 * @p target1 and @p target2 of @p qureg,
584 * conditioned upon the @p controls being in the corresponding @p states.
585 *
586 * > - See applyCompMatr2() for information about @p target1, @p target2 and @p matrix.
587 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
588 *
589 * @diagram
590 * @dot
591digraph {
592 layout=neato;
593 rankdir=LR;
594 node [fontsize=10, fontname="Menlo"];
595 edge [dir=none];
596
597 tippytopWireL [shape=plaintext, pos="0,1.5!", label="controls[1]"];
598 tippytopWireR [shape=plaintext, pos="2.5,1.5!", label=""];
599
600 topWireL [shape=plaintext, pos="0,1!", label="controls[0]"];
601 topWireR [shape=plaintext, pos="2.5,1!", label=""];
602
603 midWireL [shape=plaintext, pos="0,0.5!", label="target2"];
604 midWireR [shape=plaintext, pos="2.5,0.5!", label=""];
605
606 botWireL [shape=plaintext, pos="0,0!", label="target1"];
607 botWireR [shape=plaintext, pos="2.5,0!", label=""];
608
609 gate [shape=rectangle, label="matrix", style=filled, fillcolor=white, height=1, pos="1.25,0.25!"];
610 ctrl1 [shape=circle, label="", width=.12, style=filled, fillcolor=white, pos="1.25,1!"];
611 ctrl2 [shape=circle, label="", width=.12, style=filled, fillcolor=black, pos="1.25,1.5!"];
612 trailingCtrl [shape=plaintext, label="...", pos="1.25,2!"];
613
614 tippytopWireL -> ctrl2 -> tippytopWireR;
615 topWireL -> ctrl1 -> topWireR;
616 midWireL -> midWireR;
617 botWireL -> botWireR;
618 trailingCtrl -> ctrl2 -> ctrl1 -> gate;
619}
620 * @enddot
621 *
622 * @see
623 * - applyCompMatr2()
624 * - applyMultiStateControlledCompMatr1()
625 * @author Tyson Jones
626 */
627void applyMultiStateControlledCompMatr2(Qureg qureg, int* controls, int* states, int numControls, int target1, int target2, CompMatr2 matrix);
628
629
630// end de-mangler
631#ifdef __cplusplus
632}
633#endif
634
635#ifdef __cplusplus
636
637
638/// @notyettested
639/// @notyetvalidated
640/// @notyetdoced
641/// @cppvectoroverload
642/// @see applyMultiControlledCompMatr2()
643void applyMultiControlledCompMatr2(Qureg qureg, std::vector<int> controls, int target1, int target2, CompMatr2 matrix);
644
645
646/// @notyettested
647/// @notyetvalidated
648/// @notyetdoced
649/// @cppvectoroverload
650/// @see applyMultiStateControlledCompMatr2()
651void applyMultiStateControlledCompMatr2(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target1, int target2, CompMatr2 matrix);
652
653
654#endif // __cplusplus
655
656/** @} */
657
658
659
660/**
661 * @defgroup op_compmatr CompMatr
662 * @brief Functions for applying general many-target dense matrices, as CompMatr.
663 * @{
664 */
665
666
667#ifdef __cplusplus
668extern "C" {
669#endif
670
671
672/** @notyetdoced
673 *
674 * Applies an arbitrarily-sized dense unitary @p matrix to the
675 * @p targets (treated as increasing significance) of @p qureg.
676 *
677 * @formulae
678 *
679 * Let @f$ M = @f$ @p matrix.
680 * The qubits within @p targets are treated to be ordered least to most significant with respect
681 * to @f$ M @f$. That is, if @f$ M @f$ was hypothetically separable single-qubit matrices
682 * @f[
683 M \equiv \dots \otimes C \otimes B \otimes A
684 * @f]
685 * then this function would effect
686 * @f[
687 \hat{M}_{\text{targets}} \equiv A_{\text{targets}[0]} \cdot B_{\text{targets}[1]} \cdot C_{\text{targets}[2]} \cdot \dots
688 * @f]
689 *
690 * > [!TIP]
691 * > This function is sometimes more efficient when @p targets are specified in increasing order.
692 *
693 * @see
694 * - applyCompMatr1()
695 * - leftapplyCompMatr()
696 * - rightapplyCompMatr()
697 * @author Tyson Jones
698 */
699void applyCompMatr(Qureg qureg, int* targets, int numTargets, CompMatr matrix);
700
701
702/** @notyetdoced
703 *
704 * Applies a singly-controlled arbitrarily-sized dense unitary @p matrix to the
705 * @p targets (treated as increasing significance) of @p qureg.
706 *
707 * > - See applyCompMatr() for information about @p targets and @p matrix.
708 * > - See applyControlledCompMatr1() for information about the @p control qubit.
709 *
710 * @author Tyson Jones
711 */
712void applyControlledCompMatr(Qureg qureg, int control, int* targets, int numTargets, CompMatr matrix);
713
714
715/** @notyetdoced
716 *
717 * Applies a multiply-controlled arbitrarily-sized dense unitary @p matrix upon the
718 * @p targets of @p qureg.
719 *
720 * > - See applyCompMatr() for information about @p targets and @p matrix.
721 * > - See applyMultiControlledCompMatr1() for information about @p controls.
722 *
723 * @author Tyson Jones
724 */
725void applyMultiControlledCompMatr(Qureg qureg, int* controls, int numControls, int* targets, int numTargets, CompMatr matrix);
726
727
728/** @notyetdoced
729 *
730 * Applies an arbitrarily-controlled arbitrarily-sized dense unitary @p matrix upon the
731 * @p targets of @p qureg,
732 * conditioned upon the @p controls being in the corresponding @p states.
733 *
734 * > - See applyCompMatr() for information about @p targets and @p matrix.
735 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
736 *
737 * @author Tyson Jones
738 */
739void applyMultiStateControlledCompMatr(Qureg qureg, int* controls, int* states, int numControls, int* targets, int numTargets, CompMatr matrix);
740
741
742// end de-mangler
743#ifdef __cplusplus
744}
745#endif
746
747#ifdef __cplusplus
748
749
750/// @notyettested
751/// @notyetvalidated
752/// @notyetdoced
753/// @cppvectoroverload
754/// @see applyCompMatr()
755void applyCompMatr(Qureg qureg, std::vector<int> targets, CompMatr matrix);
756
757
758/// @notyettested
759/// @notyetvalidated
760/// @notyetdoced
761/// @cppvectoroverload
762/// @see applyControlledCompMatr()
763void applyControlledCompMatr(Qureg qureg, int control, std::vector<int> targets, CompMatr matrix);
764
765
766/// @notyettested
767/// @notyetvalidated
768/// @notyetdoced
769/// @cppvectoroverload
770/// @see applyMultiControlledCompMatr()
771void applyMultiControlledCompMatr(Qureg qureg, std::vector<int> controls, std::vector<int> targets, CompMatr matrix);
772
773
774/// @notyettested
775/// @notyetvalidated
776/// @notyetdoced
777/// @cppvectoroverload
778/// @see applyMultiStateControlledCompMatr()
779void applyMultiStateControlledCompMatr(Qureg qureg, std::vector<int> controls, std::vector<int> states, std::vector<int> targets, CompMatr matrix);
780
781
782#endif // __cplusplus
783
784/** @} */
785
786
787
788/**
789 * @defgroup op_diagmatr1 DiagMatr1
790 * @brief Functions for applying general one-qubit diagonal matrices, as DiagMatr1.
791 * @{
792 */
793
794
795#ifdef __cplusplus
796extern "C" {
797#endif
798
799
800/** @notyetdoced
801 *
802 * Applies a one-qubit diagonal unitary @p matrix to the @p target qubit of @p qureg.
803 *
804 * @see
805 * - applyCompMatr1()
806 * - leftapplyCompMatr2()
807 * - rightapplyCompMatr2()
808 */
809void applyDiagMatr1(Qureg qureg, int target, DiagMatr1 matrix);
810
811
812/** @notyetdoced
813 *
814 * Applies a singly-controlled one-qubit diagonal unitary @p matrix to the
815 * @p target qubit of @p qureg.
816 *
817 * > - See applyDiagMatr1() for information about the base operation.
818 * > - See applyControlledCompMatr1() for information about the @p control qubit.
819 *
820 * @author Tyson Jones
821 */
822void applyControlledDiagMatr1(Qureg qureg, int control, int target, DiagMatr1 matrix);
823
824
825/** @notyetdoced
826 *
827 * Applies a multiply-controlled one-qubit diagonal unitary @p matrix upon the
828 * @p target qubit of @p qureg.
829 *
830 * > - See applyDiagMatr1() for information about @p target and @p matrix.
831 * > - See applyMultiControlledCompMatr1() for information about @p controls and @p states.
832 *
833 * @author Tyson Jones
834 */
835void applyMultiControlledDiagMatr1(Qureg qureg, int* controls, int numControls, int target, DiagMatr1 matrix);
836
837
838/** @notyetdoced
839 *
840 * Applies an arbitrarily-controlled one-qubit diagonal unitary @p matrix upon the
841 * @p target qubit of @p qureg,
842 * conditioned upon the @p controls being in the corresponding @p states.
843 *
844 * > - See applyDiagMatr1() for information about @p target and @p matrix.
845 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
846 *
847 * @author Tyson Jones
848 */
849void applyMultiStateControlledDiagMatr1(Qureg qureg, int* controls, int* states, int numControls, int target, DiagMatr1 matrix);
850
851
852// end de-mangler
853#ifdef __cplusplus
854}
855#endif
856
857#ifdef __cplusplus
858
859
860/// @notyettested
861/// @notyetvalidated
862/// @notyetdoced
863/// @cppvectoroverload
864/// @see applyMultiControlledDiagMatr1()
865void applyMultiControlledDiagMatr1(Qureg qureg, std::vector<int> controls, int target, DiagMatr1 matrix);
866
867
868/// @notyettested
869/// @notyetvalidated
870/// @notyetdoced
871/// @cppvectoroverload
872/// @see applyMultiStateControlledDiagMatr1()
873void applyMultiStateControlledDiagMatr1(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target, DiagMatr1 matrix);
874
875
876#endif // __cplusplus
877
878/** @} */
879
880
881
882/**
883 * @defgroup op_diagmatr2 DiagMatr2
884 * @brief Functions for applying general two-qubit diagonal matrices, as DiagMatr2.
885 * @{
886 */
887
888
889#ifdef __cplusplus
890extern "C" {
891#endif
892
893
894/** @notyetdoced
895 *
896 * Applies a two-qubit diagonal unitary @p matrix to qubits
897 * @p target1 and @p target2 of @p qureg.
898 *
899 * @author Tyson Jones
900 */
901void applyDiagMatr2(Qureg qureg, int target1, int target2, DiagMatr2 matrix);
902
903
904/** @notyetdoced
905 *
906 * Applies a singly-controlled two-qubit diagonal unitary @p matrix to qubits
907 * @p target1 and @p target2 of @p qureg.
908 *
909 * > - See applyDiagMatr2() for information about the base operation.
910 * > - See applyControlledCompMatr1() for information about the @p control qubit.
911 *
912 * @author Tyson Jones
913 */
914void applyControlledDiagMatr2(Qureg qureg, int control, int target1, int target2, DiagMatr2 matrix);
915
916
917/** @notyetdoced
918 *
919 * Applies a multiply-controlled two-qubit diagonal unitary @p matrix upon
920 * qubits @p target1 and @p target2 of @p qureg.
921 *
922 * > - See applyDiagMatr2() for information about @p target1, @p target2 and @p matrix.
923 * > - See applyMultiControlledCompMatr1() for information about @p controls.
924 *
925 * @author Tyson Jones
926 */
927void applyMultiControlledDiagMatr2(Qureg qureg, int* controls, int numControls, int target1, int target2, DiagMatr2 matrix);
928
929
930/** @notyetdoced
931 *
932 * Applies an arbitrarily-controlled two-qubit diagonal unitary @p matrix upon
933 * qubits @p target1 and @p target2 of @p qureg,
934 * conditioned upon the @p controls being in the corresponding @p states.
935 *
936 * > - See applyDiagMatr2() for information about @p target1, @p target2 and @p matrix.
937 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
938 *
939 * @author Tyson Jones
940 */
941void applyMultiStateControlledDiagMatr2(Qureg qureg, int* controls, int* states, int numControls, int target1, int target2, DiagMatr2 matrix);
942
943
944// end de-mangler
945#ifdef __cplusplus
946}
947#endif
948
949#ifdef __cplusplus
950
951
952/// @notyettested
953/// @notyetvalidated
954/// @notyetdoced
955/// @cppvectoroverload
956/// @see applyMultiControlledDiagMatr2()
957void applyMultiControlledDiagMatr2(Qureg qureg, std::vector<int> controls, int target1, int target2, DiagMatr2 matrix);
958
959
960/// @notyettested
961/// @notyetvalidated
962/// @notyetdoced
963/// @cppvectoroverload
964/// @see applyMultiStateControlledDiagMatr2()
965void applyMultiStateControlledDiagMatr2(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target1, int target2, DiagMatr2 matrix);
966
967
968#endif // __cplusplus
969
970/** @} */
971
972
973
974/**
975 * @defgroup op_diagmatr DiagMatr
976 * @brief Functions for applying general many-qubit diagonal matrices, as DiagMatr.
977 * @{
978 */
979
980
981#ifdef __cplusplus
982extern "C" {
983#endif
984
985
986/** @notyetdoced
987 *
988 * Applies an arbitrarily-sized diagonal unitary @p matrix upon the @p targets of @p qureg.
989 *
990 * > [!TIP]
991 * > To efficiently apply a diagonal matrix upon _all_ targets of @p qureg,
992 * > use applyFullStateDiagMatr().
993 *
994 * > [!TIP]
995 * > This function is sometimes more efficient when @p targets are specified in increasing order.
996 *
997 * @see
998 * - applyDiagMatrPower()
999 * - applyControlledDiagMatr()
1000 * - applyFullStateDiagMatr()
1001 * @author Tyson Jones
1002 */
1003void applyDiagMatr(Qureg qureg, int* targets, int numTargets, DiagMatr matrix);
1004
1005
1006/** @notyetdoced
1007 *
1008 * Applies a singly-controlled arbitrarily-sized diagonal unitary @p matrix
1009 * upon the @p targets of @p qureg.
1010 *
1011 * > - See applyDiagMatr() for information about the base operation, @p targets and @p matrix.
1012 * > - See applyControlledCompMatr1() for information about the @p control qubit.
1013 *
1014 * @author Tyson Jones
1015 */
1016void applyControlledDiagMatr(Qureg qureg, int control, int* targets, int numTargets, DiagMatr matrix);
1017
1018
1019/** @notyetdoced
1020 *
1021 * Applies a multiply-controlled arbitrarily-sized diagonal unitary @p matrix upon
1022 * the @p targets of @p qureg.
1023 *
1024 * > - See applyDiagMatr() for information about @p targets and @p matrix.
1025 * > - See applyMultiControlledCompMatr1() for information about @p controls.
1026 *
1027 * @author Tyson Jones
1028 */
1029void applyMultiControlledDiagMatr(Qureg qureg, int* controls, int numControls, int* targets, int numTargets, DiagMatr matrix);
1030
1031
1032/** @notyetdoced
1033 *
1034 * Applies an arbitrarily-controlled arbitrarily-sized diagonal unitary @p matrix upon
1035 * the @p targets of @p qureg,
1036 * conditioned upon the @p controls being in the corresponding @p states.
1037 *
1038 * > - See applyDiagMatr() for information about @p targets and @p matrix.
1039 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
1040 *
1041 * @author Tyson Jones
1042 */
1043void applyMultiStateControlledDiagMatr(Qureg qureg, int* controls, int* states, int numControls, int* targets, int numTargets, DiagMatr matrix);
1044
1045
1046/** @notyetdoced
1047 *
1048 * Applies an arbitrarily-sized diagonal unitary @p matrix, raised to the power @p exponent,
1049 * upon the @p targets of @p qureg.
1050 *
1051 * > [!TIP]
1052 * > To efficiently apply an exponentiated diagonal matrix upon _all_ targets of @p qureg,
1053 * > use applyFullStateDiagMatrPower().
1054 *
1055 * > [!TIP]
1056 * > This function is sometimes more efficient when @p targets are specified in increasing order.
1057 *
1058 * @formulae
1059 *
1060 * This function is equivalent to applyDiagMatr() except that @p matrix is raised to the given @p exponent.
1061 *
1062 * @see
1063 * - applyControlledDiagMatrPower()
1064 * - applyFullStateDiagMatrPower()
1065 */
1066void applyDiagMatrPower(Qureg qureg, int* targets, int numTargets, DiagMatr matrix, qcomp exponent);
1067
1068
1069/** @notyetdoced
1070 *
1071 * Applies a singly-controlled arbitrarily-sized diagonal unitary @p matrix,
1072 * raised to the power @p exponent, upon the @p targets of @p qureg.
1073 *
1074 * > - See applyDiagMatr() for information about @p targets and @p matrix.
1075 * > - See applyDiagMatrPower() for information about @p exponent.
1076 * > - See applyControlledCompMatr1() for information about the @p control qubit.
1077 *
1078 * @author Tyson Jones
1079 */
1080void applyControlledDiagMatrPower(Qureg qureg, int control, int* targets, int numTargets, DiagMatr matrix, qcomp exponent);
1081
1082
1083/** @notyetdoced
1084 *
1085 * Applies a multiply-controlled arbitrarily-sized diagonal unitary @p matrix,
1086 * raised to the power @p exponent,
1087 * upon the @p targets of @p qureg.
1088 *
1089 * > - See applyDiagMatr() for information about @p targets and @p matrix.
1090 * > - See applyDiagMatrPower() for information about @p exponent.
1091 * > - See applyMultiControlledCompMatr1() for information about @p controls.
1092 *
1093 * @author Tyson Jones
1094 */
1095void applyMultiControlledDiagMatrPower(Qureg qureg, int* controls, int numControls, int* targets, int numTargets, DiagMatr matrix, qcomp exponent);
1096
1097
1098/** @notyetdoced
1099 *
1100 * Applies an arbitrarily-controlled arbitrarily-sized diagonal unitary @p matrix,
1101 * raised to the power @p exponent,
1102 * upon the @p targets of @p qureg,
1103 * conditioned upon the @p controls being in the corresponding @p states.
1104 *
1105 * > - See applyDiagMatr() for information about @p targets and @p matrix.
1106 * > - See applyDiagMatrPower() for information about @p exponent.
1107 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
1108 *
1109 * @author Tyson Jones
1110 */
1111void applyMultiStateControlledDiagMatrPower(Qureg qureg, int* controls, int* states, int numControls, int* targets, int numTargets, DiagMatr matrix, qcomp exponent);
1112
1113
1114// end de-mangler
1115#ifdef __cplusplus
1116}
1117#endif
1118
1119#ifdef __cplusplus
1120
1121
1122/// @notyettested
1123/// @notyetvalidated
1124/// @notyetdoced
1125/// @cppvectoroverload
1126/// @see applyDiagMatr()
1127void applyDiagMatr(Qureg qureg, std::vector<int> targets, DiagMatr matrix);
1128
1129
1130/// @notyettested
1131/// @notyetvalidated
1132/// @notyetdoced
1133/// @cppvectoroverload
1134/// @see applyControlledDiagMatr()
1135void applyControlledDiagMatr(Qureg qureg, int control, std::vector<int> targets, DiagMatr matrix);
1136
1137
1138/// @notyettested
1139/// @notyetvalidated
1140/// @notyetdoced
1141/// @cppvectoroverload
1142/// @see applyMultiControlledDiagMatr()
1143void applyMultiControlledDiagMatr(Qureg qureg, std::vector<int> controls, std::vector<int> targets, DiagMatr matrix);
1144
1145
1146/// @notyettested
1147/// @notyetvalidated
1148/// @notyetdoced
1149/// @cppvectoroverload
1150/// @see applyMultiStateControlledDiagMatr()
1151void applyMultiStateControlledDiagMatr(Qureg qureg, std::vector<int> controls, std::vector<int> states, std::vector<int> targets, DiagMatr matrix);
1152
1153
1154/// @notyettested
1155/// @notyetvalidated
1156/// @notyetdoced
1157/// @cppvectoroverload
1158/// @see applyDiagMatrPower()
1159void applyDiagMatrPower(Qureg qureg, std::vector<int> targets, DiagMatr matrix, qcomp exponent);
1160
1161
1162/// @notyettested
1163/// @notyetvalidated
1164/// @notyetdoced
1165/// @cppvectoroverload
1166/// @see applyControlledDiagMatrPower()
1167void applyControlledDiagMatrPower(Qureg qureg, int control, std::vector<int> targets, DiagMatr matrix, qcomp exponent);
1168
1169
1170/// @notyettested
1171/// @notyetvalidated
1172/// @notyetdoced
1173/// @cppvectoroverload
1174/// @see applyMultiControlledDiagMatrPower()
1175void applyMultiControlledDiagMatrPower(Qureg qureg, std::vector<int> controls, std::vector<int> targets, DiagMatr matrix, qcomp exponent);
1176
1177
1178/// @notyettested
1179/// @notyetvalidated
1180/// @notyetdoced
1181/// @cppvectoroverload
1182/// @see applyMultiStateControlledDiagMatrPower()
1183void applyMultiStateControlledDiagMatrPower(Qureg qureg, std::vector<int> controls, std::vector<int> states, std::vector<int> targets, DiagMatr matrix, qcomp exponent);
1184
1185
1186#endif // __cplusplus
1187
1188/** @} */
1189
1190
1191
1192/**
1193 * @defgroup op_fullstatediagmatr FullStateDiagMatr
1194 * @brief Functions for applying general all-qubit diagonal matrices, as FullStateDiagMatr.
1195 * @{
1196 */
1197
1198
1199#ifdef __cplusplus
1200extern "C" {
1201#endif
1202
1203
1204/// @notyetdoced
1205/// @notyetvalidated
1207
1208
1209/// @notyetdoced
1210/// @notyetvalidated
1211/// @see
1212/// - applyDiagMatrPower
1213void applyFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qcomp exponent);
1214
1215
1216// end de-mangler
1217#ifdef __cplusplus
1218}
1219#endif
1220
1221
1222/** @} */
1223
1224
1225
1226/**
1227 * @defgroup op_fixed Fixed
1228 * @brief Functions for applying the one-qubit S, T and Hadamard gates.
1229 * @{
1230 */
1231
1232
1233#ifdef __cplusplus
1234extern "C" {
1235#endif
1236
1237
1238/// @notyetdoced
1239void applyS(Qureg qureg, int target);
1240
1241
1242/** @notyetdoced
1243 *
1244 * Applies a singly-controlled S gate on the @p target qubit of @p qureg.
1245 *
1246 * > - See applyS() for information about the base operation.
1247 * > - See applyControlledCompMatr1() for information about @p control.
1248 *
1249 * @author Tyson Jones
1250 */
1251void applyControlledS(Qureg qureg, int control, int target);
1252
1253
1254/** @notyetdoced
1255 *
1256 * Applies a multiply-controlled S gate on the @p target qubit of @p qureg.
1257 *
1258 * > - See applyS() for information about the base operation.
1259 * > - See applyMultiControlledCompMatr1() for information about @p controls.
1260 *
1261 * @author Tyson Jones
1262 */
1263void applyMultiControlledS(Qureg qureg, int* controls, int numControls, int target);
1264
1265
1266/** @notyetdoced
1267 *
1268 * Applies an arbitrarily-controlled S gate on the @p target qubit of @p qureg,
1269 * conditioned upon @p controls being in the corresponding @p states.
1270 *
1271 * > - See applyS() for information about the base operation.
1272 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
1273 *
1274 * @author Tyson Jones
1275 */
1276void applyMultiStateControlledS(Qureg qureg, int* controls, int* states, int numControls, int target);
1277
1278
1279/// @notyetdoced
1280void applyT(Qureg qureg, int target);
1281
1282
1283/** @notyetdoced
1284 *
1285 * Applies a singly-controlled T gate on the @p target qubit of @p qureg.
1286 *
1287 * > - See applyT() for information about the base operation.
1288 * > - See applyControlledCompMatr1() for information about @p control.
1289 *
1290 * @author Tyson Jones
1291 */
1292void applyControlledT(Qureg qureg, int control, int target);
1293
1294
1295/** @notyetdoced
1296 *
1297 * Applies an arbitrarily-controlled T gate on the @p target qubit of @p qureg,
1298 * conditioned upon @p controls being in the corresponding @p states.
1299 *
1300 * > - See applyT() for information about the base operation.
1301 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
1302 *
1303 * @author Tyson Jones
1304 */
1305void applyMultiControlledT(Qureg qureg, int* controls, int numControls, int target);
1306
1307
1308/** @notyetdoced
1309 *
1310 * Applies an arbitrarily-controlled T gate on the @p target qubit of @p qureg,
1311 * conditioned upon @p controls being in the corresponding @p states.
1312 *
1313 * > - See applyT() for information about the base operation.
1314 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
1315 *
1316 * @author Tyson Jones
1317 */
1318void applyMultiStateControlledT(Qureg qureg, int* controls, int* states, int numControls, int target);
1319
1320
1321/// @notyetdoced
1322void applyHadamard(Qureg qureg, int target);
1323
1324
1325/** @notyetdoced
1326 *
1327 * Applies a singly-controlled Hadamard gate on the @p target qubit of @p qureg.
1328 *
1329 * > - See applyHadamard() for information about the base operation.
1330 * > - See applyControlledCompMatr1() for information about @p control.
1331 *
1332 * @author Tyson Jones
1333 */
1334void applyControlledHadamard(Qureg qureg, int control, int target);
1335
1336
1337/** @notyetdoced
1338 *
1339 * Applies an arbitrarily-controlled Hadamard gate on the @p target qubit of @p qureg,
1340 * conditioned upon @p controls being in the corresponding @p states.
1341 *
1342 * > - See applyHadamard() for information about the base operation.
1343 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
1344 *
1345 * @author Tyson Jones
1346 */
1347void applyMultiControlledHadamard(Qureg qureg, int* controls, int numControls, int target);
1348
1349
1350/** @notyetdoced
1351 *
1352 * Applies an arbitrarily-controlled Hadamard gate on the @p target qubit of @p qureg,
1353 * conditioned upon @p controls being in the corresponding @p states.
1354 *
1355 * > - See applyHadamard() for information about the base operation.
1356 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
1357 *
1358 * @author Tyson Jones
1359 */
1360void applyMultiStateControlledHadamard(Qureg qureg, int* controls, int* states, int numControls, int target);
1361
1362
1363// end de-mangler
1364#ifdef __cplusplus
1365}
1366#endif
1367
1368#ifdef __cplusplus
1369
1370
1371/// @notyettested
1372/// @notyetvalidated
1373/// @notyetdoced
1374/// @cppvectoroverload
1375/// @see applyMultiControlledS()
1376void applyMultiControlledS(Qureg qureg, std::vector<int> controls, int target);
1377
1378
1379/// @notyettested
1380/// @notyetvalidated
1381/// @notyetdoced
1382/// @cppvectoroverload
1383/// @see applyMultiStateControlledS()
1384void applyMultiStateControlledS(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target);
1385
1386
1387/// @notyettested
1388/// @notyetvalidated
1389/// @notyetdoced
1390/// @cppvectoroverload
1391/// @see applyMultiControlledT()
1392void applyMultiControlledT(Qureg qureg, std::vector<int> controls, int target);
1393
1394
1395/// @notyettested
1396/// @notyetvalidated
1397/// @notyetdoced
1398/// @cppvectoroverload
1399/// @see applyMultiStateControlledT()
1400void applyMultiStateControlledT(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target);
1401
1402
1403/// @notyettested
1404/// @notyetvalidated
1405/// @notyetdoced
1406/// @cppvectoroverload
1407/// @see applyMultiControlledHadamard()
1408void applyMultiControlledHadamard(Qureg qureg, std::vector<int> controls, int target);
1409
1410
1411/// @notyettested
1412/// @notyetvalidated
1413/// @notyetdoced
1414/// @cppvectoroverload
1415/// @see applyMultiStateControlledHadamard()
1416void applyMultiStateControlledHadamard(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target);
1417
1418
1419#endif // __cplusplus
1420
1421/** @} */
1422
1423
1424
1425/**
1426 * @defgroup op_swap Swap
1427 * @brief Functions for applying the two-qubit SWAP and related gates.
1428 * @{
1429 */
1430
1431
1432#ifdef __cplusplus
1433extern "C" {
1434#endif
1435
1436
1437/** Applies a SWAP gate between @p qubit1 and @p qubit2 of @p qureg.
1438 *
1439 * @diagram
1440 * @dot
1441digraph {
1442 rankdir=LR;
1443 layout=neato;
1444 node [fontsize=10, fontname="Menlo"];
1445 edge [dir=none];
1446
1447 topWireL [shape=plaintext, label="qubit2", pos="0,.5!"];
1448 topWireM [shape=point, label="", width=0, pos=".75,.5!"];
1449 topWireR [shape=plaintext, label="", pos="1.5,.5!"];
1450
1451 botWireL [shape=plaintext, label="qubit1", pos="0,0!"];
1452 botWireM [shape=point, label="", width=0, pos=".75,0!"];
1453 botWireR [shape=plaintext, label="", pos="1.5,0!"];
1454
1455 topWireL -> topWireR;
1456 botWireL -> botWireR;
1457 botWireM -> topWireM;
1458
1459 topX [shape=plaintext, label="✕", pos=".75,.5!", fontsize=15];
1460 botX [shape=plaintext, label="✕", pos=".75,0!", fontsize=15];
1461}
1462 * @enddot
1463 *
1464 * @notyetdoced
1465 */
1466void applySwap(Qureg qureg, int qubit1, int qubit2);
1467
1468
1469/** @notyetdoced
1470 *
1471 * Applies a singly-controlled SWAP gate upon @p qubit1 and @p qubit2 of @p qureg.
1472 *
1473 * > - See applySwap() for information about the base operation.
1474 * > - See applyControlledCompMatr1() for information about @p control.
1475 *
1476 * @author Tyson Jones
1477 */
1478void applyControlledSwap(Qureg qureg, int control, int qubit1, int qubit2);
1479
1480
1481/** @notyetdoced
1482 *
1483 * Applies a multiply-controlled SWAP gate on @p qubit1 and @p qubit2 of @p qureg.
1484 *
1485 * > - See applySwap() for information about the base operation.
1486 * > - See applyMultiControlledCompMatr1() for information about @p controls.
1487 *
1488 * @author Tyson Jones
1489 */
1490void applyMultiControlledSwap(Qureg qureg, int* controls, int numControls, int qubit1, int qubit2);
1491
1492
1493/** @notyetdoced
1494 *
1495 * Applies an arbitrarily-controlled SWAP gate on @p qubit1 and @p qubit2 of @p qureg,
1496 * conditioned upon @p controls being in the corresponding @p states.
1497 *
1498 * > - See applySwap() for information about the base operation.
1499 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
1500 *
1501 * @author Tyson Jones
1502 */
1503void applyMultiStateControlledSwap(Qureg qureg, int* controls, int* states, int numControls, int qubit1, int qubit2);
1504
1505
1506/// @notyetdoced
1507void applySqrtSwap(Qureg qureg, int qubit1, int qubit2);
1508
1509
1510/** @notyetdoced
1511 *
1512 * Applies a singly-controlled square-root-of-SWAP gate upon @p qubit1 and @p qubit2 of @p qureg.
1513 *
1514 * > - See applySqrtSwap() for information about the base operation.
1515 * > - See applyControlledCompMatr1() for information about @p control.
1516 *
1517 * @author Tyson Jones
1518 */
1519void applyControlledSqrtSwap(Qureg qureg, int control, int qubit1, int qubit2);
1520
1521
1522/** @notyetdoced
1523 *
1524 * Applies a multiply-controlled square-root-of-SWAP gate on @p qubit1 and @p qubit2 of @p qureg.
1525 *
1526 * > - See applySqrtSwap() for information about the base operation.
1527 * > - See applyMultiControlledCompMatr1() for information about @p controls.
1528 *
1529 * @author Tyson Jones
1530 */
1531void applyMultiControlledSqrtSwap(Qureg qureg, int* controls, int numControls, int qubit1, int qubit2);
1532
1533
1534/** @notyetdoced
1535 *
1536 * Applies an arbitrarily-controlled square-root-of-SWAP gate on @p qubit1 and @p qubit2 of @p qureg,
1537 * conditioned upon @p controls being in the corresponding @p states.
1538 *
1539 * > - See applySqrtSwap() for information about the base operation.
1540 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
1541 *
1542 * @author Tyson Jones
1543 */
1544void applyMultiStateControlledSqrtSwap(Qureg qureg, int* controls, int* states, int numControls, int qubit1, int qubit2);
1545
1546
1547// end de-mangler
1548#ifdef __cplusplus
1549}
1550#endif
1551
1552#ifdef __cplusplus
1553
1554
1555/// @notyettested
1556/// @notyetvalidated
1557/// @notyetdoced
1558/// @cppvectoroverload
1559/// @see applyMultiControlledSwap()
1560void applyMultiControlledSwap(Qureg qureg, std::vector<int> controls, int qubit1, int qubit2);
1561
1562
1563/// @notyettested
1564/// @notyetvalidated
1565/// @notyetdoced
1566/// @cppvectoroverload
1567/// @see applyMultiStateControlledSwap()
1568void applyMultiStateControlledSwap(Qureg qureg, std::vector<int> controls, std::vector<int> states, int qubit1, int qubit2);
1569
1570
1571/// @notyettested
1572/// @notyetvalidated
1573/// @notyetdoced
1574/// @cppvectoroverload
1575/// @see applyMultiControlledSqrtSwap()
1576void applyMultiControlledSqrtSwap(Qureg qureg, std::vector<int> controls, int qubit1, int qubit2);
1577
1578
1579/// @notyettested
1580/// @notyetvalidated
1581/// @notyetdoced
1582/// @cppvectoroverload
1583/// @see applyMultiStateControlledSqrtSwap()
1584void applyMultiStateControlledSqrtSwap(Qureg qureg, std::vector<int> controls, std::vector<int> states, int qubit1, int qubit2);
1585
1586
1587#endif // __cplusplus
1588
1589/** @} */
1590
1591
1592
1593/**
1594 * @defgroup op_pauli Pauli
1595 * @brief Functions for applying the individual one-qubit Pauli operators.
1596 * @{
1597 */
1598
1599
1600#ifdef __cplusplus
1601extern "C" {
1602#endif
1603
1604
1605/// @notyetdoced
1606void applyPauliX(Qureg qureg, int target);
1607
1608
1609/// @notyetdoced
1610void applyPauliY(Qureg qureg, int target);
1611
1612
1613/// @notyetdoced
1614void applyPauliZ(Qureg qureg, int target);
1615
1616
1617/** @notyetdoced
1618 *
1619 * Applies a singly-controlled Pauli @c X operator (or NOT gate) upon the @p target qubit of @p qureg.
1620 *
1621 * > - See applyPauliX() for information about the base operation.
1622 * > - See applyControlledCompMatr1() for information about @p control.
1623 *
1624 * @author Tyson Jones
1625 */
1626void applyControlledPauliX(Qureg qureg, int control, int target);
1627
1628
1629/** @notyetdoced
1630 *
1631 * Applies a singly-controlled Pauli @c Y operator upon the @p target qubit of @p qureg.
1632 *
1633 * > - See applyPauliY() for information about the base operation.
1634 * > - See applyControlledCompMatr1() for information about @p control.
1635 *
1636 * @author Tyson Jones
1637 */
1638void applyControlledPauliY(Qureg qureg, int control, int target);
1639
1640
1641/** @notyetdoced
1642 *
1643 * Applies a singly-controlled Pauli @c Z operator upon the @p target qubit of @p qureg.
1644 *
1645 * > - See applyPauliZ() for information about the base operation.
1646 * > - See applyControlledCompMatr1() for information about @p control.
1647 *
1648 * @author Tyson Jones
1649 */
1650void applyControlledPauliZ(Qureg qureg, int control, int target);
1651
1652
1653/** @notyetdoced
1654 *
1655 * Applies a multiply-controlled Pauli @c X operator (or NOT gate) upon the @p target qubit of @p qureg.
1656 *
1657 * > - See applyPauliX() for information about the base operation.
1658 * > - See applyMultiControlledCompMatr1() for information about @p controls.
1659 *
1660 * @author Tyson Jones
1661 */
1662void applyMultiControlledPauliX(Qureg qureg, int* controls, int numControls, int target);
1663
1664
1665/** @notyetdoced
1666 *
1667 * Applies a multiply-controlled Pauli @c Y operator (or NOT gate) upon the @p target qubit of @p qureg.
1668 *
1669 * > - See applyPauliY() for information about the base operation.
1670 * > - See applyMultiControlledCompMatr1() for information about @p controls.
1671 *
1672 * @author Tyson Jones
1673 */
1674void applyMultiControlledPauliY(Qureg qureg, int* controls, int numControls, int target);
1675
1676
1677/** @notyetdoced
1678 *
1679 * Applies a multiply-controlled Pauli @c Z operator (or NOT gate) upon the @p target qubit of @p qureg.
1680 *
1681 * > - See applyPauliZ() for information about the base operation.
1682 * > - See applyMultiControlledCompMatr1() for information about @p controls.
1683 *
1684 * @author Tyson Jones
1685 */
1686void applyMultiControlledPauliZ(Qureg qureg, int* controls, int numControls, int target);
1687
1688
1689/** @notyetdoced
1690 *
1691 * Applies an arbitrarily-controlled Pauli @c X operator (or NOT gate) upon the @p target qubit of @p qureg,
1692 * conditioned upon @p controls being in the corresponding @p states.
1693 *
1694 * > - See applyPauliX() for information about the base operation.
1695 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
1696 *
1697 * @author Tyson Jones
1698 */
1699void applyMultiStateControlledPauliX(Qureg qureg, int* controls, int* states, int numControls, int target);
1700
1701
1702/** @notyetdoced
1703 *
1704 * Applies an arbitrarily-controlled Pauli @c Y operator upon the @p target qubit of @p qureg,
1705 * conditioned upon @p controls being in the corresponding @p states.
1706 *
1707 * > - See applyPauliY() for information about the base operation.
1708 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
1709 *
1710 * @author Tyson Jones
1711 */
1712void applyMultiStateControlledPauliY(Qureg qureg, int* controls, int* states, int numControls, int target);
1713
1714
1715/** @notyetdoced
1716 *
1717 * Applies an arbitrarily-controlled Pauli @c Z operator upon the @p target qubit of @p qureg,
1718 * conditioned upon @p controls being in the corresponding @p states.
1719 *
1720 * > - See applyPauliZ() for information about the base operation.
1721 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
1722 *
1723 * @author Tyson Jones
1724 */
1725void applyMultiStateControlledPauliZ(Qureg qureg, int* controls, int* states, int numControls, int target);
1726
1727
1728// end de-mangler
1729#ifdef __cplusplus
1730}
1731#endif
1732
1733#ifdef __cplusplus
1734
1735
1736/// @notyettested
1737/// @notyetvalidated
1738/// @notyetdoced
1739/// @cppvectoroverload
1740/// @see applyMultiControlledPauliX()
1741void applyMultiControlledPauliX(Qureg qureg, std::vector<int> controls, int target);
1742
1743
1744/// @notyettested
1745/// @notyetvalidated
1746/// @notyetdoced
1747/// @cppvectoroverload
1748/// @see applyMultiControlledPauliY()
1749void applyMultiControlledPauliY(Qureg qureg, std::vector<int> controls, int target);
1750
1751
1752/// @notyettested
1753/// @notyetvalidated
1754/// @notyetdoced
1755/// @cppvectoroverload
1756/// @see applyMultiControlledPauliZ()
1757void applyMultiControlledPauliZ(Qureg qureg, std::vector<int> controls, int target);
1758
1759
1760/// @notyettested
1761/// @notyetvalidated
1762/// @notyetdoced
1763/// @cppvectoroverload
1764/// @see applyMultiStateControlledPauliX()
1765void applyMultiStateControlledPauliX(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target);
1766
1767
1768/// @notyettested
1769/// @notyetvalidated
1770/// @notyetdoced
1771/// @cppvectoroverload
1772/// @see applyMultiStateControlledPauliY()
1773void applyMultiStateControlledPauliY(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target);
1774
1775
1776/// @notyettested
1777/// @notyetvalidated
1778/// @notyetdoced
1779/// @cppvectoroverload
1780/// @see applyMultiStateControlledPauliZ()
1781void applyMultiStateControlledPauliZ(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target);
1782
1783
1784#endif // __cplusplus
1785
1786/** @} */
1787
1788
1789
1790/**
1791 * @defgroup op_paulistr PauliStr
1792 * @brief Functions for applying a tensor product of Pauli operators, as a PauliStr
1793 * @{
1794 */
1795
1796
1797#ifdef __cplusplus
1798extern "C" {
1799#endif
1800
1801
1802/// @notyetdoced
1803void applyPauliStr(Qureg qureg, PauliStr str);
1804
1805
1806/** @notyetdoced
1807 *
1808 * Applies a singly-controlled tensor product of Pauli operators @p str upon @p qureg.
1809 *
1810 * > - See applyPauliStr() for information about @p str.
1811 * > - See applyControlledCompMatr1() for information about @p control.
1812 *
1813 * @author Tyson Jones
1814 */
1815void applyControlledPauliStr(Qureg qureg, int control, PauliStr str);
1816
1817
1818/** @notyetdoced
1819 *
1820 * Applies a multiply-controlled tensor product of Pauli operators @p str upon @p qureg.
1821 *
1822 * > - See applyPauliStr() for information about @p str.
1823 * > - See applyMultiControlledCompMatr1() for information about @p controls.
1824 *
1825 * @author Tyson Jones
1826 */
1827void applyMultiControlledPauliStr(Qureg qureg, int* controls, int numControls, PauliStr str);
1828
1829
1830/** @notyetdoced
1831 *
1832 * Applies an arbitrarily-controlled tensor product of Pauli operators @p str upon @p qureg,
1833 * conditioned upon @p controls being in the corresponding @p states.
1834 *
1835 * > - See applyPauliStr() for information about @p str.
1836 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
1837 *
1838 * @author Tyson Jones
1839 */
1840void applyMultiStateControlledPauliStr(Qureg qureg, int* controls, int* states, int numControls, PauliStr str);
1841
1842
1843// end de-mangler
1844#ifdef __cplusplus
1845}
1846#endif
1847
1848#ifdef __cplusplus
1849
1850
1851/// @notyettested
1852/// @notyetvalidated
1853/// @notyetdoced
1854/// @cppvectoroverload
1855/// @see applyMultiControlledPauliStr()
1856void applyMultiControlledPauliStr(Qureg qureg, std::vector<int> controls, PauliStr str);
1857
1858
1859/// @notyettested
1860/// @notyetvalidated
1861/// @notyetdoced
1862/// @cppvectoroverload
1863/// @see applyMultiStateControlledPauliStr()
1864void applyMultiStateControlledPauliStr(Qureg qureg, std::vector<int> controls, std::vector<int> states, PauliStr str);
1865
1866
1867#endif // __cplusplus
1868
1869/** @} */
1870
1871
1872
1873/**
1874 * @defgroup op_rotation Rotations
1875 * @brief Functions for applying one-qubit rotations around Pauli and arbitrary axis.
1876 * @{
1877 */
1878
1879
1880#ifdef __cplusplus
1881extern "C" {
1882#endif
1883
1884
1885/** @notyetdoced
1886 *
1887 * @formulae
1888 *
1889 * Let @f$ \theta = @f$ @p angle.
1890 * This function effects unitary
1891 * @f[
1892 \hat{R}_{x}(\theta)
1893 =
1894 \exp \left(
1895 - \iu \frac{\theta}{2}
1896 \hat{\sigma}_x
1897 \right)
1898 * @f]
1899 * upon the @p target qubit, where @f$ \hat{\sigma}_x @f$ is the Pauli @c X matrix.
1900 *
1901 * @equivalences
1902 *
1903 * - This function is entirely equivalent to calling applyPauliGadget() with a single-site PauliStr.
1904 * ```
1905 applyPauliGadget(qureg, getInlinePauliStr("X", {target}), angle);
1906 * ```
1907 * - This function is faster than, but otherwise equivalent to, invoking applyRotateAroundAxis()
1908 * with an axis vector equal to the X-axis.
1909 * ```
1910 applyRotateAroundAxis(qureg, target, qreal angle, 1,0,0);
1911 * ```
1912 * - This function is faster than, but otherwise equivalent to, effecting @f$ \hat{R}_{x}(\theta) @f$ as a CompMatr1.
1913 * ```
1914 qcomp c = cos(angle/2);
1915 qcomp s = sin(angle/2) * (-1.i);
1916 CompMatr1 matr = getInlineCompMatr1({{c, s}, {s, c}});
1917 applyCompMatr1(qureg, target, matr);
1918 * ```
1919 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
1920 */
1921void applyRotateX(Qureg qureg, int target, qreal angle);
1922
1923
1924/** @notyetdoced
1925 *
1926 * @formulae
1927 *
1928 * Let @f$ \theta = @f$ @p angle.
1929 * This function effects unitary
1930 * @f[
1931 \hat{R}_{y}(\theta)
1932 =
1933 \exp \left(
1934 - \iu \frac{\theta}{2}
1935 \hat{\sigma}_y
1936 \right)
1937 * @f]
1938 * upon the @p target qubit, where @f$ \hat{\sigma}_y @f$ is the Pauli @c Y matrix.
1939 *
1940 * @equivalences
1941 *
1942 * - This function is entirely equivalent to calling applyPauliGadget() with a single-site PauliStr.
1943 * ```
1944 applyPauliGadget(qureg, getInlinePauliStr("Y", {target}), angle);
1945 * ```
1946 * - This function is faster than, but otherwise equivalent to, invoking applyRotateAroundAxis()
1947 * with an axis vector equal to the Y-axis.
1948 * ```
1949 applyRotateAroundAxis(qureg, target, qreal angle, 0,1,0);
1950 * ```
1951 * - This function is faster than, but otherwise equivalent to, effecting @f$ \hat{R}_{y}(\theta) @f$ as a CompMatr1.
1952 * ```
1953 qcomp c = cos(angle/2);
1954 qcomp s = sin(angle/2);
1955 CompMatr1 matr = getInlineCompMatr1({{c, -s}, {s, c}});
1956 applyCompMatr1(qureg, target, matr);
1957 * ```
1958 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
1959 */
1960void applyRotateY(Qureg qureg, int target, qreal angle);
1961
1962
1963/** @notyetdoced
1964 *
1965 * @formulae
1966 *
1967 * Let @f$ \theta = @f$ @p angle.
1968 * This function effects unitary
1969 * @f[
1970 \hat{R}_{z}(\theta)
1971 =
1972 \exp \left(
1973 - \iu \frac{\theta}{2}
1974 \hat{\sigma}_z
1975 \right)
1976 * @f]
1977 * upon the @p target qubit, where @f$ \hat{\sigma}_z @f$ is the Pauli @c Z matrix.
1978 *
1979 * @equivalences
1980 *
1981 * - This function is entirely equivalent to calling applyPauliGadget() with a single-site PauliStr.
1982 * ```
1983 applyPauliGadget(qureg, getInlinePauliStr("Z", {target}), angle);
1984 * ```
1985 * - This function is faster than, but otherwise equivalent to, invoking applyRotateAroundAxis()
1986 * with an axis vector equal to the Z-axis.
1987 * ```
1988 applyRotateAroundAxis(qureg, target, qreal angle, 0,0,1);
1989 * ```
1990 * - This function is faster than, but otherwise equivalent to, effecting @f$ \hat{R}_{z}(\theta) @f$ as a DiagMatr1.
1991 * ```
1992 qcomp a = cexp(- angle / 2 * 1.i);
1993 qcomp b = cexp( angle / 2 * 1.i);
1994 DiagMatr1 matr = getInlineDiagMatr1({a, b});
1995 applyDiagMatr1(qureg, target, matr);
1996 * ```
1997 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
1998 */
1999void applyRotateZ(Qureg qureg, int target, qreal angle);
2000
2001
2002/** @notyetdoced
2003 *
2004 * Applies a singly-controlled one-qubit rotation of @p angle around the @c X axis,
2005 * upon the @p target qubit of @p qureg.
2006 *
2007 * > - See applyRotateX() for information about the base operation, and @p angle.
2008 * > - See applyControlledCompMatr1() for information about @p control.
2009 *
2010 * @author Tyson Jones
2011 */
2012void applyControlledRotateX(Qureg qureg, int control, int target, qreal angle);
2013
2014
2015/** @notyetdoced
2016 *
2017 * Applies a singly-controlled one-qubit rotation of @p angle around the @c Y axis,
2018 * upon the @p target qubit of @p qureg.
2019 *
2020 * > - See applyRotateY() for information about the base operation, and @p angle.
2021 * > - See applyControlledCompMatr1() for information about @p control.
2022 *
2023 * @author Tyson Jones
2024 */
2025void applyControlledRotateY(Qureg qureg, int control, int target, qreal angle);
2026
2027
2028/** @notyetdoced
2029 *
2030 * Applies a singly-controlled one-qubit rotation of @p angle around the @c Z axis,
2031 * upon the @p target qubit of @p qureg.
2032 *
2033 * > - See applyRotateZ() for information about the base operation, and @p angle.
2034 * > - See applyControlledCompMatr1() for information about @p control.
2035 *
2036 * @author Tyson Jones
2037 */
2038void applyControlledRotateZ(Qureg qureg, int control, int target, qreal angle);
2039
2040
2041/** @notyetdoced
2042 *
2043 * Applies a multiply-controlled one-qubit rotation of @p angle around the @c X axis,
2044 * upon the @p target qubit of @p qureg.
2045 *
2046 * > - See applyRotateX() for information about the base operation, and @p angle.
2047 * > - See applyMultiControlledCompMatr1() for information about @p controls.
2048 *
2049 * @author Tyson Jones
2050 */
2051void applyMultiControlledRotateX(Qureg qureg, int* controls, int numControls, int target, qreal angle);
2052
2053
2054/** @notyetdoced
2055 *
2056 * Applies a multiply-controlled one-qubit rotation of @p angle around the @c Y axis,
2057 * upon the @p target qubit of @p qureg.
2058 *
2059 * > - See applyRotateY() for information about the base operation, and @p angle.
2060 * > - See applyMultiControlledCompMatr1() for information about @p controls.
2061 *
2062 * @author Tyson Jones
2063 */
2064void applyMultiControlledRotateY(Qureg qureg, int* controls, int numControls, int target, qreal angle);
2065
2066
2067/** @notyetdoced
2068 *
2069 * Applies a multiply-controlled one-qubit rotation of @p angle around the @c Z axis,
2070 * upon the @p target qubit of @p qureg.
2071 *
2072 * > - See applyRotateZ() for information about the base operation, and @p angle.
2073 * > - See applyMultiControlledCompMatr1() for information about @p controls.
2074 *
2075 * @author Tyson Jones
2076 */
2077void applyMultiControlledRotateZ(Qureg qureg, int* controls, int numControls, int target, qreal angle);
2078
2079
2080/** @notyetdoced
2081 *
2082 * Applies an arbitrarily-controlled one-qubit rotation of @p angle around the @c X axis,
2083 * upon the @p target qubit of @p qureg,
2084 * conditioned upon @p controls being in the corresponding @p states.
2085 *
2086 * > - See applyRotateX() for information about the base operation, and @p angle.
2087 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
2088 *
2089 * @author Tyson Jones
2090 */
2091void applyMultiStateControlledRotateX(Qureg qureg, int* controls, int* states, int numControls, int target, qreal angle);
2092
2093
2094/** @notyetdoced
2095 *
2096 * Applies an arbitrarily-controlled one-qubit rotation of @p angle around the @c Y axis,
2097 * upon the @p target qubit of @p qureg,
2098 * conditioned upon @p controls being in the corresponding @p states.
2099 *
2100 * > - See applyRotateY() for information about the base operation, and @p angle.
2101 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
2102 *
2103 * @author Tyson Jones
2104 */
2105void applyMultiStateControlledRotateY(Qureg qureg, int* controls, int* states, int numControls, int target, qreal angle);
2106
2107
2108/** @notyetdoced
2109 *
2110 * Applies an arbitrarily-controlled one-qubit rotation of @p angle around the @c Z axis,
2111 * upon the @p target qubit of @p qureg,
2112 * conditioned upon @p controls being in the corresponding @p states.
2113 *
2114 * > - See applyRotateZ() for information about the base operation, and @p angle.
2115 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
2116 *
2117 * @author Tyson Jones
2118 */
2119void applyMultiStateControlledRotateZ(Qureg qureg, int* controls, int* states, int numControls, int target, qreal angle);
2120
2121
2122/** @notyetdoced
2123 *
2124 * Rotates the @p target qubit of @p qureg by @p angle around an arbitrary axis specified by
2125 * vector @p axisX, @p axisY, @p axisZ.
2126 *
2127 * @formulae
2128 *
2129 * Let @f$ \theta = @f$ @p angle and @f$ \vec{n} = ( @f$ @p axisX, @p axisY, @p axisZ @f$ ) @f$,
2130 * with corresponding unit vector @f$ \bar{n} @f$.
2131 * Further, let @f$ \vec{\sigma} = (\hat{\sigma}_x, \hat{\sigma}_y, \hat{\sigma}_z) @f$ denote a vector of the Pauli matrices.
2132 *
2133 * This function effects unitary
2134 * @f[
2135 \hat{R}_{\bar{n}}(\theta)
2136 =
2137 \exp \left(
2138 - \iu \frac{\theta}{2}
2139 \bar{n} \cdot \vec{\sigma}
2140 \right)
2141 * @f]
2142 * upon the target qubit. Explicitly,
2143 * @f[
2144 \hat{R}_{\bar{n}}(\theta)
2145 \equiv
2146 \begin{pmatrix}
2147 \cos\left( \frac{\theta}{2} \right) - \iu \, \bar{n}_z \sin\left( \frac{\theta}{2} \right)
2148 &
2149 - \, (\bar{n}_y + \bar{n}_x \, \iu ) \sin\left( \frac{\theta}{2} \right)
2150 \\
2151 (\bar{n}_y - \bar{n}_x \, \iu ) \sin\left( \frac{\theta}{2} \right)
2152 &
2153 \cos\left( \frac{\theta}{2} \right) + \iu \, \bar{n}_z \sin\left( \frac{\theta}{2} \right)
2154 \end{pmatrix}
2155 * @f]
2156 * where
2157 * @f[
2158 \bar{n}_i
2159 =
2160 \frac{\vec{n}_i}{\| \vec{n} \|_2}
2161 =
2162 \frac{\vec{n}_i}{ \sqrt{ {\vec{n}_x}^2 + {\vec{n}_y}^2 + {\vec{n}_z}^2 } }.
2163 * @f]
2164 *
2165 * @equivalences
2166 *
2167 * - Assuming @f$ \| \vec{n} \|_2 \ne 0 @f$, this function is agnostic to the normalisation
2168 * of the axis vector.
2169 * ```
2170 applyRotateAroundAxis(qureg, target, angle, x, y, z);
2171 applyRotateAroundAxis(qureg, target, angle, 5*x,5*y,5*z); // equivalent
2172 * ```
2173 * - This function is entirely equivalent to preparing @f$ \hat{R}_{\bar{n}}(\theta) @f$
2174 * as a CompMatr1 and effecting it upon the state via applyCompMatr1().
2175 * - This function is both more accurate and efficient than equivalently instantiating a
2176 * three-term PauliStrSum @f$ \hat{H} = \bar{n} \cdot \vec{\sigma}@f$ and effecting
2177 * @f$ \exp \left(\iu \alpha \hat{H} \right) @f$ via applyTrotterizedPauliStrSumGadget()
2178 * with @f$ \alpha = - \theta/2 @f$ and very many repetitions.
2179 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
2180 */
2181void applyRotateAroundAxis(Qureg qureg, int target, qreal angle, qreal axisX, qreal axisY, qreal axisZ);
2182
2183
2184/** @notyetdoced
2185 *
2186 * Applies a singly-controlled one-qubit rotation of @p angle around an arbitrary axis,
2187 * upon the @p target qubit of @p qureg.
2188 *
2189 * > - See applyRotateAroundAxis() for information about the base operation, @p angle, @p axisX, @p axisY and @p axisZ.
2190 * > - See applyControlledCompMatr1() for information about @p control.
2191 *
2192 * @author Tyson Jones
2193 */
2194void applyControlledRotateAroundAxis(Qureg qureg, int control, int target, qreal angle, qreal axisX, qreal axisY, qreal axisZ);
2195
2196
2197/** @notyetdoced
2198 *
2199 * Applies a multiply-controlled one-qubit rotation of @p angle around an arbitrary axis,
2200 * upon the @p target qubit of @p qureg.
2201 *
2202 * > - See applyRotateAroundAxis() for information about the base operation, @p angle, @p axisX, @p axisY and @p axisZ.
2203 * > - See applyMultiControlledCompMatr1() for information about @p controls.
2204 *
2205 * @author Tyson Jones
2206 */
2207void applyMultiControlledRotateAroundAxis(Qureg qureg, int* controls, int numControls, int target, qreal angle, qreal axisX, qreal axisY, qreal axisZ);
2208
2209
2210/** @notyetdoced
2211 *
2212 * Applies an arbitrarily-controlled one-qubit rotation of @p angle around an arbitrary axis,
2213 * upon the @p target qubit of @p qureg,
2214 * conditioned upon @p controls being in the corresponding @p states.
2215 *
2216 * > - See applyRotateAroundAxis() for information about the base operation, @p angle, @p axisX, @p axisY and @p axisZ.
2217 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
2218 *
2219 * @author Tyson Jones
2220 */
2221void applyMultiStateControlledRotateAroundAxis(Qureg qureg, int* controls, int* states, int numControls, int target, qreal angle, qreal axisX, qreal axisY, qreal axisZ);
2222
2223
2224// end de-mangler
2225#ifdef __cplusplus
2226}
2227#endif
2228
2229#ifdef __cplusplus
2230
2231
2232/// @notyettested
2233/// @notyetvalidated
2234/// @notyetdoced
2235/// @cppvectoroverload
2236/// @see applyMultiControlledRotateX()
2237void applyMultiControlledRotateX(Qureg qureg, std::vector<int> controls, int target, qreal angle);
2238
2239
2240/// @notyettested
2241/// @notyetvalidated
2242/// @notyetdoced
2243/// @cppvectoroverload
2244/// @see applyMultiControlledRotateY()
2245void applyMultiControlledRotateY(Qureg qureg, std::vector<int> controls, int target, qreal angle);
2246
2247
2248/// @notyettested
2249/// @notyetvalidated
2250/// @notyetdoced
2251/// @cppvectoroverload
2252/// @see applyMultiControlledRotateZ()
2253void applyMultiControlledRotateZ(Qureg qureg, std::vector<int> controls, int target, qreal angle);
2254
2255
2256/// @notyettested
2257/// @notyetvalidated
2258/// @notyetdoced
2259/// @cppvectoroverload
2260/// @see applyMultiStateControlledRotateX()
2261void applyMultiStateControlledRotateX(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target, qreal angle);
2262
2263
2264/// @notyettested
2265/// @notyetvalidated
2266/// @notyetdoced
2267/// @cppvectoroverload
2268/// @see applyMultiStateControlledRotateY()
2269void applyMultiStateControlledRotateY(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target, qreal angle);
2270
2271
2272/// @notyettested
2273/// @notyetvalidated
2274/// @notyetdoced
2275/// @cppvectoroverload
2276/// @see applyMultiStateControlledRotateZ()
2277void applyMultiStateControlledRotateZ(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target, qreal angle);
2278
2279
2280/// @notyettested
2281/// @notyetvalidated
2282/// @notyetdoced
2283/// @cppvectoroverload
2284/// @see applyMultiControlledRotateAroundAxis()
2285void applyMultiControlledRotateAroundAxis(Qureg qureg, std::vector<int> controls, int target, qreal angle, qreal axisX, qreal axisY, qreal axisZ);
2286
2287
2288/// @notyettested
2289/// @notyetvalidated
2290/// @notyetdoced
2291/// @cppvectoroverload
2292/// @see applyMultiStateControlledRotateAroundAxis()
2293void applyMultiStateControlledRotateAroundAxis(Qureg qureg, std::vector<int> controls, std::vector<int> states, int target, qreal angle, qreal axisX, qreal axisY, qreal axisZ);
2294
2295
2296#endif // __cplusplus
2297
2298/** @} */
2299
2300
2301
2302/**
2303 * @defgroup op_pauligadget PauliStr gadgets
2304 * @brief Functions for applying many-qubit rotations around arbitrary PauliStr.
2305 * @{
2306 */
2307
2308
2309#ifdef __cplusplus
2310extern "C" {
2311#endif
2312
2313
2314/** @notyetdoced
2315 *
2316 * Applies a many-qubit rotation upon @p qureg, generated by tensor product of Pauli operators @p str.
2317 *
2318 * @formulae
2319 *
2320 * Let @f$ \hat{\sigma} = @f$ @p str and @f$ \theta = @f$ @p angle.
2321 *
2322 * This function effects unitary
2323 * @f[
2324 R_{\hat{\sigma}}(\theta) = \exp \left( - \iu \, \frac{\theta}{2} \, \hat{\sigma} \right),
2325 * @f]
2326 * which affects only the qubits for which @f$ \hat{\sigma} @f$ is not the identity
2327 * Pauli. As such, this effects a multi-qubit rotation around an arbitrary Pauli string.
2328 *
2329 * @equivalences
2330 *
2331 * - Because @f$ R_{\hat{\sigma}}(\theta) @f$ satisfies
2332 * @f[
2333 R_{\hat{\sigma}}(\theta) \equiv
2334 \cos\left( \frac{\theta}{2} \right) \, \id
2335 - \iu \sin\left( \frac{\theta}{2} \right) \, \hat{\sigma},
2336 * @f]
2337 * this function is equivalent to (but much faster than) effecting @f$ \hat{\sigma} @f$
2338 * upon a clone which is subsequently combined.
2339 * ```
2340 // prepare |temp> = str |qureg>
2341 Qureg temp = createCloneQureg(qureg);
2342 applyPauliStr(temp, str);
2343
2344 // set |qureg> = cos(theta/2) |qureg> - i sin(theta/2) str |qureg>
2345 qcomp coeffs[] = {cos(theta/2), -1i * sin(theta/2)};
2346 Qureg quregs[] = {qureg, temp};
2347 setQuregToWeightedSum(qureg, coeffs, quregs, 2);
2348 * ```
2349 * - When @p str contains only @f$ \hat{Z} @f$ or @f$ \id @f$ Paulis, this function will
2350 * automatically invoke applyPhaseGadget() which leverages an optimised implementation.
2351 * - When @p str contains only @f$ \id @f$ Paulis, this function merely effects a change
2352 * of global phase upon statevectors of @f$ -\theta/2 @f$, leaving density matrices
2353 * unchanged.
2354 * ```
2355 qcomp factor = cexp(- theta / 2 * 1.i);
2356 setQuregToWeightedSum(qureg, &factor, &qureg, 1);
2357 * ```
2358 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
2359 *
2360 * @myexample
2361 * ```
2362 Qureg qureg = createQureg(10);
2363 qreal theta = 3.14;
2364
2365 // verbosely
2366 int numPaulis = 4;
2367 char* paulis = "XYIZ";
2368 int targets[] = {0,1,5,7};
2369 PauliStr str = getPauliStr(paulis, targets, numPaulis);
2370 applyPauliGadget(qureg, str, angle);
2371
2372 // concisely
2373 applyPauliGadget(qureg, getInlinePauliStr("XYZ",{0,1,7}), theta);
2374 * ```
2375 *
2376 * @see
2377 * - applyNonUnitaryPauliGadget()
2378 */
2379void applyPauliGadget(Qureg qureg, PauliStr str, qreal angle);
2380
2381
2382/** @notyetdoced
2383 *
2384 * This function generalises applyPauliGadget() to accept a complex angle.
2385 */
2386void applyNonUnitaryPauliGadget(Qureg qureg, PauliStr str, qcomp angle);
2387
2388
2389/** @notyetdoced
2390 *
2391 * Applies a singly-controlled many-qubit rotation upon @p qureg,
2392 * generated by tensor product of Pauli operators @p str.
2393 *
2394 * > - See applyPauliGadget() for information about the base operation, @p angle, and @p str.
2395 * > - See applyControlledCompMatr1() for information about @p control.
2396 *
2397 * @author Tyson Jones
2398 */
2399void applyControlledPauliGadget(Qureg qureg, int control, PauliStr str, qreal angle);
2400
2401
2402/** @notyetdoced
2403 *
2404 * Applies a multiply-controlled many-qubit rotation upon @p qureg,
2405 * generated by tensor product of Pauli operators @p str.
2406 *
2407 * > - See applyPauliGadget() for information about the base operation, @p angle, and @p str.
2408 * > - See applyMultiControlledCompMatr1() for information about @p controls.
2409 *
2410 * @author Tyson Jones
2411 */
2412void applyMultiControlledPauliGadget(Qureg qureg, int* controls, int numControls, PauliStr str, qreal angle);
2413
2414
2415/** @notyetdoced
2416 *
2417 * Applies an arbitrarily-controlled many-qubit rotation upon @p qureg, generated by tensor product of Pauli operators @p str,
2418 * and conditioned upon @p controls being in the corresponding @p states.
2419 *
2420 * > - See applyPauliGadget() for information about the base operation, @p angle, and @p str.
2421 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
2422 *
2423 * @author Tyson Jones
2424 */
2425void applyMultiStateControlledPauliGadget(Qureg qureg, int* controls, int* states, int numControls, PauliStr str, qreal angle);
2426
2427
2428// end de-mangler
2429#ifdef __cplusplus
2430}
2431#endif
2432
2433#ifdef __cplusplus
2434
2435
2436/// @notyettested
2437/// @notyetvalidated
2438/// @notyetdoced
2439/// @cppvectoroverload
2440/// @see applyMultiControlledPauliGadget()
2441void applyMultiControlledPauliGadget(Qureg qureg, std::vector<int> controls, PauliStr str, qreal angle);
2442
2443
2444/// @notyettested
2445/// @notyetvalidated
2446/// @notyetdoced
2447/// @cppvectoroverload
2448/// @see applyMultiStateControlledPauliGadget()
2449void applyMultiStateControlledPauliGadget(Qureg qureg, std::vector<int> controls, std::vector<int> states, PauliStr str, qreal angle);
2450
2451
2452#endif // __cplusplus
2453
2454/** @} */
2455
2456
2457
2458/**
2459 * @defgroup op_phasegadget Phase gates
2460 * @brief Functions for applying many-qubit rotations around the Pauli @c Z axis, and phase flips and shifts.
2461 * @{
2462 */
2463
2464
2465#ifdef __cplusplus
2466extern "C" {
2467#endif
2468
2469
2470/** @notyetdoced
2471 *
2472 * Applies a many-qubit @c Z rotation upon @p qureg, generated by a tensor product of Pauli @c Z operators
2473 * upon @p targets.
2474 *
2475 * @formulae
2476 *
2477 * Let @f$ \vec{t} = @f$ @p targets and @f$ \theta = @f$ @p angle.
2478 *
2479 * This function effects diagonal unitary
2480 * @f[
2481 R_{\hat{Z}}(\theta) = \exp \left( - \iu \, \frac{\theta}{2} \, \bigotimes_{t \,\in\, \vec{t}} \hat{Z}_t \right).
2482 * @f]
2483 *
2484 * > [!TIP]
2485 * > This function is sometimes more efficient when @p targets are specified in increasing order,
2486 * > though the effect of this function is incidentally unaffected by the ordering of @p targets.
2487 *
2488 * @equivalences
2489 *
2490 * - This function is equivalent to calling applyPauliGadget() with a PauliStr containing only @f$ \hat{Z} @f$ and @f$ \id @f$.
2491 * This latter function will actually automatically invoke applyPhaseGadget() which has an optimised implementation.
2492 * - This function is equivalent to, albeit much faster than, preparing a DiagMatr with @f$ \pm 1 @f$ elements (depending upon
2493 * the parity of the targeted set bits) and effecting it with applyDiagMatr().
2494 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
2495 */
2496void applyPhaseGadget(Qureg qureg, int* targets, int numTargets, qreal angle);
2497
2498
2499/** @notyetdoced
2500 *
2501 * Applies a singly-controlled many-qubit @c Z rotation upon @p qureg,
2502 * generated by a tensor product of Pauli @c Z operators upon @p targets.
2503 *
2504 * > - See applyPhaseGadget() for information about the base operation, @p angle, and @p targets.
2505 * > - See applyControlledCompMatr1() for information about @p control.
2506 *
2507 * @author Tyson Jones
2508 */
2509void applyControlledPhaseGadget(Qureg qureg, int control, int* targets, int numTargets, qreal angle);
2510
2511
2512/** @notyetdoced
2513 *
2514 * Applies a multiply-controlled many-qubit @c Z rotation upon @p qureg,
2515 * generated by a tensor product of Pauli @c Z operators upon @p targets.
2516 *
2517 * > - See applyPhaseGadget() for information about the base operation, @p angle, and @p targets.
2518 * > - See applyMultiControlledCompMatr1() for information about @p controls.
2519 *
2520 * @author Tyson Jones
2521 */
2522void applyMultiControlledPhaseGadget(Qureg qureg, int* controls, int numControls, int* targets, int numTargets, qreal angle);
2523
2524
2525/** @notyetdoced
2526 *
2527 * Applies an arbitrarily-controlled many-qubit @c Z rotation upon @p qureg, generated by a tensor product of Pauli @c Z operators
2528 * upon @p targets, and conditioned upon @p controls being in the corresponding @p states.
2529 *
2530 * > - See applyPhaseGadget() for information about the base operation, @p angle, and @p targets.
2531 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
2532 *
2533 * @author Tyson Jones
2534 */
2535void applyMultiStateControlledPhaseGadget(Qureg qureg, int* controls, int* states, int numControls, int* targets, int numTargets, qreal angle);
2536
2537
2538/** @notyetdoced
2539 *
2540 * This function is a mere alias of applyPauliZ(), meaningfully differing only for many targets.
2541 */
2542void applyPhaseFlip(Qureg qureg, int target);
2543
2544
2545/** @notyetdoced
2546 *
2547 * @formulae
2548 *
2549 * Let @f$ \theta = @f$ @p angle. This function effects diagonal unitary
2550 *
2551 * @f[
2552 \hat{U}(\theta) = \begin{pmatrix} 1 & 0 \\ 0 & e^{\iu \theta} \end{pmatrix}
2553 * @f]
2554 * upon the @p target qubit.
2555 *
2556 * @equivalences
2557 *
2558 * - This function is equivalent to, albeit much faster than, a Z-axis rotation with
2559 * an adjustment to the global phase (which is redundant upon density matrices).
2560 * @f[
2561 * \hat{U}(\theta) \equiv \hat{R}_z(\theta) \cdot e^{\iu \frac{\theta}{2}} \hat{\id}
2562 * @f]
2563 * ```
2564 applyRotateZ(qureg, target, angle);
2565 applyPauliGadget(qureg, getPauliStr("I"), angle); // global phase
2566 * ```
2567 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
2568 */
2569void applyPhaseShift(Qureg qureg, int target, qreal angle);
2570
2571
2572/** @notyetdoced
2573 *
2574 * Applies a two-qubit phase flip upon qubits @p target1 and @p target2 of @p qureg.
2575 *
2576 * @formulae
2577 *
2578 * This function flips the sign of all computational basis states for which
2579 * the targeted qubits are in state @f$ \ket{1}\ket{1} @f$. This is equivalent
2580 * to the diagonal unitary
2581 *
2582 * @f[
2583 \hat{U}(\theta) = \begin{pmatrix} 1 \\ & 1 \\ & & 1 \\ & & & -1 \end{pmatrix},
2584 * @f]
2585 * effected upon the target qubits.
2586 *
2587 * @diagram
2588 * @dot
2589digraph {
2590 rankdir=LR;
2591 layout=neato;
2592 node [fontsize=10, fontname="Menlo"];
2593 edge [dir=none];
2594
2595 topWireL [shape=plaintext, label="target1", pos="0,.5!"];
2596 topWireM [shape=point, label="", width=.1, pos=".75,.5!"]
2597 topWireR [shape=plaintext, label="", pos="1.5,.5!"];
2598
2599 botWireL [shape=plaintext, label="target2", pos="0,0!"];
2600 botWireM [shape=point, label="", width=.1, pos=".75,0!"];
2601 botWireR [shape=plaintext, label="", pos="1.5,0!"];
2602
2603 topWireL -> topWireR;
2604 botWireL -> botWireR;
2605 botWireM -> topWireM;
2606}
2607 * @enddot
2608 *
2609 * @equivalences
2610 *
2611 * - The target qubits are interchangeable, ergo
2612 * ```
2613 applyTwoQubitPhaseFlip(qureg, target1, target2);
2614 applyTwoQubitPhaseFlip(qureg, target2, target1); // equivalent
2615 * ```
2616 * - This function is entirely equivalent to a controlled Pauli-Z unitary (or a hypothetical
2617 * controlled variant of applyPhaseFlip()) with either target qubit substituted for the control qubit.
2618 * ```
2619 applyControlledPauliZ(qureg, target1, target2);
2620 * ```
2621 * - This function is faster and more accurate than, but otherwise equivalent to, a two-qubit phase shift
2622 * with angle @f$ = \pi @f$.
2623 * ```
2624 applyTwoQubitPhaseShift(qureg, target1, target2, 3.141592653); // approx equiv
2625 * ```
2626 */
2627void applyTwoQubitPhaseFlip(Qureg qureg, int target1, int target2);
2628
2629
2630/** @notyetdoced
2631 *
2632 * Applies a two-qubit phase shift upon qubits @p target1 and @p target2 of @p qureg.
2633 *
2634 * @formulae
2635 *
2636 * Let @f$ \theta = @f$ @p angle.
2637 * This function multiplies factor @f$ e^{\iu \theta} @f$ upon all computational basis states
2638 * for which the targeted qubits are in state @f$ \ket{1}\ket{1} @f$. This is equivalent
2639 * to the diagonal unitary
2640 *
2641 * @f[
2642 \hat{U}(\theta) = \begin{pmatrix} 1 \\ & 1 \\ & & 1 \\ & & & e^{\iu \theta} \end{pmatrix},
2643 * @f]
2644 * effected upon the target qubits.
2645 *
2646 * @diagram
2647 * @dot
2648digraph {
2649 rankdir=LR;
2650 layout=neato;
2651 node [fontsize=10, fontname="Menlo"];
2652 edge [dir=none];
2653
2654 topWireL [shape=plaintext, label="target1", pos="0,.5!"];
2655 topWireM [shape=point, label="", width=.1, pos=".75,.5!"]
2656 topWireR [shape=plaintext, label="", pos="1.5,.5!"];
2657
2658 botWireL [shape=plaintext, label="target2", pos="0,0!"];
2659 botWireM [shape=point, label="", width=.1, pos=".75,0!"];
2660 botWireR [shape=plaintext, label="", pos="1.5,0!"];
2661
2662 topWireL -> topWireR;
2663 botWireL -> botWireR;
2664 botWireM -> topWireM;
2665
2666 angle [shape=plaintext, label="θ", pos=".85,-.2!"];
2667}
2668 * @enddot
2669 *
2670 * @equivalences
2671 *
2672 * - The target qubits are interchangeable, ergo
2673 * ```
2674 applyTwoQubitPhaseShift(qureg, target1, target2, angle);
2675 applyTwoQubitPhaseShift(qureg, target2, target1, angle); // equivalent
2676 * ```
2677 * - This function is equivalent to a controlled variant of applyPhaseShift(), treating
2678 * either target qubit as the control qubit.
2679 * - This function generalises applyTwoQubitPhaseFlip() to arbitrary changes in phase.
2680 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
2681 */
2682void applyTwoQubitPhaseShift(Qureg qureg, int target1, int target2, qreal angle);
2683
2684
2685/** @notyetdoced
2686 *
2687 * @formulae
2688 *
2689 * This function flips the sign of all computational basis states for which
2690 * the targeted qubits are all in state @f$ \ket{1} @f$. This is equivalent
2691 * to the diagonal unitary
2692 * @f[
2693 \hat{U}(\theta) = \begin{pmatrix} 1 \\ & \ddots \\ & & 1 \\ & & & -1 \end{pmatrix},
2694 * @f]
2695 * effected upon the target qubits.
2696 *
2697 * > [!TIP]
2698 * > This function is sometimes more efficient when @p targets are specified in increasing order,
2699 * > though the effect of this function is incidentally unaffected by the ordering of @p targets.
2700 *
2701 * @equivalences
2702 *
2703 * - The ordering of @p targets has no affect on the effected operation.
2704 * - This function is entirely equivalent to a multi-controlled Pauli-Z unitary (or a hypothetical
2705 * many-controlled variant of applyPhaseFlip()) with all but one arbitrary target qubit becoming
2706 * control qubits.
2707 * ```
2708 applyMultiControlledPauliZ(qureg, targets, numTargets-1, targets[0]);
2709 * ```
2710 * - This function is faster and more accurate than, but otherwise equivalent to, a multi-qubit phase shift
2711 * with angle @f$ = \pi @f$.
2712 * ```
2713 applyMultiQubitPhaseShift(qureg, targets, numTargets, 3.141592653); // approx equiv
2714 * ```
2715 */
2716void applyMultiQubitPhaseFlip(Qureg qureg, int* targets, int numTargets);
2717
2718
2719/** @notyetdoced
2720 *
2721 * @formulae
2722 *
2723 * Let @f$ \theta = @f$ @p angle.
2724 * This function multiplies factor @f$ e^{\iu \theta} @f$ upon all computational basis states
2725 * for which all targeted qubits are in state @f$ \ket{1} @f$. This is equivalent
2726 * to the diagonal unitary
2727 * @f[
2728 \hat{U}(\theta) = \begin{pmatrix} 1 \\ & \ddots \\ & & 1 \\ & & & e^{\iu \theta} \end{pmatrix},
2729 * @f]
2730 * effected upon the target qubits.
2731 *
2732 * > [!TIP]
2733 * > This function is sometimes more efficient when @p targets are specified in increasing order,
2734 * > though the effect of this function is incidentally unaffected by the ordering of @p targets.
2735 *
2736 * @diagram
2737 * @dot
2738digraph {
2739 rankdir=LR;
2740 layout=neato;
2741 node [fontsize=10, fontname="Menlo"];
2742 edge [dir=none];
2743
2744 topWireL [shape=plaintext, label="target1", pos="0,.5!"];
2745 topWireM [shape=point, label="", width=.1, pos=".75,.5!"]
2746 topWireR [shape=plaintext, label="", pos="1.5,.5!"];
2747
2748 botWireL [shape=plaintext, label="target2", pos="0,0!"];
2749 botWireM [shape=point, label="", width=.1, pos=".75,0!"];
2750 botWireR [shape=plaintext, label="", pos="1.5,0!"];
2751
2752 topWireL -> topWireR;
2753 botWireL -> botWireR;
2754 botWireM -> topWireM;
2755
2756 angle [shape=plaintext, label="θ", pos=".85,-.2!"];
2757}
2758 * @enddot
2759 *
2760 * @equivalences
2761 *
2762 * - The ordering of @p targets has no affect on the effected operation.
2763 * - This function is equivalent to a multi-controlled variant of applyPhaseShift(), treating all
2764 * but one arbitrary target qubit as control qubits.
2765 * - This function generalises applyMultiQubitPhaseFlip() to arbitrary changes in phase.
2766 * - Passing @p angle=0 is equivalent to effecting the identity, leaving the state unchanged.
2767 */
2768void applyMultiQubitPhaseShift(Qureg qureg, int* targets, int numTargets, qreal angle);
2769
2770
2771// end de-mangler
2772#ifdef __cplusplus
2773}
2774#endif
2775
2776#ifdef __cplusplus
2777
2778
2779/// @notyettested
2780/// @notyetvalidated
2781/// @notyetdoced
2782/// @cppvectoroverload
2783/// @see applyPhaseGadget()
2784void applyPhaseGadget(Qureg qureg, std::vector<int> targets, qreal angle);
2785
2786
2787/// @notyettested
2788/// @notyetvalidated
2789/// @notyetdoced
2790/// @cppvectoroverload
2791/// @see applyControlledPhaseGadget()
2792void applyControlledPhaseGadget(Qureg qureg, int control, std::vector<int> targets, qreal angle);
2793
2794
2795/// @notyettested
2796/// @notyetvalidated
2797/// @notyetdoced
2798/// @cppvectoroverload
2799/// @see applyMultiControlledPhaseGadget()
2800void applyMultiControlledPhaseGadget(Qureg qureg, std::vector<int> controls, std::vector<int> targets, qreal angle);
2801
2802
2803/// @notyettested
2804/// @notyetvalidated
2805/// @notyetdoced
2806/// @cppvectoroverload
2807/// @see applyMultiStateControlledPhaseGadget()
2808void applyMultiStateControlledPhaseGadget(Qureg qureg, std::vector<int> controls, std::vector<int> states, std::vector<int> targets, qreal angle);
2809
2810
2811/// @notyettested
2812/// @notyetvalidated
2813/// @notyetdoced
2814/// @cppvectoroverload
2815/// @see applyMultiQubitPhaseFlip()
2816void applyMultiQubitPhaseFlip(Qureg qureg, std::vector<int> targets);
2817
2818
2819/// @notyettested
2820/// @notyetvalidated
2821/// @notyetdoced
2822/// @cppvectoroverload
2823/// @see applyMultiQubitPhaseShift()
2824void applyMultiQubitPhaseShift(Qureg qureg, std::vector<int> targets, qreal angle);
2825
2826
2827#endif // __cplusplus
2828
2829/** @} */
2830
2831
2832
2833/**
2834 * @defgroup op_nots Many-not gates
2835 * @brief Functions for effecting many-qubit NOT gates
2836 * @{
2837 */
2838
2839
2840#ifdef __cplusplus
2841extern "C" {
2842#endif
2843
2844
2845/** @notyetdoced
2846 *
2847 * Applies a many-qubit NOT gate (or tensor product of Pauli @c X operators) upon the @p targets of @p qureg.
2848 *
2849 * > [!TIP]
2850 * > This function is sometimes more efficient when @p targets are specified in increasing order,
2851 * > though the effect of this function is incidentally unaffected by the ordering of @p targets.
2852 *
2853 * @author Tyson Jones
2854 */
2855void applyMultiQubitNot(Qureg qureg, int* targets, int numTargets);
2856
2857
2858/** @notyetdoced
2859 *
2860 * Applies a singly-controlled many-qubit NOT gate (or tensor product of Pauli @c X operators)
2861 * upon the @p targets of @p qureg.
2862 *
2863 * > - See applyMultiQubitNot() for information about the base operation.
2864 * > - See applyControlledCompMatr1() for information about @p control.
2865 *
2866 * @author Tyson Jones
2867 */
2868void applyControlledMultiQubitNot(Qureg qureg, int control, int* targets, int numTargets);
2869
2870
2871/** @notyetdoced
2872 *
2873 * Applies a multiply-controlled many-qubit NOT gate (or tensor product of Pauli @c X operators)
2874 * upon the @p targets of @p qureg.
2875 *
2876 * > - See applyMultiQubitNot() for information about the base operation.
2877 * > - See applyMultiControlledCompMatr1() for information about @p controls.
2878 *
2879 * @author Tyson Jones
2880 */
2881void applyMultiControlledMultiQubitNot(Qureg qureg, int* controls, int numControls, int* targets, int numTargets);
2882
2883
2884/** @notyetdoced
2885 *
2886 * Applies an arbitrarily-controlled many-qubit NOT gate (or tensor product of Pauli @c X operators) upon the @p targets of @p qureg,
2887 * conditioned upon @p controls being in the corresponding @p states.
2888 *
2889 * > - See applyMultiQubitNot() for information about the base operation.
2890 * > - See applyMultiStateControlledCompMatr1() for information about @p controls and @p states.
2891 *
2892 * @author Tyson Jones
2893 */
2894void applyMultiStateControlledMultiQubitNot(Qureg qureg, int* controls, int* states, int numControls, int* targets, int numTargets);
2895
2896
2897// end de-mangler
2898#ifdef __cplusplus
2899}
2900#endif
2901
2902#ifdef __cplusplus
2903
2904
2905/// @notyettested
2906/// @notyetvalidated
2907/// @notyetdoced
2908/// @cppvectoroverload
2909/// @see applyMultiQubitNot()
2910void applyMultiQubitNot(Qureg qureg, std::vector<int> targets);
2911
2912
2913/// @notyettested
2914/// @notyetvalidated
2915/// @notyetdoced
2916/// @cppvectoroverload
2917/// @see applyControlledMultiQubitNot()
2918void applyControlledMultiQubitNot(Qureg qureg, int control, std::vector<int> targets);
2919
2920
2921/// @notyettested
2922/// @notyetvalidated
2923/// @notyetdoced
2924/// @cppvectoroverload
2925/// @see applyMultiControlledMultiQubitNot()
2926void applyMultiControlledMultiQubitNot(Qureg qureg, std::vector<int> controls, std::vector<int> targets);
2927
2928
2929/// @notyettested
2930/// @notyetvalidated
2931/// @notyetdoced
2932/// @cppvectoroverload
2933/// @see applyMultiStateControlledMultiQubitNot()
2934void applyMultiStateControlledMultiQubitNot(Qureg qureg, std::vector<int> controls, std::vector<int> states, std::vector<int> targets);
2935
2936
2937#endif // __cplusplus
2938
2939/** @} */
2940
2941
2942
2943/**
2944 * @defgroup op_measurement Measurements
2945 * @brief Functions for effecting destructive measurements.
2946 * @{
2947 */
2948
2949
2950#ifdef __cplusplus
2951extern "C" {
2952#endif
2953
2954
2955/// @notyetdoced
2956int applyQubitMeasurement(Qureg qureg, int target);
2957
2958
2959/// @notyetdoced
2960int applyQubitMeasurementAndGetProb(Qureg qureg, int target, qreal* probability);
2961
2962
2963/// @notyetdoced
2964qreal applyForcedQubitMeasurement(Qureg qureg, int target, int outcome);
2965
2966
2967/// @notyetdoced
2968qindex applyMultiQubitMeasurement(Qureg qureg, int* qubits, int numQubits);
2969
2970
2971/// @notyetdoced
2972qindex applyMultiQubitMeasurementAndGetProb(Qureg qureg, int* qubits, int numQubits, qreal* probability);
2973
2974
2975/// @notyetdoced
2976qreal applyForcedMultiQubitMeasurement(Qureg qureg, int* qubits, int* outcomes, int numQubits);
2977
2978
2979// end de-mangler
2980#ifdef __cplusplus
2981}
2982#endif
2983
2984#ifdef __cplusplus
2985
2986
2987/// @notyetdoced
2988/// @cppvectoroverload
2989/// @see applyMultiQubitMeasurement()
2990qindex applyMultiQubitMeasurement(Qureg qureg, std::vector<int> qubits);
2991
2992
2993/// @notyetdoced
2994/// @cppvectoroverload
2995/// @see applyMultiQubitMeasurementAndGetProb()
2996qindex applyMultiQubitMeasurementAndGetProb(Qureg qureg, std::vector<int> qubits, qreal* probability);
2997
2998
2999/// @notyetdoced
3000/// @cppvectoroverload
3001/// @see applyForcedMultiQubitMeasurement()
3002qreal applyForcedMultiQubitMeasurement(Qureg qureg, std::vector<int> qubits, std::vector<int> outcomes);
3003
3004
3005#endif // __cplusplus
3006
3007/** @} */
3008
3009
3010
3011/**
3012 * @defgroup op_projectors Projectors
3013 * @brief Functions for effecting projectors which break the state normalisation.
3014 * @{
3015 */
3016
3017
3018#ifdef __cplusplus
3019extern "C" {
3020#endif
3021
3022
3023/// @notyetdoced
3024void applyQubitProjector(Qureg qureg, int target, int outcome);
3025
3026
3027/// @notyetdoced
3028void applyMultiQubitProjector(Qureg qureg, int* qubits, int* outcomes, int numQubits);
3029
3030
3031// end de-mangler
3032#ifdef __cplusplus
3033}
3034#endif
3035
3036#ifdef __cplusplus
3037
3038
3039/// @notyetdoced
3040/// @cppvectoroverload
3041/// @see applyMultiQubitProjector()
3042void applyMultiQubitProjector(Qureg qureg, std::vector<int> qubits, std::vector<int> outcomes);
3043
3044
3045#endif // __cplusplus
3046
3047/** @} */
3048
3049
3050
3051/**
3052 * @defgroup op_qft QFT
3053 * @brief Functions for applying the Quantum Fourier Transform.
3054 * @{
3055 */
3056
3057
3058#ifdef __cplusplus
3059extern "C" {
3060#endif
3061
3062
3063/**
3064 * Applies the Quantum Fourier Transform upon the specified @p targets of @p qureg.
3065 * Alternatively, applies the Inverse Quantum Fourier Transform according to @p inverse.
3066 *
3067 * @formulae
3068 *
3069 * Letting @f$ N @f$ = @p numTargets, the @f$ N @f$ qubit Quantum Fourier Transform maps each
3070 * computational basis state of the targeted qubits, @f$ \ket{j} @f$, according to
3071 * @f[
3072 \ket{j} \rightarrow \frac{1}{\sqrt{2^N}} \sum_{k=0}^{2^N-1} e^{2 \pi i j k / 2^N} \ket{k}.
3073 * @f]
3074 * Similarly the Inverse Quantum Fourier Transform maps each basis state like
3075 * @f[
3076 \ket{j} \rightarrow \frac{1}{\sqrt{2^N}} \sum_{k=0}^{2^N-1} e^{-2 \pi i j k / 2^N} \ket{k}.
3077 * @f]
3078 *
3079 * @param[in,out] qureg the state to modify.
3080 * @param[in] targets the indices of the target qubits.
3081 * @param[in] numTargets the length of list @p targets
3082 * @param[in] inverse whether to apply the inverse QFT or forward QFT
3083 * @throws @validationerror
3084 * - if @p qureg is uninitialised.
3085* - if @p targets are invalid qubit indices.
3086* - if @p targets are not unique.
3087 * - if @p numTargets < 1.
3088 * @see
3089 * - applyFullQuantumFourierTransform()
3090 * @author Vasco Ferreira
3091 */
3092void applyQuantumFourierTransform(Qureg qureg, int* targets, int numTargets, bool inverse);
3093
3094
3095/**
3096 * Applies the Quantum Fourier Transform upon all qubits in @p qureg. Alternatively,
3097 * applies the Inverse Quantum Fourier Transform according to @p inverse.
3098 *
3099 * @formulae
3100 *
3101 * The Quantum Fourier Transform maps each computational basis state @f$ \ket{j} @f$
3102 * in an @f$ N @f$ qubit @p qureg according to
3103 * @f[
3104 \ket{j} \rightarrow \frac{1}{\sqrt{2^N}} \sum_{k=0}^{2^N-1} e^{2 \pi i j k / 2^N} \ket{k}.
3105 * @f]
3106 * Similarly the Inverse Quantum Fourier Transform maps each basis state like
3107 * @f[
3108 \ket{j} \rightarrow \frac{1}{\sqrt{2^N}} \sum_{k=0}^{2^N-1} e^{-2 \pi i j k / 2^N} \ket{k}.
3109 * @f]
3110 *
3111 * @equivalences
3112 *
3113 * - This function wraps applyQuantumFourierTransform(), passing all qubits in the @p qureg as targets.
3114 *
3115 * @param[in,out] qureg the state to modify.
3116 * @param[in] inverse whether to apply the inverse QFT or forward QFT
3117 * @throws @validationerror
3118 * - if @p qureg is uninitialised.
3119 * @see
3120 * - applyQuantumFourierTransform()
3121 * @author Vasco Ferreira
3122 */
3123void applyFullQuantumFourierTransform(Qureg qureg, bool inverse);
3124
3125
3126// end de-mangler
3127#ifdef __cplusplus
3128}
3129#endif
3130
3131#ifdef __cplusplus
3132
3133
3134/// @notyetdoced
3135/// @cppvectoroverload
3136/// @see applyQuantumFourierTransform()
3137void applyQuantumFourierTransform(Qureg qureg, std::vector<int> targets, bool inverse);
3138
3139
3140#endif // __cplusplus
3141
3142/** @} */
3143
3144
3145
3146#endif // OPERATIONS_H
3147
3148/** @} */ // (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 matrix)
void applyMultiControlledCompMatr2(Qureg qureg, int *controls, int numControls, int target1, int target2, CompMatr2 matrix)
void applyControlledCompMatr2(Qureg qureg, int control, int target1, int target2, CompMatr2 matrix)
void applyCompMatr2(Qureg qureg, int target1, int target2, CompMatr2 matrix)
void applyMultiStateControlledCompMatr(Qureg qureg, int *controls, int *states, int numControls, int *targets, int numTargets, CompMatr matrix)
void applyControlledCompMatr(Qureg qureg, int control, int *targets, int numTargets, CompMatr matrix)
void applyCompMatr(Qureg qureg, int *targets, int numTargets, CompMatr matrix)
void applyMultiControlledCompMatr(Qureg qureg, int *controls, int numControls, int *targets, int numTargets, CompMatr matrix)
void applyDiagMatr1(Qureg qureg, int target, DiagMatr1 matrix)
void applyMultiControlledDiagMatr1(Qureg qureg, int *controls, int numControls, int target, DiagMatr1 matrix)
void applyControlledDiagMatr1(Qureg qureg, int control, int target, DiagMatr1 matrix)
void applyMultiStateControlledDiagMatr1(Qureg qureg, int *controls, int *states, int numControls, int target, DiagMatr1 matrix)
void applyDiagMatr2(Qureg qureg, int target1, int target2, DiagMatr2 matrix)
void applyMultiControlledDiagMatr2(Qureg qureg, int *controls, int numControls, int target1, int target2, DiagMatr2 matrix)
void applyControlledDiagMatr2(Qureg qureg, int control, int target1, int target2, DiagMatr2 matrix)
void applyMultiStateControlledDiagMatr2(Qureg qureg, int *controls, int *states, int numControls, int target1, int target2, DiagMatr2 matrix)
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 applyQuantumFourierTransform(Qureg qureg, int *targets, int numTargets, bool inverse)
void applyFullQuantumFourierTransform(Qureg qureg, bool inverse)
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 applyControlledRotateAroundAxis(Qureg qureg, int control, int target, qreal angle, qreal axisX, qreal axisY, qreal axisZ)
void applyRotateZ(Qureg qureg, int target, qreal angle)
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 *controls, int numControls, int target, qreal angle, qreal axisX, qreal axisY, qreal axisZ)
void applyMultiStateControlledRotateAroundAxis(Qureg qureg, int *controls, int *states, int numControls, int target, qreal angle, qreal axisX, qreal axisY, qreal axisZ)
void applyMultiControlledRotateY(Qureg qureg, int *controls, int numControls, int target, qreal angle)
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