QuEST.c
Go to the documentation of this file.
1 // Distributed under MIT licence. See https://github.com/QuEST-Kit/QuEST/blob/master/LICENCE.txt for details
2 
18 # include "QuEST.h"
19 # include "QuEST_precision.h"
20 # include "QuEST_internal.h"
21 # include "QuEST_validation.h"
22 # include "QuEST_qasm.h"
23 
24 # include <stdlib.h>
25 # include <string.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 
32 /*
33  * state-vector management
34  */
35 
36 Qureg createQureg(int numQubits, QuESTEnv env) {
37  validateNumQubitsInQureg(numQubits, env.numRanks, __func__);
38 
39  Qureg qureg;
40  statevec_createQureg(&qureg, numQubits, env);
41  qureg.isDensityMatrix = 0;
42  qureg.numQubitsRepresented = numQubits;
43  qureg.numQubitsInStateVec = numQubits;
44 
45  qasm_setup(&qureg);
46  initZeroState(qureg); // safe call to public function
47  return qureg;
48 }
49 
50 Qureg createDensityQureg(int numQubits, QuESTEnv env) {
51  validateNumQubitsInQureg(2*numQubits, env.numRanks, __func__);
52 
53  Qureg qureg;
54  statevec_createQureg(&qureg, 2*numQubits, env);
55  qureg.isDensityMatrix = 1;
56  qureg.numQubitsRepresented = numQubits;
57  qureg.numQubitsInStateVec = 2*numQubits;
58 
59  qasm_setup(&qureg);
60  initZeroState(qureg); // safe call to public function
61  return qureg;
62 }
63 
65 
66  Qureg newQureg;
67  statevec_createQureg(&newQureg, qureg.numQubitsInStateVec, env);
68  newQureg.isDensityMatrix = qureg.isDensityMatrix;
71 
72  qasm_setup(&newQureg);
73  statevec_cloneQureg(newQureg, qureg);
74  return newQureg;
75 }
76 
77 void destroyQureg(Qureg qureg, QuESTEnv env) {
78  statevec_destroyQureg(qureg, env);
79  qasm_free(qureg);
80 }
81 
82 
83 /*
84  * QASM
85  */
86 
88  qasm_startRecording(qureg);
89 }
90 
91 void stopRecordingQASM(Qureg qureg) {
92  qasm_stopRecording(qureg);
93 }
94 
95 void clearRecordedQASM(Qureg qureg) {
96  qasm_clearRecorded(qureg);
97 }
98 
99 void printRecordedQASM(Qureg qureg) {
100  qasm_printRecorded(qureg);
101 }
102 
103 void writeRecordedQASMToFile(Qureg qureg, char* filename) {
104  int success = qasm_writeRecordedToFile(qureg, filename);
105  validateFileOpened(success, filename, __func__);
106 }
107 
108 
109 /*
110  * state initialisation
111  */
112 
113 void initZeroState(Qureg qureg) {
114  statevec_initZeroState(qureg); // valid for both statevec and density matrices
115 
116  qasm_recordInitZero(qureg);
117 }
118 
119 void initBlankState(Qureg qureg) {
121 
122  qasm_recordComment(qureg, "Here, the register was initialised to an unphysical all-zero-amplitudes 'state'.");
123 }
124 
125 void initPlusState(Qureg qureg) {
126  if (qureg.isDensityMatrix)
127  densmatr_initPlusState(qureg);
128  else
129  statevec_initPlusState(qureg);
130 
131  qasm_recordInitPlus(qureg);
132 }
133 
134 void initClassicalState(Qureg qureg, long long int stateInd) {
135  validateStateIndex(qureg, stateInd, __func__);
136 
137  if (qureg.isDensityMatrix)
138  densmatr_initClassicalState(qureg, stateInd);
139  else
140  statevec_initClassicalState(qureg, stateInd);
141 
142  qasm_recordInitClassical(qureg, stateInd);
143 }
144 
145 void initPureState(Qureg qureg, Qureg pure) {
146  validateSecondQuregStateVec(pure, __func__);
147  validateMatchingQuregDims(qureg, pure, __func__);
148 
149  if (qureg.isDensityMatrix)
150  densmatr_initPureState(qureg, pure);
151  else
152  statevec_cloneQureg(qureg, pure);
153 
154  qasm_recordComment(qureg, "Here, the register was initialised to an undisclosed given pure state.");
155 }
156 
157 void initStateFromAmps(Qureg qureg, qreal* reals, qreal* imags) {
158 
159  statevec_setAmps(qureg, 0, reals, imags, qureg.numAmpsTotal);
160 
161  qasm_recordComment(qureg, "Here, the register was initialised to an undisclosed given pure state.");
162 }
163 
164 void cloneQureg(Qureg targetQureg, Qureg copyQureg) {
165  validateMatchingQuregTypes(targetQureg, copyQureg, __func__);
166  validateMatchingQuregDims(targetQureg, copyQureg, __func__);
167 
168  statevec_cloneQureg(targetQureg, copyQureg);
169 }
170 
171 
172 /*
173  * unitary gates
174  */
175 
176 void hadamard(Qureg qureg, int targetQubit) {
177  validateTarget(qureg, targetQubit, __func__);
178 
179  statevec_hadamard(qureg, targetQubit);
180  if (qureg.isDensityMatrix) {
181  statevec_hadamard(qureg, targetQubit+qureg.numQubitsRepresented);
182  }
183 
184  qasm_recordGate(qureg, GATE_HADAMARD, targetQubit);
185 }
186 
187 void rotateX(Qureg qureg, int targetQubit, qreal angle) {
188  validateTarget(qureg, targetQubit, __func__);
189 
190  statevec_rotateX(qureg, targetQubit, angle);
191  if (qureg.isDensityMatrix) {
192  statevec_rotateX(qureg, targetQubit+qureg.numQubitsRepresented, -angle);
193  }
194 
195  qasm_recordParamGate(qureg, GATE_ROTATE_X, targetQubit, angle);
196 }
197 
198 void rotateY(Qureg qureg, int targetQubit, qreal angle) {
199  validateTarget(qureg, targetQubit, __func__);
200 
201  statevec_rotateY(qureg, targetQubit, angle);
202  if (qureg.isDensityMatrix) {
203  statevec_rotateY(qureg, targetQubit+qureg.numQubitsRepresented, angle);
204  }
205 
206  qasm_recordParamGate(qureg, GATE_ROTATE_Y, targetQubit, angle);
207 }
208 
209 void rotateZ(Qureg qureg, int targetQubit, qreal angle) {
210  validateTarget(qureg, targetQubit, __func__);
211 
212  statevec_rotateZ(qureg, targetQubit, angle);
213  if (qureg.isDensityMatrix) {
214  statevec_rotateZ(qureg, targetQubit+qureg.numQubitsRepresented, -angle);
215  }
216 
217  qasm_recordParamGate(qureg, GATE_ROTATE_Z, targetQubit, angle);
218 }
219 
220 void controlledRotateX(Qureg qureg, int controlQubit, int targetQubit, qreal angle) {
221  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
222 
223  statevec_controlledRotateX(qureg, controlQubit, targetQubit, angle);
224  if (qureg.isDensityMatrix) {
225  int shift = qureg.numQubitsRepresented;
226  statevec_controlledRotateX(qureg, controlQubit+shift, targetQubit+shift, -angle);
227  }
228 
229  qasm_recordControlledParamGate(qureg, GATE_ROTATE_X, controlQubit, targetQubit, angle);
230 }
231 
232 void controlledRotateY(Qureg qureg, int controlQubit, int targetQubit, qreal angle) {
233  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
234 
235  statevec_controlledRotateY(qureg, controlQubit, targetQubit, angle);
236  if (qureg.isDensityMatrix) {
237  int shift = qureg.numQubitsRepresented;
238  statevec_controlledRotateY(qureg, controlQubit+shift, targetQubit+shift, angle); // rotateY is real
239  }
240 
241  qasm_recordControlledParamGate(qureg, GATE_ROTATE_Y, controlQubit, targetQubit, angle);
242 }
243 
244 void controlledRotateZ(Qureg qureg, int controlQubit, int targetQubit, qreal angle) {
245  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
246 
247  statevec_controlledRotateZ(qureg, controlQubit, targetQubit, angle);
248  if (qureg.isDensityMatrix) {
249  int shift = qureg.numQubitsRepresented;
250  statevec_controlledRotateZ(qureg, controlQubit+shift, targetQubit+shift, -angle);
251  }
252 
253  qasm_recordControlledParamGate(qureg, GATE_ROTATE_Z, controlQubit, targetQubit, angle);
254 }
255 
256 void twoQubitUnitary(Qureg qureg, int targetQubit1, int targetQubit2, ComplexMatrix4 u) {
257  validateMultiTargets(qureg, (int []) {targetQubit1, targetQubit2}, 2, __func__);
258  validateTwoQubitUnitaryMatrix(qureg, u, __func__);
259 
260  statevec_twoQubitUnitary(qureg, targetQubit1, targetQubit2, u);
261  if (qureg.isDensityMatrix) {
262  int shift = qureg.numQubitsRepresented;
263  statevec_twoQubitUnitary(qureg, targetQubit1+shift, targetQubit2+shift, getConjugateMatrix4(u));
264  }
265 
266  qasm_recordComment(qureg, "Here, an undisclosed 2-qubit unitary was applied.");
267 }
268 
269 void controlledTwoQubitUnitary(Qureg qureg, int controlQubit, int targetQubit1, int targetQubit2, ComplexMatrix4 u) {
270  validateMultiControlsMultiTargets(qureg, (int[]) {controlQubit}, 1, (int[]) {targetQubit1, targetQubit2}, 2, __func__);
271  validateTwoQubitUnitaryMatrix(qureg, u, __func__);
272 
273  statevec_controlledTwoQubitUnitary(qureg, controlQubit, targetQubit1, targetQubit2, u);
274  if (qureg.isDensityMatrix) {
275  int shift = qureg.numQubitsRepresented;
276  statevec_controlledTwoQubitUnitary(qureg, controlQubit+shift, targetQubit1+shift, targetQubit2+shift, getConjugateMatrix4(u));
277  }
278 
279  qasm_recordComment(qureg, "Here, an undisclosed controlled 2-qubit unitary was applied.");
280 }
281 
282 void multiControlledTwoQubitUnitary(Qureg qureg, int* controlQubits, int numControlQubits, int targetQubit1, int targetQubit2, ComplexMatrix4 u) {
283  validateMultiControlsMultiTargets(qureg, controlQubits, numControlQubits, (int[]) {targetQubit1, targetQubit2}, 2, __func__);
284  validateTwoQubitUnitaryMatrix(qureg, u, __func__);
285 
286  long long int ctrlQubitsMask = getQubitBitMask(controlQubits, numControlQubits);
287  statevec_multiControlledTwoQubitUnitary(qureg, ctrlQubitsMask, targetQubit1, targetQubit2, u);
288  if (qureg.isDensityMatrix) {
289  int shift = qureg.numQubitsRepresented;
290  statevec_multiControlledTwoQubitUnitary(qureg, ctrlQubitsMask<<shift, targetQubit1+shift, targetQubit2+shift, getConjugateMatrix4(u));
291  }
292 
293  qasm_recordComment(qureg, "Here, an undisclosed multi-controlled 2-qubit unitary was applied.");
294 }
295 
296 void multiQubitUnitary(Qureg qureg, int* targs, int numTargs, ComplexMatrixN u) {
297  validateMultiTargets(qureg, targs, numTargs, __func__);
298  validateMultiQubitUnitaryMatrix(qureg, u, numTargs, __func__);
299 
300  statevec_multiQubitUnitary(qureg, targs, numTargs, u);
301  if (qureg.isDensityMatrix) {
302  int shift = qureg.numQubitsRepresented;
303  shiftIndices(targs, numTargs, shift);
305  statevec_multiQubitUnitary(qureg, targs, numTargs, u);
306  shiftIndices(targs, numTargs, -shift);
308  }
309 
310  qasm_recordComment(qureg, "Here, an undisclosed multi-qubit unitary was applied.");
311 }
312 
313 void controlledMultiQubitUnitary(Qureg qureg, int ctrl, int* targs, int numTargs, ComplexMatrixN u) {
314  validateMultiControlsMultiTargets(qureg, (int[]) {ctrl}, 1, targs, numTargs, __func__);
315  validateMultiQubitUnitaryMatrix(qureg, u, numTargs, __func__);
316 
317  statevec_controlledMultiQubitUnitary(qureg, ctrl, targs, numTargs, u);
318  if (qureg.isDensityMatrix) {
319  int shift = qureg.numQubitsRepresented;
320  shiftIndices(targs, numTargs, shift);
322  statevec_controlledMultiQubitUnitary(qureg, ctrl+shift, targs, numTargs, u);
323  shiftIndices(targs, numTargs, -shift);
325  }
326 
327  qasm_recordComment(qureg, "Here, an undisclosed controlled multi-qubit unitary was applied.");
328 }
329 
330 void multiControlledMultiQubitUnitary(Qureg qureg, int* ctrls, int numCtrls, int* targs, int numTargs, ComplexMatrixN u) {
331  validateMultiControlsMultiTargets(qureg, ctrls, numCtrls, targs, numTargs, __func__);
332  validateMultiQubitUnitaryMatrix(qureg, u, numTargs, __func__);
333 
334  long long int ctrlMask = getQubitBitMask(ctrls, numCtrls);
335  statevec_multiControlledMultiQubitUnitary(qureg, ctrlMask, targs, numTargs, u);
336  if (qureg.isDensityMatrix) {
337  int shift = qureg.numQubitsRepresented;
338  shiftIndices(targs, numTargs, shift);
340  statevec_multiControlledMultiQubitUnitary(qureg, ctrlMask<<shift, targs, numTargs, u);
341  shiftIndices(targs, numTargs, -shift);
343  }
344 
345  qasm_recordComment(qureg, "Here, an undisclosed multi-controlled multi-qubit unitary was applied.");
346 }
347 
348 void unitary(Qureg qureg, int targetQubit, ComplexMatrix2 u) {
349  validateTarget(qureg, targetQubit, __func__);
350  validateOneQubitUnitaryMatrix(u, __func__);
351 
352  statevec_unitary(qureg, targetQubit, u);
353  if (qureg.isDensityMatrix) {
354  statevec_unitary(qureg, targetQubit+qureg.numQubitsRepresented, getConjugateMatrix2(u));
355  }
356 
357  qasm_recordUnitary(qureg, u, targetQubit);
358 }
359 
360 void controlledUnitary(Qureg qureg, int controlQubit, int targetQubit, ComplexMatrix2 u) {
361  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
362  validateOneQubitUnitaryMatrix(u, __func__);
363 
364  statevec_controlledUnitary(qureg, controlQubit, targetQubit, u);
365  if (qureg.isDensityMatrix) {
366  int shift = qureg.numQubitsRepresented;
367  statevec_controlledUnitary(qureg, controlQubit+shift, targetQubit+shift, getConjugateMatrix2(u));
368  }
369 
370  qasm_recordControlledUnitary(qureg, u, controlQubit, targetQubit);
371 }
372 
373 void multiControlledUnitary(Qureg qureg, int* controlQubits, int numControlQubits, int targetQubit, ComplexMatrix2 u) {
374  validateMultiControlsTarget(qureg, controlQubits, numControlQubits, targetQubit, __func__);
375  validateOneQubitUnitaryMatrix(u, __func__);
376 
377  long long int ctrlQubitsMask = getQubitBitMask(controlQubits, numControlQubits);
378  long long int ctrlFlipMask = 0;
379  statevec_multiControlledUnitary(qureg, ctrlQubitsMask, ctrlFlipMask, targetQubit, u);
380  if (qureg.isDensityMatrix) {
381  int shift = qureg.numQubitsRepresented;
382  statevec_multiControlledUnitary(qureg, ctrlQubitsMask<<shift, ctrlFlipMask<<shift, targetQubit+shift, getConjugateMatrix2(u));
383  }
384 
385  qasm_recordMultiControlledUnitary(qureg, u, controlQubits, numControlQubits, targetQubit);
386 }
387 
388 void multiStateControlledUnitary(Qureg qureg, int* controlQubits, int* controlState, int numControlQubits, int targetQubit, ComplexMatrix2 u) {
389  validateMultiControlsTarget(qureg, controlQubits, numControlQubits, targetQubit, __func__);
390  validateOneQubitUnitaryMatrix(u, __func__);
391  validateControlState(controlState, numControlQubits, __func__);
392 
393  long long int ctrlQubitsMask = getQubitBitMask(controlQubits, numControlQubits);
394  long long int ctrlFlipMask = getControlFlipMask(controlQubits, controlState, numControlQubits);
395  statevec_multiControlledUnitary(qureg, ctrlQubitsMask, ctrlFlipMask, targetQubit, u);
396  if (qureg.isDensityMatrix) {
397  int shift = qureg.numQubitsRepresented;
398  statevec_multiControlledUnitary(qureg, ctrlQubitsMask<<shift, ctrlFlipMask<<shift, targetQubit+shift, getConjugateMatrix2(u));
399  }
400 
401  qasm_recordMultiStateControlledUnitary(qureg, u, controlQubits, controlState, numControlQubits, targetQubit);
402 }
403 
404 void compactUnitary(Qureg qureg, int targetQubit, Complex alpha, Complex beta) {
405  validateTarget(qureg, targetQubit, __func__);
406  validateUnitaryComplexPair(alpha, beta, __func__);
407 
408  statevec_compactUnitary(qureg, targetQubit, alpha, beta);
409  if (qureg.isDensityMatrix) {
410  int shift = qureg.numQubitsRepresented;
411  statevec_compactUnitary(qureg, targetQubit+shift, getConjugateScalar(alpha), getConjugateScalar(beta));
412  }
413 
414  qasm_recordCompactUnitary(qureg, alpha, beta, targetQubit);
415 }
416 
417 void controlledCompactUnitary(Qureg qureg, int controlQubit, int targetQubit, Complex alpha, Complex beta) {
418  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
419  validateUnitaryComplexPair(alpha, beta, __func__);
420 
421  statevec_controlledCompactUnitary(qureg, controlQubit, targetQubit, alpha, beta);
422  if (qureg.isDensityMatrix) {
423  int shift = qureg.numQubitsRepresented;
425  controlQubit+shift, targetQubit+shift,
426  getConjugateScalar(alpha), getConjugateScalar(beta));
427  }
428 
429  qasm_recordControlledCompactUnitary(qureg, alpha, beta, controlQubit, targetQubit);
430 }
431 
432 void pauliX(Qureg qureg, int targetQubit) {
433  validateTarget(qureg, targetQubit, __func__);
434 
435  statevec_pauliX(qureg, targetQubit);
436  if (qureg.isDensityMatrix) {
437  statevec_pauliX(qureg, targetQubit+qureg.numQubitsRepresented);
438  }
439 
440  qasm_recordGate(qureg, GATE_SIGMA_X, targetQubit);
441 }
442 
443 void pauliY(Qureg qureg, int targetQubit) {
444  validateTarget(qureg, targetQubit, __func__);
445 
446  statevec_pauliY(qureg, targetQubit);
447  if (qureg.isDensityMatrix) {
448  statevec_pauliYConj(qureg, targetQubit + qureg.numQubitsRepresented);
449  }
450 
451  qasm_recordGate(qureg, GATE_SIGMA_Y, targetQubit);
452 }
453 
454 void pauliZ(Qureg qureg, int targetQubit) {
455  validateTarget(qureg, targetQubit, __func__);
456 
457  statevec_pauliZ(qureg, targetQubit);
458  if (qureg.isDensityMatrix) {
459  statevec_pauliZ(qureg, targetQubit+qureg.numQubitsRepresented);
460  }
461 
462  qasm_recordGate(qureg, GATE_SIGMA_Z, targetQubit);
463 }
464 
465 void sGate(Qureg qureg, int targetQubit) {
466  validateTarget(qureg, targetQubit, __func__);
467 
468  statevec_sGate(qureg, targetQubit);
469  if (qureg.isDensityMatrix) {
470  statevec_sGateConj(qureg, targetQubit+qureg.numQubitsRepresented);
471  }
472 
473  qasm_recordGate(qureg, GATE_S, targetQubit);
474 }
475 
476 void tGate(Qureg qureg, int targetQubit) {
477  validateTarget(qureg, targetQubit, __func__);
478 
479  statevec_tGate(qureg, targetQubit);
480  if (qureg.isDensityMatrix) {
481  statevec_tGateConj(qureg, targetQubit+qureg.numQubitsRepresented);
482  }
483 
484  qasm_recordGate(qureg, GATE_T, targetQubit);
485 }
486 
487 void phaseShift(Qureg qureg, int targetQubit, qreal angle) {
488  validateTarget(qureg, targetQubit, __func__);
489 
490  statevec_phaseShift(qureg, targetQubit, angle);
491  if (qureg.isDensityMatrix) {
492  statevec_phaseShift(qureg, targetQubit+qureg.numQubitsRepresented, -angle);
493  }
494 
495  qasm_recordParamGate(qureg, GATE_PHASE_SHIFT, targetQubit, angle);
496 }
497 
498 void controlledPhaseShift(Qureg qureg, int idQubit1, int idQubit2, qreal angle) {
499  validateControlTarget(qureg, idQubit1, idQubit2, __func__);
500 
501  statevec_controlledPhaseShift(qureg, idQubit1, idQubit2, angle);
502  if (qureg.isDensityMatrix) {
503  int shift = qureg.numQubitsRepresented;
504  statevec_controlledPhaseShift(qureg, idQubit1+shift, idQubit2+shift, -angle);
505  }
506 
507  qasm_recordControlledParamGate(qureg, GATE_PHASE_SHIFT, idQubit1, idQubit2, angle);
508 }
509 
510 void multiControlledPhaseShift(Qureg qureg, int *controlQubits, int numControlQubits, qreal angle) {
511  validateMultiQubits(qureg, controlQubits, numControlQubits, __func__);
512 
513  statevec_multiControlledPhaseShift(qureg, controlQubits, numControlQubits, angle);
514  if (qureg.isDensityMatrix) {
515  int shift = qureg.numQubitsRepresented;
516  shiftIndices(controlQubits, numControlQubits, shift);
517  statevec_multiControlledPhaseShift(qureg, controlQubits, numControlQubits, -angle);
518  shiftIndices(controlQubits, numControlQubits, -shift);
519  }
520 
521  qasm_recordMultiControlledParamGate(qureg, GATE_PHASE_SHIFT, controlQubits, numControlQubits-1, controlQubits[numControlQubits-1], angle);
522 }
523 
524 void controlledNot(Qureg qureg, int controlQubit, int targetQubit) {
525  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
526 
527  statevec_controlledNot(qureg, controlQubit, targetQubit);
528  if (qureg.isDensityMatrix) {
529  int shift = qureg.numQubitsRepresented;
530  statevec_controlledNot(qureg, controlQubit+shift, targetQubit+shift);
531  }
532 
533  qasm_recordControlledGate(qureg, GATE_SIGMA_X, controlQubit, targetQubit);
534 }
535 
536 void multiQubitNot(Qureg qureg, int* targs, int numTargs) {
537  validateMultiTargets(qureg, targs, numTargs, __func__);
538 
539  long long int targMask = getQubitBitMask(targs, numTargs);
540  statevec_multiControlledMultiQubitNot(qureg, 0, targMask);
541  if (qureg.isDensityMatrix) {
542  int shift = qureg.numQubitsRepresented;
543  statevec_multiControlledMultiQubitNot(qureg, 0, targMask<<shift);
544  }
545 
546  qasm_recordMultiControlledMultiQubitNot(qureg, NULL, 0, targs, numTargs);
547 }
548 
549 void multiControlledMultiQubitNot(Qureg qureg, int* ctrls, int numCtrls, int* targs, int numTargs) {
550  validateMultiControlsMultiTargets(qureg, ctrls, numCtrls, targs, numTargs, __func__);
551 
552  long long int ctrlMask = getQubitBitMask(ctrls, numCtrls);
553  long long int targMask = getQubitBitMask(targs, numTargs);
554  statevec_multiControlledMultiQubitNot(qureg, ctrlMask, targMask);
555  if (qureg.isDensityMatrix) {
556  int shift = qureg.numQubitsRepresented;
557  statevec_multiControlledMultiQubitNot(qureg, ctrlMask<<shift, targMask<<shift);
558  }
559 
560  qasm_recordMultiControlledMultiQubitNot(qureg, ctrls, numCtrls, targs, numTargs);
561 }
562 
563 void controlledPauliY(Qureg qureg, int controlQubit, int targetQubit) {
564  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
565 
566  statevec_controlledPauliY(qureg, controlQubit, targetQubit);
567  if (qureg.isDensityMatrix) {
568  int shift = qureg.numQubitsRepresented;
569  statevec_controlledPauliYConj(qureg, controlQubit+shift, targetQubit+shift);
570  }
571 
572  qasm_recordControlledGate(qureg, GATE_SIGMA_Y, controlQubit, targetQubit);
573 }
574 
575 void controlledPhaseFlip(Qureg qureg, int idQubit1, int idQubit2) {
576  validateControlTarget(qureg, idQubit1, idQubit2, __func__);
577 
578  statevec_controlledPhaseFlip(qureg, idQubit1, idQubit2);
579  if (qureg.isDensityMatrix) {
580  int shift = qureg.numQubitsRepresented;
581  statevec_controlledPhaseFlip(qureg, idQubit1+shift, idQubit2+shift);
582  }
583 
584  qasm_recordControlledGate(qureg, GATE_SIGMA_Z, idQubit1, idQubit2);
585 }
586 
587 void multiControlledPhaseFlip(Qureg qureg, int *controlQubits, int numControlQubits) {
588  validateMultiQubits(qureg, controlQubits, numControlQubits, __func__);
589 
590  statevec_multiControlledPhaseFlip(qureg, controlQubits, numControlQubits);
591  if (qureg.isDensityMatrix) {
592  int shift = qureg.numQubitsRepresented;
593  shiftIndices(controlQubits, numControlQubits, shift);
594  statevec_multiControlledPhaseFlip(qureg, controlQubits, numControlQubits);
595  shiftIndices(controlQubits, numControlQubits, -shift);
596  }
597 
598  qasm_recordMultiControlledGate(qureg, GATE_SIGMA_Z, controlQubits, numControlQubits-1, controlQubits[numControlQubits-1]);
599 }
600 
601 void rotateAroundAxis(Qureg qureg, int rotQubit, qreal angle, Vector axis) {
602  validateTarget(qureg, rotQubit, __func__);
603  validateVector(axis, __func__);
604 
605  statevec_rotateAroundAxis(qureg, rotQubit, angle, axis);
606  if (qureg.isDensityMatrix) {
607  int shift = qureg.numQubitsRepresented;
608  statevec_rotateAroundAxisConj(qureg, rotQubit+shift, angle, axis);
609  }
610 
611  qasm_recordAxisRotation(qureg, angle, axis, rotQubit);
612 }
613 
614 void controlledRotateAroundAxis(Qureg qureg, int controlQubit, int targetQubit, qreal angle, Vector axis) {
615  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
616  validateVector(axis, __func__);
617 
618  statevec_controlledRotateAroundAxis(qureg, controlQubit, targetQubit, angle, axis);
619  if (qureg.isDensityMatrix) {
620  int shift = qureg.numQubitsRepresented;
621  statevec_controlledRotateAroundAxisConj(qureg, controlQubit+shift, targetQubit+shift, angle, axis);
622  }
623 
624  qasm_recordControlledAxisRotation(qureg, angle, axis, controlQubit, targetQubit);
625 }
626 
627 void swapGate(Qureg qureg, int qb1, int qb2) {
628  validateUniqueTargets(qureg, qb1, qb2, __func__);
629 
630  statevec_swapQubitAmps(qureg, qb1, qb2);
631  if (qureg.isDensityMatrix) {
632  int shift = qureg.numQubitsRepresented;
633  statevec_swapQubitAmps(qureg, qb1+shift, qb2+shift);
634  }
635 
636  qasm_recordControlledGate(qureg, GATE_SWAP, qb1, qb2);
637 }
638 
639 void sqrtSwapGate(Qureg qureg, int qb1, int qb2) {
640  validateUniqueTargets(qureg, qb1, qb2, __func__);
641  validateMultiQubitMatrixFitsInNode(qureg, 2, __func__); // uses 2qb unitary in QuEST_common
642 
643  statevec_sqrtSwapGate(qureg, qb1, qb2);
644  if (qureg.isDensityMatrix) {
645  int shift = qureg.numQubitsRepresented;
646  statevec_sqrtSwapGateConj(qureg, qb1+shift, qb2+shift);
647  }
648 
649  qasm_recordControlledGate(qureg, GATE_SQRT_SWAP, qb1, qb2);
650 }
651 
652 void multiRotateZ(Qureg qureg, int* qubits, int numQubits, qreal angle) {
653  validateMultiTargets(qureg, qubits, numQubits, __func__);
654 
655  long long int mask = getQubitBitMask(qubits, numQubits);
656  statevec_multiRotateZ(qureg, mask, angle);
657  if (qureg.isDensityMatrix) {
658  int shift = qureg.numQubitsRepresented;
659  statevec_multiRotateZ(qureg, mask << shift, -angle);
660  }
661 
662  // @TODO: create actual QASM
663  qasm_recordComment(qureg,
664  "Here a %d-qubit multiRotateZ of angle %g was performed (QASM not yet implemented)",
665  numQubits, angle);
666 }
667 
668 void multiControlledMultiRotateZ(Qureg qureg, int* controlQubits, int numControls, int* targetQubits, int numTargets, qreal angle) {
669  validateMultiControlsMultiTargets(qureg, controlQubits, numControls, targetQubits, numTargets, __func__);
670 
671  long long int ctrlMask = getQubitBitMask(controlQubits, numControls);
672  long long int targMask = getQubitBitMask(targetQubits, numTargets);
673  statevec_multiControlledMultiRotateZ(qureg, ctrlMask, targMask, angle);
674  if (qureg.isDensityMatrix) {
675  int shift = qureg.numQubitsRepresented;
676  statevec_multiControlledMultiRotateZ(qureg, ctrlMask<<shift, targMask<<shift, - angle);
677  }
678 
679  // @TODO: create actual QASM
680  qasm_recordComment(qureg,
681  "Here a %d-control %d-target multiControlledMultiRotateZ of angle %g was performed (QASM not yet implemented)",
682  numControls, numTargets, angle);
683 }
684 
685 void multiRotatePauli(Qureg qureg, int* targetQubits, enum pauliOpType* targetPaulis, int numTargets, qreal angle) {
686  validateMultiTargets(qureg, targetQubits, numTargets, __func__);
687  validatePauliCodes(targetPaulis, numTargets, __func__);
688 
689  int conj=0;
690  statevec_multiRotatePauli(qureg, targetQubits, targetPaulis, numTargets, angle, conj);
691  if (qureg.isDensityMatrix) {
692  conj = 1;
693  int shift = qureg.numQubitsRepresented;
694  shiftIndices(targetQubits, numTargets, shift);
695  statevec_multiRotatePauli(qureg, targetQubits, targetPaulis, numTargets, angle, conj);
696  shiftIndices(targetQubits, numTargets, -shift);
697  }
698 
699  // @TODO: create actual QASM
700  qasm_recordComment(qureg,
701  "Here a %d-qubit multiRotatePauli of angle %g was performed (QASM not yet implemented)",
702  numTargets, angle);
703 }
704 
705 void multiControlledMultiRotatePauli(Qureg qureg, int* controlQubits, int numControls, int* targetQubits, enum pauliOpType* targetPaulis, int numTargets, qreal angle) {
706  validateMultiControlsMultiTargets(qureg, controlQubits, numControls, targetQubits, numTargets, __func__);
707  validatePauliCodes(targetPaulis, numTargets, __func__);
708 
709  int conj=0;
710  long long int ctrlMask = getQubitBitMask(controlQubits, numControls);
711  statevec_multiControlledMultiRotatePauli(qureg, ctrlMask, targetQubits, targetPaulis, numTargets, angle, conj);
712  if (qureg.isDensityMatrix) {
713  conj = 1;
714  int shift = qureg.numQubitsRepresented;
715  shiftIndices(targetQubits, numTargets, shift);
716  statevec_multiControlledMultiRotatePauli(qureg, ctrlMask<<shift, targetQubits, targetPaulis, numTargets, angle, conj);
717  shiftIndices(targetQubits, numTargets, -shift);
718  }
719 
720  // @TODO: create actual QASM
721  qasm_recordComment(qureg,
722  "Here a %d-control %d-target multiControlledMultiRotatePauli of angle %g was performed (QASM not yet implemented)",
723  numControls, numTargets, angle);
724 }
725 
726 void applyPhaseFunc(Qureg qureg, int* qubits, int numQubits, enum bitEncoding encoding, qreal* coeffs, qreal* exponents, int numTerms) {
727  validateMultiQubits(qureg, qubits, numQubits, __func__);
728  validateBitEncoding(numQubits, encoding, __func__);
729  validatePhaseFuncTerms(numQubits, encoding, coeffs, exponents, numTerms, NULL, 0, __func__);
730 
731  int conj = 0;
732  statevec_applyPhaseFuncOverrides(qureg, qubits, numQubits, encoding, coeffs, exponents, numTerms, NULL, NULL, 0, conj);
733  if (qureg.isDensityMatrix) {
734  conj = 1;
735  shiftIndices(qubits, numQubits, qureg.numQubitsRepresented);
736  statevec_applyPhaseFuncOverrides(qureg, qubits, numQubits, encoding, coeffs, exponents, numTerms, NULL, NULL, 0, conj);
737  shiftIndices(qubits, numQubits, - qureg.numQubitsRepresented);
738  }
739 
740  qasm_recordPhaseFunc(qureg, qubits, numQubits, encoding, coeffs, exponents, numTerms, NULL, NULL, 0);
741 }
742 
743 void applyPhaseFuncOverrides(Qureg qureg, int* qubits, int numQubits, enum bitEncoding encoding, qreal* coeffs, qreal* exponents, int numTerms, long long int* overrideInds, qreal* overridePhases, int numOverrides) {
744  validateMultiQubits(qureg, qubits, numQubits, __func__);
745  validateBitEncoding(numQubits, encoding, __func__);
746  validatePhaseFuncOverrides(numQubits, encoding, overrideInds, numOverrides, __func__);
747  validatePhaseFuncTerms(numQubits, encoding, coeffs, exponents, numTerms, overrideInds, numOverrides, __func__);
748 
749  int conj = 0;
750  statevec_applyPhaseFuncOverrides(qureg, qubits, numQubits, encoding, coeffs, exponents, numTerms, overrideInds, overridePhases, numOverrides, conj);
751  if (qureg.isDensityMatrix) {
752  conj = 1;
753  shiftIndices(qubits, numQubits, qureg.numQubitsRepresented);
754  statevec_applyPhaseFuncOverrides(qureg, qubits, numQubits, encoding, coeffs, exponents, numTerms, overrideInds, overridePhases, numOverrides, conj);
755  shiftIndices(qubits, numQubits, - qureg.numQubitsRepresented);
756  }
757 
758  qasm_recordPhaseFunc(qureg, qubits, numQubits, encoding, coeffs, exponents, numTerms, overrideInds, overridePhases, numOverrides);
759 }
760 
761 void applyMultiVarPhaseFunc(Qureg qureg, int* qubits, int* numQubitsPerReg, int numRegs, enum bitEncoding encoding, qreal* coeffs, qreal* exponents, int* numTermsPerReg) {
762  validateQubitSubregs(qureg, qubits, numQubitsPerReg, numRegs, __func__);
763  validateMultiRegBitEncoding(numQubitsPerReg, numRegs, encoding, __func__);
764  validateMultiVarPhaseFuncTerms(numQubitsPerReg, numRegs, encoding, exponents, numTermsPerReg, __func__);
765 
766  int conj = 0;
767  statevec_applyMultiVarPhaseFuncOverrides(qureg, qubits, numQubitsPerReg, numRegs, encoding, coeffs, exponents, numTermsPerReg, NULL, NULL, 0, conj);
768  if (qureg.isDensityMatrix) {
769  conj = 1;
770  shiftSubregIndices(qubits, numQubitsPerReg, numRegs, qureg.numQubitsRepresented);
771  statevec_applyMultiVarPhaseFuncOverrides(qureg, qubits, numQubitsPerReg, numRegs, encoding, coeffs, exponents, numTermsPerReg, NULL, NULL, 0, conj);
772  shiftSubregIndices(qubits, numQubitsPerReg, numRegs, - qureg.numQubitsRepresented);
773  }
774 
775  qasm_recordMultiVarPhaseFunc(qureg, qubits, numQubitsPerReg, numRegs, encoding, coeffs, exponents, numTermsPerReg, NULL, NULL, 0);
776 }
777 
778 void applyMultiVarPhaseFuncOverrides(Qureg qureg, int* qubits, int* numQubitsPerReg, int numRegs, enum bitEncoding encoding, qreal* coeffs, qreal* exponents, int* numTermsPerReg, long long int* overrideInds, qreal* overridePhases, int numOverrides) {
779  validateQubitSubregs(qureg, qubits, numQubitsPerReg, numRegs, __func__);
780  validateMultiRegBitEncoding(numQubitsPerReg, numRegs, encoding, __func__);
781  validateMultiVarPhaseFuncTerms(numQubitsPerReg, numRegs, encoding, exponents, numTermsPerReg, __func__);
782  validateMultiVarPhaseFuncOverrides(numQubitsPerReg, numRegs, encoding, overrideInds, numOverrides, __func__);
783 
784  int conj = 0;
785  statevec_applyMultiVarPhaseFuncOverrides(qureg, qubits, numQubitsPerReg, numRegs, encoding, coeffs, exponents, numTermsPerReg, overrideInds, overridePhases, numOverrides, conj);
786  if (qureg.isDensityMatrix) {
787  conj = 1;
788  shiftSubregIndices(qubits, numQubitsPerReg, numRegs, qureg.numQubitsRepresented);
789  statevec_applyMultiVarPhaseFuncOverrides(qureg, qubits, numQubitsPerReg, numRegs, encoding, coeffs, exponents, numTermsPerReg, overrideInds, overridePhases, numOverrides, conj);
790  shiftSubregIndices(qubits, numQubitsPerReg, numRegs, - qureg.numQubitsRepresented);
791  }
792 
793  qasm_recordMultiVarPhaseFunc(qureg, qubits, numQubitsPerReg, numRegs, encoding, coeffs, exponents, numTermsPerReg, overrideInds, overridePhases, numOverrides);
794 }
795 
796 void applyNamedPhaseFunc(Qureg qureg, int* qubits, int* numQubitsPerReg, int numRegs, enum bitEncoding encoding, enum phaseFunc functionNameCode) {
797  validateQubitSubregs(qureg, qubits, numQubitsPerReg, numRegs, __func__);
798  validateMultiRegBitEncoding(numQubitsPerReg, numRegs, encoding, __func__);
799  validatePhaseFuncName(functionNameCode, numRegs, 0, __func__);
800 
801  int conj = 0;
802  statevec_applyParamNamedPhaseFuncOverrides(qureg, qubits, numQubitsPerReg, numRegs, encoding, functionNameCode, NULL, 0, NULL, NULL, 0, conj);
803  if (qureg.isDensityMatrix) {
804  conj = 1;
805  shiftSubregIndices(qubits, numQubitsPerReg, numRegs, qureg.numQubitsRepresented);
806  statevec_applyParamNamedPhaseFuncOverrides(qureg, qubits, numQubitsPerReg, numRegs, encoding, functionNameCode, NULL, 0, NULL, NULL, 0, conj);
807  shiftSubregIndices(qubits, numQubitsPerReg, numRegs, - qureg.numQubitsRepresented);
808  }
809 
810  qasm_recordNamedPhaseFunc(qureg, qubits, numQubitsPerReg, numRegs, encoding, functionNameCode, NULL, 0, NULL, NULL, 0);
811 }
812 
813 void applyNamedPhaseFuncOverrides(Qureg qureg, int* qubits, int* numQubitsPerReg, int numRegs, enum bitEncoding encoding, enum phaseFunc functionNameCode, long long int* overrideInds, qreal* overridePhases, int numOverrides) {
814  validateQubitSubregs(qureg, qubits, numQubitsPerReg, numRegs, __func__);
815  validateMultiRegBitEncoding(numQubitsPerReg, numRegs, encoding, __func__);
816  validatePhaseFuncName(functionNameCode, numRegs, 0, __func__);
817  validateMultiVarPhaseFuncOverrides(numQubitsPerReg, numRegs, encoding, overrideInds, numOverrides, __func__);
818 
819  int conj = 0;
820  statevec_applyParamNamedPhaseFuncOverrides(qureg, qubits, numQubitsPerReg, numRegs, encoding, functionNameCode, NULL, 0, overrideInds, overridePhases, numOverrides, conj);
821  if (qureg.isDensityMatrix) {
822  conj = 1;
823  shiftSubregIndices(qubits, numQubitsPerReg, numRegs, qureg.numQubitsRepresented);
824  statevec_applyParamNamedPhaseFuncOverrides(qureg, qubits, numQubitsPerReg, numRegs, encoding, functionNameCode, NULL, 0, overrideInds, overridePhases, numOverrides, conj);
825  shiftSubregIndices(qubits, numQubitsPerReg, numRegs, - qureg.numQubitsRepresented);
826  }
827 
828  qasm_recordNamedPhaseFunc(qureg, qubits, numQubitsPerReg, numRegs, encoding, functionNameCode, NULL, 0, overrideInds, overridePhases, numOverrides);
829 }
830 
831 void applyParamNamedPhaseFunc(Qureg qureg, int* qubits, int* numQubitsPerReg, int numRegs, enum bitEncoding encoding, enum phaseFunc functionNameCode, qreal* params, int numParams) {
832  validateQubitSubregs(qureg, qubits, numQubitsPerReg, numRegs, __func__);
833  validateMultiRegBitEncoding(numQubitsPerReg, numRegs, encoding, __func__);
834  validatePhaseFuncName(functionNameCode, numRegs, numParams, __func__);
835 
836  int conj = 0;
837  statevec_applyParamNamedPhaseFuncOverrides(qureg, qubits, numQubitsPerReg, numRegs, encoding, functionNameCode, params, numParams, NULL, NULL, 0, conj);
838  if (qureg.isDensityMatrix) {
839  conj = 1;
840  shiftSubregIndices(qubits, numQubitsPerReg, numRegs, qureg.numQubitsRepresented);
841  statevec_applyParamNamedPhaseFuncOverrides(qureg, qubits, numQubitsPerReg, numRegs, encoding, functionNameCode, params, numParams, NULL, NULL, 0, conj);
842  shiftSubregIndices(qubits, numQubitsPerReg, numRegs, - qureg.numQubitsRepresented);
843  }
844 
845  qasm_recordNamedPhaseFunc(qureg, qubits, numQubitsPerReg, numRegs, encoding, functionNameCode, params, numParams, NULL, NULL, 0);
846 }
847 
848 void applyParamNamedPhaseFuncOverrides(Qureg qureg, int* qubits, int* numQubitsPerReg, int numRegs, enum bitEncoding encoding, enum phaseFunc functionNameCode, qreal* params, int numParams, long long int* overrideInds, qreal* overridePhases, int numOverrides) {
849  validateQubitSubregs(qureg, qubits, numQubitsPerReg, numRegs, __func__);
850  validateMultiRegBitEncoding(numQubitsPerReg, numRegs, encoding, __func__);
851  validatePhaseFuncName(functionNameCode, numRegs, numParams, __func__);
852  validateMultiVarPhaseFuncOverrides(numQubitsPerReg, numRegs, encoding, overrideInds, numOverrides, __func__);
853 
854  int conj = 0;
855  statevec_applyParamNamedPhaseFuncOverrides(qureg, qubits, numQubitsPerReg, numRegs, encoding, functionNameCode, params, numParams, overrideInds, overridePhases, numOverrides, conj);
856  if (qureg.isDensityMatrix) {
857  conj = 1;
858  shiftSubregIndices(qubits, numQubitsPerReg, numRegs, qureg.numQubitsRepresented);
859  statevec_applyParamNamedPhaseFuncOverrides(qureg, qubits, numQubitsPerReg, numRegs, encoding, functionNameCode, params, numParams, overrideInds, overridePhases, numOverrides, conj);
860  shiftSubregIndices(qubits, numQubitsPerReg, numRegs, - qureg.numQubitsRepresented);
861  }
862 
863  qasm_recordNamedPhaseFunc(qureg, qubits, numQubitsPerReg, numRegs, encoding, functionNameCode, params, numParams, overrideInds, overridePhases, numOverrides);
864 }
865 
866 void applyQFT(Qureg qureg, int* qubits, int numQubits) {
867  validateMultiTargets(qureg, qubits, numQubits, __func__);
868 
869  qasm_recordComment(qureg, "Beginning of QFT circuit");
870 
871  agnostic_applyQFT(qureg, qubits, numQubits);
872 
873  qasm_recordComment(qureg, "End of QFT circuit");
874 }
875 
876 void applyFullQFT(Qureg qureg) {
877 
878  qasm_recordComment(qureg, "Beginning of QFT circuit");
879 
880  int qubits[100];
881  for (int i=0; i<qureg.numQubitsRepresented; i++)
882  qubits[i] = i;
883  agnostic_applyQFT(qureg, qubits, qureg.numQubitsRepresented);
884 
885  qasm_recordComment(qureg, "End of QFT circuit");
886 }
887 
888 void applyProjector(Qureg qureg, int qubit, int outcome) {
889  validateTarget(qureg, qubit, __func__);
890  validateOutcome(outcome, __func__);
891 
892  qreal renorm = 1;
893 
894  if (qureg.isDensityMatrix)
895  densmatr_collapseToKnownProbOutcome(qureg, qubit, outcome, renorm);
896  else
897  statevec_collapseToKnownProbOutcome(qureg, qubit, outcome, renorm);
898 
899  qasm_recordComment(qureg, "Here, qubit %d was un-physically projected into outcome %d", qubit, outcome);
900 }
901 
902 
903 
904 /*
905  * register attributes
906  */
907 
908 int getNumQubits(Qureg qureg) {
909  return qureg.numQubitsRepresented;
910 }
911 
912 long long int getNumAmps(Qureg qureg) {
913  validateStateVecQureg(qureg, __func__);
914 
915  return qureg.numAmpsTotal;
916 }
917 
918 qreal getRealAmp(Qureg qureg, long long int index) {
919  validateStateVecQureg(qureg, __func__);
920  validateAmpIndex(qureg, index, __func__);
921 
922  return statevec_getRealAmp(qureg, index);
923 }
924 
925 qreal getImagAmp(Qureg qureg, long long int index) {
926  validateStateVecQureg(qureg, __func__);
927  validateAmpIndex(qureg, index, __func__);
928 
929  return statevec_getImagAmp(qureg, index);
930 }
931 
932 qreal getProbAmp(Qureg qureg, long long int index) {
933  validateStateVecQureg(qureg, __func__);
934  validateAmpIndex(qureg, index, __func__);
935 
936  return statevec_getProbAmp(qureg, index);
937 }
938 
939 Complex getAmp(Qureg qureg, long long int index) {
940  validateStateVecQureg(qureg, __func__);
941  validateAmpIndex(qureg, index, __func__);
942 
943  Complex amp;
944  amp.real = statevec_getRealAmp(qureg, index);
945  amp.imag = statevec_getImagAmp(qureg, index);
946  return amp;
947 }
948 
949 Complex getDensityAmp(Qureg qureg, long long int row, long long int col) {
950  validateDensityMatrQureg(qureg, __func__);
951  validateAmpIndex(qureg, row, __func__);
952  validateAmpIndex(qureg, col, __func__);
953 
954  long long ind = row + col*(1LL << qureg.numQubitsRepresented);
955  Complex amp;
956  amp.real = statevec_getRealAmp(qureg, ind);
957  amp.imag = statevec_getImagAmp(qureg, ind);
958  return amp;
959 }
960 
961 
962 /*
963  * non-unitary actions
964  */
965 
966 qreal collapseToOutcome(Qureg qureg, int measureQubit, int outcome) {
967  validateTarget(qureg, measureQubit, __func__);
968  validateOutcome(outcome, __func__);
969 
970  qreal outcomeProb;
971  if (qureg.isDensityMatrix) {
972  outcomeProb = densmatr_calcProbOfOutcome(qureg, measureQubit, outcome);
973  validateMeasurementProb(outcomeProb, __func__);
974  densmatr_collapseToKnownProbOutcome(qureg, measureQubit, outcome, outcomeProb);
975  } else {
976  outcomeProb = statevec_calcProbOfOutcome(qureg, measureQubit, outcome);
977  validateMeasurementProb(outcomeProb, __func__);
978  statevec_collapseToKnownProbOutcome(qureg, measureQubit, outcome, outcomeProb);
979  }
980 
981  qasm_recordMeasurement(qureg, measureQubit);
982  return outcomeProb;
983 }
984 
985 int measureWithStats(Qureg qureg, int measureQubit, qreal *outcomeProb) {
986  validateTarget(qureg, measureQubit, __func__);
987 
988  int outcome;
989  if (qureg.isDensityMatrix)
990  outcome = densmatr_measureWithStats(qureg, measureQubit, outcomeProb);
991  else
992  outcome = statevec_measureWithStats(qureg, measureQubit, outcomeProb);
993 
994  qasm_recordMeasurement(qureg, measureQubit);
995  return outcome;
996 }
997 
998 int measure(Qureg qureg, int measureQubit) {
999  validateTarget(qureg, measureQubit, __func__);
1000 
1001  int outcome;
1002  qreal discardedProb;
1003  if (qureg.isDensityMatrix)
1004  outcome = densmatr_measureWithStats(qureg, measureQubit, &discardedProb);
1005  else
1006  outcome = statevec_measureWithStats(qureg, measureQubit, &discardedProb);
1007 
1008  qasm_recordMeasurement(qureg, measureQubit);
1009  return outcome;
1010 }
1011 
1012 void mixDensityMatrix(Qureg combineQureg, qreal otherProb, Qureg otherQureg) {
1013  validateDensityMatrQureg(combineQureg, __func__);
1014  validateDensityMatrQureg(otherQureg, __func__);
1015  validateMatchingQuregDims(combineQureg, otherQureg, __func__);
1016  validateProb(otherProb, __func__);
1017 
1018  densmatr_mixDensityMatrix(combineQureg, otherProb, otherQureg);
1019 }
1020 
1021 void setAmps(Qureg qureg, long long int startInd, qreal* reals, qreal* imags, long long int numAmps) {
1022  validateStateVecQureg(qureg, __func__);
1023  validateNumAmps(qureg, startInd, numAmps, __func__);
1024 
1025  statevec_setAmps(qureg, startInd, reals, imags, numAmps);
1026 
1027  qasm_recordComment(qureg, "Here, some amplitudes in the statevector were manually edited.");
1028 }
1029 
1030 void setDensityAmps(Qureg qureg, qreal* reals, qreal* imags) {
1031  long long int numAmps = qureg.numAmpsTotal;
1032  statevec_setAmps(qureg, 0, reals, imags, numAmps);
1033 
1034  qasm_recordComment(qureg, "Here, some amplitudes in the density matrix were manually edited.");
1035 }
1036 
1037 void setWeightedQureg(Complex fac1, Qureg qureg1, Complex fac2, Qureg qureg2, Complex facOut, Qureg out) {
1038  validateMatchingQuregTypes(qureg1, qureg2, __func__);
1039  validateMatchingQuregTypes(qureg1, out, __func__);
1040  validateMatchingQuregDims(qureg1, qureg2, __func__);
1041  validateMatchingQuregDims(qureg1, out, __func__);
1042 
1043  statevec_setWeightedQureg(fac1, qureg1, fac2, qureg2, facOut, out);
1044 
1045  qasm_recordComment(out, "Here, the register was modified to an undisclosed and possibly unphysical state (setWeightedQureg).");
1046 }
1047 
1048 void applyPauliSum(Qureg inQureg, enum pauliOpType* allPauliCodes, qreal* termCoeffs, int numSumTerms, Qureg outQureg) {
1049  validateMatchingQuregTypes(inQureg, outQureg, __func__);
1050  validateMatchingQuregDims(inQureg, outQureg, __func__);
1051  validateNumPauliSumTerms(numSumTerms, __func__);
1052  validatePauliCodes(allPauliCodes, numSumTerms*inQureg.numQubitsRepresented, __func__);
1053 
1054  statevec_applyPauliSum(inQureg, allPauliCodes, termCoeffs, numSumTerms, outQureg);
1055 
1056  qasm_recordComment(outQureg, "Here, the register was modified to an undisclosed and possibly unphysical state (applyPauliSum).");
1057 }
1058 
1059 void applyPauliHamil(Qureg inQureg, PauliHamil hamil, Qureg outQureg) {
1060  validateMatchingQuregTypes(inQureg, outQureg, __func__);
1061  validateMatchingQuregDims(inQureg, outQureg, __func__);
1062  validatePauliHamil(hamil, __func__);
1063  validateMatchingQuregPauliHamilDims(inQureg, hamil, __func__);
1064 
1065  statevec_applyPauliSum(inQureg, hamil.pauliCodes, hamil.termCoeffs, hamil.numSumTerms, outQureg);
1066 
1067  qasm_recordComment(outQureg, "Here, the register was modified to an undisclosed and possibly unphysical state (applyPauliHamil).");
1068 }
1069 
1070 void applyTrotterCircuit(Qureg qureg, PauliHamil hamil, qreal time, int order, int reps) {
1071  validateTrotterParams(order, reps, __func__);
1072  validatePauliHamil(hamil, __func__);
1073  validateMatchingQuregPauliHamilDims(qureg, hamil, __func__);
1074 
1075  qasm_recordComment(qureg,
1076  "Beginning of Trotter circuit (time %g, order %d, %d repetitions).",
1077  time, order, reps);
1078 
1079  agnostic_applyTrotterCircuit(qureg, hamil, time, order, reps);
1080 
1081  qasm_recordComment(qureg, "End of Trotter circuit");
1082 }
1083 
1084 void applyMatrix2(Qureg qureg, int targetQubit, ComplexMatrix2 u) {
1085  validateTarget(qureg, targetQubit, __func__);
1086 
1087  // actually just left-multiplies any complex matrix
1088  statevec_unitary(qureg, targetQubit, u);
1089 
1090  qasm_recordComment(qureg, "Here, an undisclosed 2-by-2 matrix (possibly non-unitary) was multiplied onto qubit %d", targetQubit);
1091 }
1092 
1093 void applyMatrix4(Qureg qureg, int targetQubit1, int targetQubit2, ComplexMatrix4 u) {
1094  validateMultiTargets(qureg, (int []) {targetQubit1, targetQubit2}, 2, __func__);
1095  validateMultiQubitMatrixFitsInNode(qureg, 2, __func__);
1096 
1097  // actually just left-multiplies any complex matrix
1098  statevec_twoQubitUnitary(qureg, targetQubit1, targetQubit2, u);
1099 
1100  qasm_recordComment(qureg, "Here, an undisclosed 4-by-4 matrix (possibly non-unitary) was multiplied onto qubits %d and %d", targetQubit1, targetQubit2);
1101 }
1102 
1103 void applyMatrixN(Qureg qureg, int* targs, int numTargs, ComplexMatrixN u) {
1104  validateMultiTargets(qureg, targs, numTargs, __func__);
1105  validateMultiQubitMatrix(qureg, u, numTargs, __func__);
1106 
1107  // actually just left-multiplies any complex matrix
1108  statevec_multiQubitUnitary(qureg, targs, numTargs, u);
1109 
1110  int dim = (1 << numTargs);
1111  qasm_recordComment(qureg, "Here, an undisclosed %d-by-%d matrix (possibly non-unitary) was multiplied onto %d undisclosed qubits", dim, dim, numTargs);
1112 }
1113 
1114 void applyMultiControlledMatrixN(Qureg qureg, int* ctrls, int numCtrls, int* targs, int numTargs, ComplexMatrixN u) {
1115  validateMultiControlsMultiTargets(qureg, ctrls, numCtrls, targs, numTargs, __func__);
1116  validateMultiQubitMatrix(qureg, u, numTargs, __func__);
1117 
1118  // actually just left-multiplies any complex matrix
1119  long long int ctrlMask = getQubitBitMask(ctrls, numCtrls);
1120  statevec_multiControlledMultiQubitUnitary(qureg, ctrlMask, targs, numTargs, u);
1121 
1122  int numTot = numTargs + numCtrls;
1123  int dim = (1 << numTot );
1124  qasm_recordComment(qureg, "Here, an undisclosed %d-by-%d matrix (possibly non-unitary, and including %d controlled qubits) was multiplied onto %d undisclosed qubits", dim, dim, numCtrls, numTot);
1125 }
1126 
1128  validateDiagonalOp(qureg, op, __func__);
1129 
1130  if (qureg.isDensityMatrix)
1131  densmatr_applyDiagonalOp(qureg, op);
1132  else
1133  statevec_applyDiagonalOp(qureg, op);
1134 
1135  qasm_recordComment(qureg, "Here, the register was modified to an undisclosed and possibly unphysical state (via applyDiagonalOp).");
1136 }
1137 
1138 
1139 /*
1140  * calculations
1141  */
1142 
1144  if (qureg.isDensityMatrix)
1145  return densmatr_calcTotalProb(qureg);
1146  else
1147  return statevec_calcTotalProb(qureg);
1148 }
1149 
1151  validateStateVecQureg(bra, __func__);
1152  validateStateVecQureg(ket, __func__);
1153  validateMatchingQuregDims(bra, ket, __func__);
1154 
1155  return statevec_calcInnerProduct(bra, ket);
1156 }
1157 
1159  validateDensityMatrQureg(rho1, __func__);
1160  validateDensityMatrQureg(rho2, __func__);
1161  validateMatchingQuregDims(rho1, rho2, __func__);
1162 
1163  return densmatr_calcInnerProduct(rho1, rho2);
1164 }
1165 
1166 qreal calcProbOfOutcome(Qureg qureg, int measureQubit, int outcome) {
1167  validateTarget(qureg, measureQubit, __func__);
1168  validateOutcome(outcome, __func__);
1169 
1170  if (qureg.isDensityMatrix)
1171  return densmatr_calcProbOfOutcome(qureg, measureQubit, outcome);
1172  else
1173  return statevec_calcProbOfOutcome(qureg, measureQubit, outcome);
1174 }
1175 
1176 void calcProbOfAllOutcomes(qreal* retProbs, Qureg qureg, int* qubits, int numQubits) {
1177  validateMultiTargets(qureg, qubits, numQubits, __func__);
1178 
1179  if (qureg.isDensityMatrix)
1180  densmatr_calcProbOfAllOutcomes(retProbs, qureg, qubits, numQubits);
1181  else
1182  statevec_calcProbOfAllOutcomes(retProbs, qureg, qubits, numQubits);
1183 }
1184 
1186  validateDensityMatrQureg(qureg, __func__);
1187 
1188  return densmatr_calcPurity(qureg);
1189 }
1190 
1191 qreal calcFidelity(Qureg qureg, Qureg pureState) {
1192  validateSecondQuregStateVec(pureState, __func__);
1193  validateMatchingQuregDims(qureg, pureState, __func__);
1194 
1195  if (qureg.isDensityMatrix)
1196  return densmatr_calcFidelity(qureg, pureState);
1197  else
1198  return statevec_calcFidelity(qureg, pureState);
1199 }
1200 
1201 qreal calcExpecPauliProd(Qureg qureg, int* targetQubits, enum pauliOpType* pauliCodes, int numTargets, Qureg workspace) {
1202  validateMultiTargets(qureg, targetQubits, numTargets, __func__);
1203  validatePauliCodes(pauliCodes, numTargets, __func__);
1204  validateMatchingQuregTypes(qureg, workspace, __func__);
1205  validateMatchingQuregDims(qureg, workspace, __func__);
1206 
1207  return statevec_calcExpecPauliProd(qureg, targetQubits, pauliCodes, numTargets, workspace);
1208 }
1209 
1210 qreal calcExpecPauliSum(Qureg qureg, enum pauliOpType* allPauliCodes, qreal* termCoeffs, int numSumTerms, Qureg workspace) {
1211  validateNumPauliSumTerms(numSumTerms, __func__);
1212  validatePauliCodes(allPauliCodes, numSumTerms*qureg.numQubitsRepresented, __func__);
1213  validateMatchingQuregTypes(qureg, workspace, __func__);
1214  validateMatchingQuregDims(qureg, workspace, __func__);
1215 
1216  return statevec_calcExpecPauliSum(qureg, allPauliCodes, termCoeffs, numSumTerms, workspace);
1217 }
1218 
1219 qreal calcExpecPauliHamil(Qureg qureg, PauliHamil hamil, Qureg workspace) {
1220  validateMatchingQuregTypes(qureg, workspace, __func__);
1221  validateMatchingQuregDims(qureg, workspace, __func__);
1222  validatePauliHamil(hamil, __func__);
1223  validateMatchingQuregPauliHamilDims(qureg, hamil, __func__);
1224 
1225  return statevec_calcExpecPauliSum(qureg, hamil.pauliCodes, hamil.termCoeffs, hamil.numSumTerms, workspace);
1226 }
1227 
1229  validateDiagonalOp(qureg, op, __func__);
1230 
1231  if (qureg.isDensityMatrix)
1232  return densmatr_calcExpecDiagonalOp(qureg, op);
1233  else
1234  return statevec_calcExpecDiagonalOp(qureg, op);
1235 }
1236 
1238  validateDensityMatrQureg(a, __func__);
1239  validateDensityMatrQureg(b, __func__);
1240  validateMatchingQuregDims(a, b, __func__);
1241 
1243 }
1244 
1245 
1246 /*
1247  * decoherence
1248  */
1249 
1250 void mixDephasing(Qureg qureg, int targetQubit, qreal prob) {
1251  validateDensityMatrQureg(qureg, __func__);
1252  validateTarget(qureg, targetQubit, __func__);
1253  validateOneQubitDephaseProb(prob, __func__);
1254 
1255  densmatr_mixDephasing(qureg, targetQubit, 2*prob);
1256  qasm_recordComment(qureg,
1257  "Here, a phase (Z) error occured on qubit %d with probability %g", targetQubit, prob);
1258 }
1259 
1260 void mixTwoQubitDephasing(Qureg qureg, int qubit1, int qubit2, qreal prob) {
1261  validateDensityMatrQureg(qureg, __func__);
1262  validateUniqueTargets(qureg, qubit1, qubit2, __func__);
1263  validateTwoQubitDephaseProb(prob, __func__);
1264 
1265  ensureIndsIncrease(&qubit1, &qubit2);
1266  densmatr_mixTwoQubitDephasing(qureg, qubit1, qubit2, (4*prob)/3.0);
1267  qasm_recordComment(qureg,
1268  "Here, a phase (Z) error occured on either or both of qubits "
1269  "%d and %d with total probability %g", qubit1, qubit2, prob);
1270 }
1271 
1272 void mixDepolarising(Qureg qureg, int targetQubit, qreal prob) {
1273  validateDensityMatrQureg(qureg, __func__);
1274  validateTarget(qureg, targetQubit, __func__);
1275  validateOneQubitDepolProb(prob, __func__);
1276 
1277  densmatr_mixDepolarising(qureg, targetQubit, (4*prob)/3.0);
1278  qasm_recordComment(qureg,
1279  "Here, a homogeneous depolarising error (X, Y, or Z) occured on "
1280  "qubit %d with total probability %g", targetQubit, prob);
1281 }
1282 
1283 void mixDamping(Qureg qureg, int targetQubit, qreal prob) {
1284  validateDensityMatrQureg(qureg, __func__);
1285  validateTarget(qureg, targetQubit, __func__);
1286  validateOneQubitDampingProb(prob, __func__);
1287 
1288  densmatr_mixDamping(qureg, targetQubit, prob);
1289 }
1290 
1291 void mixTwoQubitDepolarising(Qureg qureg, int qubit1, int qubit2, qreal prob) {
1292  validateDensityMatrQureg(qureg, __func__);
1293  validateUniqueTargets(qureg, qubit1, qubit2, __func__);
1294  validateTwoQubitDepolProb(prob, __func__);
1295 
1296  ensureIndsIncrease(&qubit1, &qubit2);
1297  densmatr_mixTwoQubitDepolarising(qureg, qubit1, qubit2, (16*prob)/15.0);
1298  qasm_recordComment(qureg,
1299  "Here, a homogeneous depolarising error occured on qubits %d and %d "
1300  "with total probability %g", qubit1, qubit2, prob);
1301 }
1302 
1303 void mixPauli(Qureg qureg, int qubit, qreal probX, qreal probY, qreal probZ) {
1304  validateDensityMatrQureg(qureg, __func__);
1305  validateTarget(qureg, qubit, __func__);
1306  validateOneQubitPauliProbs(probX, probY, probZ, __func__);
1307 
1308  densmatr_mixPauli(qureg, qubit, probX, probY, probZ);
1309  qasm_recordComment(qureg,
1310  "Here, X, Y and Z errors occured on qubit %d with probabilities "
1311  "%g, %g and %g respectively", qubit, probX, probY, probZ);
1312 }
1313 
1314 void mixKrausMap(Qureg qureg, int target, ComplexMatrix2 *ops, int numOps) {
1315  validateDensityMatrQureg(qureg, __func__);
1316  validateTarget(qureg, target, __func__);
1317  validateOneQubitKrausMap(qureg, ops, numOps, __func__);
1318 
1319  densmatr_mixKrausMap(qureg, target, ops, numOps);
1320  qasm_recordComment(qureg,
1321  "Here, an undisclosed Kraus map was effected on qubit %d", target);
1322 }
1323 
1324 void mixTwoQubitKrausMap(Qureg qureg, int target1, int target2, ComplexMatrix4 *ops, int numOps) {
1325  validateDensityMatrQureg(qureg, __func__);
1326  validateMultiTargets(qureg, (int[]) {target1,target2}, 2, __func__);
1327  validateTwoQubitKrausMap(qureg, ops, numOps, __func__);
1328 
1329  densmatr_mixTwoQubitKrausMap(qureg, target1, target2, ops, numOps);
1330  qasm_recordComment(qureg,
1331  "Here, an undisclosed two-qubit Kraus map was effected on qubits %d and %d", target1, target2);
1332 }
1333 
1334 void mixMultiQubitKrausMap(Qureg qureg, int* targets, int numTargets, ComplexMatrixN* ops, int numOps) {
1335  validateDensityMatrQureg(qureg, __func__);
1336  validateMultiTargets(qureg, targets, numTargets, __func__);
1337  validateMultiQubitKrausMap(qureg, numTargets, ops, numOps, __func__);
1338 
1339  densmatr_mixMultiQubitKrausMap(qureg, targets, numTargets, ops, numOps);
1340  qasm_recordComment(qureg,
1341  "Here, an undisclosed %d-qubit Kraus map was applied to undisclosed qubits", numTargets);
1342 }
1343 
1344 /*
1345  * other data structures
1346  */
1347 
1349  validateNumQubitsInMatrix(numQubits, __func__);
1350 
1351  int numRows = 1 << numQubits;
1352 
1353  ComplexMatrixN m = {
1354  .numQubits = numQubits,
1355  .real = malloc(numRows * sizeof *m.real),
1356  .imag = malloc(numRows * sizeof *m.imag)};
1357 
1358  for (int n=0; n < 1<<numQubits; n++) {
1359  m.real[n] = calloc(numRows, sizeof **m.real);
1360  m.imag[n] = calloc(numRows, sizeof **m.imag);
1361  }
1362 
1363  // error if the ComplexMatrixN was not successfully malloc'ds
1364  validateMatrixInit(m, __func__);
1365 
1366  return m;
1367  }
1368 
1370  /* this checks m.real/imag != NULL, which is only ever set when the mallocs
1371  * in createComplexMatrixN fail, which already prompts an error. Hence
1372  * this check if useless
1373  */
1374  validateMatrixInit(m, __func__);
1375 
1376  int numRows = 1 << m.numQubits;
1377  for (int r=0; r < numRows; r++) {
1378  free(m.real[r]);
1379  free(m.imag[r]);
1380  }
1381  free(m.real);
1382  free(m.imag);
1383 }
1384 
1385 #ifndef _WIN32
1387  validateMatrixInit(m, __func__);
1388 
1389  int dim = 1 << m.numQubits;
1390  for (int i=0; i<dim; i++)
1391  for (int j=0; j<dim; j++) {
1392  m.real[i][j] = re[i][j];
1393  m.imag[i][j] = im[i][j];
1394  }
1395 }
1396 #endif
1397 
1398 PauliHamil createPauliHamil(int numQubits, int numSumTerms) {
1399  validateHamilParams(numQubits, numSumTerms, __func__);
1400 
1401  PauliHamil h;
1402  h.numQubits = numQubits;
1403  h.numSumTerms = numSumTerms;
1404  h.termCoeffs = malloc(numSumTerms * sizeof *h.termCoeffs);
1405  h.pauliCodes = malloc(numQubits*numSumTerms * sizeof *h.pauliCodes);
1406 
1407  // initialise pauli codes to identity
1408  for (int i=0; i<numQubits*numSumTerms; i++)
1409  h.pauliCodes[i] = PAULI_I;
1410 
1411  return h;
1412 }
1413 
1415 
1416  free(h.termCoeffs);
1417  free(h.pauliCodes);
1418 }
1419 
1421 
1422  /* The validation in this function must close the file handle and free
1423  * allocated memory before raising an error (whether that's a C exit, or
1424  * an overriden C++ exception).
1425  */
1426 
1427  FILE* file = fopen(fn, "r");
1428  int success = (file != NULL);
1429  validateFileOpened(success, fn, __func__);
1430 
1431  /* file format: coeff {term} \n where {term} is #numQubits values of
1432  * 0 1 2 3 signifying I X Y Z acting on that qubit index
1433  */
1434 
1435  // count the number of qubits (ignore trailing whitespace)
1436  int numQubits = -1; // to exclude coeff at start
1437  char ch = getc(file);
1438  char prev = '0'; // anything not space
1439  while (ch != '\n' && ch != EOF) {
1440  if (ch == ' ' && prev != ' ') // skip multiple spaces
1441  numQubits++;
1442  prev = ch;
1443  ch = getc(file);
1444  }
1445  // edge-case: if we hit EOF/newline without a space
1446  if (prev != ' ')
1447  numQubits++;
1448 
1449  /* TODO:
1450  * The below code may break on Windows where newlines are multiple characters
1451  */
1452 
1453  // count the number of terms (being cautious of trailing newlines)
1454  int numTerms = 0;
1455  prev = '\n';
1456  rewind(file);
1457  while ((ch=getc(file)) != EOF) {
1458  if (ch == '\n' && prev != '\n')
1459  numTerms++;
1460  prev = ch;
1461  }
1462  // edge-case: if we hit EOF without a newline, count that line
1463  if (prev != '\n')
1464  numTerms++;
1465 
1466  // validate the inferred number of terms and qubits (closes file if error)
1467  validateHamilFileParams(numQubits, numTerms, file, fn, __func__);
1468 
1469  // allocate space for PauliHamil data
1470  PauliHamil h = createPauliHamil(numQubits, numTerms);
1471 
1472  // specifier for a qreal number then a space
1473  char strSpec[50];
1474  strcpy(strSpec, REAL_SPECIFIER);
1475  strcat(strSpec, " ");
1476 
1477  // collect coefficients and terms
1478  rewind(file);
1479  for (int t=0; t<numTerms; t++) {
1480 
1481  // record coefficient, and validate (closes file and frees h if error)
1482  success = fscanf(file, strSpec, &(h.termCoeffs[t])) == 1;
1483  validateHamilFileCoeffParsed(success, h, file, fn, __func__);
1484 
1485  // record Pauli operations, and validate (closes file and frees h if error)
1486  for (int q=0; q<numQubits; q++) {
1487  int i = t*numQubits + q;
1488 
1489  // verbose, to avoid type warnings
1490  int code;
1491  success = fscanf(file, "%d ", &code) == 1;
1492  h.pauliCodes[i] = (enum pauliOpType) code;
1493  validateHamilFilePauliParsed(success, h, file, fn, __func__);
1494  validateHamilFilePauliCode(h.pauliCodes[i], h, file, fn, __func__);
1495  }
1496 
1497  // the trailing newline is magically eaten
1498  }
1499 
1500  fclose(file);
1501  return h;
1502 }
1503 
1504 void initPauliHamil(PauliHamil hamil, qreal* coeffs, enum pauliOpType* codes) {
1505  validateHamilParams(hamil.numQubits, hamil.numSumTerms, __func__);
1506  validatePauliCodes(codes, hamil.numSumTerms*hamil.numQubits, __func__);
1507 
1508  int i=0;
1509  for (int t=0; t<hamil.numSumTerms; t++) {
1510  hamil.termCoeffs[t] = coeffs[t];
1511  for (int q=0; q<hamil.numQubits; q++) {
1512  hamil.pauliCodes[i] = codes[i];
1513  i++;
1514  }
1515  }
1516 }
1517 
1518 DiagonalOp createDiagonalOp(int numQubits, QuESTEnv env) {
1519  validateNumQubitsInDiagOp(numQubits, env.numRanks, __func__);
1520 
1521  return agnostic_createDiagonalOp(numQubits, env);
1522 }
1523 
1525  // env accepted for API consistency
1526  validateDiagOpInit(op, __func__);
1527 
1529 }
1530 
1532  validateDiagOpInit(op, __func__);
1533 
1535 }
1536 
1537 void initDiagonalOp(DiagonalOp op, qreal* real, qreal* imag) {
1538  validateDiagOpInit(op, __func__);
1539 
1540  agnostic_setDiagonalOpElems(op, 0, real, imag, 1LL << op.numQubits);
1541 }
1542 
1543 void setDiagonalOpElems(DiagonalOp op, long long int startInd, qreal* real, qreal* imag, long long int numElems) {
1544  validateDiagOpInit(op, __func__);
1545  validateNumElems(op, startInd, numElems, __func__);
1546 
1547  agnostic_setDiagonalOpElems(op, startInd, real, imag, numElems);
1548 }
1549 
1551  validateHamilParams(hamil.numQubits, hamil.numSumTerms, __func__);
1552  validateDiagOpInit(op, __func__);
1553  validateDiagPauliHamil(op, hamil, __func__);
1554 
1556 }
1557 
1559  PauliHamil h = createPauliHamilFromFile(fn); // validates fn
1560  validateDiagPauliHamilFromFile(h, env.numRanks, __func__); // destroys h if invalid
1561 
1564 
1565  destroyPauliHamil(h);
1566  return op;
1567 }
1568 
1569 /*
1570  * debug
1571  */
1572 
1573 int compareStates(Qureg qureg1, Qureg qureg2, qreal precision) {
1574  validateMatchingQuregDims(qureg1, qureg2, __func__);
1575  return statevec_compareStates(qureg1, qureg2, precision);
1576 }
1577 
1578 void initDebugState(Qureg qureg) {
1579  statevec_initDebugState(qureg);
1580 }
1581 
1582 void initStateFromSingleFile(Qureg *qureg, char filename[200], QuESTEnv env) {
1583  int success = statevec_initStateFromSingleFile(qureg, filename, env);
1584  validateFileOpened(success, filename, __func__);
1585 }
1586 
1587 void initStateOfSingleQubit(Qureg *qureg, int qubitId, int outcome) {
1588  validateStateVecQureg(*qureg, __func__);
1589  validateTarget(*qureg, qubitId, __func__);
1590  validateOutcome(outcome, __func__);
1591  statevec_initStateOfSingleQubit(qureg, qubitId, outcome);
1592 }
1593 
1594 void reportStateToScreen(Qureg qureg, QuESTEnv env, int reportRank) {
1595  statevec_reportStateToScreen(qureg, env, reportRank);
1596 }
1597 
1599  validatePauliHamil(hamil, __func__);
1600 
1601  for (int t=0; t<hamil.numSumTerms; t++) {
1602  printf(REAL_QASM_FORMAT, hamil.termCoeffs[t]);
1603  printf("\t");
1604  for (int q=0; q<hamil.numQubits; q++)
1605  printf("%d ", (int) hamil.pauliCodes[q+t*hamil.numQubits]);
1606  printf("\n");
1607  }
1608 }
1609 
1610 int getQuEST_PREC(void) {
1611  return sizeof(qreal)/4;
1612 }
1613 
1615 
1616  // seed Mersenne Twister random number generator with two keys -- time and pid
1617  unsigned long int keys[2];
1618  getQuESTDefaultSeedKey(keys);
1619  seedQuEST(env, keys, 2);
1620 }
1621 
1622 void getQuESTSeeds(QuESTEnv env, unsigned long int** seeds, int* numSeeds) {
1623  *seeds = env.seeds;
1624  *numSeeds = env.numSeeds;
1625 }
1626 
1627 
1628 #ifdef __cplusplus
1629 }
1630 #endif
void agnostic_destroyDiagonalOp(DiagonalOp op)
Definition: QuEST_cpu.c:1368
void densmatr_mixDepolarising(Qureg qureg, int targetQubit, qreal depolLevel)
void controlledRotateZ(Qureg qureg, int controlQubit, int targetQubit, qreal angle)
Applies a controlled rotation by a given angle around the Z-axis of the Bloch-sphere.
Definition: QuEST.c:244
void qasm_printRecorded(Qureg qureg)
Definition: QuEST_qasm.c:871
void statevec_phaseShift(Qureg qureg, int targetQubit, qreal angle)
Definition: QuEST_common.c:254
void mixDephasing(Qureg qureg, int targetQubit, qreal prob)
Mixes a density matrix qureg to induce single-qubit dephasing noise.
Definition: QuEST.c:1250
int compareStates(Qureg qureg1, Qureg qureg2, qreal precision)
Return whether two given wavefunctions are equivalent within a given precision Global phase included ...
Definition: QuEST.c:1573
qreal getProbAmp(Qureg qureg, long long int index)
Get the probability of a state-vector at an index in the full state vector.
Definition: QuEST.c:932
void validateDensityMatrQureg(Qureg qureg, const char *caller)
void initBlankState(Qureg qureg)
Initialises a qureg to have all-zero-amplitudes.
Definition: QuEST.c:119
Represents a 3-vector of real numbers.
Definition: QuEST.h:198
void validateMultiControlsTarget(Qureg qureg, int *controlQubits, int numControlQubits, int targetQubit, const char *caller)
void statevec_sGate(Qureg qureg, int targetQubit)
Definition: QuEST_common.c:268
void statevec_pauliZ(Qureg qureg, int targetQubit)
Definition: QuEST_common.c:261
pauliOpType
Codes for specifying Pauli operators.
Definition: QuEST.h:96
void statevec_rotateX(Qureg qureg, int rotQubit, qreal angle)
Definition: QuEST_common.c:296
void validateMeasurementProb(qreal prob, const char *caller)
void applyPhaseFunc(Qureg qureg, int *qubits, int numQubits, enum bitEncoding encoding, qreal *coeffs, qreal *exponents, int numTerms)
Induces a phase change upon each amplitude of qureg, determined by the passed exponential polynomial ...
Definition: QuEST.c:726
void validateTarget(Qureg qureg, int targetQubit, const char *caller)
void applyMultiControlledMatrixN(Qureg qureg, int *ctrls, int numCtrls, int *targs, int numTargs, ComplexMatrixN u)
Apply a general N-by-N matrix, which may be non-unitary, with additional controlled qubits.
Definition: QuEST.c:1114
void twoQubitUnitary(Qureg qureg, int targetQubit1, int targetQubit2, ComplexMatrix4 u)
Apply a general two-qubit unitary (including a global phase factor).
Definition: QuEST.c:256
void controlledRotateX(Qureg qureg, int controlQubit, int targetQubit, qreal angle)
Applies a controlled rotation by a given angle around the X-axis of the Bloch-sphere.
Definition: QuEST.c:220
void applyNamedPhaseFuncOverrides(Qureg qureg, int *qubits, int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, enum phaseFunc functionNameCode, long long int *overrideInds, qreal *overridePhases, int numOverrides)
Induces a phase change upon each amplitude of qureg, determined by a named (and potentially multi-var...
Definition: QuEST.c:813
void agnostic_applyQFT(Qureg qureg, int *qubits, int numQubits)
Definition: QuEST_common.c:849
void initPauliHamil(PauliHamil hamil, qreal *coeffs, enum pauliOpType *codes)
Initialise PauliHamil instance hamil with the given term coefficients and Pauli codes (one for every ...
Definition: QuEST.c:1504
void validateBitEncoding(int numQubits, enum bitEncoding encoding, const char *caller)
void validateOutcome(int outcome, const char *caller)
void validateMultiRegBitEncoding(int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, const char *caller)
void validateMultiVarPhaseFuncOverrides(int *numQubitsPerReg, const int numRegs, enum bitEncoding encoding, long long int *overrideInds, int numOverrides, const char *caller)
void densmatr_mixKrausMap(Qureg qureg, int target, ComplexMatrix2 *ops, int numOps)
Definition: QuEST_common.c:644
void initPureState(Qureg qureg, Qureg pure)
Initialise qureg into to a given pure state of an equivalent Hilbert dimension.
Definition: QuEST.c:145
void applyProjector(Qureg qureg, int qubit, int outcome)
Force the target qubit of qureg into the given classical outcome, via a non-renormalising projection.
Definition: QuEST.c:888
void rotateAroundAxis(Qureg qureg, int rotQubit, qreal angle, Vector axis)
Rotate a single qubit by a given angle around a given Vector on the Bloch-sphere.
Definition: QuEST.c:601
void mixDepolarising(Qureg qureg, int targetQubit, qreal prob)
Mixes a density matrix qureg to induce single-qubit homogeneous depolarising noise.
Definition: QuEST.c:1272
void validateHamilFileCoeffParsed(int parsed, PauliHamil h, FILE *file, char *fn, const char *caller)
void statevec_multiControlledMultiRotatePauli(Qureg qureg, long long int ctrlMask, int *targetQubits, enum pauliOpType *targetPaulis, int numTargets, qreal angle, int applyConj)
Definition: QuEST_common.c:453
void qasm_recordParamGate(Qureg qureg, TargetGate gate, int targetQubit, qreal param)
Definition: QuEST_qasm.c:187
void seedQuESTDefault(QuESTEnv *env)
Seeds the random number generator with the (master node) current time and process ID.
Definition: QuEST.c:1614
void validateStateIndex(Qureg qureg, long long int stateInd, const char *caller)
void densmatr_initPlusState(Qureg targetQureg)
Definition: QuEST_cpu.c:1165
qreal calcTotalProb(Qureg qureg)
A debugging function which calculates the probability of the qubits in qureg being in any state,...
Definition: QuEST.c:1143
void mixDamping(Qureg qureg, int targetQubit, qreal prob)
Mixes a density matrix qureg to induce single-qubit amplitude damping (decay to 0 state).
Definition: QuEST.c:1283
void destroyComplexMatrixN(ComplexMatrixN m)
Destroy a ComplexMatrixN instance created with createComplexMatrixN()
Definition: QuEST.c:1369
void shiftIndices(int *indices, int numIndices, int shift)
Definition: QuEST_common.c:156
void applyNamedPhaseFunc(Qureg qureg, int *qubits, int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, enum phaseFunc functionNameCode)
Induces a phase change upon each amplitude of qureg, determined by a named (and potentially multi-var...
Definition: QuEST.c:796
void calcProbOfAllOutcomes(qreal *retProbs, Qureg qureg, int *qubits, int numQubits)
Populates outcomeProbs with the probabilities of every outcome of the sub-register contained in qubit...
Definition: QuEST.c:1176
qreal densmatr_calcInnerProduct(Qureg a, Qureg b)
qreal statevec_calcExpecPauliProd(Qureg qureg, int *targetQubits, enum pauliOpType *pauliCodes, int numTargets, Qureg workspace)
Definition: QuEST_common.c:509
void reportPauliHamil(PauliHamil hamil)
Print the PauliHamil to screen.
Definition: QuEST.c:1598
void validateHamilParams(int numQubits, int numTerms, const char *caller)
void qasm_free(Qureg qureg)
Definition: QuEST_qasm.c:887
void statevec_controlledTwoQubitUnitary(Qureg qureg, int controlQubit, int targetQubit1, int targetQubit2, ComplexMatrix4 u)
Definition: QuEST_common.c:567
@ PAULI_I
Definition: QuEST.h:96
Complex getDensityAmp(Qureg qureg, long long int row, long long int col)
Get an amplitude from a density matrix at a given row and column.
Definition: QuEST.c:949
void multiControlledMultiQubitNot(Qureg qureg, int *ctrls, int numCtrls, int *targs, int numTargs)
Apply a NOT (or Pauli X) gate with multiple control and target qubits.
Definition: QuEST.c:549
@ GATE_T
Definition: QuEST_qasm.h:24
@ GATE_PHASE_SHIFT
Definition: QuEST_qasm.h:32
void qasm_recordUnitary(Qureg qureg, ComplexMatrix2 u, int targetQubit)
Definition: QuEST_qasm.c:208
DiagonalOp createDiagonalOpFromPauliHamilFile(char *fn, QuESTEnv env)
Creates and initialiases a diagonal operator from the Z Pauli Hamiltonian encoded in file with filena...
Definition: QuEST.c:1558
void validateStateVecQureg(Qureg qureg, const char *caller)
void qasm_recordInitZero(Qureg qureg)
Definition: QuEST_qasm.c:428
ComplexMatrixN createComplexMatrixN(int numQubits)
Allocate dynamic memory for a square complex matrix of any size, which can be passed to functions lik...
Definition: QuEST.c:1348
qreal statevec_calcExpecPauliSum(Qureg qureg, enum pauliOpType *allCodes, qreal *termCoeffs, int numSumTerms, Qureg workspace)
Definition: QuEST_common.c:524
void qasm_recordMultiControlledGate(Qureg qureg, TargetGate gate, int *controlQubits, int numControlQubits, int targetQubit)
Definition: QuEST_qasm.c:317
qreal getImagAmp(Qureg qureg, long long int index)
Get the imaginary component of the complex probability amplitude at an index in the state vector.
Definition: QuEST.c:925
void validateMultiQubitMatrixFitsInNode(Qureg qureg, int numTargets, const char *caller)
void controlledRotateAroundAxis(Qureg qureg, int controlQubit, int targetQubit, qreal angle, Vector axis)
Applies a controlled rotation by a given angle around a given vector on the Bloch-sphere.
Definition: QuEST.c:614
void mixKrausMap(Qureg qureg, int target, ComplexMatrix2 *ops, int numOps)
Apply a general single-qubit Kraus map to a density matrix, as specified by at most four Kraus operat...
Definition: QuEST.c:1314
void statevec_twoQubitUnitary(Qureg qureg, int targetQubit1, int targetQubit2, ComplexMatrix4 u)
Definition: QuEST_common.c:561
void statevec_tGateConj(Qureg qureg, int targetQubit)
Definition: QuEST_common.c:289
qreal densmatr_calcPurity(Qureg qureg)
Computes the trace of the density matrix squared.
void syncDiagonalOp(DiagonalOp op)
Update the GPU memory with the current values in op.real and op.imag.
Definition: QuEST.c:1531
void destroyDiagonalOp(DiagonalOp op, QuESTEnv env)
Destroys a DiagonalOp created with createDiagonalOp(), freeing its memory.
Definition: QuEST.c:1524
void multiControlledTwoQubitUnitary(Qureg qureg, int *controlQubits, int numControlQubits, int targetQubit1, int targetQubit2, ComplexMatrix4 u)
Apply a general multi-controlled two-qubit unitary (including a global phase factor).
Definition: QuEST.c:282
void validateNumAmps(Qureg qureg, long long int startInd, long long int numAmps, const char *caller)
void qasm_clearRecorded(Qureg qureg)
Definition: QuEST_qasm.c:864
void statevec_unitary(Qureg qureg, int targetQubit, ComplexMatrix2 u)
void qasm_recordInitPlus(Qureg qureg)
Definition: QuEST_qasm.c:443
qreal collapseToOutcome(Qureg qureg, int measureQubit, int outcome)
Updates qureg to be consistent with measuring measureQubit in the given outcome (0 or 1),...
Definition: QuEST.c:966
ComplexMatrix4 getConjugateMatrix4(ComplexMatrix4 src)
Definition: QuEST_common.c:110
@ GATE_ROTATE_X
Definition: QuEST_qasm.h:27
int numSeeds
Definition: QuEST.h:367
void validateNumQubitsInQureg(int numQubits, int numRanks, const char *caller)
void validateMultiQubitUnitaryMatrix(Qureg qureg, ComplexMatrixN u, int numTargs, const char *caller)
qreal calcPurity(Qureg qureg)
Calculates the purity of a density matrix, by the trace of the density matrix squared.
Definition: QuEST.c:1185
void statevec_multiControlledMultiQubitUnitary(Qureg qureg, long long int ctrlMask, int *targs, int numTargs, ComplexMatrixN u)
This calls swapQubitAmps only when it would involve a distributed communication; if the qubit chunks ...
void validateHamilFilePauliParsed(int parsed, PauliHamil h, FILE *file, char *fn, const char *caller)
void statevec_multiRotateZ(Qureg qureg, long long int mask, qreal angle)
Definition: QuEST_cpu.c:3316
qreal calcProbOfOutcome(Qureg qureg, int measureQubit, int outcome)
Gives the probability of a specified qubit being measured in the given outcome (0 or 1).
Definition: QuEST.c:1166
void getQuESTDefaultSeedKey(unsigned long int *key)
Definition: QuEST_common.c:195
void qasm_recordControlledCompactUnitary(Qureg qureg, Complex alpha, Complex beta, int controlQubit, int targetQubit)
Definition: QuEST_qasm.c:265
void agnostic_syncDiagonalOp(DiagonalOp op)
Definition: QuEST_cpu.c:1373
void statevec_destroyQureg(Qureg qureg, QuESTEnv env)
Definition: QuEST_cpu.c:1328
qreal statevec_calcProbOfOutcome(Qureg qureg, int measureQubit, int outcome)
void getQuESTSeeds(QuESTEnv env, unsigned long int **seeds, int *numSeeds)
Obtain the seeds presently used in random number generation.
Definition: QuEST.c:1622
void clearRecordedQASM(Qureg qureg)
Clear all QASM so far recorded.
Definition: QuEST.c:95
int measure(Qureg qureg, int measureQubit)
Measures a single qubit, collapsing it randomly to 0 or 1.
Definition: QuEST.c:998
@ GATE_ROTATE_Z
Definition: QuEST_qasm.h:29
qreal calcFidelity(Qureg qureg, Qureg pureState)
Calculates the fidelity of qureg (a state-vector or density matrix) against a reference pure state (n...
Definition: QuEST.c:1191
void validateHamilFilePauliCode(enum pauliOpType code, PauliHamil h, FILE *file, char *fn, const char *caller)
void unitary(Qureg qureg, int targetQubit, ComplexMatrix2 u)
Apply a general single-qubit unitary (including a global phase factor).
Definition: QuEST.c:348
void validateProb(qreal prob, const char *caller)
@ GATE_SIGMA_Z
Definition: QuEST_qasm.h:23
void statevec_controlledPauliY(Qureg qureg, int controlQubit, int targetQubit)
void validateMultiVarPhaseFuncTerms(int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, qreal *exponents, int *numTermsPerReg, const char *caller)
void mixTwoQubitDepolarising(Qureg qureg, int qubit1, int qubit2, qreal prob)
Mixes a density matrix qureg to induce two-qubit homogeneous depolarising noise.
Definition: QuEST.c:1291
void densmatr_mixMultiQubitKrausMap(Qureg qureg, int *targets, int numTargets, ComplexMatrixN *ops, int numOps)
Definition: QuEST_common.c:701
Complex getConjugateScalar(Complex scalar)
Definition: QuEST_common.c:91
void statevec_controlledPhaseShift(Qureg qureg, int idQubit1, int idQubit2, qreal angle)
Definition: QuEST_cpu.c:3226
Complex calcExpecDiagonalOp(Qureg qureg, DiagonalOp op)
Computes the expected value of the diagonal operator op for state qureg.
Definition: QuEST.c:1228
@ GATE_HADAMARD
Definition: QuEST_qasm.h:26
ComplexMatrix2 getConjugateMatrix2(ComplexMatrix2 src)
Definition: QuEST_common.c:105
void statevec_initStateOfSingleQubit(Qureg *qureg, int qubitId, int outcome)
Initialise the state vector of probability amplitudes such that one qubit is set to 'outcome' and all...
Definition: QuEST_cpu.c:1611
void sGate(Qureg qureg, int targetQubit)
Apply the single-qubit S gate.
Definition: QuEST.c:465
void qasm_startRecording(Qureg qureg)
Definition: QuEST_qasm.c:85
void cloneQureg(Qureg targetQureg, Qureg copyQureg)
Overwrite the amplitudes of targetQureg with those from copyQureg.
Definition: QuEST.c:164
void validatePhaseFuncOverrides(const int numQubits, enum bitEncoding encoding, long long int *overrideInds, int numOverrides, const char *caller)
Represents a 4x4 matrix of complex numbers.
Definition: QuEST.h:175
void rotateY(Qureg qureg, int targetQubit, qreal angle)
Rotate a single qubit by a given angle around the Y-axis of the Bloch-sphere.
Definition: QuEST.c:198
void densmatr_initClassicalState(Qureg qureg, long long int stateInd)
Definition: QuEST_cpu.c:1126
void applyPauliHamil(Qureg inQureg, PauliHamil hamil, Qureg outQureg)
Modifies outQureg to be the result of applying PauliHamil (a Hermitian but not necessarily unitary op...
Definition: QuEST.c:1059
Information about the environment the program is running in.
Definition: QuEST.h:362
void setDensityAmps(Qureg qureg, qreal *reals, qreal *imags)
Set elements in the underlying state vector represenation of a density matrix.
Definition: QuEST.c:1030
void applyQFT(Qureg qureg, int *qubits, int numQubits)
Applies the quantum Fourier transform (QFT) to a specific subset of qubits of the register qureg.
Definition: QuEST.c:866
PauliHamil createPauliHamilFromFile(char *fn)
Creates a PauliHamil instance, a real-weighted sum of products of Pauli operators,...
Definition: QuEST.c:1420
void applyPhaseFuncOverrides(Qureg qureg, int *qubits, int numQubits, enum bitEncoding encoding, qreal *coeffs, qreal *exponents, int numTerms, long long int *overrideInds, qreal *overridePhases, int numOverrides)
Induces a phase change upon each amplitude of qureg, determined by the passed exponential polynomial ...
Definition: QuEST.c:743
void multiControlledPhaseShift(Qureg qureg, int *controlQubits, int numControlQubits, qreal angle)
Introduce a phase factor on state of the passed qubits.
Definition: QuEST.c:510
void setDiagonalOpElems(DiagonalOp op, long long int startInd, qreal *real, qreal *imag, long long int numElems)
Modifies a subset (starting at index startInd, and ending at index startInd + numElems) of the elemen...
Definition: QuEST.c:1543
void statevec_multiControlledPhaseShift(Qureg qureg, int *controlQubits, int numControlQubits, qreal angle)
Definition: QuEST_cpu.c:3266
void statevec_pauliY(Qureg qureg, int targetQubit)
Represents a general 2^N by 2^N matrix of complex numbers.
Definition: QuEST.h:186
void qasm_recordMultiControlledMultiQubitNot(Qureg qureg, int *ctrls, int numCtrls, int *targs, int numTargs)
Definition: QuEST_qasm.c:382
void validateTwoQubitDepolProb(qreal prob, const char *caller)
void statevec_controlledMultiQubitUnitary(Qureg qureg, int ctrl, int *targets, int numTargets, ComplexMatrixN u)
Definition: QuEST_common.c:579
void validateNumPauliSumTerms(int numTerms, const char *caller)
qreal statevec_calcFidelity(Qureg qureg, Qureg pureState)
Definition: QuEST_common.c:380
#define qreal
void validateMatrixInit(ComplexMatrixN matr, const char *caller)
void multiRotatePauli(Qureg qureg, int *targetQubits, enum pauliOpType *targetPaulis, int numTargets, qreal angle)
Apply a multi-qubit multi-Pauli rotation, also known as a Pauli gadget, on a selected number of qubit...
Definition: QuEST.c:685
void validateFileOpened(int opened, char *fn, const char *caller)
void qasm_recordMultiStateControlledUnitary(Qureg qureg, ComplexMatrix2 u, int *controlQubits, int *controlState, int numControlQubits, int targetQubit)
Definition: QuEST_qasm.c:363
void stopRecordingQASM(Qureg qureg)
Disable QASM recording.
Definition: QuEST.c:91
void setAmps(Qureg qureg, long long int startInd, qreal *reals, qreal *imags, long long int numAmps)
Overwrites a subset of the amplitudes in state-vector qureg, with those passed in reals and imags.
Definition: QuEST.c:1021
void multiControlledPhaseFlip(Qureg qureg, int *controlQubits, int numControlQubits)
Apply the multiple-qubit controlled phase flip gate, also known as the multiple-qubit controlled paul...
Definition: QuEST.c:587
void multiQubitUnitary(Qureg qureg, int *targs, int numTargs, ComplexMatrixN u)
Apply a general multi-qubit unitary (including a global phase factor) with any number of target qubit...
Definition: QuEST.c:296
void statevec_sqrtSwapGate(Qureg qureg, int qb1, int qb2)
Definition: QuEST_common.c:387
void multiControlledMultiRotateZ(Qureg qureg, int *controlQubits, int numControls, int *targetQubits, int numTargets, qreal angle)
Apply a multi-controlled multi-target Z rotation, also known as a controlled phase gadget.
Definition: QuEST.c:668
Complex getAmp(Qureg qureg, long long int index)
Get the complex amplitude at a given index in the state vector.
Definition: QuEST.c:939
qreal statevec_getProbAmp(Qureg qureg, long long int index)
Definition: QuEST_common.c:248
void controlledPauliY(Qureg qureg, int controlQubit, int targetQubit)
Apply the controlled pauliY (single control, single target) gate, also known as the c-Y and c-sigma-Y...
Definition: QuEST.c:563
DiagonalOp agnostic_createDiagonalOp(int numQubits, QuESTEnv env)
Definition: QuEST_cpu.c:1346
void initComplexMatrixN(ComplexMatrixN m, qreal re[][1<< m.numQubits], qreal im[][1<< m.numQubits])
Initialises a ComplexMatrixN instance to have the passed real and imag values.
Definition: QuEST.c:1386
void statevec_swapQubitAmps(Qureg qureg, int qb1, int qb2)
void statevec_controlledPauliYConj(Qureg qureg, int controlQubit, int targetQubit)
int measureWithStats(Qureg qureg, int measureQubit, qreal *outcomeProb)
Measures a single qubit, collapsing it randomly to 0 or 1, and additionally gives the probability of ...
Definition: QuEST.c:985
int numQubitsInStateVec
Number of qubits in the state-vector - this is double the number represented for mixed states.
Definition: QuEST.h:329
qreal calcExpecPauliHamil(Qureg qureg, PauliHamil hamil, Qureg workspace)
Computes the expected value of qureg under Hermitian operator hamil.
Definition: QuEST.c:1219
void validateVector(Vector vec, const char *caller)
void multiControlledMultiQubitUnitary(Qureg qureg, int *ctrls, int numCtrls, int *targs, int numTargs, ComplexMatrixN u)
Apply a general multi-controlled multi-qubit unitary (including a global phase factor).
Definition: QuEST.c:330
qreal densmatr_calcTotalProb(Qureg qureg)
void rotateX(Qureg qureg, int targetQubit, qreal angle)
Rotate a single qubit by a given angle around the X-axis of the Bloch-sphere.
Definition: QuEST.c:187
void statevec_multiControlledMultiQubitNot(Qureg qureg, int ctrlMask, int targMask)
void validateMultiQubits(Qureg qureg, int *qubits, int numQubits, const char *caller)
void densmatr_collapseToKnownProbOutcome(Qureg qureg, int measureQubit, int outcome, qreal outcomeProb)
Renorms (/prob) every | * outcome * >< * outcome * | state, setting all others to zero.
Definition: QuEST_cpu.c:791
void statevec_controlledUnitary(Qureg qureg, int controlQubit, int targetQubit, ComplexMatrix2 u)
Complex statevec_calcExpecDiagonalOp(Qureg qureg, DiagonalOp op)
void setWeightedQureg(Complex fac1, Qureg qureg1, Complex fac2, Qureg qureg2, Complex facOut, Qureg out)
Modifies qureg out to the result of (facOut out + fac1 qureg1 + fac2 qureg2), imposing no constraints...
Definition: QuEST.c:1037
void qasm_recordControlledGate(Qureg qureg, TargetGate gate, int controlQubit, int targetQubit)
Definition: QuEST_qasm.c:239
void multiControlledMultiRotatePauli(Qureg qureg, int *controlQubits, int numControls, int *targetQubits, enum pauliOpType *targetPaulis, int numTargets, qreal angle)
Apply a multi-controlled multi-target multi-Pauli rotation, also known as a controlled Pauli gadget.
Definition: QuEST.c:705
qreal calcHilbertSchmidtDistance(Qureg a, Qureg b)
Computes the Hilbert Schmidt distance between two density matrices a and b, defined as the Frobenius ...
Definition: QuEST.c:1237
void validateControlTarget(Qureg qureg, int controlQubit, int targetQubit, const char *caller)
void qasm_recordAxisRotation(Qureg qureg, qreal angle, Vector axis, int targetQubit)
Definition: QuEST_qasm.c:224
void validateDiagonalOp(Qureg qureg, DiagonalOp op, const char *caller)
void densmatr_mixDensityMatrix(Qureg combineQureg, qreal otherProb, Qureg otherQureg)
Definition: QuEST_cpu.c:901
void statevec_applyParamNamedPhaseFuncOverrides(Qureg qureg, int *qubits, int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, enum phaseFunc functionNameCode, qreal *params, int numParams, long long int *overrideInds, qreal *overridePhases, int numOverrides, int conj)
Definition: QuEST_cpu.c:4446
@ GATE_SQRT_SWAP
Definition: QuEST_qasm.h:34
void statevec_multiControlledMultiRotateZ(Qureg qureg, long long int ctrlMask, long long int targMask, qreal angle)
Definition: QuEST_cpu.c:3358
void pauliZ(Qureg qureg, int targetQubit)
Apply the single-qubit Pauli-Z (also known as the Z, sigma-Z or phase-flip) gate.
Definition: QuEST.c:454
phaseFunc
Flags for specifying named phase functions.
Definition: QuEST.h:231
void statevec_calcProbOfAllOutcomes(qreal *retProbs, Qureg qureg, int *qubits, int numQubits)
@ GATE_SIGMA_X
Definition: QuEST_qasm.h:21
void qasm_recordMeasurement(Qureg qureg, int measureQubit)
Definition: QuEST_qasm.c:411
void qasm_stopRecording(Qureg qureg)
Definition: QuEST_qasm.c:89
void statevec_initZeroState(Qureg qureg)
Definition: QuEST_cpu.c:1494
void applyDiagonalOp(Qureg qureg, DiagonalOp op)
Apply a diagonal operator, which is possibly non-unitary and non-Hermitian, to the entire qureg.
Definition: QuEST.c:1127
qreal * termCoeffs
The real coefficient of each Pauli product. This is an array of length PauliHamil....
Definition: QuEST.h:283
void applyMatrix4(Qureg qureg, int targetQubit1, int targetQubit2, ComplexMatrix4 u)
Apply a general 4-by-4 matrix, which may be non-unitary.
Definition: QuEST.c:1093
void initStateOfSingleQubit(Qureg *qureg, int qubitId, int outcome)
Initialise the state vector of probability amplitudes such that one qubit is set to 'outcome' and all...
Definition: QuEST.c:1587
void agnostic_applyTrotterCircuit(Qureg qureg, PauliHamil hamil, qreal time, int order, int reps)
Definition: QuEST_common.c:840
void densmatr_mixDephasing(Qureg qureg, int targetQubit, qreal dephase)
Definition: QuEST_cpu.c:85
void validateOneQubitDephaseProb(qreal prob, const char *caller)
void densmatr_calcProbOfAllOutcomes(qreal *retProbs, Qureg qureg, int *qubits, int numQubits)
void swapGate(Qureg qureg, int qb1, int qb2)
Performs a SWAP gate between qubit1 and qubit2.
Definition: QuEST.c:627
void statevec_applyPhaseFuncOverrides(Qureg qureg, int *qubits, int numQubits, enum bitEncoding encoding, qreal *coeffs, qreal *exponents, int numTerms, long long int *overrideInds, qreal *overridePhases, int numOverrides, int conj)
Definition: QuEST_cpu.c:4268
enum pauliOpType * pauliCodes
The Pauli operators acting on each qubit, flattened over every operator.
Definition: QuEST.h:281
void statevec_tGate(Qureg qureg, int targetQubit)
Definition: QuEST_common.c:275
void statevec_initBlankState(Qureg qureg)
Definition: QuEST_cpu.c:1464
void initStateFromAmps(Qureg qureg, qreal *reals, qreal *imags)
Initialise qureg by specifying all amplitudes.
Definition: QuEST.c:157
void statevec_reportStateToScreen(Qureg qureg, QuESTEnv env, int reportRank)
Print the current state vector of probability amplitudes for a set of qubits to standard out.
Definition: QuEST_cpu.c:1439
void validateControlState(int *controlState, int numControlQubits, const char *caller)
void statevec_applyDiagonalOp(Qureg qureg, DiagonalOp op)
Definition: QuEST_cpu.c:4047
void validateMultiTargets(Qureg qureg, int *targetQubits, int numTargetQubits, const char *caller)
void qasm_recordInitClassical(Qureg qureg, long long int stateInd)
Definition: QuEST_qasm.c:471
void statevec_setAmps(Qureg qureg, long long int startInd, qreal *reals, qreal *imags, long long int numAmps)
Definition: QuEST_cpu.c:1248
int qasm_writeRecordedToFile(Qureg qureg, char *filename)
returns success of file write
Definition: QuEST_qasm.c:876
void qasm_recordControlledParamGate(Qureg qureg, TargetGate gate, int controlQubit, int targetQubit, qreal param)
Definition: QuEST_qasm.c:248
void statevec_cloneQureg(Qureg targetQureg, Qureg copyQureg)
works for both statevectors and density matrices
Definition: QuEST_cpu.c:1572
void statevec_rotateAroundAxis(Qureg qureg, int rotQubit, qreal angle, Vector axis)
Definition: QuEST_common.c:314
void writeRecordedQASMToFile(Qureg qureg, char *filename)
Writes recorded QASM to a file, throwing an error if inaccessible.
Definition: QuEST.c:103
int numRanks
Definition: QuEST.h:365
void densmatr_mixTwoQubitDephasing(Qureg qureg, int qubit1, int qubit2, qreal dephase)
Definition: QuEST_cpu.c:90
void setConjugateMatrixN(ComplexMatrixN m)
Definition: QuEST_common.c:115
void validateMatchingQuregDims(Qureg qureg1, Qureg qureg2, const char *caller)
qreal getRealAmp(Qureg qureg, long long int index)
Get the real component of the complex probability amplitude at an index in the state vector.
Definition: QuEST.c:918
void controlledPhaseFlip(Qureg qureg, int idQubit1, int idQubit2)
Apply the (two-qubit) controlled phase flip gate, also known as the controlled pauliZ gate.
Definition: QuEST.c:575
void densmatr_mixTwoQubitKrausMap(Qureg qureg, int target1, int target2, ComplexMatrix4 *ops, int numOps)
Definition: QuEST_common.c:682
void statevec_multiControlledTwoQubitUnitary(Qureg qureg, long long int ctrlMask, int targetQubit1, int targetQubit2, ComplexMatrix4 u)
This calls swapQubitAmps only when it would involve a distributed communication; if the qubit chunks ...
void statevec_initPlusState(Qureg qureg)
Definition: QuEST_cpu.c:1504
void qasm_recordControlledAxisRotation(Qureg qureg, qreal angle, Vector axis, int controlQubit, int targetQubit)
Definition: QuEST_qasm.c:301
int numQubits
The number of qubits this operator can act on (informing its size)
Definition: QuEST.h:300
int numSumTerms
The number of terms in the weighted sum, or the number of Pauli products.
Definition: QuEST.h:285
long long int getQubitBitMask(int *qubits, int numQubits)
Definition: QuEST_common.c:50
void statevec_compactUnitary(Qureg qureg, int targetQubit, Complex alpha, Complex beta)
Represents a diagonal complex operator on the full Hilbert state of a Qureg.
Definition: QuEST.h:297
A Pauli Hamiltonian, expressed as a real-weighted sum of pauli products, and which can hence represen...
Definition: QuEST.h:277
int getNumQubits(Qureg qureg)
Returns the number of qubits represented by qureg.
Definition: QuEST.c:908
void validateNumElems(DiagonalOp op, long long int startInd, long long int numElems, const char *caller)
void densmatr_mixDamping(Qureg qureg, int targetQubit, qreal damping)
Complex calcInnerProduct(Qureg bra, Qureg ket)
Computes the inner product of two equal-size state vectors, given by.
Definition: QuEST.c:1150
void statevec_multiRotatePauli(Qureg qureg, int *targetQubits, enum pauliOpType *targetPaulis, int numTargets, qreal angle, int applyConj)
applyConj=1 will apply conjugate operation, else applyConj=0
Definition: QuEST_common.c:414
void statevec_multiControlledPhaseFlip(Qureg qureg, int *controlQubits, int numControlQubits)
Definition: QuEST_cpu.c:3718
void destroyQureg(Qureg qureg, QuESTEnv env)
Deallocate a Qureg, freeing its memory.
Definition: QuEST.c:77
void validateOneQubitKrausMap(Qureg qureg, ComplexMatrix2 *ops, int numOps, const char *caller)
void applyParamNamedPhaseFuncOverrides(Qureg qureg, int *qubits, int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, enum phaseFunc functionNameCode, qreal *params, int numParams, long long int *overrideInds, qreal *overridePhases, int numOverrides)
Induces a phase change upon each amplitude of qureg, determined by a named, parameterised (and potent...
Definition: QuEST.c:848
void qasm_recordComment(Qureg qureg, char *comment,...)
Definition: QuEST_qasm.c:121
Complex densmatr_calcExpecDiagonalOp(Qureg qureg, DiagonalOp op)
void controlledMultiQubitUnitary(Qureg qureg, int ctrl, int *targs, int numTargs, ComplexMatrixN u)
Apply a general controlled multi-qubit unitary (including a global phase factor).
Definition: QuEST.c:313
void densmatr_mixTwoQubitDepolarising(Qureg qureg, int qubit1, int qubit2, qreal depolLevel)
void statevec_multiQubitUnitary(Qureg qureg, int *targets, int numTargets, ComplexMatrixN u)
Definition: QuEST_common.c:573
void multiQubitNot(Qureg qureg, int *targs, int numTargs)
Apply a NOT (or Pauli X) gate with multiple target qubits, which has the same effect as (but is much ...
Definition: QuEST.c:536
void mixTwoQubitKrausMap(Qureg qureg, int target1, int target2, ComplexMatrix4 *ops, int numOps)
Apply a general two-qubit Kraus map to a density matrix, as specified by at most sixteen Kraus operat...
Definition: QuEST.c:1324
qreal ** real
Definition: QuEST.h:189
void validateQubitSubregs(Qureg qureg, int *qubits, int *numQubitsPerReg, const int numRegs, const char *caller)
void initDebugState(Qureg qureg)
Initialises qureg to be in the un-normalised, non-physical state with with -th complex amplitude give...
Definition: QuEST.c:1578
void initStateFromSingleFile(Qureg *qureg, char filename[200], QuESTEnv env)
Initialises the wavefunction amplitudes according to those specified in a file.
Definition: QuEST.c:1582
void statevec_controlledRotateAroundAxis(Qureg qureg, int controlQubit, int targetQubit, qreal angle, Vector axis)
Definition: QuEST_common.c:330
void startRecordingQASM(Qureg qureg)
Enable QASM recording.
Definition: QuEST.c:87
void statevec_applyPauliSum(Qureg inQureg, enum pauliOpType *allCodes, qreal *termCoeffs, int numSumTerms, Qureg outQureg)
Definition: QuEST_common.c:538
void applyPauliSum(Qureg inQureg, enum pauliOpType *allPauliCodes, qreal *termCoeffs, int numSumTerms, Qureg outQureg)
Modifies outQureg to be the result of applying the weighted sum of Pauli products (a Hermitian but no...
Definition: QuEST.c:1048
void validateDiagPauliHamil(DiagonalOp op, PauliHamil hamil, const char *caller)
void applyMatrixN(Qureg qureg, int *targs, int numTargs, ComplexMatrixN u)
Apply a general N-by-N matrix, which may be non-unitary, on any number of target qubits.
Definition: QuEST.c:1103
Complex statevec_calcInnerProduct(Qureg bra, Qureg ket)
Terrible code which unnecessarily individually computes and sums the real and imaginary components of...
void statevec_rotateAroundAxisConj(Qureg qureg, int rotQubit, qreal angle, Vector axis)
Definition: QuEST_common.c:321
void statevec_sGateConj(Qureg qureg, int targetQubit)
Definition: QuEST_common.c:282
unsigned long int * seeds
Definition: QuEST.h:366
void applyMultiVarPhaseFunc(Qureg qureg, int *qubits, int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, qreal *coeffs, qreal *exponents, int *numTermsPerReg)
Induces a phase change upon each amplitude of qureg, determined by a multi-variable exponential polyn...
Definition: QuEST.c:761
void compactUnitary(Qureg qureg, int targetQubit, Complex alpha, Complex beta)
Apply a single-qubit unitary parameterised by two given complex scalars.
Definition: QuEST.c:404
void initClassicalState(Qureg qureg, long long int stateInd)
Initialise qureg into the classical state (also known as a "computational basis state") with index st...
Definition: QuEST.c:134
void validateOneQubitDepolProb(qreal prob, const char *caller)
int getQuEST_PREC(void)
Definition: QuEST.c:1610
void statevec_setWeightedQureg(Complex fac1, Qureg qureg1, Complex fac2, Qureg qureg2, Complex facOut, Qureg out)
Definition: QuEST_cpu.c:4005
void statevec_collapseToKnownProbOutcome(Qureg qureg, int measureQubit, int outcome, qreal outcomeProb)
void validateTwoQubitKrausMap(Qureg qureg, ComplexMatrix4 *ops, int numOps, const char *caller)
void pauliY(Qureg qureg, int targetQubit)
Apply the single-qubit Pauli-Y (also known as the Y or sigma-Y) gate.
Definition: QuEST.c:443
void shiftSubregIndices(int *allInds, int *numIndsPerReg, int numRegs, int shift)
Definition: QuEST_common.c:161
long long int getControlFlipMask(int *controlQubits, int *controlState, int numControlQubits)
Definition: QuEST_common.c:60
void qasm_recordMultiControlledUnitary(Qureg qureg, ComplexMatrix2 u, int *controlQubits, int numControlQubits, int targetQubit)
additionally performs Rz on target to restore the global phase lost from u in QASM U(a,...
Definition: QuEST_qasm.c:342
qreal statevec_getImagAmp(Qureg qureg, long long int index)
Represents a system of qubits.
Definition: QuEST.h:322
void qasm_recordMultiControlledParamGate(Qureg qureg, TargetGate gate, int *controlQubits, int numControlQubits, int targetQubit, qreal param)
Definition: QuEST_qasm.c:325
void controlledPhaseShift(Qureg qureg, int idQubit1, int idQubit2, qreal angle)
Introduce a phase factor on state of qubits idQubit1 and idQubit2.
Definition: QuEST.c:498
void mixTwoQubitDephasing(Qureg qureg, int qubit1, int qubit2, qreal prob)
Mixes a density matrix qureg to induce two-qubit dephasing noise.
Definition: QuEST.c:1260
void controlledUnitary(Qureg qureg, int controlQubit, int targetQubit, ComplexMatrix2 u)
Apply a general controlled unitary (single control, single target), which can include a global phase ...
Definition: QuEST.c:360
int statevec_measureWithStats(Qureg qureg, int measureQubit, qreal *outcomeProb)
Definition: QuEST_common.c:364
void validateDiagPauliHamilFromFile(PauliHamil hamil, int numRanks, const char *caller)
void validateNumQubitsInMatrix(int numQubits, const char *caller)
void statevec_initDebugState(Qureg qureg)
Initialise the state vector of probability amplitudes to an (unphysical) state with each component of...
Definition: QuEST_cpu.c:1657
qreal ** imag
Definition: QuEST.h:190
void validatePhaseFuncName(enum phaseFunc funcCode, int numRegs, int numParams, const char *caller)
void initDiagonalOp(DiagonalOp op, qreal *real, qreal *imag)
Overwrites the entire DiagonalOp op with the given real and imag complex elements.
Definition: QuEST.c:1537
void statevec_controlledNot(Qureg qureg, int controlQubit, int targetQubit)
void agnostic_initDiagonalOpFromPauliHamil(DiagonalOp op, PauliHamil hamil)
Definition: QuEST_cpu.c:1377
void phaseShift(Qureg qureg, int targetQubit, qreal angle)
Shift the phase between and of a single qubit by a given angle.
Definition: QuEST.c:487
void validatePauliHamil(PauliHamil hamil, const char *caller)
void validateTwoQubitUnitaryMatrix(Qureg qureg, ComplexMatrix4 u, const char *caller)
void statevec_controlledRotateX(Qureg qureg, int controlQubit, int targetQubit, qreal angle)
Definition: QuEST_common.c:346
void validateDiagOpInit(DiagonalOp op, const char *caller)
void controlledNot(Qureg qureg, int controlQubit, int targetQubit)
Apply the controlled not (single control, single target) gate, also known as the c-X,...
Definition: QuEST.c:524
long long int getNumAmps(Qureg qureg)
Returns the number of complex amplitudes in a state-vector qureg.
Definition: QuEST.c:912
qreal densmatr_calcFidelity(Qureg qureg, Qureg pureState)
void applyMultiVarPhaseFuncOverrides(Qureg qureg, int *qubits, int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, qreal *coeffs, qreal *exponents, int *numTermsPerReg, long long int *overrideInds, qreal *overridePhases, int numOverrides)
Induces a phase change upon each amplitude of qureg, determined by a multi-variable exponential polyn...
Definition: QuEST.c:778
void initDiagonalOpFromPauliHamil(DiagonalOp op, PauliHamil hamil)
Populates the diagonal operator op to be equivalent to the given Pauli Hamiltonian hamil,...
Definition: QuEST.c:1550
void statevec_initClassicalState(Qureg qureg, long long int stateInd)
Definition: QuEST_cpu.c:1536
void validateMatchingQuregPauliHamilDims(Qureg qureg, PauliHamil hamil, const char *caller)
int isDensityMatrix
Whether this instance is a density-state representation.
Definition: QuEST.h:325
void statevec_hadamard(Qureg qureg, int targetQubit)
void statevec_rotateY(Qureg qureg, int rotQubit, qreal angle)
Definition: QuEST_common.c:302
void validateMatchingQuregTypes(Qureg qureg1, Qureg qureg2, const char *caller)
int numQubits
Definition: QuEST.h:188
void validateAmpIndex(Qureg qureg, long long int ampInd, const char *caller)
void pauliX(Qureg qureg, int targetQubit)
Apply the single-qubit Pauli-X (also known as the X, sigma-X, NOT or bit-flip) gate.
Definition: QuEST.c:432
Qureg createCloneQureg(Qureg qureg, QuESTEnv env)
Create a new Qureg which is an exact clone of the passed qureg, which can be either a state-vector or...
Definition: QuEST.c:64
void statevec_multiControlledUnitary(Qureg qureg, long long int ctrlQubitsMask, long long int ctrlFlipMask, int targetQubit, ComplexMatrix2 u)
qreal calcExpecPauliSum(Qureg qureg, enum pauliOpType *allPauliCodes, qreal *termCoeffs, int numSumTerms, Qureg workspace)
Computes the expected value of a sum of products of Pauli operators.
Definition: QuEST.c:1210
int statevec_initStateFromSingleFile(Qureg *qureg, char filename[200], QuESTEnv env)
Definition: QuEST_cpu.c:1691
void validateHamilFileParams(int numQubits, int numTerms, FILE *file, char *fn, const char *caller)
void validateOneQubitUnitaryMatrix(ComplexMatrix2 u, const char *caller)
void controlledTwoQubitUnitary(Qureg qureg, int controlQubit, int targetQubit1, int targetQubit2, ComplexMatrix4 u)
Apply a general controlled two-qubit unitary (including a global phase factor).
Definition: QuEST.c:269
void applyFullQFT(Qureg qureg)
Applies the quantum Fourier transform (QFT) to the entirety of qureg.
Definition: QuEST.c:876
void validateSecondQuregStateVec(Qureg qureg2, const char *caller)
int numQubits
The number of qubits informing the Hilbert dimension of the Hamiltonian.
Definition: QuEST.h:287
void statevec_sqrtSwapGateConj(Qureg qureg, int qb1, int qb2)
Definition: QuEST_common.c:400
void statevec_controlledRotateZ(Qureg qureg, int controlQubit, int targetQubit, qreal angle)
Definition: QuEST_common.c:358
int numQubitsRepresented
The number of qubits represented in either the state-vector or density matrix.
Definition: QuEST.h:327
void statevec_pauliX(Qureg qureg, int targetQubit)
long long int numAmpsTotal
Total number of amplitudes, which are possibly distributed among machines.
Definition: QuEST.h:334
void validateMultiControlsMultiTargets(Qureg qureg, int *controlQubits, int numControlQubits, int *targetQubits, int numTargetQubits, const char *caller)
@ GATE_S
Definition: QuEST_qasm.h:25
@ GATE_SWAP
Definition: QuEST_qasm.h:33
qreal real
Definition: QuEST.h:105
void validatePhaseFuncTerms(int numQubits, enum bitEncoding encoding, qreal *coeffs, qreal *exponents, int numTerms, long long int *overrideInds, int numOverrides, const char *caller)
void mixDensityMatrix(Qureg combineQureg, qreal otherProb, Qureg otherQureg)
Modifies combineQureg to become (1-prob)combineProb + prob otherQureg.
Definition: QuEST.c:1012
Qureg createQureg(int numQubits, QuESTEnv env)
Creates a state-vector Qureg object representing a set of qubits which will remain in a pure state.
Definition: QuEST.c:36
void destroyPauliHamil(PauliHamil h)
Destroy a PauliHamil instance, created with either createPauliHamil() or createPauliHamilFromFile().
Definition: QuEST.c:1414
void densmatr_mixPauli(Qureg qureg, int qubit, qreal probX, qreal probY, qreal probZ)
Definition: QuEST_common.c:743
void tGate(Qureg qureg, int targetQubit)
Apply the single-qubit T gate.
Definition: QuEST.c:476
void multiRotateZ(Qureg qureg, int *qubits, int numQubits, qreal angle)
Apply a multi-qubit Z rotation, also known as a phase gadget, on a selected number of qubits.
Definition: QuEST.c:652
qreal imag
Definition: QuEST.h:106
void agnostic_setDiagonalOpElems(DiagonalOp op, long long int startInd, qreal *real, qreal *imag, long long int numElems)
Definition: QuEST_cpu.c:4228
void statevec_controlledPhaseFlip(Qureg qureg, int idQubit1, int idQubit2)
Definition: QuEST_cpu.c:3687
void validateMultiQubitKrausMap(Qureg qureg, int numTargs, ComplexMatrixN *ops, int numOps, const char *caller)
void validateMultiQubitMatrix(Qureg qureg, ComplexMatrixN u, int numTargs, const char *caller)
void validateNumQubitsInDiagOp(int numQubits, int numRanks, const char *caller)
@ GATE_SIGMA_Y
Definition: QuEST_qasm.h:22
void qasm_recordMultiVarPhaseFunc(Qureg qureg, int *qubits, int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, qreal *coeffs, qreal *exponents, int *numTermsPerReg, long long int *overrideInds, qreal *overridePhases, int numOverrides)
Definition: QuEST_qasm.c:666
void applyParamNamedPhaseFunc(Qureg qureg, int *qubits, int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, enum phaseFunc functionNameCode, qreal *params, int numParams)
Induces a phase change upon each amplitude of qureg, determined by a named, paramaterized (and potent...
Definition: QuEST.c:831
void qasm_recordCompactUnitary(Qureg qureg, Complex alpha, Complex beta, int targetQubit)
Definition: QuEST_qasm.c:196
void seedQuEST(QuESTEnv *env, unsigned long int *seedArray, int numSeeds)
Seeds the random number generator with a custom array of key(s), overriding the default keys.
void mixPauli(Qureg qureg, int qubit, qreal probX, qreal probY, qreal probZ)
Mixes a density matrix qureg to induce general single-qubit Pauli noise.
Definition: QuEST.c:1303
void ensureIndsIncrease(int *ind1, int *ind2)
Definition: QuEST_common.c:70
qreal densmatr_calcHilbertSchmidtDistance(Qureg a, Qureg b)
int statevec_compareStates(Qureg mq1, Qureg mq2, qreal precision)
Definition: QuEST_cpu.c:1741
void qasm_recordControlledUnitary(Qureg qureg, ComplexMatrix2 u, int controlQubit, int targetQubit)
additionally performs Rz on target to restore the global phase lost from u in QASM U(a,...
Definition: QuEST_qasm.c:279
void hadamard(Qureg qureg, int targetQubit)
Apply the single-qubit Hadamard gate.
Definition: QuEST.c:176
Represents one complex number.
Definition: QuEST.h:103
void statevec_controlledRotateY(Qureg qureg, int controlQubit, int targetQubit, qreal angle)
Definition: QuEST_common.c:352
void applyMatrix2(Qureg qureg, int targetQubit, ComplexMatrix2 u)
Apply a general 2-by-2 matrix, which may be non-unitary.
Definition: QuEST.c:1084
void statevec_controlledRotateAroundAxisConj(Qureg qureg, int controlQubit, int targetQubit, qreal angle, Vector axis)
Definition: QuEST_common.c:337
void rotateZ(Qureg qureg, int targetQubit, qreal angle)
Rotate a single qubit by a given angle around the Z-axis of the Bloch-sphere (also known as a phase s...
Definition: QuEST.c:209
void multiControlledUnitary(Qureg qureg, int *controlQubits, int numControlQubits, int targetQubit, ComplexMatrix2 u)
Apply a general multiple-control single-target unitary, which can include a global phase factor.
Definition: QuEST.c:373
void initZeroState(Qureg qureg)
Initialise qureg into the zero state.
Definition: QuEST.c:113
void validateTrotterParams(int order, int reps, const char *caller)
void qasm_setup(Qureg *qureg)
Definition: QuEST_qasm.c:61
void qasm_recordGate(Qureg qureg, TargetGate gate, int targetQubit)
Definition: QuEST_qasm.c:179
void validatePauliCodes(enum pauliOpType *pauliCodes, int numPauliCodes, const char *caller)
qreal calcDensityInnerProduct(Qureg rho1, Qureg rho2)
Computes the Hilbert-Schmidt scalar product (which is equivalent to the Frobenius inner product of ma...
Definition: QuEST.c:1158
void statevec_createQureg(Qureg *qureg, int numQubits, QuESTEnv env)
Definition: QuEST_cpu.c:1290
qreal densmatr_calcProbOfOutcome(Qureg qureg, int measureQubit, int outcome)
Qureg createDensityQureg(int numQubits, QuESTEnv env)
Creates a density matrix Qureg object representing a set of qubits which can enter noisy and mixed st...
Definition: QuEST.c:50
void validateUnitaryComplexPair(Complex alpha, Complex beta, const char *caller)
@ GATE_ROTATE_Y
Definition: QuEST_qasm.h:28
void statevec_rotateZ(Qureg qureg, int rotQubit, qreal angle)
Definition: QuEST_common.c:308
void applyTrotterCircuit(Qureg qureg, PauliHamil hamil, qreal time, int order, int reps)
Applies a trotterisation of unitary evolution to qureg.
Definition: QuEST.c:1070
PauliHamil createPauliHamil(int numQubits, int numSumTerms)
Dynamically allocates a Hamiltonian expressed as a real-weighted sum of products of Pauli operators.
Definition: QuEST.c:1398
void initPlusState(Qureg qureg)
Initialise qureg into the plus state.
Definition: QuEST.c:125
qreal calcExpecPauliProd(Qureg qureg, int *targetQubits, enum pauliOpType *pauliCodes, int numTargets, Qureg workspace)
Computes the expected value of a product of Pauli operators.
Definition: QuEST.c:1201
void validateOneQubitDampingProb(qreal prob, const char *caller)
void controlledCompactUnitary(Qureg qureg, int controlQubit, int targetQubit, Complex alpha, Complex beta)
Apply a controlled unitary (single control, single target) parameterised by two given complex scalars...
Definition: QuEST.c:417
void qasm_recordNamedPhaseFunc(Qureg qureg, int *qubits, int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, enum phaseFunc funcName, qreal *params, int numParams, long long int *overrideInds, qreal *overridePhases, int numOverrides)
Definition: QuEST_qasm.c:726
void multiStateControlledUnitary(Qureg qureg, int *controlQubits, int *controlState, int numControlQubits, int targetQubit, ComplexMatrix2 u)
Apply a general single-qubit unitary with multiple control qubits, conditioned upon a specific bit se...
Definition: QuEST.c:388
void statevec_controlledCompactUnitary(Qureg qureg, int controlQubit, int targetQubit, Complex alpha, Complex beta)
qreal statevec_getRealAmp(Qureg qureg, long long int index)
void sqrtSwapGate(Qureg qureg, int qb1, int qb2)
Performs a sqrt SWAP gate between qubit1 and qubit2.
Definition: QuEST.c:639
void validateUniqueTargets(Qureg qureg, int qubit1, int qubit2, const char *caller)
bitEncoding
Flags for specifying how the bits in sub-register computational basis states are mapped to indices in...
Definition: QuEST.h:269
void mixMultiQubitKrausMap(Qureg qureg, int *targets, int numTargets, ComplexMatrixN *ops, int numOps)
Apply a general N-qubit Kraus map to a density matrix, as specified by at most (2N)^2 Kraus operators...
Definition: QuEST.c:1334
void printRecordedQASM(Qureg qureg)
Print recorded QASM to stdout.
Definition: QuEST.c:99
void statevec_pauliYConj(Qureg qureg, int targetQubit)
void validateTwoQubitDephaseProb(qreal prob, const char *caller)
void reportStateToScreen(Qureg qureg, QuESTEnv env, int reportRank)
Print the current state vector of probability amplitudes for a set of qubits to standard out.
Definition: QuEST.c:1594
DiagonalOp createDiagonalOp(int numQubits, QuESTEnv env)
Creates a DiagonalOp representing a diagonal operator on the full Hilbert space of a Qureg.
Definition: QuEST.c:1518
int densmatr_measureWithStats(Qureg qureg, int measureQubit, qreal *outcomeProb)
Definition: QuEST_common.c:372
qreal statevec_calcTotalProb(Qureg qureg)
Represents a 2x2 matrix of complex numbers.
Definition: QuEST.h:137
void densmatr_initPureState(Qureg targetQureg, Qureg copyQureg)
void qasm_recordPhaseFunc(Qureg qureg, int *qubits, int numQubits, enum bitEncoding encoding, qreal *coeffs, qreal *exponents, int numTerms, long long int *overrideInds, qreal *overridePhases, int numOverrides)
Definition: QuEST_qasm.c:490
void validateOneQubitPauliProbs(qreal probX, qreal probY, qreal probZ, const char *caller)
void controlledRotateY(Qureg qureg, int controlQubit, int targetQubit, qreal angle)
Applies a controlled rotation by a given angle around the Y-axis of the Bloch-sphere.
Definition: QuEST.c:232
void statevec_applyMultiVarPhaseFuncOverrides(Qureg qureg, int *qubits, int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, qreal *coeffs, qreal *exponents, int *numTermsPerReg, long long int *overrideInds, qreal *overridePhases, int numOverrides, int conj)
Definition: QuEST_cpu.c:4345
void densmatr_applyDiagonalOp(Qureg qureg, DiagonalOp op)