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 # include <stdlib.h>
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 
30 /*
31  * state-vector management
32  */
33 
34 Qureg createQureg(int numQubits, QuESTEnv env) {
35  validateNumQubitsInQureg(numQubits, env.numRanks, __func__);
36 
37  Qureg qureg;
38  statevec_createQureg(&qureg, numQubits, env);
39  qureg.isDensityMatrix = 0;
40  qureg.numQubitsRepresented = numQubits;
41  qureg.numQubitsInStateVec = numQubits;
42 
43  qasm_setup(&qureg);
44  initZeroState(qureg); // safe call to public function
45  return qureg;
46 }
47 
48 Qureg createDensityQureg(int numQubits, QuESTEnv env) {
49  validateNumQubitsInQureg(2*numQubits, env.numRanks, __func__);
50 
51  Qureg qureg;
52  statevec_createQureg(&qureg, 2*numQubits, env);
53  qureg.isDensityMatrix = 1;
54  qureg.numQubitsRepresented = numQubits;
55  qureg.numQubitsInStateVec = 2*numQubits;
56 
57  qasm_setup(&qureg);
58  initZeroState(qureg); // safe call to public function
59  return qureg;
60 }
61 
63 
64  Qureg newQureg;
65  statevec_createQureg(&newQureg, qureg.numQubitsInStateVec, env);
66  newQureg.isDensityMatrix = qureg.isDensityMatrix;
69 
70  qasm_setup(&newQureg);
71  statevec_cloneQureg(newQureg, qureg);
72  return newQureg;
73 }
74 
75 void destroyQureg(Qureg qureg, QuESTEnv env) {
76  statevec_destroyQureg(qureg, env);
77  qasm_free(qureg);
78 }
79 
80 
81 /*
82  * QASM
83  */
84 
86  qasm_startRecording(qureg);
87 }
88 
89 void stopRecordingQASM(Qureg qureg) {
90  qasm_stopRecording(qureg);
91 }
92 
93 void clearRecordedQASM(Qureg qureg) {
94  qasm_clearRecorded(qureg);
95 }
96 
97 void printRecordedQASM(Qureg qureg) {
98  qasm_printRecorded(qureg);
99 }
100 
101 void writeRecordedQASMToFile(Qureg qureg, char* filename) {
102  int success = qasm_writeRecordedToFile(qureg, filename);
103  validateFileOpened(success, __func__);
104 }
105 
106 
107 /*
108  * state initialisation
109  */
110 
111 void initZeroState(Qureg qureg) {
112  statevec_initZeroState(qureg); // valid for both statevec and density matrices
113 
114  qasm_recordInitZero(qureg);
115 }
116 
117 void initBlankState(Qureg qureg) {
119 
120  qasm_recordComment(qureg, "Here, the register was initialised to an unphysical all-zero-amplitudes 'state'.");
121 }
122 
123 void initPlusState(Qureg qureg) {
124  if (qureg.isDensityMatrix)
125  densmatr_initPlusState(qureg);
126  else
127  statevec_initPlusState(qureg);
128 
129  qasm_recordInitPlus(qureg);
130 }
131 
132 void initClassicalState(Qureg qureg, long long int stateInd) {
133  validateStateIndex(qureg, stateInd, __func__);
134 
135  if (qureg.isDensityMatrix)
136  densmatr_initClassicalState(qureg, stateInd);
137  else
138  statevec_initClassicalState(qureg, stateInd);
139 
140  qasm_recordInitClassical(qureg, stateInd);
141 }
142 
143 void initPureState(Qureg qureg, Qureg pure) {
144  validateSecondQuregStateVec(pure, __func__);
145  validateMatchingQuregDims(qureg, pure, __func__);
146 
147  if (qureg.isDensityMatrix)
148  densmatr_initPureState(qureg, pure);
149  else
150  statevec_cloneQureg(qureg, pure);
151 
152  qasm_recordComment(qureg, "Here, the register was initialised to an undisclosed given pure state.");
153 }
154 
155 void initStateFromAmps(Qureg qureg, qreal* reals, qreal* imags) {
156  validateStateVecQureg(qureg, __func__);
157 
158  statevec_setAmps(qureg, 0, reals, imags, qureg.numAmpsTotal);
159 
160  qasm_recordComment(qureg, "Here, the register was initialised to an undisclosed given pure state.");
161 }
162 
163 void cloneQureg(Qureg targetQureg, Qureg copyQureg) {
164  validateMatchingQuregTypes(targetQureg, copyQureg, __func__);
165  validateMatchingQuregDims(targetQureg, copyQureg, __func__);
166 
167  statevec_cloneQureg(targetQureg, copyQureg);
168 }
169 
170 
171 /*
172  * unitary gates
173  */
174 
175 void hadamard(Qureg qureg, const int targetQubit) {
176  validateTarget(qureg, targetQubit, __func__);
177 
178  statevec_hadamard(qureg, targetQubit);
179  if (qureg.isDensityMatrix) {
180  statevec_hadamard(qureg, targetQubit+qureg.numQubitsRepresented);
181  }
182 
183  qasm_recordGate(qureg, GATE_HADAMARD, targetQubit);
184 }
185 
186 void rotateX(Qureg qureg, const int targetQubit, qreal angle) {
187  validateTarget(qureg, targetQubit, __func__);
188 
189  statevec_rotateX(qureg, targetQubit, angle);
190  if (qureg.isDensityMatrix) {
191  statevec_rotateX(qureg, targetQubit+qureg.numQubitsRepresented, -angle);
192  }
193 
194  qasm_recordParamGate(qureg, GATE_ROTATE_X, targetQubit, angle);
195 }
196 
197 void rotateY(Qureg qureg, const int targetQubit, qreal angle) {
198  validateTarget(qureg, targetQubit, __func__);
199 
200  statevec_rotateY(qureg, targetQubit, angle);
201  if (qureg.isDensityMatrix) {
202  statevec_rotateY(qureg, targetQubit+qureg.numQubitsRepresented, angle);
203  }
204 
205  qasm_recordParamGate(qureg, GATE_ROTATE_Y, targetQubit, angle);
206 }
207 
208 void rotateZ(Qureg qureg, const int targetQubit, qreal angle) {
209  validateTarget(qureg, targetQubit, __func__);
210 
211  statevec_rotateZ(qureg, targetQubit, angle);
212  if (qureg.isDensityMatrix) {
213  statevec_rotateZ(qureg, targetQubit+qureg.numQubitsRepresented, -angle);
214  }
215 
216  qasm_recordParamGate(qureg, GATE_ROTATE_Z, targetQubit, angle);
217 }
218 
219 void controlledRotateX(Qureg qureg, const int controlQubit, const int targetQubit, qreal angle) {
220  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
221 
222  statevec_controlledRotateX(qureg, controlQubit, targetQubit, angle);
223  if (qureg.isDensityMatrix) {
224  int shift = qureg.numQubitsRepresented;
225  statevec_controlledRotateX(qureg, controlQubit+shift, targetQubit+shift, -angle);
226  }
227 
228  qasm_recordControlledParamGate(qureg, GATE_ROTATE_X, controlQubit, targetQubit, angle);
229 }
230 
231 void controlledRotateY(Qureg qureg, const int controlQubit, const int targetQubit, qreal angle) {
232  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
233 
234  statevec_controlledRotateY(qureg, controlQubit, targetQubit, angle);
235  if (qureg.isDensityMatrix) {
236  int shift = qureg.numQubitsRepresented;
237  statevec_controlledRotateY(qureg, controlQubit+shift, targetQubit+shift, angle); // rotateY is real
238  }
239 
240  qasm_recordControlledParamGate(qureg, GATE_ROTATE_Y, controlQubit, targetQubit, angle);
241 }
242 
243 void controlledRotateZ(Qureg qureg, const int controlQubit, const int targetQubit, qreal angle) {
244  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
245 
246  statevec_controlledRotateZ(qureg, controlQubit, targetQubit, angle);
247  if (qureg.isDensityMatrix) {
248  int shift = qureg.numQubitsRepresented;
249  statevec_controlledRotateZ(qureg, controlQubit+shift, targetQubit+shift, -angle);
250  }
251 
252  qasm_recordControlledParamGate(qureg, GATE_ROTATE_Z, controlQubit, targetQubit, angle);
253 }
254 
255 void twoQubitUnitary(Qureg qureg, const int targetQubit1, const int targetQubit2, ComplexMatrix4 u) {
256  validateMultiTargets(qureg, (int []) {targetQubit1, targetQubit2}, 2, __func__);
257  validateTwoQubitUnitaryMatrix(qureg, u, __func__);
258 
259  statevec_twoQubitUnitary(qureg, targetQubit1, targetQubit2, u);
260  if (qureg.isDensityMatrix) {
261  int shift = qureg.numQubitsRepresented;
262  statevec_twoQubitUnitary(qureg, targetQubit1+shift, targetQubit2+shift, getConjugateMatrix4(u));
263  }
264 
265  qasm_recordComment(qureg, "Here, an undisclosed 2-qubit unitary was applied.");
266 }
267 
268 void controlledTwoQubitUnitary(Qureg qureg, const int controlQubit, const int targetQubit1, const int targetQubit2, ComplexMatrix4 u) {
269  validateMultiControlsMultiTargets(qureg, (int[]) {controlQubit}, 1, (int[]) {targetQubit1, targetQubit2}, 2, __func__);
270  validateTwoQubitUnitaryMatrix(qureg, u, __func__);
271 
272  statevec_controlledTwoQubitUnitary(qureg, controlQubit, targetQubit1, targetQubit2, u);
273  if (qureg.isDensityMatrix) {
274  int shift = qureg.numQubitsRepresented;
275  statevec_controlledTwoQubitUnitary(qureg, controlQubit+shift, targetQubit1+shift, targetQubit2+shift, getConjugateMatrix4(u));
276  }
277 
278  qasm_recordComment(qureg, "Here, an undisclosed controlled 2-qubit unitary was applied.");
279 }
280 
281 void multiControlledTwoQubitUnitary(Qureg qureg, int* controlQubits, const int numControlQubits, const int targetQubit1, const int targetQubit2, ComplexMatrix4 u) {
282  validateMultiControlsMultiTargets(qureg, controlQubits, numControlQubits, (int[]) {targetQubit1, targetQubit2}, 2, __func__);
283  validateTwoQubitUnitaryMatrix(qureg, u, __func__);
284 
285  long long int ctrlQubitsMask = getQubitBitMask(controlQubits, numControlQubits);
286  statevec_multiControlledTwoQubitUnitary(qureg, ctrlQubitsMask, targetQubit1, targetQubit2, u);
287  if (qureg.isDensityMatrix) {
288  int shift = qureg.numQubitsRepresented;
289  statevec_multiControlledTwoQubitUnitary(qureg, ctrlQubitsMask<<shift, targetQubit1+shift, targetQubit2+shift, getConjugateMatrix4(u));
290  }
291 
292  qasm_recordComment(qureg, "Here, an undisclosed multi-controlled 2-qubit unitary was applied.");
293 }
294 
295 void multiQubitUnitary(Qureg qureg, int* targs, const int numTargs, ComplexMatrixN u) {
296  validateMultiTargets(qureg, targs, numTargs, __func__);
297  validateMultiQubitUnitaryMatrix(qureg, u, numTargs, __func__);
298 
299  statevec_multiQubitUnitary(qureg, targs, numTargs, u);
300  if (qureg.isDensityMatrix) {
301  int shift = qureg.numQubitsRepresented;
302  shiftIndices(targs, numTargs, shift);
304  statevec_multiQubitUnitary(qureg, targs, numTargs, u);
305  shiftIndices(targs, numTargs, -shift);
307  }
308 
309  qasm_recordComment(qureg, "Here, an undisclosed multi-qubit unitary was applied.");
310 }
311 
312 void controlledMultiQubitUnitary(Qureg qureg, int ctrl, int* targs, const int numTargs, ComplexMatrixN u) {
313  validateMultiControlsMultiTargets(qureg, (int[]) {ctrl}, 1, targs, numTargs, __func__);
314  validateMultiQubitUnitaryMatrix(qureg, u, numTargs, __func__);
315 
316  statevec_controlledMultiQubitUnitary(qureg, ctrl, targs, numTargs, u);
317  if (qureg.isDensityMatrix) {
318  int shift = qureg.numQubitsRepresented;
319  shiftIndices(targs, numTargs, shift);
321  statevec_controlledMultiQubitUnitary(qureg, ctrl+shift, targs, numTargs, u);
322  shiftIndices(targs, numTargs, -shift);
324  }
325 
326  qasm_recordComment(qureg, "Here, an undisclosed controlled multi-qubit unitary was applied.");
327 }
328 
329 void multiControlledMultiQubitUnitary(Qureg qureg, int* ctrls, const int numCtrls, int* targs, const int numTargs, ComplexMatrixN u) {
330  validateMultiControlsMultiTargets(qureg, ctrls, numCtrls, targs, numTargs, __func__);
331  validateMultiQubitUnitaryMatrix(qureg, u, numTargs, __func__);
332 
333  long long int ctrlMask = getQubitBitMask(ctrls, numCtrls);
334  statevec_multiControlledMultiQubitUnitary(qureg, ctrlMask, targs, numTargs, u);
335  if (qureg.isDensityMatrix) {
336  int shift = qureg.numQubitsRepresented;
337  shiftIndices(targs, numTargs, shift);
339  statevec_multiControlledMultiQubitUnitary(qureg, ctrlMask<<shift, targs, numTargs, u);
340  shiftIndices(targs, numTargs, -shift);
342  }
343 
344  qasm_recordComment(qureg, "Here, an undisclosed multi-controlled multi-qubit unitary was applied.");
345 }
346 
347 void unitary(Qureg qureg, const int targetQubit, ComplexMatrix2 u) {
348  validateTarget(qureg, targetQubit, __func__);
349  validateOneQubitUnitaryMatrix(u, __func__);
350 
351  statevec_unitary(qureg, targetQubit, u);
352  if (qureg.isDensityMatrix) {
353  statevec_unitary(qureg, targetQubit+qureg.numQubitsRepresented, getConjugateMatrix2(u));
354  }
355 
356  qasm_recordUnitary(qureg, u, targetQubit);
357 }
358 
359 void controlledUnitary(Qureg qureg, const int controlQubit, const int targetQubit, ComplexMatrix2 u) {
360  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
361  validateOneQubitUnitaryMatrix(u, __func__);
362 
363  statevec_controlledUnitary(qureg, controlQubit, targetQubit, u);
364  if (qureg.isDensityMatrix) {
365  int shift = qureg.numQubitsRepresented;
366  statevec_controlledUnitary(qureg, controlQubit+shift, targetQubit+shift, getConjugateMatrix2(u));
367  }
368 
369  qasm_recordControlledUnitary(qureg, u, controlQubit, targetQubit);
370 }
371 
372 void multiControlledUnitary(Qureg qureg, int* controlQubits, const int numControlQubits, const int targetQubit, ComplexMatrix2 u) {
373  validateMultiControlsTarget(qureg, controlQubits, numControlQubits, targetQubit, __func__);
374  validateOneQubitUnitaryMatrix(u, __func__);
375 
376  long long int ctrlQubitsMask = getQubitBitMask(controlQubits, numControlQubits);
377  long long int ctrlFlipMask = 0;
378  statevec_multiControlledUnitary(qureg, ctrlQubitsMask, ctrlFlipMask, targetQubit, u);
379  if (qureg.isDensityMatrix) {
380  int shift = qureg.numQubitsRepresented;
381  statevec_multiControlledUnitary(qureg, ctrlQubitsMask<<shift, ctrlFlipMask<<shift, targetQubit+shift, getConjugateMatrix2(u));
382  }
383 
384  qasm_recordMultiControlledUnitary(qureg, u, controlQubits, numControlQubits, targetQubit);
385 }
386 
387 void multiStateControlledUnitary(Qureg qureg, int* controlQubits, int* controlState, const int numControlQubits, const int targetQubit, ComplexMatrix2 u) {
388  validateMultiControlsTarget(qureg, controlQubits, numControlQubits, targetQubit, __func__);
389  validateOneQubitUnitaryMatrix(u, __func__);
390  validateControlState(controlState, numControlQubits, __func__);
391 
392  long long int ctrlQubitsMask = getQubitBitMask(controlQubits, numControlQubits);
393  long long int ctrlFlipMask = getControlFlipMask(controlQubits, controlState, numControlQubits);
394  statevec_multiControlledUnitary(qureg, ctrlQubitsMask, ctrlFlipMask, targetQubit, u);
395  if (qureg.isDensityMatrix) {
396  int shift = qureg.numQubitsRepresented;
397  statevec_multiControlledUnitary(qureg, ctrlQubitsMask<<shift, ctrlFlipMask<<shift, targetQubit+shift, getConjugateMatrix2(u));
398  }
399 
400  qasm_recordMultiStateControlledUnitary(qureg, u, controlQubits, controlState, numControlQubits, targetQubit);
401 }
402 
403 void compactUnitary(Qureg qureg, const int targetQubit, Complex alpha, Complex beta) {
404  validateTarget(qureg, targetQubit, __func__);
405  validateUnitaryComplexPair(alpha, beta, __func__);
406 
407  statevec_compactUnitary(qureg, targetQubit, alpha, beta);
408  if (qureg.isDensityMatrix) {
409  int shift = qureg.numQubitsRepresented;
410  statevec_compactUnitary(qureg, targetQubit+shift, getConjugateScalar(alpha), getConjugateScalar(beta));
411  }
412 
413  qasm_recordCompactUnitary(qureg, alpha, beta, targetQubit);
414 }
415 
416 void controlledCompactUnitary(Qureg qureg, const int controlQubit, const int targetQubit, Complex alpha, Complex beta) {
417  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
418  validateUnitaryComplexPair(alpha, beta, __func__);
419 
420  statevec_controlledCompactUnitary(qureg, controlQubit, targetQubit, alpha, beta);
421  if (qureg.isDensityMatrix) {
422  int shift = qureg.numQubitsRepresented;
424  controlQubit+shift, targetQubit+shift,
425  getConjugateScalar(alpha), getConjugateScalar(beta));
426  }
427 
428  qasm_recordControlledCompactUnitary(qureg, alpha, beta, controlQubit, targetQubit);
429 }
430 
431 void pauliX(Qureg qureg, const int targetQubit) {
432  validateTarget(qureg, targetQubit, __func__);
433 
434  statevec_pauliX(qureg, targetQubit);
435  if (qureg.isDensityMatrix) {
436  statevec_pauliX(qureg, targetQubit+qureg.numQubitsRepresented);
437  }
438 
439  qasm_recordGate(qureg, GATE_SIGMA_X, targetQubit);
440 }
441 
442 void pauliY(Qureg qureg, const int targetQubit) {
443  validateTarget(qureg, targetQubit, __func__);
444 
445  statevec_pauliY(qureg, targetQubit);
446  if (qureg.isDensityMatrix) {
447  statevec_pauliYConj(qureg, targetQubit + qureg.numQubitsRepresented);
448  }
449 
450  qasm_recordGate(qureg, GATE_SIGMA_Y, targetQubit);
451 }
452 
453 void pauliZ(Qureg qureg, const int targetQubit) {
454  validateTarget(qureg, targetQubit, __func__);
455 
456  statevec_pauliZ(qureg, targetQubit);
457  if (qureg.isDensityMatrix) {
458  statevec_pauliZ(qureg, targetQubit+qureg.numQubitsRepresented);
459  }
460 
461  qasm_recordGate(qureg, GATE_SIGMA_Z, targetQubit);
462 }
463 
464 void sGate(Qureg qureg, const int targetQubit) {
465  validateTarget(qureg, targetQubit, __func__);
466 
467  statevec_sGate(qureg, targetQubit);
468  if (qureg.isDensityMatrix) {
469  statevec_sGateConj(qureg, targetQubit+qureg.numQubitsRepresented);
470  }
471 
472  qasm_recordGate(qureg, GATE_S, targetQubit);
473 }
474 
475 void tGate(Qureg qureg, const int targetQubit) {
476  validateTarget(qureg, targetQubit, __func__);
477 
478  statevec_tGate(qureg, targetQubit);
479  if (qureg.isDensityMatrix) {
480  statevec_tGateConj(qureg, targetQubit+qureg.numQubitsRepresented);
481  }
482 
483  qasm_recordGate(qureg, GATE_T, targetQubit);
484 }
485 
486 void phaseShift(Qureg qureg, const int targetQubit, qreal angle) {
487  validateTarget(qureg, targetQubit, __func__);
488 
489  statevec_phaseShift(qureg, targetQubit, angle);
490  if (qureg.isDensityMatrix) {
491  statevec_phaseShift(qureg, targetQubit+qureg.numQubitsRepresented, -angle);
492  }
493 
494  qasm_recordParamGate(qureg, GATE_PHASE_SHIFT, targetQubit, angle);
495 }
496 
497 void controlledPhaseShift(Qureg qureg, const int idQubit1, const int idQubit2, qreal angle) {
498  validateControlTarget(qureg, idQubit1, idQubit2, __func__);
499 
500  statevec_controlledPhaseShift(qureg, idQubit1, idQubit2, angle);
501  if (qureg.isDensityMatrix) {
502  int shift = qureg.numQubitsRepresented;
503  statevec_controlledPhaseShift(qureg, idQubit1+shift, idQubit2+shift, -angle);
504  }
505 
506  qasm_recordControlledParamGate(qureg, GATE_PHASE_SHIFT, idQubit1, idQubit2, angle);
507 }
508 
509 void multiControlledPhaseShift(Qureg qureg, int *controlQubits, int numControlQubits, qreal angle) {
510  validateMultiQubits(qureg, controlQubits, numControlQubits, __func__);
511 
512  statevec_multiControlledPhaseShift(qureg, controlQubits, numControlQubits, angle);
513  if (qureg.isDensityMatrix) {
514  int shift = qureg.numQubitsRepresented;
515  shiftIndices(controlQubits, numControlQubits, shift);
516  statevec_multiControlledPhaseShift(qureg, controlQubits, numControlQubits, -angle);
517  shiftIndices(controlQubits, numControlQubits, -shift);
518  }
519 
520  qasm_recordMultiControlledParamGate(qureg, GATE_PHASE_SHIFT, controlQubits, numControlQubits-1, controlQubits[numControlQubits-1], angle);
521 }
522 
523 void controlledNot(Qureg qureg, const int controlQubit, const int targetQubit) {
524  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
525 
526  statevec_controlledNot(qureg, controlQubit, targetQubit);
527  if (qureg.isDensityMatrix) {
528  int shift = qureg.numQubitsRepresented;
529  statevec_controlledNot(qureg, controlQubit+shift, targetQubit+shift);
530  }
531 
532  qasm_recordControlledGate(qureg, GATE_SIGMA_X, controlQubit, targetQubit);
533 }
534 
535 void controlledPauliY(Qureg qureg, const int controlQubit, const int targetQubit) {
536  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
537 
538  statevec_controlledPauliY(qureg, controlQubit, targetQubit);
539  if (qureg.isDensityMatrix) {
540  int shift = qureg.numQubitsRepresented;
541  statevec_controlledPauliYConj(qureg, controlQubit+shift, targetQubit+shift);
542  }
543 
544  qasm_recordControlledGate(qureg, GATE_SIGMA_Y, controlQubit, targetQubit);
545 }
546 
547 void controlledPhaseFlip(Qureg qureg, const int idQubit1, const int idQubit2) {
548  validateControlTarget(qureg, idQubit1, idQubit2, __func__);
549 
550  statevec_controlledPhaseFlip(qureg, idQubit1, idQubit2);
551  if (qureg.isDensityMatrix) {
552  int shift = qureg.numQubitsRepresented;
553  statevec_controlledPhaseFlip(qureg, idQubit1+shift, idQubit2+shift);
554  }
555 
556  qasm_recordControlledGate(qureg, GATE_SIGMA_Z, idQubit1, idQubit2);
557 }
558 
559 void multiControlledPhaseFlip(Qureg qureg, int *controlQubits, int numControlQubits) {
560  validateMultiQubits(qureg, controlQubits, numControlQubits, __func__);
561 
562  statevec_multiControlledPhaseFlip(qureg, controlQubits, numControlQubits);
563  if (qureg.isDensityMatrix) {
564  int shift = qureg.numQubitsRepresented;
565  shiftIndices(controlQubits, numControlQubits, shift);
566  statevec_multiControlledPhaseFlip(qureg, controlQubits, numControlQubits);
567  shiftIndices(controlQubits, numControlQubits, -shift);
568  }
569 
570  qasm_recordMultiControlledGate(qureg, GATE_SIGMA_Z, controlQubits, numControlQubits-1, controlQubits[numControlQubits-1]);
571 }
572 
573 void rotateAroundAxis(Qureg qureg, const int rotQubit, qreal angle, Vector axis) {
574  validateTarget(qureg, rotQubit, __func__);
575  validateVector(axis, __func__);
576 
577  statevec_rotateAroundAxis(qureg, rotQubit, angle, axis);
578  if (qureg.isDensityMatrix) {
579  int shift = qureg.numQubitsRepresented;
580  statevec_rotateAroundAxisConj(qureg, rotQubit+shift, angle, axis);
581  }
582 
583  qasm_recordAxisRotation(qureg, angle, axis, rotQubit);
584 }
585 
586 void controlledRotateAroundAxis(Qureg qureg, const int controlQubit, const int targetQubit, qreal angle, Vector axis) {
587  validateControlTarget(qureg, controlQubit, targetQubit, __func__);
588  validateVector(axis, __func__);
589 
590  statevec_controlledRotateAroundAxis(qureg, controlQubit, targetQubit, angle, axis);
591  if (qureg.isDensityMatrix) {
592  int shift = qureg.numQubitsRepresented;
593  statevec_controlledRotateAroundAxisConj(qureg, controlQubit+shift, targetQubit+shift, angle, axis);
594  }
595 
596  qasm_recordControlledAxisRotation(qureg, angle, axis, controlQubit, targetQubit);
597 }
598 
599 void swapGate(Qureg qureg, int qb1, int qb2) {
600  validateUniqueTargets(qureg, qb1, qb2, __func__);
601 
602  statevec_swapQubitAmps(qureg, qb1, qb2);
603  if (qureg.isDensityMatrix) {
604  int shift = qureg.numQubitsRepresented;
605  statevec_swapQubitAmps(qureg, qb1+shift, qb2+shift);
606  }
607 
608  qasm_recordControlledGate(qureg, GATE_SWAP, qb1, qb2);
609 }
610 
611 void sqrtSwapGate(Qureg qureg, int qb1, int qb2) {
612  validateUniqueTargets(qureg, qb1, qb2, __func__);
613  validateMultiQubitMatrixFitsInNode(qureg, 2, __func__); // uses 2qb unitary in QuEST_common
614 
615  statevec_sqrtSwapGate(qureg, qb1, qb2);
616  if (qureg.isDensityMatrix) {
617  int shift = qureg.numQubitsRepresented;
618  statevec_sqrtSwapGateConj(qureg, qb1+shift, qb2+shift);
619  }
620 
621  qasm_recordControlledGate(qureg, GATE_SQRT_SWAP, qb1, qb2);
622 }
623 
624 void multiRotateZ(Qureg qureg, int* qubits, int numQubits, qreal angle) {
625  validateMultiTargets(qureg, qubits, numQubits, __func__);
626 
627  long long int mask = getQubitBitMask(qubits, numQubits);
628  statevec_multiRotateZ(qureg, mask, angle);
629  if (qureg.isDensityMatrix) {
630  int shift = qureg.numQubitsRepresented;
631  statevec_multiRotateZ(qureg, mask << shift, -angle);
632  }
633 
634  // @TODO: create actual QASM
635  qasm_recordComment(qureg,
636  "Here a %d-qubit multiRotateZ of angle %g was performed (QASM not yet implemented)",
637  numQubits, angle);
638 }
639 
640 void multiRotatePauli(Qureg qureg, int* targetQubits, enum pauliOpType* targetPaulis, int numTargets, qreal angle) {
641  validateMultiTargets(qureg, targetQubits, numTargets, __func__);
642  validatePauliCodes(targetPaulis, numTargets, __func__);
643 
644  int conj=0;
645  statevec_multiRotatePauli(qureg, targetQubits, targetPaulis, numTargets, angle, conj);
646  if (qureg.isDensityMatrix) {
647  conj = 1;
648  int shift = qureg.numQubitsRepresented;
649  shiftIndices(targetQubits, numTargets, shift);
650  statevec_multiRotatePauli(qureg, targetQubits, targetPaulis, numTargets, angle, conj);
651  shiftIndices(targetQubits, numTargets, -shift);
652  }
653 
654  // @TODO: create actual QASM
655  qasm_recordComment(qureg,
656  "Here a %d-qubit multiRotatePauli of angle %g was performed (QASM not yet implemented)",
657  numTargets, angle);
658 }
659 
660 
661 
662 /*
663  * register attributes
664  */
665 
666 int getNumQubits(Qureg qureg) {
667  return qureg.numQubitsRepresented;
668 }
669 
670 long long int getNumAmps(Qureg qureg) {
671  validateStateVecQureg(qureg, __func__);
672 
673  return qureg.numAmpsTotal;
674 }
675 
676 qreal getRealAmp(Qureg qureg, long long int index) {
677  validateStateVecQureg(qureg, __func__);
678  validateAmpIndex(qureg, index, __func__);
679 
680  return statevec_getRealAmp(qureg, index);
681 }
682 
683 qreal getImagAmp(Qureg qureg, long long int index) {
684  validateStateVecQureg(qureg, __func__);
685  validateAmpIndex(qureg, index, __func__);
686 
687  return statevec_getImagAmp(qureg, index);
688 }
689 
690 qreal getProbAmp(Qureg qureg, long long int index) {
691  validateStateVecQureg(qureg, __func__);
692  validateAmpIndex(qureg, index, __func__);
693 
694  return statevec_getProbAmp(qureg, index);
695 }
696 
697 Complex getAmp(Qureg qureg, long long int index) {
698  validateStateVecQureg(qureg, __func__);
699  validateAmpIndex(qureg, index, __func__);
700 
701  Complex amp;
702  amp.real = statevec_getRealAmp(qureg, index);
703  amp.imag = statevec_getImagAmp(qureg, index);
704  return amp;
705 }
706 
707 Complex getDensityAmp(Qureg qureg, long long int row, long long int col) {
708  validateDensityMatrQureg(qureg, __func__);
709  validateAmpIndex(qureg, row, __func__);
710  validateAmpIndex(qureg, col, __func__);
711 
712  long long ind = row + col*(1LL << qureg.numQubitsRepresented);
713  Complex amp;
714  amp.real = statevec_getRealAmp(qureg, ind);
715  amp.imag = statevec_getImagAmp(qureg, ind);
716  return amp;
717 }
718 
719 
720 /*
721  * non-unitary actions
722  */
723 
724 qreal collapseToOutcome(Qureg qureg, const int measureQubit, int outcome) {
725  validateTarget(qureg, measureQubit, __func__);
726  validateOutcome(outcome, __func__);
727 
728  qreal outcomeProb;
729  if (qureg.isDensityMatrix) {
730  outcomeProb = densmatr_calcProbOfOutcome(qureg, measureQubit, outcome);
731  validateMeasurementProb(outcomeProb, __func__);
732  densmatr_collapseToKnownProbOutcome(qureg, measureQubit, outcome, outcomeProb);
733  } else {
734  outcomeProb = statevec_calcProbOfOutcome(qureg, measureQubit, outcome);
735  validateMeasurementProb(outcomeProb, __func__);
736  statevec_collapseToKnownProbOutcome(qureg, measureQubit, outcome, outcomeProb);
737  }
738 
739  qasm_recordMeasurement(qureg, measureQubit);
740  return outcomeProb;
741 }
742 
743 int measureWithStats(Qureg qureg, int measureQubit, qreal *outcomeProb) {
744  validateTarget(qureg, measureQubit, __func__);
745 
746  int outcome;
747  if (qureg.isDensityMatrix)
748  outcome = densmatr_measureWithStats(qureg, measureQubit, outcomeProb);
749  else
750  outcome = statevec_measureWithStats(qureg, measureQubit, outcomeProb);
751 
752  qasm_recordMeasurement(qureg, measureQubit);
753  return outcome;
754 }
755 
756 int measure(Qureg qureg, int measureQubit) {
757  validateTarget(qureg, measureQubit, __func__);
758 
759  int outcome;
760  qreal discardedProb;
761  if (qureg.isDensityMatrix)
762  outcome = densmatr_measureWithStats(qureg, measureQubit, &discardedProb);
763  else
764  outcome = statevec_measureWithStats(qureg, measureQubit, &discardedProb);
765 
766  qasm_recordMeasurement(qureg, measureQubit);
767  return outcome;
768 }
769 
770 void mixDensityMatrix(Qureg combineQureg, qreal otherProb, Qureg otherQureg) {
771  validateDensityMatrQureg(combineQureg, __func__);
772  validateDensityMatrQureg(otherQureg, __func__);
773  validateMatchingQuregDims(combineQureg, otherQureg, __func__);
774  validateProb(otherProb, __func__);
775 
776  densmatr_mixDensityMatrix(combineQureg, otherProb, otherQureg);
777 }
778 
779 void setAmps(Qureg qureg, long long int startInd, qreal* reals, qreal* imags, long long int numAmps) {
780  validateStateVecQureg(qureg, __func__);
781  validateNumAmps(qureg, startInd, numAmps, __func__);
782 
783  statevec_setAmps(qureg, startInd, reals, imags, numAmps);
784 
785  qasm_recordComment(qureg, "Here, some amplitudes in the statevector were manually edited.");
786 }
787 
788 void setDensityAmps(Qureg qureg, qreal* reals, qreal* imags) {
789  long long int numAmps = qureg.numAmpsTotal;
790  statevec_setAmps(qureg, 0, reals, imags, numAmps);
791 
792  qasm_recordComment(qureg, "Here, some amplitudes in the density matrix were manually edited.");
793 }
794 
795 void setWeightedQureg(Complex fac1, Qureg qureg1, Complex fac2, Qureg qureg2, Complex facOut, Qureg out) {
796  validateMatchingQuregTypes(qureg1, qureg2, __func__);
797  validateMatchingQuregTypes(qureg1, out, __func__);
798  validateMatchingQuregDims(qureg1, qureg2, __func__);
799  validateMatchingQuregDims(qureg1, out, __func__);
800 
801  statevec_setWeightedQureg(fac1, qureg1, fac2, qureg2, facOut, out);
802 
803  qasm_recordComment(out, "Here, the register was modified to an undisclosed and possibly unphysical state (setWeightedQureg).");
804 }
805 
806 void applyPauliSum(Qureg inQureg, enum pauliOpType* allPauliCodes, qreal* termCoeffs, int numSumTerms, Qureg outQureg) {
807  validateMatchingQuregTypes(inQureg, outQureg, __func__);
808  validateMatchingQuregDims(inQureg, outQureg, __func__);
809  validateNumPauliSumTerms(numSumTerms, __func__);
810  validatePauliCodes(allPauliCodes, numSumTerms*inQureg.numQubitsRepresented, __func__);
811 
812  statevec_applyPauliSum(inQureg, allPauliCodes, termCoeffs, numSumTerms, outQureg);
813 
814  qasm_recordComment(outQureg, "Here, the register was modified to an undisclosed and possibly unphysical state (applyPauliSum).");
815 }
816 
817 
818 /*
819  * calculations
820  */
821 
823  if (qureg.isDensityMatrix)
824  return densmatr_calcTotalProb(qureg);
825  else
826  return statevec_calcTotalProb(qureg);
827 }
828 
830  validateStateVecQureg(bra, __func__);
831  validateStateVecQureg(ket, __func__);
832  validateMatchingQuregDims(bra, ket, __func__);
833 
834  return statevec_calcInnerProduct(bra, ket);
835 }
836 
838  validateDensityMatrQureg(rho1, __func__);
839  validateDensityMatrQureg(rho2, __func__);
840  validateMatchingQuregDims(rho1, rho2, __func__);
841 
842  return densmatr_calcInnerProduct(rho1, rho2);
843 }
844 
845 qreal calcProbOfOutcome(Qureg qureg, const int measureQubit, int outcome) {
846  validateTarget(qureg, measureQubit, __func__);
847  validateOutcome(outcome, __func__);
848 
849  if (qureg.isDensityMatrix)
850  return densmatr_calcProbOfOutcome(qureg, measureQubit, outcome);
851  else
852  return statevec_calcProbOfOutcome(qureg, measureQubit, outcome);
853 }
854 
856  validateDensityMatrQureg(qureg, __func__);
857 
858  return densmatr_calcPurity(qureg);
859 }
860 
861 qreal calcFidelity(Qureg qureg, Qureg pureState) {
862  validateSecondQuregStateVec(pureState, __func__);
863  validateMatchingQuregDims(qureg, pureState, __func__);
864 
865  if (qureg.isDensityMatrix)
866  return densmatr_calcFidelity(qureg, pureState);
867  else
868  return statevec_calcFidelity(qureg, pureState);
869 }
870 
871 qreal calcExpecPauliProd(Qureg qureg, int* targetQubits, enum pauliOpType* pauliCodes, int numTargets, Qureg workspace) {
872  validateMultiTargets(qureg, targetQubits, numTargets, __func__);
873  validatePauliCodes(pauliCodes, numTargets, __func__);
874  validateMatchingQuregTypes(qureg, workspace, __func__);
875  validateMatchingQuregDims(qureg, workspace, __func__);
876 
877  return statevec_calcExpecPauliProd(qureg, targetQubits, pauliCodes, numTargets, workspace);
878 }
879 
880 qreal calcExpecPauliSum(Qureg qureg, enum pauliOpType* allPauliCodes, qreal* termCoeffs, int numSumTerms, Qureg workspace) {
881  validateNumPauliSumTerms(numSumTerms, __func__);
882  validatePauliCodes(allPauliCodes, numSumTerms*qureg.numQubitsRepresented, __func__);
883  validateMatchingQuregTypes(qureg, workspace, __func__);
884  validateMatchingQuregDims(qureg, workspace, __func__);
885 
886  return statevec_calcExpecPauliSum(qureg, allPauliCodes, termCoeffs, numSumTerms, workspace);
887 }
888 
890  validateDensityMatrQureg(a, __func__);
891  validateDensityMatrQureg(b, __func__);
892  validateMatchingQuregDims(a, b, __func__);
893 
895 }
896 
897 
898 /*
899  * decoherence
900  */
901 
902 void mixDephasing(Qureg qureg, const int targetQubit, qreal prob) {
903  validateDensityMatrQureg(qureg, __func__);
904  validateTarget(qureg, targetQubit, __func__);
905  validateOneQubitDephaseProb(prob, __func__);
906 
907  densmatr_mixDephasing(qureg, targetQubit, 2*prob);
908  qasm_recordComment(qureg,
909  "Here, a phase (Z) error occured on qubit %d with probability %g", targetQubit, prob);
910 }
911 
912 void mixTwoQubitDephasing(Qureg qureg, int qubit1, int qubit2, qreal prob) {
913  validateDensityMatrQureg(qureg, __func__);
914  validateUniqueTargets(qureg, qubit1, qubit2, __func__);
915  validateTwoQubitDephaseProb(prob, __func__);
916 
917  ensureIndsIncrease(&qubit1, &qubit2);
918  densmatr_mixTwoQubitDephasing(qureg, qubit1, qubit2, (4*prob)/3.0);
919  qasm_recordComment(qureg,
920  "Here, a phase (Z) error occured on either or both of qubits "
921  "%d and %d with total probability %g", qubit1, qubit2, prob);
922 }
923 
924 void mixDepolarising(Qureg qureg, const int targetQubit, qreal prob) {
925  validateDensityMatrQureg(qureg, __func__);
926  validateTarget(qureg, targetQubit, __func__);
927  validateOneQubitDepolProb(prob, __func__);
928 
929  densmatr_mixDepolarising(qureg, targetQubit, (4*prob)/3.0);
930  qasm_recordComment(qureg,
931  "Here, a homogeneous depolarising error (X, Y, or Z) occured on "
932  "qubit %d with total probability %g", targetQubit, prob);
933 }
934 
935 void mixDamping(Qureg qureg, const int targetQubit, qreal prob) {
936  validateDensityMatrQureg(qureg, __func__);
937  validateTarget(qureg, targetQubit, __func__);
938  validateOneQubitDampingProb(prob, __func__);
939 
940  densmatr_mixDamping(qureg, targetQubit, prob);
941 }
942 
943 void mixTwoQubitDepolarising(Qureg qureg, int qubit1, int qubit2, qreal prob) {
944  validateDensityMatrQureg(qureg, __func__);
945  validateUniqueTargets(qureg, qubit1, qubit2, __func__);
946  validateTwoQubitDepolProb(prob, __func__);
947 
948  ensureIndsIncrease(&qubit1, &qubit2);
949  densmatr_mixTwoQubitDepolarising(qureg, qubit1, qubit2, (16*prob)/15.0);
950  qasm_recordComment(qureg,
951  "Here, a homogeneous depolarising error occured on qubits %d and %d "
952  "with total probability %g", qubit1, qubit2, prob);
953 }
954 
955 void mixPauli(Qureg qureg, int qubit, qreal probX, qreal probY, qreal probZ) {
956  validateDensityMatrQureg(qureg, __func__);
957  validateTarget(qureg, qubit, __func__);
958  validateOneQubitPauliProbs(probX, probY, probZ, __func__);
959 
960  densmatr_mixPauli(qureg, qubit, probX, probY, probZ);
961  qasm_recordComment(qureg,
962  "Here, X, Y and Z errors occured on qubit %d with probabilities "
963  "%g, %g and %g respectively", qubit, probX, probY, probZ);
964 }
965 
966 void mixKrausMap(Qureg qureg, int target, ComplexMatrix2 *ops, int numOps) {
967  validateDensityMatrQureg(qureg, __func__);
968  validateTarget(qureg, target, __func__);
969  validateOneQubitKrausMap(qureg, ops, numOps, __func__);
970 
971  densmatr_mixKrausMap(qureg, target, ops, numOps);
972  qasm_recordComment(qureg,
973  "Here, an undisclosed Kraus map was effected on qubit %d", target);
974 }
975 
976 void mixTwoQubitKrausMap(Qureg qureg, int target1, int target2, ComplexMatrix4 *ops, int numOps) {
977  validateDensityMatrQureg(qureg, __func__);
978  validateMultiTargets(qureg, (int[]) {target1,target2}, 2, __func__);
979  validateTwoQubitKrausMap(qureg, ops, numOps, __func__);
980 
981  densmatr_mixTwoQubitKrausMap(qureg, target1, target2, ops, numOps);
982  qasm_recordComment(qureg,
983  "Here, an undisclosed two-qubit Kraus map was effected on qubits %d and %d", target1, target2);
984 }
985 
986 void mixMultiQubitKrausMap(Qureg qureg, int* targets, int numTargets, ComplexMatrixN* ops, int numOps) {
987  validateDensityMatrQureg(qureg, __func__);
988  validateMultiTargets(qureg, targets, numTargets, __func__);
989  validateMultiQubitKrausMap(qureg, numTargets, ops, numOps, __func__);
990 
991  densmatr_mixMultiQubitKrausMap(qureg, targets, numTargets, ops, numOps);
992  qasm_recordComment(qureg,
993  "Here, an undisclosed %d-qubit Kraus map was applied to undisclosed qubits", numTargets);
994 }
995 
996 /*
997  * other data structures
998  */
999 
1001  validateNumQubitsInMatrix(numQubits, __func__);
1002 
1003  int numRows = 1 << numQubits;
1004 
1005  ComplexMatrixN m = {
1006  .numQubits = numQubits,
1007  .real = malloc(numRows * sizeof *m.real),
1008  .imag = malloc(numRows * sizeof *m.imag)};
1009 
1010  for (int n=0; n < 1<<numQubits; n++) {
1011  m.real[n] = calloc(numRows, sizeof **m.real);
1012  m.imag[n] = calloc(numRows, sizeof **m.imag);
1013  }
1014 
1015  // error if the ComplexMatrixN was not successfully malloc'ds
1016  validateMatrixInit(m, __func__);
1017 
1018  return m;
1019  }
1020 
1022  /* this checks m.real/imag != NULL, which is only ever set when the mallocs
1023  * in createComplexMatrixN fail, which already prompts an error. Hence
1024  * this check if useless
1025  */
1026  validateMatrixInit(m, __func__);
1027 
1028  int numRows = 1 << m.numQubits;
1029  for (int r=0; r < numRows; r++) {
1030  free(m.real[r]);
1031  free(m.imag[r]);
1032  }
1033  free(m.real);
1034  free(m.imag);
1035 }
1036 
1038  validateMatrixInit(m, __func__);
1039 
1040  int dim = 1 << m.numQubits;
1041  for (int i=0; i<dim; i++)
1042  for (int j=0; j<dim; j++) {
1043  m.real[i][j] = re[i][j];
1044  m.imag[i][j] = im[i][j];
1045  }
1046 }
1047 
1048 /*
1049  * debug
1050  */
1051 
1052 int compareStates(Qureg qureg1, Qureg qureg2, qreal precision) {
1053  validateMatchingQuregDims(qureg1, qureg2, __func__);
1054  return statevec_compareStates(qureg1, qureg2, precision);
1055 }
1056 
1057 void initDebugState(Qureg qureg) {
1058  statevec_initDebugState(qureg);
1059 }
1060 
1061 void initStateFromSingleFile(Qureg *qureg, char filename[200], QuESTEnv env) {
1062  int success = statevec_initStateFromSingleFile(qureg, filename, env);
1063  validateFileOpened(success, __func__);
1064 }
1065 
1066 void initStateOfSingleQubit(Qureg *qureg, int qubitId, int outcome) {
1067  validateStateVecQureg(*qureg, __func__);
1068  validateTarget(*qureg, qubitId, __func__);
1069  validateOutcome(outcome, __func__);
1070  statevec_initStateOfSingleQubit(qureg, qubitId, outcome);
1071 }
1072 
1073 void reportStateToScreen(Qureg qureg, QuESTEnv env, int reportRank) {
1074  statevec_reportStateToScreen(qureg, env, reportRank);
1075 }
1076 
1077 int getQuEST_PREC(void) {
1078  return sizeof(qreal)/4;
1079 }
1080 
1081 
1082 #ifdef __cplusplus
1083 }
1084 #endif
void qasm_printRecorded(Qureg qureg)
Definition: QuEST_qasm.c:484
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:1052
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:690
void validateDensityMatrQureg(Qureg qureg, const char *caller)
void initBlankState(Qureg qureg)
Initialises a qureg to have all-zero-amplitudes.
Definition: QuEST.c:117
Represents a 3-vector of real numbers.
Definition: QuEST.h:148
pauliOpType
Codes for specifying Pauli operators.
Definition: QuEST.h:96
void validateMeasurementProb(qreal prob, const char *caller)
void controlledPauliY(Qureg qureg, const int controlQubit, const int targetQubit)
Apply the controlled pauliY (single control, single target) gate, also known as the c-Y and c-sigma-Y...
Definition: QuEST.c:535
void statevec_pauliYConj(Qureg qureg, const int targetQubit)
void validateTarget(Qureg qureg, int targetQubit, const char *caller)
void validateOutcome(int outcome, const char *caller)
void densmatr_mixKrausMap(Qureg qureg, int target, ComplexMatrix2 *ops, int numOps)
Definition: QuEST_common.c:599
void statevec_multiQubitUnitary(Qureg qureg, int *targets, const int numTargets, ComplexMatrixN u)
Definition: QuEST_common.c:528
void initPureState(Qureg qureg, Qureg pure)
Initialise a set of qubits, which can be a state vector or density matrix, to a given pure state.
Definition: QuEST.c:143
void tGate(Qureg qureg, const int targetQubit)
Apply the single-qubit T gate.
Definition: QuEST.c:475
void statevec_pauliY(Qureg qureg, const int targetQubit)
void statevec_hadamard(Qureg qureg, const int targetQubit)
void qasm_recordParamGate(Qureg qureg, TargetGate gate, int targetQubit, qreal param)
Definition: QuEST_qasm.c:186
void validateStateIndex(Qureg qureg, long long int stateInd, const char *caller)
void densmatr_initPlusState(Qureg targetQureg)
Definition: QuEST_cpu.c:1153
qreal calcTotalProb(Qureg qureg)
A debugging function which calculates the probability of the qubits in qureg being in any state,...
Definition: QuEST.c:822
void destroyComplexMatrixN(ComplexMatrixN m)
Destroy a ComplexMatrixN instance created with createComplexMatrixN()
Definition: QuEST.c:1021
void rotateZ(Qureg qureg, const 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:208
void shiftIndices(int *indices, int numIndices, int shift)
Definition: QuEST_common.c:149
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:464
void qasm_free(Qureg qureg)
Definition: QuEST_qasm.c:500
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:707
@ 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:207
void statevec_controlledRotateAroundAxisConj(Qureg qureg, const int controlQubit, const int targetQubit, qreal angle, Vector axis)
Definition: QuEST_common.c:333
void validateStateVecQureg(Qureg qureg, const char *caller)
void qasm_recordInitZero(Qureg qureg)
Definition: QuEST_qasm.c:415
ComplexMatrixN createComplexMatrixN(int numQubits)
Create (dynamically) a square complex matrix which can be passed to the multi-qubit general unitary f...
Definition: QuEST.c:1000
qreal statevec_calcExpecPauliSum(Qureg qureg, enum pauliOpType *allCodes, qreal *termCoeffs, int numSumTerms, Qureg workspace)
Definition: QuEST_common.c:479
void statevec_controlledTwoQubitUnitary(Qureg qureg, const int controlQubit, const int targetQubit1, const int targetQubit2, ComplexMatrix4 u)
Definition: QuEST_common.c:522
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:683
void validateMultiQubitMatrixFitsInNode(Qureg qureg, int numTargets, const char *caller)
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:966
qreal densmatr_calcPurity(Qureg qureg)
Computes the trace of the density matrix squared.
void validateNumAmps(Qureg qureg, long long int startInd, long long int numAmps, const char *caller)
void qasm_clearRecorded(Qureg qureg)
Definition: QuEST_qasm.c:477
void statevec_phaseShift(Qureg qureg, const int targetQubit, qreal angle)
Definition: QuEST_common.c:250
void qasm_recordInitPlus(Qureg qureg)
Definition: QuEST_qasm.c:430
void densmatr_mixDephasing(Qureg qureg, const int targetQubit, qreal dephase)
Definition: QuEST_cpu.c:79
ComplexMatrix4 getConjugateMatrix4(ComplexMatrix4 src)
Definition: QuEST_common.c:103
@ GATE_ROTATE_X
Definition: QuEST_qasm.h:27
void mixDephasing(Qureg qureg, const int targetQubit, qreal prob)
Mixes a density matrix qureg to induce single-qubit dephasing noise.
Definition: QuEST.c:902
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:855
void statevec_multiRotateZ(Qureg qureg, long long int mask, qreal angle)
Definition: QuEST_cpu.c:3069
void statevec_multiControlledMultiQubitUnitary(Qureg qureg, long long int ctrlMask, int *targs, const int numTargs, ComplexMatrixN u)
This calls swapQubitAmps only when it would involve a distributed communication; if the qubit chunks ...
void qasm_recordControlledCompactUnitary(Qureg qureg, Complex alpha, Complex beta, int controlQubit, int targetQubit)
Definition: QuEST_qasm.c:264
void statevec_destroyQureg(Qureg qureg, QuESTEnv env)
Definition: QuEST_cpu.c:1316
void clearRecordedQASM(Qureg qureg)
Clear all QASM so far recorded.
Definition: QuEST.c:93
int measure(Qureg qureg, int measureQubit)
Measures a single qubit, collapsing it randomly to 0 or 1.
Definition: QuEST.c:756
@ GATE_ROTATE_Z
Definition: QuEST_qasm.h:29
qreal calcFidelity(Qureg qureg, Qureg pureState)
Calculates the fidelity of qureg (a statevector or density matrix) against a reference pure state (ne...
Definition: QuEST.c:861
void densmatr_collapseToKnownProbOutcome(Qureg qureg, const int measureQubit, int outcome, qreal outcomeProb)
Renorms (/prob) every | * outcome * >< * outcome * | state, setting all others to zero.
Definition: QuEST_cpu.c:784
void validateProb(qreal prob, const char *caller)
@ GATE_SIGMA_Z
Definition: QuEST_qasm.h:23
void statevec_pauliX(Qureg qureg, const int targetQubit)
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:943
void densmatr_mixMultiQubitKrausMap(Qureg qureg, int *targets, int numTargets, ComplexMatrixN *ops, int numOps)
Definition: QuEST_common.c:642
Complex getConjugateScalar(Complex scalar)
Definition: QuEST_common.c:84
void rotateX(Qureg qureg, const int targetQubit, qreal angle)
Rotate a single qubit by a given angle around the X-axis of the Bloch-sphere.
Definition: QuEST.c:186
@ GATE_HADAMARD
Definition: QuEST_qasm.h:26
ComplexMatrix2 getConjugateMatrix2(ComplexMatrix2 src)
Definition: QuEST_common.c:98
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:1513
void statevec_rotateZ(Qureg qureg, const int rotQubit, qreal angle)
Definition: QuEST_common.c:304
void qasm_startRecording(Qureg qureg)
Definition: QuEST_qasm.c:84
void cloneQureg(Qureg targetQureg, Qureg copyQureg)
Set targetQureg to be a clone of copyQureg.
Definition: QuEST.c:163
void multiControlledTwoQubitUnitary(Qureg qureg, int *controlQubits, const int numControlQubits, const int targetQubit1, const int targetQubit2, ComplexMatrix4 u)
Apply a general multi-controlled two-qubit unitary (including a global phase factor).
Definition: QuEST.c:281
void statevec_controlledNot(Qureg qureg, const int controlQubit, const int targetQubit)
Represents a 4x4 matrix of complex numbers.
Definition: QuEST.h:125
void validateMultiTargets(Qureg qureg, int *targetQubits, const int numTargetQubits, const char *caller)
void densmatr_initClassicalState(Qureg qureg, long long int stateInd)
Definition: QuEST_cpu.c:1114
Information about the environment the program is running in.
Definition: QuEST.h:199
void setDensityAmps(Qureg qureg, qreal *reals, qreal *imags)
Set elements in the underlying state vector represenation of a density matrix.
Definition: QuEST.c:788
void pauliZ(Qureg qureg, const int targetQubit)
Apply the single-qubit Pauli-Z (also known as the Z, sigma-Z or phase-flip) gate.
Definition: QuEST.c:453
void multiControlledPhaseShift(Qureg qureg, int *controlQubits, int numControlQubits, qreal angle)
Introduce a phase factor on state of the passed qubits.
Definition: QuEST.c:509
void statevec_multiControlledPhaseShift(Qureg qureg, int *controlQubits, int numControlQubits, qreal angle)
Definition: QuEST_cpu.c:3019
Represents a general 2^N by 2^N matrix of complex numbers.
Definition: QuEST.h:136
void validateTwoQubitDepolProb(qreal prob, const char *caller)
long long int getControlFlipMask(int *controlQubits, int *controlState, const int numControlQubits)
Definition: QuEST_common.c:53
void controlledPhaseFlip(Qureg qureg, const int idQubit1, const int idQubit2)
Apply the (two-qubit) controlled phase flip gate, also known as the controlled pauliZ gate.
Definition: QuEST.c:547
void validateNumPauliSumTerms(int numTerms, const char *caller)
qreal statevec_calcFidelity(Qureg qureg, Qureg pureState)
Definition: QuEST_common.c:376
#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 on a selected number of qubits.
Definition: QuEST.c:640
void stopRecordingQASM(Qureg qureg)
Disable QASM recording.
Definition: QuEST.c:89
void setAmps(Qureg qureg, long long int startInd, qreal *reals, qreal *imags, long long int numAmps)
Overwrites a subset of the amplitudes in qureg, with those passed in reals and imags.
Definition: QuEST.c:779
void multiControlledUnitary(Qureg qureg, int *controlQubits, const int numControlQubits, const int targetQubit, ComplexMatrix2 u)
Apply a general multiple-control single-target unitary, which can include a global phase factor.
Definition: QuEST.c:372
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:559
void statevec_sqrtSwapGate(Qureg qureg, int qb1, int qb2)
Definition: QuEST_common.c:383
void qasm_recordMultiControlledParamGate(Qureg qureg, TargetGate gate, int *controlQubits, const int numControlQubits, const int targetQubit, qreal param)
Definition: QuEST_qasm.c:324
Complex getAmp(Qureg qureg, long long int index)
Get the complex amplitude at a given index in the state vector.
Definition: QuEST.c:697
qreal statevec_getProbAmp(Qureg qureg, long long int index)
Definition: QuEST_common.c:244
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:1037
void qasm_recordAxisRotation(Qureg qureg, qreal angle, Vector axis, const int targetQubit)
Definition: QuEST_qasm.c:223
void statevec_swapQubitAmps(Qureg qureg, int qb1, int qb2)
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:743
int numQubitsInStateVec
Number of qubits in the state-vector - this is double the number represented for mixed states.
Definition: QuEST.h:167
void statevec_tGate(Qureg qureg, const int targetQubit)
Definition: QuEST_common.c:271
void validateVector(Vector vec, const char *caller)
void controlledMultiQubitUnitary(Qureg qureg, int ctrl, int *targs, const int numTargs, ComplexMatrixN u)
Apply a general controlled multi-qubit unitary (including a global phase factor).
Definition: QuEST.c:312
qreal densmatr_calcTotalProb(Qureg qureg)
void statevec_rotateAroundAxisConj(Qureg qureg, const int rotQubit, qreal angle, Vector axis)
Definition: QuEST_common.c:317
void multiStateControlledUnitary(Qureg qureg, int *controlQubits, int *controlState, const int numControlQubits, const int targetQubit, ComplexMatrix2 u)
Apply a general multiple-control, conditioned on a specific bit sequence, single-target unitary,...
Definition: QuEST.c:387
long long int getQubitBitMask(int *qubits, const int numQubits)
Definition: QuEST_common.c:43
void densmatr_mixDepolarising(Qureg qureg, const int targetQubit, qreal depolLevel)
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:795
void multiControlledMultiQubitUnitary(Qureg qureg, int *ctrls, const int numCtrls, int *targs, const int numTargs, ComplexMatrixN u)
Apply a general multi-controlled multi-qubit unitary (including a global phase factor).
Definition: QuEST.c:329
void qasm_recordControlledGate(Qureg qureg, TargetGate gate, int controlQubit, int targetQubit)
Definition: QuEST_qasm.c:238
void phaseShift(Qureg qureg, const int targetQubit, qreal angle)
Shift the phase between and of a single qubit by a given angle.
Definition: QuEST.c:486
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:889
void qasm_recordMultiStateControlledUnitary(Qureg qureg, ComplexMatrix2 u, int *controlQubits, int *controlState, const int numControlQubits, const int targetQubit)
Definition: QuEST_qasm.c:362
void validateControlTarget(Qureg qureg, int controlQubit, int targetQubit, const char *caller)
void densmatr_mixDensityMatrix(Qureg combineQureg, qreal otherProb, Qureg otherQureg)
Definition: QuEST_cpu.c:889
void statevec_rotateX(Qureg qureg, const int rotQubit, qreal angle)
Definition: QuEST_common.c:292
void multiQubitUnitary(Qureg qureg, int *targs, const int numTargs, ComplexMatrixN u)
Apply a general multi-qubit unitary (including a global phase factor) with any number of target qubit...
Definition: QuEST.c:295
@ GATE_SQRT_SWAP
Definition: QuEST_qasm.h:34
void compactUnitary(Qureg qureg, const int targetQubit, Complex alpha, Complex beta)
Apply a single-qubit unitary parameterised by two given complex scalars.
Definition: QuEST.c:403
void statevec_twoQubitUnitary(Qureg qureg, const int targetQubit1, const int targetQubit2, ComplexMatrix4 u)
Definition: QuEST_common.c:516
@ GATE_SIGMA_X
Definition: QuEST_qasm.h:21
void statevec_pauliZ(Qureg qureg, const int targetQubit)
Definition: QuEST_common.c:257
void qasm_stopRecording(Qureg qureg)
Definition: QuEST_qasm.c:88
void statevec_initZeroState(Qureg qureg)
Definition: QuEST_cpu.c:1396
void hadamard(Qureg qureg, const int targetQubit)
Apply the single-qubit Hadamard gate.
Definition: QuEST.c:175
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:1066
void rotateY(Qureg qureg, const int targetQubit, qreal angle)
Rotate a single qubit by a given angle around the Y-axis of the Bloch-sphere.
Definition: QuEST.c:197
void statevec_controlledRotateZ(Qureg qureg, const int controlQubit, const int targetQubit, qreal angle)
Definition: QuEST_common.c:354
void validateOneQubitDephaseProb(qreal prob, const char *caller)
void swapGate(Qureg qureg, int qb1, int qb2)
Performs a SWAP gate between qubit1 and qubit2.
Definition: QuEST.c:599
void controlledUnitary(Qureg qureg, const int controlQubit, const int targetQubit, ComplexMatrix2 u)
Apply a general controlled unitary (single control, single target), which can include a global phase ...
Definition: QuEST.c:359
void controlledRotateY(Qureg qureg, const int controlQubit, const int targetQubit, qreal angle)
Applies a controlled rotation by a given angle around the Y-axis of the Bloch-sphere.
Definition: QuEST.c:231
void statevec_initBlankState(Qureg qureg)
Definition: QuEST_cpu.c:1366
void initStateFromAmps(Qureg qureg, qreal *reals, qreal *imags)
Initialise qureg by specifying the complete statevector.
Definition: QuEST.c:155
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:1334
void controlledNot(Qureg qureg, const int controlQubit, const int targetQubit)
Apply the controlled not (single control, single target) gate, also known as the c-X,...
Definition: QuEST.c:523
void qasm_recordInitClassical(Qureg qureg, long long int stateInd)
Definition: QuEST_qasm.c:458
void statevec_setAmps(Qureg qureg, long long int startInd, qreal *reals, qreal *imags, long long int numAmps)
Definition: QuEST_cpu.c:1236
int qasm_writeRecordedToFile(Qureg qureg, char *filename)
returns success of file write
Definition: QuEST_qasm.c:489
void qasm_recordControlledParamGate(Qureg qureg, TargetGate gate, int controlQubit, int targetQubit, qreal param)
Definition: QuEST_qasm.c:247
void statevec_cloneQureg(Qureg targetQureg, Qureg copyQureg)
works for both statevectors and density matrices
Definition: QuEST_cpu.c:1474
void writeRecordedQASMToFile(Qureg qureg, char *filename)
Writes recorded QASM to a file, throwing an error if inaccessible.
Definition: QuEST.c:101
int numRanks
Definition: QuEST.h:202
void setConjugateMatrixN(ComplexMatrixN m)
Definition: QuEST_common.c:108
void validateMatchingQuregDims(Qureg qureg1, Qureg qureg2, const char *caller)
void controlledRotateAroundAxis(Qureg qureg, const int controlQubit, const 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:586
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:676
void densmatr_mixTwoQubitKrausMap(Qureg qureg, int target1, int target2, ComplexMatrix4 *ops, int numOps)
Definition: QuEST_common.c:634
void statevec_initPlusState(Qureg qureg)
Definition: QuEST_cpu.c:1406
void qasm_recordControlledAxisRotation(Qureg qureg, qreal angle, Vector axis, int controlQubit, int targetQubit)
Definition: QuEST_qasm.c:300
void controlledTwoQubitUnitary(Qureg qureg, const int controlQubit, const int targetQubit1, const int targetQubit2, ComplexMatrix4 u)
Apply a general controlled two-qubit unitary (including a global phase factor).
Definition: QuEST.c:268
void qasm_recordMultiControlledUnitary(Qureg qureg, ComplexMatrix2 u, int *controlQubits, const int numControlQubits, const int targetQubit)
additionally performs Rz on target to restore the global phase lost from u in QASM U(a,...
Definition: QuEST_qasm.c:341
int getNumQubits(Qureg qureg)
Get the number of qubits in a qureg object.
Definition: QuEST.c:666
Complex calcInnerProduct(Qureg bra, Qureg ket)
Computes the inner product of two equal-size state vectors, given by.
Definition: QuEST.c:829
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:410
void statevec_multiControlledPhaseFlip(Qureg qureg, int *controlQubits, int numControlQubits)
Definition: QuEST_cpu.c:3291
void controlledPhaseShift(Qureg qureg, const int idQubit1, const int idQubit2, qreal angle)
Introduce a phase factor on state of qubits idQubit1 and idQubit2.
Definition: QuEST.c:497
void destroyQureg(Qureg qureg, QuESTEnv env)
Deallocate a Qureg object representing a set of qubits.
Definition: QuEST.c:75
void densmatr_mixTwoQubitDephasing(Qureg qureg, const int qubit1, const int qubit2, qreal dephase)
Definition: QuEST_cpu.c:84
void validateOneQubitKrausMap(Qureg qureg, ComplexMatrix2 *ops, int numOps, const char *caller)
void qasm_recordComment(Qureg qureg, char *comment,...)
Definition: QuEST_qasm.c:120
void densmatr_mixTwoQubitDepolarising(Qureg qureg, int qubit1, int qubit2, qreal depolLevel)
void statevec_sGateConj(Qureg qureg, const int targetQubit)
Definition: QuEST_common.c:278
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:976
void statevec_multiControlledUnitary(Qureg qureg, long long int ctrlQubitsMask, long long int ctrlFlipMask, const int targetQubit, ComplexMatrix2 u)
qreal ** real
Definition: QuEST.h:139
void initDebugState(Qureg qureg)
Initialises qureg to be in the un-normalised, non-physical state with with n-th complex amplitude (2n...
Definition: QuEST.c:1057
void statevec_rotateY(Qureg qureg, const int rotQubit, qreal angle)
Definition: QuEST_common.c:298
void initStateFromSingleFile(Qureg *qureg, char filename[200], QuESTEnv env)
Initialises the wavefunction amplitudes according to those specified in a file.
Definition: QuEST.c:1061
void startRecordingQASM(Qureg qureg)
Enable QASM recording.
Definition: QuEST.c:85
void statevec_applyPauliSum(Qureg inQureg, enum pauliOpType *allCodes, qreal *termCoeffs, int numSumTerms, Qureg outQureg)
Definition: QuEST_common.c:493
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:806
void mixDamping(Qureg qureg, const int targetQubit, qreal prob)
Mixes a density matrix qureg to induce single-qubit amplitude damping (decay to 0 state).
Definition: QuEST.c:935
Complex statevec_calcInnerProduct(Qureg bra, Qureg ket)
Terrible code which unnecessarily individually computes and sums the real and imaginary components of...
void statevec_controlledUnitary(Qureg qureg, const int controlQubit, const int targetQubit, ComplexMatrix2 u)
void initClassicalState(Qureg qureg, long long int stateInd)
Initialise a set of qubits to the classical state (also known as a "computational basis state") with...
Definition: QuEST.c:132
void validateOneQubitDepolProb(qreal prob, const char *caller)
int getQuEST_PREC(void)
Definition: QuEST.c:1077
void statevec_setWeightedQureg(Complex fac1, Qureg qureg1, Complex fac2, Qureg qureg2, Complex facOut, Qureg out)
Definition: QuEST_cpu.c:3579
void validateMultiQubits(Qureg qureg, int *qubits, const int numQubits, const char *caller)
void statevec_controlledPhaseShift(Qureg qureg, const int idQubit1, const int idQubit2, qreal angle)
Definition: QuEST_cpu.c:2980
void validateTwoQubitKrausMap(Qureg qureg, ComplexMatrix4 *ops, int numOps, const char *caller)
void densmatr_mixDamping(Qureg qureg, const int targetQubit, qreal damping)
qreal statevec_calcProbOfOutcome(Qureg qureg, const int measureQubit, int outcome)
void statevec_collapseToKnownProbOutcome(Qureg qureg, const int measureQubit, int outcome, qreal outcomeProb)
qreal statevec_getImagAmp(Qureg qureg, long long int index)
void unitary(Qureg qureg, const int targetQubit, ComplexMatrix2 u)
Apply a general single-qubit unitary (including a global phase factor).
Definition: QuEST.c:347
Represents a system of qubits.
Definition: QuEST.h:160
void controlledRotateZ(Qureg qureg, const int controlQubit, const int targetQubit, qreal angle)
Applies a controlled rotation by a given angle around the Z-axis of the Bloch-sphere.
Definition: QuEST.c:243
void mixTwoQubitDephasing(Qureg qureg, int qubit1, int qubit2, qreal prob)
Mixes a density matrix qureg to induce two-qubit dephasing noise.
Definition: QuEST.c:912
int statevec_measureWithStats(Qureg qureg, int measureQubit, qreal *outcomeProb)
Definition: QuEST_common.c:360
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:1559
qreal ** imag
Definition: QuEST.h:140
void statevec_controlledPhaseFlip(Qureg qureg, const int idQubit1, const int idQubit2)
Definition: QuEST_cpu.c:3260
qreal densmatr_calcProbOfOutcome(Qureg qureg, const int measureQubit, int outcome)
void validateTwoQubitUnitaryMatrix(Qureg qureg, ComplexMatrix4 u, const char *caller)
long long int getNumAmps(Qureg qureg)
Get the number of probability amplitudes in a qureg object, given by 2^numQubits.
Definition: QuEST.c:670
void controlledCompactUnitary(Qureg qureg, const int controlQubit, const int targetQubit, Complex alpha, Complex beta)
Apply a controlled unitary (single control, single target) parameterised by two given complex scalars...
Definition: QuEST.c:416
qreal densmatr_calcFidelity(Qureg qureg, Qureg pureState)
void statevec_controlledRotateY(Qureg qureg, const int controlQubit, const int targetQubit, qreal angle)
Definition: QuEST_common.c:348
void statevec_initClassicalState(Qureg qureg, long long int stateInd)
Definition: QuEST_cpu.c:1438
int isDensityMatrix
Whether this instance is a density-state representation.
Definition: QuEST.h:163
void statevec_controlledCompactUnitary(Qureg qureg, const int controlQubit, const int targetQubit, Complex alpha, Complex beta)
void statevec_sGate(Qureg qureg, const int targetQubit)
Definition: QuEST_common.c:264
void validateMatchingQuregTypes(Qureg qureg1, Qureg qureg2, const char *caller)
int numQubits
Definition: QuEST.h:138
void validateAmpIndex(Qureg qureg, long long int ampInd, const char *caller)
Qureg createCloneQureg(Qureg qureg, QuESTEnv env)
Create a new Qureg which is an exact clone of the passed qureg, which can be either a statevector or ...
Definition: QuEST.c:62
qreal collapseToOutcome(Qureg qureg, const int measureQubit, int outcome)
Updates qureg to be consistent with measuring measureQubit in the given outcome (0 or 1),...
Definition: QuEST.c:724
void controlledRotateX(Qureg qureg, const int controlQubit, const int targetQubit, qreal angle)
Applies a controlled rotation by a given angle around the X-axis of the Bloch-sphere.
Definition: QuEST.c:219
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:880
void statevec_tGateConj(Qureg qureg, const int targetQubit)
Definition: QuEST_common.c:285
int statevec_initStateFromSingleFile(Qureg *qureg, char filename[200], QuESTEnv env)
Definition: QuEST_cpu.c:1593
void validateOneQubitUnitaryMatrix(ComplexMatrix2 u, const char *caller)
void validateSecondQuregStateVec(Qureg qureg2, const char *caller)
void qasm_recordMeasurement(Qureg qureg, const int measureQubit)
Definition: QuEST_qasm.c:398
void statevec_sqrtSwapGateConj(Qureg qureg, int qb1, int qb2)
Definition: QuEST_common.c:396
void statevec_controlledMultiQubitUnitary(Qureg qureg, int ctrl, int *targets, const int numTargets, ComplexMatrixN u)
Definition: QuEST_common.c:534
int numQubitsRepresented
The number of qubits represented in either the state-vector or density matrix.
Definition: QuEST.h:165
long long int numAmpsTotal
Total number of amplitudes, which are possibly distributed among machines.
Definition: QuEST.h:172
@ GATE_S
Definition: QuEST_qasm.h:25
@ GATE_SWAP
Definition: QuEST_qasm.h:33
qreal real
Definition: QuEST.h:105
void validateControlState(int *controlState, const int numControlQubits, const char *caller)
void mixDensityMatrix(Qureg combineQureg, qreal otherProb, Qureg otherQureg)
Modifies combineQureg to become (1-prob)combineProb + prob otherQureg.
Definition: QuEST.c:770
Qureg createQureg(int numQubits, QuESTEnv env)
Create a Qureg object representing a set of qubits which will remain in a pure state.
Definition: QuEST.c:34
void statevec_controlledRotateX(Qureg qureg, const int controlQubit, const int targetQubit, qreal angle)
Definition: QuEST_common.c:342
qreal calcProbOfOutcome(Qureg qureg, const int measureQubit, int outcome)
Gives the probability of a specified qubit being measured in the given outcome (0 or 1).
Definition: QuEST.c:845
void densmatr_mixPauli(Qureg qureg, int qubit, qreal probX, qreal probY, qreal probZ)
Definition: QuEST_common.c:675
void multiRotateZ(Qureg qureg, int *qubits, int numQubits, qreal angle)
Apply a multi-qubit Z rotation on a selected number of qubits.
Definition: QuEST.c:624
qreal imag
Definition: QuEST.h:106
void statevec_controlledPauliYConj(Qureg qureg, const int controlQubit, const int targetQubit)
void pauliY(Qureg qureg, const int targetQubit)
Apply the single-qubit Pauli-Y (also known as the Y or sigma-Y) gate.
Definition: QuEST.c:442
void validateFileOpened(int found, const char *caller)
void validateMultiQubitKrausMap(Qureg qureg, int numTargs, ComplexMatrixN *ops, int numOps, const char *caller)
@ GATE_SIGMA_Y
Definition: QuEST_qasm.h:22
void statevec_unitary(Qureg qureg, const int targetQubit, ComplexMatrix2 u)
void qasm_recordCompactUnitary(Qureg qureg, Complex alpha, Complex beta, int targetQubit)
Definition: QuEST_qasm.c:195
void statevec_controlledRotateAroundAxis(Qureg qureg, const int controlQubit, const int targetQubit, qreal angle, Vector axis)
Definition: QuEST_common.c:326
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:955
void ensureIndsIncrease(int *ind1, int *ind2)
Definition: QuEST_common.c:63
qreal densmatr_calcHilbertSchmidtDistance(Qureg a, Qureg b)
int statevec_compareStates(Qureg mq1, Qureg mq2, qreal precision)
Definition: QuEST_cpu.c:1643
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:278
Represents one complex number.
Definition: QuEST.h:103
void statevec_rotateAroundAxis(Qureg qureg, const int rotQubit, qreal angle, Vector axis)
Definition: QuEST_common.c:310
void twoQubitUnitary(Qureg qureg, const int targetQubit1, const int targetQubit2, ComplexMatrix4 u)
Apply a general two-qubit unitary (including a global phase factor).
Definition: QuEST.c:255
void sGate(Qureg qureg, const int targetQubit)
Apply the single-qubit S gate.
Definition: QuEST.c:464
void statevec_multiControlledTwoQubitUnitary(Qureg qureg, long long int ctrlMask, const int targetQubit1, const int targetQubit2, ComplexMatrix4 u)
This calls swapQubitAmps only when it would involve a distributed communication; if the qubit chunks ...
void rotateAroundAxis(Qureg qureg, const 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:573
void qasm_recordMultiControlledGate(Qureg qureg, TargetGate gate, int *controlQubits, const int numControlQubits, const int targetQubit)
Definition: QuEST_qasm.c:316
void initZeroState(Qureg qureg)
Initialise a set of qubits to the classical zero state .
Definition: QuEST.c:111
void qasm_setup(Qureg *qureg)
Definition: QuEST_qasm.c:60
void qasm_recordGate(Qureg qureg, TargetGate gate, int targetQubit)
Definition: QuEST_qasm.c:178
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:837
void statevec_createQureg(Qureg *qureg, int numQubits, QuESTEnv env)
Definition: QuEST_cpu.c:1278
Qureg createDensityQureg(int numQubits, QuESTEnv env)
Create a Qureg for qubits which are represented by a density matrix, and can be in mixed states.
Definition: QuEST.c:48
void validateUnitaryComplexPair(Complex alpha, Complex beta, const char *caller)
@ GATE_ROTATE_Y
Definition: QuEST_qasm.h:28
void validateMultiControlsMultiTargets(Qureg qureg, int *controlQubits, const int numControlQubits, int *targetQubits, const int numTargetQubits, const char *caller)
void initPlusState(Qureg qureg)
Initialise a set of qubits to the plus state (and similarly for density matrices).
Definition: QuEST.c:123
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:871
void validateOneQubitDampingProb(qreal prob, const char *caller)
void statevec_controlledPauliY(Qureg qureg, const int controlQubit, const int targetQubit)
void pauliX(Qureg qureg, const int targetQubit)
Apply the single-qubit Pauli-X (also known as the X, sigma-X, NOT or bit-flip) gate.
Definition: QuEST.c:431
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:611
void validateUniqueTargets(Qureg qureg, int qubit1, int qubit2, const char *caller)
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:986
void printRecordedQASM(Qureg qureg)
Print recorded QASM to stdout.
Definition: QuEST.c:97
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:1073
int densmatr_measureWithStats(Qureg qureg, int measureQubit, qreal *outcomeProb)
Definition: QuEST_common.c:368
qreal statevec_calcTotalProb(Qureg qureg)
Represents a 2x2 matrix of complex numbers.
Definition: QuEST.h:114
void densmatr_initPureState(Qureg targetQureg, Qureg copyQureg)
void statevec_compactUnitary(Qureg qureg, const int targetQubit, Complex alpha, Complex beta)
void validateOneQubitPauliProbs(qreal probX, qreal probY, qreal probZ, const char *caller)
void validateMultiControlsTarget(Qureg qureg, int *controlQubits, const int numControlQubits, const int targetQubit, const char *caller)
void mixDepolarising(Qureg qureg, const int targetQubit, qreal prob)
Mixes a density matrix qureg to induce single-qubit homogeneous depolarising noise.
Definition: QuEST.c:924