QuEST_qasm.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 
16 # include "QuEST.h"
17 # include "QuEST_precision.h"
18 # include "QuEST_internal.h"
19 # include "QuEST_qasm.h"
20 
21 # include <math.h>
22 # include <stdio.h>
23 # include <stdlib.h>
24 # include <stdarg.h>
25 # include <string.h>
26 
27 # define QUREG_LABEL "q" // QASM var-name for the quantum register
28 # define MESREG_LABEL "c" // QASM var-name for the classical measurement register
29 # define CTRL_LABEL_PREF "c" // QASM syntax which prefixes gates when controlled
30 # define MEASURE_CMD "measure" // QASM cmd for measurement operation
31 # define INIT_ZERO_CMD "reset" // QASM cmd for setting state 0
32 # define COMMENT_PREF "//" // QASM syntax for a comment ;)
33 
34 # define MAX_LINE_LEN 1024 // maximum length (#chars) of a single QASM instruction
35 # define BUF_INIT_SIZE 1024 // initial size of the QASM buffer (#chars)
36 # define BUF_GROW_FAC 2 // growth factor when buffer dynamically resizes
37 # define MAX_REG_SYMBS 24 // maximum number of single-char symbols in phase function QASM
38 
39 static const char* qasmGateLabels[] = {
40  [GATE_SIGMA_X] = "x",
41  [GATE_SIGMA_Y] = "y",
42  [GATE_SIGMA_Z] = "z",
43  [GATE_T] = "t",
44  [GATE_S] = "s",
45  [GATE_HADAMARD] = "h",
46  [GATE_ROTATE_X] = "Rx",
47  [GATE_ROTATE_Y] = "Ry",
48  [GATE_ROTATE_Z] = "Rz",
49  [GATE_UNITARY] = "U", // needs phase fix when controlled
50  [GATE_PHASE_SHIFT] = "Rz",// needs phase fix when controlled
51  [GATE_SWAP] = "swap", // needs decomp into cNOTs?
52  [GATE_SQRT_SWAP] = "sqrtswap" // needs decomp into cNOTs and Rx(pi/2)?
53 };
54 
55 // @TODO make a proper internal error thing
56 void bufferOverflow(void) {
57  printf("!!!\nINTERNAL ERROR: QASM line buffer filled!\n!!!");
58  exit(1);
59 }
60 
61 void qasm_setup(Qureg* qureg) {
62 
63  // populate and attach QASM logger
64  QASMLogger *qasmLog = malloc(sizeof *qasmLog);
65  qureg->qasmLog = qasmLog;
66  if (qasmLog == NULL)
68 
69  qasmLog->isLogging = 0;
70  qasmLog->bufferSize = BUF_INIT_SIZE;
71  qasmLog->buffer = malloc(qasmLog->bufferSize * sizeof *(qasmLog->buffer));
72  if (qasmLog->buffer == NULL)
74 
75  // add headers and quantum / classical register creation
76  qasmLog->bufferFill = snprintf(
77  qasmLog->buffer, qasmLog->bufferSize,
78  "OPENQASM 2.0;\nqreg %s[%d];\ncreg %s[%d];\n",
81  if (qasmLog->bufferFill >= qasmLog->bufferSize)
83 }
84 
86  qureg.qasmLog->isLogging = 1;
87 }
88 
90  qureg.qasmLog->isLogging = 0;
91 }
92 
93 void addStringToQASM(Qureg qureg, char line[], int lineLen) {
94 
95  char* buf = qureg.qasmLog->buffer;
96  int bufSize = qureg.qasmLog->bufferSize;
97  int bufFill = qureg.qasmLog->bufferFill;
98 
99  // grow QASM buffer if necessary
100  if (lineLen + bufFill > bufSize) {
101 
102  int newBufSize = BUF_GROW_FAC * bufSize;
103  if (lineLen + bufFill > newBufSize)
104  bufferOverflow();
105 
106  char* newBuffer = malloc(newBufSize * sizeof *newBuffer);
107  sprintf(newBuffer, "%s", buf);
108  free(buf);
109 
110  qureg.qasmLog->bufferSize = newBufSize;
111  qureg.qasmLog->buffer = newBuffer;
112  bufSize = newBufSize;
113  buf = newBuffer;
114  }
115 
116  // add new str
117  int addedChars = snprintf(buf+bufFill, bufSize-bufFill, "%s", line);
118  qureg.qasmLog->bufferFill += addedChars;
119 }
120 
121 void qasm_recordComment(Qureg qureg, char* comment, ...) {
122 
123  if (!qureg.qasmLog->isLogging)
124  return;
125 
126  // write formatted comment to buff
127  va_list argp;
128  va_start(argp, comment);
129  char buff[MAX_LINE_LEN - 4];
130  vsnprintf(buff, MAX_LINE_LEN-5, comment, argp);
131  va_end(argp);
132 
133  // add chars to buff, write to QASM logger
134  char line[MAX_LINE_LEN + 1]; // for trailing \0
135  int len = snprintf(line, MAX_LINE_LEN, "%s %s\n", COMMENT_PREF, buff);
136  addStringToQASM(qureg, line, len);
137 }
138 
139 void addGateToQASM(Qureg qureg, TargetGate gate, int* controlQubits, int numControlQubits, int targetQubit, qreal* params, int numParams) {
140 
141  int len = 0;
142  char line[MAX_LINE_LEN + 1]; // for trailing \0
143 
144  // add control labels
145  for (int i=0; i < numControlQubits; i++)
146  len += snprintf(line+len, MAX_LINE_LEN-len, "%s", CTRL_LABEL_PREF);
147 
148  // add target gate
149  len += snprintf(line+len, MAX_LINE_LEN-len, "%s", qasmGateLabels[gate]);
150 
151  // add parameters
152  if (numParams > 0) {
153  len += snprintf(line+len, MAX_LINE_LEN-len, "(");
154  for (int i=0; i < numParams; i++) {
155  len += snprintf(line+len, MAX_LINE_LEN-len, REAL_QASM_FORMAT, params[i]);
156  if (i != numParams - 1)
157  len += snprintf(line+len, MAX_LINE_LEN-len, ",");
158  }
159  len += snprintf(line+len, MAX_LINE_LEN-len, ")");
160  }
161 
162  // add space
163  len += snprintf(line+len, MAX_LINE_LEN-len, " ");
164 
165  // add control qubits
166  for (int i=0; i < numControlQubits; i++)
167  len += snprintf(line+len, MAX_LINE_LEN-len, "%s[%d],", QUREG_LABEL, controlQubits[i]);
168 
169  // add target qubit, colon and newline
170  len += snprintf(line+len, MAX_LINE_LEN-len, "%s[%d];\n", QUREG_LABEL, targetQubit);
171 
172  // check whether we overflowed buffer
173  if (len >= MAX_LINE_LEN)
174  bufferOverflow();
175 
176  addStringToQASM(qureg, line, len);
177 }
178 
179 void qasm_recordGate(Qureg qureg, TargetGate gate, int targetQubit) {
180 
181  if (!qureg.qasmLog->isLogging)
182  return;
183 
184  addGateToQASM(qureg, gate, NULL, 0, targetQubit, NULL, 0);
185 }
186 
187 void qasm_recordParamGate(Qureg qureg, TargetGate gate, int targetQubit, qreal param) {
188 
189  if (!qureg.qasmLog->isLogging)
190  return;
191 
192  qreal params[1] = {param};
193  addGateToQASM(qureg, gate, NULL, 0, targetQubit, params, 1);
194 }
195 
196 void qasm_recordCompactUnitary(Qureg qureg, Complex alpha, Complex beta, int targetQubit) {
197 
198  if (!qureg.qasmLog->isLogging)
199  return;
200 
201  qreal rz2, ry, rz1;
202  getZYZRotAnglesFromComplexPair(alpha, beta, &rz2, &ry, &rz1);
203 
204  qreal params[3] = {rz2, ry, rz1};
205  addGateToQASM(qureg, GATE_UNITARY, NULL, 0, targetQubit, params, 3);
206 }
207 
208 void qasm_recordUnitary(Qureg qureg, ComplexMatrix2 u, int targetQubit) {
209 
210  if (!qureg.qasmLog->isLogging)
211  return;
212 
213  Complex alpha, beta;
214  qreal discardedGlobalPhase;
215  getComplexPairAndPhaseFromUnitary(u, &alpha, &beta, &discardedGlobalPhase);
216 
217  qreal rz2, ry, rz1;
218  getZYZRotAnglesFromComplexPair(alpha, beta, &rz2, &ry, &rz1);
219 
220  qreal params[3] = {rz2, ry, rz1};
221  addGateToQASM(qureg, GATE_UNITARY, NULL, 0, targetQubit, params, 3);
222 }
223 
224 void qasm_recordAxisRotation(Qureg qureg, qreal angle, Vector axis, int targetQubit) {
225 
226  if (!qureg.qasmLog->isLogging)
227  return;
228 
229  Complex alpha, beta;
230  getComplexPairFromRotation(angle, axis, &alpha, &beta);
231 
232  qreal rz2, ry, rz1;
233  getZYZRotAnglesFromComplexPair(alpha, beta, &rz2, &ry, &rz1);
234 
235  qreal params[3] = {rz2, ry, rz1};
236  addGateToQASM(qureg, GATE_UNITARY, NULL, 0, targetQubit, params, 3);
237 }
238 
239 void qasm_recordControlledGate(Qureg qureg, TargetGate gate, int controlQubit, int targetQubit) {
240 
241  if (!qureg.qasmLog->isLogging)
242  return;
243 
244  int controls[1] = {controlQubit};
245  addGateToQASM(qureg, gate, controls, 1, targetQubit, 0, 0);
246 }
247 
248 void qasm_recordControlledParamGate(Qureg qureg, TargetGate gate, int controlQubit, int targetQubit, qreal param) {
249 
250  if (!qureg.qasmLog->isLogging)
251  return;
252 
253  int controls[1] = {controlQubit};
254  qreal params[1] = {param};
255  addGateToQASM(qureg, gate, controls, 1, targetQubit, params, 1);
256 
257  // correct the global phase of controlled phase shifts
258  if (gate == GATE_PHASE_SHIFT) {
259  qasm_recordComment(qureg, "Restoring the discarded global phase of the previous controlled phase gate");
260  qreal phaseFix[1] = {param/2.0};
261  addGateToQASM(qureg, GATE_ROTATE_Z, NULL, 0, targetQubit, phaseFix, 1);
262  }
263 }
264 
265 void qasm_recordControlledCompactUnitary(Qureg qureg, Complex alpha, Complex beta, int controlQubit, int targetQubit) {
266 
267  if (!qureg.qasmLog->isLogging)
268  return;
269 
270  qreal rz2, ry, rz1;
271  getZYZRotAnglesFromComplexPair(alpha, beta, &rz2, &ry, &rz1);
272 
273  int controls[1] = {controlQubit};
274  qreal params[3] = {rz2, ry, rz1};
275  addGateToQASM(qureg, GATE_UNITARY, controls, 1, targetQubit, params, 3);
276 }
277 
279 void qasm_recordControlledUnitary(Qureg qureg, ComplexMatrix2 u, int controlQubit, int targetQubit) {
280 
281  if (!qureg.qasmLog->isLogging)
282  return;
283 
284  Complex alpha, beta;
285  qreal globalPhase;
286  getComplexPairAndPhaseFromUnitary(u, &alpha, &beta, &globalPhase);
287 
288  qreal rz2, ry, rz1;
289  getZYZRotAnglesFromComplexPair(alpha, beta, &rz2, &ry, &rz1);
290 
291  int controls[1] = {controlQubit};
292  qreal params[3] = {rz2, ry, rz1};
293  addGateToQASM(qureg, GATE_UNITARY, controls, 1, targetQubit, params, 3);
294 
295  // add Rz
296  qasm_recordComment(qureg, "Restoring the discarded global phase of the previous controlled unitary");
297  qreal phaseFix[1] = {globalPhase};
298  addGateToQASM(qureg, GATE_ROTATE_Z, NULL, 0, targetQubit, phaseFix, 1);
299 }
300 
301 void qasm_recordControlledAxisRotation(Qureg qureg, qreal angle, Vector axis, int controlQubit, int targetQubit) {
302 
303  if (!qureg.qasmLog->isLogging)
304  return;
305 
306  Complex alpha, beta;
307  getComplexPairFromRotation(angle, axis, &alpha, &beta);
308 
309  qreal rz2, ry, rz1;
310  getZYZRotAnglesFromComplexPair(alpha, beta, &rz2, &ry, &rz1);
311 
312  int controls[1] = {controlQubit};
313  qreal params[3] = {rz2, ry, rz1};
314  addGateToQASM(qureg, GATE_UNITARY, controls, 1, targetQubit, params, 3);
315 }
316 
317 void qasm_recordMultiControlledGate(Qureg qureg, TargetGate gate, int* controlQubits, int numControlQubits, int targetQubit) {
318 
319  if (!qureg.qasmLog->isLogging)
320  return;
321 
322  addGateToQASM(qureg, gate, controlQubits, numControlQubits, targetQubit, NULL, 0);
323 }
324 
325 void qasm_recordMultiControlledParamGate(Qureg qureg, TargetGate gate, int* controlQubits, int numControlQubits, int targetQubit, qreal param) {
326 
327  if (!qureg.qasmLog->isLogging)
328  return;
329 
330  qreal params[1] = {param};
331  addGateToQASM(qureg, gate, controlQubits, numControlQubits, targetQubit, params, 1);
332 
333  // correct the global phase of controlled phase shifts
334  if (gate == GATE_PHASE_SHIFT) {
335  qasm_recordComment(qureg, "Restoring the discarded global phase of the previous multicontrolled phase gate");
336  qreal phaseFix[1] = {param/2.0};
337  addGateToQASM(qureg, GATE_ROTATE_Z, NULL, 0, targetQubit, phaseFix, 1);
338  }
339 }
340 
342 void qasm_recordMultiControlledUnitary(Qureg qureg, ComplexMatrix2 u, int* controlQubits, int numControlQubits, int targetQubit) {
343 
344  if (!qureg.qasmLog->isLogging)
345  return;
346 
347  Complex alpha, beta;
348  qreal globalPhase;
349  getComplexPairAndPhaseFromUnitary(u, &alpha, &beta, &globalPhase);
350 
351  qreal rz2, ry, rz1;
352  getZYZRotAnglesFromComplexPair(alpha, beta, &rz2, &ry, &rz1);
353 
354  qreal params[3] = {rz2, ry, rz1};
355  addGateToQASM(qureg, GATE_UNITARY, controlQubits, numControlQubits, targetQubit, params, 3);
356 
357  // add Rz
358  qasm_recordComment(qureg, "Restoring the discarded global phase of the previous multicontrolled unitary");
359  qreal phaseFix[1] = {globalPhase};
360  addGateToQASM(qureg, GATE_ROTATE_Z, NULL, 0, targetQubit, phaseFix, 1);
361 }
362 
364  Qureg qureg, ComplexMatrix2 u, int* controlQubits, int* controlState, int numControlQubits, int targetQubit
365 ) {
366  if (!qureg.qasmLog->isLogging)
367  return;
368 
369  qasm_recordComment(qureg, "NOTing some gates so that the subsequent unitary is controlled-on-0");
370  for (int i=0; i < numControlQubits; i++)
371  if (controlState[i] == 0)
372  addGateToQASM(qureg, GATE_SIGMA_X, NULL, 0, controlQubits[i], NULL, 0);
373 
374  qasm_recordMultiControlledUnitary(qureg, u, controlQubits, numControlQubits, targetQubit);
375 
376  qasm_recordComment(qureg, "Undoing the NOTing of the controlled-on-0 qubits of the previous unitary");
377  for (int i=0; i < numControlQubits; i++)
378  if (controlState[i] == 0)
379  addGateToQASM(qureg, GATE_SIGMA_X, NULL, 0, controlQubits[i], NULL, 0);
380 }
381 
382 void qasm_recordMultiControlledMultiQubitNot(Qureg qureg, int* ctrls, int numCtrls, int* targs, int numTargs) {
383 
384  if (!qureg.qasmLog->isLogging)
385  return;
386 
387  qasm_recordComment(qureg, "The following %d gates resulted from a single %s() call", numTargs,
388  (numCtrls > 0)? "multiControlledMultiQubitNot" : "multiQubitNot");
389 
390  for (int t=0; t<numTargs; t++)
391  addGateToQASM(qureg, GATE_SIGMA_X, ctrls, numCtrls, targs[t], NULL, 0);
392 }
393 
394 /* not actually used, D'Oh!
395 void qasm_recordMultiControlledAxisRotation(Qureg qureg, qreal angle, Vector axis, int* controlQubits, int numControlQubits, int targetQubit) {
396 
397  if (!qureg.qasmLog->isLogging)
398  return;
399 
400  Complex alpha, beta;
401  getComplexPairFromRotation(angle, axis, &alpha, &beta);
402 
403  qreal rz2, ry, rz1;
404  getZYZRotAnglesFromComplexPair(alpha, beta, &rz2, &ry, &rz1);
405 
406  qreal params[3] = {rz2, ry, rz1};
407  addGateToQASM(qureg, GATE_UNITARY, controlQubits, numControlQubits, targetQubit, params, 3);
408 }
409 */
410 
411 void qasm_recordMeasurement(Qureg qureg, int measureQubit) {
412 
413  if (!qureg.qasmLog->isLogging)
414  return;
415 
416  char line[MAX_LINE_LEN + 1]; // for trailing \0
417  int len = snprintf(
418  line, MAX_LINE_LEN, "%s %s[%d] -> %s[%d];\n",
419  MEASURE_CMD, QUREG_LABEL, measureQubit, MESREG_LABEL, measureQubit);
420 
421  // check whether we overflowed buffer
422  if (len >= MAX_LINE_LEN)
423  bufferOverflow();
424 
425  addStringToQASM(qureg, line, len);
426 }
427 
429 
430  if (!qureg.qasmLog->isLogging)
431  return;
432 
433  char line[MAX_LINE_LEN + 1]; // for trailing \0
434  int len = snprintf(line, MAX_LINE_LEN, "%s %s;\n", INIT_ZERO_CMD, QUREG_LABEL);
435 
436  // check whether we overflowed buffer
437  if (len >= MAX_LINE_LEN)
438  bufferOverflow();
439 
440  addStringToQASM(qureg, line, len);
441 }
442 
444 
445  if (!qureg.qasmLog->isLogging)
446  return;
447 
448  // add an explanatory comment
449  char buf[MAX_LINE_LEN+1];
450  sprintf(buf, "Initialising state |+>");
451  qasm_recordComment(qureg, buf);
452 
453  // it's valid QASM to h the register (I think)
454  // |+> = H |0>
455  qasm_recordInitZero(qureg);
456  int charsWritten = snprintf(
457  buf, MAX_LINE_LEN, "%s %s;\n",
459  if (charsWritten >= MAX_LINE_LEN)
460  bufferOverflow();
461  addStringToQASM(qureg, buf, charsWritten);
462 
463  // old code (before above QASM shortcut)
464  /*
465  qasm_recordInitZero(qureg);
466  for (int q=0; q < qureg.numQubitsRepresented; q++)
467  qasm_recordGate(qureg, GATE_HADAMARD, q);
468  */
469 }
470 
471 void qasm_recordInitClassical(Qureg qureg, long long int stateInd) {
472 
473  if (!qureg.qasmLog->isLogging)
474  return;
475 
476  // add an explanatory comment
477  char cmt[MAX_LINE_LEN+1];
478  sprintf(cmt, "Initialising state |%lld>", stateInd);
479  qasm_recordComment(qureg, cmt);
480 
481  // start in |0>
482  qasm_recordInitZero(qureg);
483 
484  // NOT the 1 bits in stateInd
485  for (int q=0; q < qureg.numQubitsRepresented; q++)
486  if ((stateInd >> q) & 1)
487  qasm_recordGate(qureg, GATE_SIGMA_X, q);
488 }
489 
490 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) {
491 
492  if (!qureg.qasmLog->isLogging)
493  return;
494 
495  qasm_recordComment(qureg, "Here, applyPhaseFunc() multiplied a complex scalar of the form");
496 
497  // record like:
498  // exp(i (-.5 x^2 + .5 x^(-1.5) - 1.3 x^4 ))
499  char line[MAX_LINE_LEN+1];
500  int len = snprintf(line, MAX_LINE_LEN, "// exp(i (");
501  for (int t=0; t<numTerms; t++) {
502  len += snprintf(line+len, MAX_LINE_LEN-len,
503  (exponents[t] > 0)?
504  (REAL_QASM_FORMAT " x^" REAL_QASM_FORMAT) :
505  (REAL_QASM_FORMAT " x^(" REAL_QASM_FORMAT ")"),
506  (t>0)?
507  absReal(coeffs[t]) :
508  coeffs[t],
509  exponents[t]);
510  if (t < numTerms-1)
511  len += snprintf(line+len, MAX_LINE_LEN-len, (coeffs[t+1] > 0)? " + ":" - ");
512  }
513  len += snprintf(line+len, MAX_LINE_LEN-len, "))\n");
514 
515  if (len >= MAX_LINE_LEN)
516  bufferOverflow();
517  addStringToQASM(qureg, line, len);
518 
519  char encBuf[MAX_LINE_LEN];
520  if (encoding == UNSIGNED) sprintf(encBuf, "an unsigned");
521  if (encoding == TWOS_COMPLEMENT) sprintf(encBuf, "a two's complement");
522  qasm_recordComment(qureg, " upon every substate |x>, informed by qubits (under %s binary encoding)", encBuf);
523 
524  // record like:
525  // {0, 3, 2}
526  len=0;
527  len = snprintf(line, MAX_LINE_LEN, "// {");
528  for (int q=0; q<numQubits; q++)
529  len += snprintf(line+len, MAX_LINE_LEN-len, (q < numQubits-1)? "%d, ":"%d}\n", qubits[q]);
530 
531  if (len >= MAX_LINE_LEN)
532  bufferOverflow();
533  addStringToQASM(qureg, line, len);
534 
535  if (numOverrides > 0) {
536  // optionally record like:
537  // |0> -> exp(i .45)
538  // |1> -> exp(i (-.5))
539  qasm_recordComment(qureg, " though with overrides");
540  for (int v=0; v<numOverrides; v++)
541  qasm_recordComment(qureg, (overridePhases[v] >= 0)?
542  " |%lld> -> exp(i " REAL_QASM_FORMAT ")" :
543  " |%lld> -> exp(i (" REAL_QASM_FORMAT "))",
544  overrideInds[v], overridePhases[v]);
545  }
546 
547  // Here, applyPhaseFunction() multiplied a complex scalar of the form
548  // exp(i (.5 x^2 + .5 x^(-1.5) - 1.3 x^4 ))
549  // upon every sub-state |x>, informed by qubits
550  // {0, 1, 2}
551  // though with overrides
552  // |0> -> exp(i .45)
553  // |1> -> exp(i (-.5))
554 }
555 
556 char getPhaseFuncSymbol(int numSymbs, int ind) {
557 
558  static char xyz[7] = {'x', 'y', 'z', 't', 'r', 'v', 'u'};
559  if (numSymbs <= 7)
560  return xyz[ind];
561 
562  static char abc[MAX_REG_SYMBS] = {'a','b','c','d','e','f','g','h','j','k','l','m','n','p','q','r','s','t','u','v','w','x','y','z'}; // no i or o
563  if (numSymbs <= MAX_REG_SYMBS)
564  return abc[ind];
565 
566  // we should never reach here, since caller should handle when numSymbs > 24
567  bufferOverflow();
568  return 'x';
569 }
570 
571 void addMultiVarRegsToQASM(Qureg qureg, int* qubits, int* numQubitsPerReg, int numRegs, enum bitEncoding encoding) {
572 
573  char encBuf[MAX_LINE_LEN];
574  if (encoding == UNSIGNED) sprintf(encBuf, "an unsigned");
575  if (encoding == TWOS_COMPLEMENT) sprintf(encBuf, "a two's complement");
576  qasm_recordComment(qureg, " upon substates informed by qubits (under %s binary encoding)", encBuf);
577 
578  char line[MAX_LINE_LEN+1];
579  int len = 0;
580 
581  // record like:
582  // |x> = {0, 3, 2}
583  // |y> = {1, 2}
584  int qInd = 0;
585  for (int r=0; r<numRegs; r++) {
586  len = 0;
587  if (numRegs <= MAX_REG_SYMBS)
588  len += snprintf(line+len, MAX_LINE_LEN-len, "// |%c> = {", getPhaseFuncSymbol(numRegs,r));
589  else
590  len += snprintf(line+len, MAX_LINE_LEN-len, "// |x%d> = {", r);
591  for (int q=0; q<numQubitsPerReg[r]; q++)
592  len += snprintf(line+len, MAX_LINE_LEN-len, (q < numQubitsPerReg[r]-1)? "%d, ":"%d}\n", qubits[qInd++]);
593 
594  if (len >= MAX_LINE_LEN)
595  bufferOverflow();
596  addStringToQASM(qureg, line, len);
597  }
598 }
599 
600 void addMultiVarOverridesToQASM(Qureg qureg, int numRegs, long long int* overrideInds, qreal* overridePhases, int numOverrides) {
601 
602  qasm_recordComment(qureg, " though with overrides");
603 
604  char line[MAX_LINE_LEN+1];
605  int len = 0;
606 
607  // record like:
608  // |x=0, y=1, z=2> -> exp(i .45)
609  // |x=0, y=1, z=5> -> exp(i (-.5))
610  int vInd=0;
611  for (int v=0; v<numOverrides; v++) {
612  len = 0;
613  len += snprintf(line+len, MAX_LINE_LEN-len, "// |");
614  for (int r=0; r<numRegs; r++) {
615  if (numRegs <= MAX_REG_SYMBS)
616  len += snprintf(line+len, MAX_LINE_LEN-len,
617  (r<numRegs-1)?
618  "%c=%lld, " :
619  "%c=%lld>",
620  getPhaseFuncSymbol(numRegs,r),
621  overrideInds[vInd++]);
622  else
623  len += snprintf(line+len, MAX_LINE_LEN-len,
624  (r<numRegs-1)?
625  "x%d=%lld, " :
626  "x%d=%lld>",
627  r,
628  overrideInds[vInd++]);
629  }
630  len += snprintf(line+len, MAX_LINE_LEN-len,
631  (overridePhases[v] >= 0)?
632  " -> exp(i " REAL_QASM_FORMAT ")\n" :
633  " -> exp(i (" REAL_QASM_FORMAT "))\n",
634  overridePhases[v]);
635 
636  if (len >= MAX_LINE_LEN)
637  bufferOverflow();
638  addStringToQASM(qureg, line, len);
639  }
640 }
641 
642 void addShiftValuesToQASM(Qureg qureg, enum phaseFunc funcName, int numRegs, qreal* params) {
643 
644  char line[MAX_LINE_LEN+1];
645  int len = 0;
646  int numDeltas;
647  if (funcName == SCALED_INVERSE_SHIFTED_NORM)
648  numDeltas = numRegs;
649  else if (funcName == SCALED_INVERSE_SHIFTED_DISTANCE)
650  numDeltas = numRegs / 2;
651  else
652  return;
653 
654  qasm_recordComment(qureg, " with the additional parameters");
655 
656  for (int k=0; k<numDeltas; k++) {
657  len = 0;
658  len += snprintf(line+len, MAX_LINE_LEN-len, "// delta%d = " REAL_QASM_FORMAT "\n", k, params[2+k]);
659  if (len >= MAX_LINE_LEN)
660  bufferOverflow();
661  addStringToQASM(qureg, line, len);
662  }
663 
664 }
665 
666 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) {
667 
668  if (!qureg.qasmLog->isLogging)
669  return;
670 
671  qasm_recordComment(qureg, "Here, applyMultiVarPhaseFunc() multiplied a complex scalar of the form");
672 
673  // Here, applyMultiVarPhaseFunction() multiplied a complex scalar of the form
674  // exp(i (
675  // .5 x^2 + .6 x + x
676  // - y^2 - 5 y - y
677  // + z^2 + z^3 ))
678 
679  qasm_recordComment(qureg, " exp(i (");
680  char line[MAX_LINE_LEN+1];
681  int len=0;
682 
683  int tFlatInd = 0;
684  for (int r=0; r<numRegs; r++) {
685  len = snprintf(line, MAX_LINE_LEN, "// ");
686 
687  // manually force sign of first term
688  len += snprintf(line+len, MAX_LINE_LEN-len, (coeffs[tFlatInd] > 0)? " + ":" - ");
689 
690  for (int t=0; t<numTermsPerReg[r]; t++) {
691  if (numRegs <= MAX_REG_SYMBS)
692  len += snprintf(line+len, MAX_LINE_LEN-len,
693  (exponents[tFlatInd] > 0)?
694  REAL_QASM_FORMAT " %c^" REAL_QASM_FORMAT :
695  REAL_QASM_FORMAT " %c^(" REAL_QASM_FORMAT ")",
696  absReal(coeffs[tFlatInd]),
697  getPhaseFuncSymbol(numRegs,r),
698  exponents[tFlatInd]);
699  else
700  len += snprintf(line+len, MAX_LINE_LEN-len,
701  (exponents[tFlatInd] > 0)?
702  REAL_QASM_FORMAT " x%d^" REAL_QASM_FORMAT :
703  REAL_QASM_FORMAT " x%d^(" REAL_QASM_FORMAT ")",
704  absReal(coeffs[tFlatInd]), r, exponents[tFlatInd]);
705  if (t < numTermsPerReg[r]-1)
706  len += snprintf(line+len, MAX_LINE_LEN-len, (coeffs[tFlatInd+1] > 0)? " + ":" - ");
707  tFlatInd++;
708  }
709 
710  if (r < numRegs-1)
711  len += snprintf(line+len, MAX_LINE_LEN-len, "\n");
712  else
713  len += snprintf(line+len, MAX_LINE_LEN-len, " ))\n");
714 
715  if (len >= MAX_LINE_LEN)
716  bufferOverflow();
717  addStringToQASM(qureg, line, len);
718  }
719 
720  addMultiVarRegsToQASM(qureg, qubits, numQubitsPerReg, numRegs, encoding);
721 
722  if (numOverrides > 0)
723  addMultiVarOverridesToQASM(qureg, numRegs, overrideInds, overridePhases, numOverrides);
724 }
725 
726 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) {
727  // I apologise to my future self and my esteemed readers for such terrible code
728 
729  if (!qureg.qasmLog->isLogging)
730  return;
731 
732  qasm_recordComment(qureg, "Here, applyNamedPhaseFunc() multiplied a complex scalar of form");
733  char line[MAX_LINE_LEN+1];
734 
735  int len = snprintf(line, MAX_LINE_LEN, "// exp(i ");
736 
737  // record norm-based function, like: (-1.0) / sqrt(x^2 + y^2 + z^2 + ...)
738  if (funcName == NORM || funcName == SCALED_NORM ||
739  funcName == INVERSE_NORM || funcName == SCALED_INVERSE_NORM ||
740  funcName == SCALED_INVERSE_SHIFTED_NORM)
741  {
742  // coefficient
743  if (funcName == SCALED_NORM || funcName == SCALED_INVERSE_NORM || funcName == SCALED_INVERSE_SHIFTED_NORM)
744  len += snprintf(line+len, MAX_LINE_LEN-len,
745  (params[0]>0)?
746  REAL_QASM_FORMAT " " :
747  "(" REAL_QASM_FORMAT ") ",
748  params[0]);
749 
750  // sqrt(
751  if (funcName == NORM || funcName == SCALED_NORM)
752  len += snprintf(line+len, MAX_LINE_LEN-len, "sqrt(");
753  else if (funcName == INVERSE_NORM)
754  len += snprintf(line+len, MAX_LINE_LEN-len, "1 / sqrt(");
755  else if (funcName == SCALED_INVERSE_NORM || funcName == SCALED_INVERSE_SHIFTED_NORM)
756  len += snprintf(line+len, MAX_LINE_LEN-len, "/ sqrt(");
757 
758  // x^2 + y^2 + ...
759  if (numRegs <= MAX_REG_SYMBS)
760  for (int r=0; r<numRegs; r++) {
761  if (funcName == SCALED_INVERSE_SHIFTED_NORM)
762  len += snprintf(line+len, MAX_LINE_LEN-len,
763  (params[2+r] < 0)?
764  "(%c^2+" REAL_QASM_FORMAT ")" :
765  "(%c^2-" REAL_QASM_FORMAT ")",
766  getPhaseFuncSymbol(numRegs,r), fabs(params[2+r]));
767  else
768  len += snprintf(line+len, MAX_LINE_LEN-len, "%c^2", getPhaseFuncSymbol(numRegs,r));
769  len += snprintf(line+len, MAX_LINE_LEN-len, (r < numRegs - 1)? " + ":"))\n");
770  }
771  else {
772  if (funcName == SCALED_INVERSE_SHIFTED_NORM)
773  len += snprintf(line+len, MAX_LINE_LEN-len, "(x0-delta0)^2 + (x1-delta1)^2 + (x2-delta2)^2... ))\n");
774  else
775  len += snprintf(line+len, MAX_LINE_LEN-len, "x0^2 + x1^2 + x2^2... ))\n");
776  }
777  }
778  // record product-based, like (-1.0) 1/(x y z) ...
779  else if (funcName == PRODUCT || funcName == SCALED_PRODUCT ||
780  funcName == INVERSE_PRODUCT || funcName == SCALED_INVERSE_PRODUCT)
781  {
782  // coefficient
783  if (funcName == SCALED_PRODUCT || funcName == SCALED_INVERSE_PRODUCT)
784  len += snprintf(line+len, MAX_LINE_LEN-len,
785  (params[0]>0)?
786  REAL_QASM_FORMAT " ":
787  "(" REAL_QASM_FORMAT ") ",
788  params[0]);
789 
790  // reciprocal
791  if (funcName == INVERSE_PRODUCT)
792  len += snprintf(line+len, MAX_LINE_LEN-len, "1 / (");
793  else if (funcName == SCALED_INVERSE_PRODUCT)
794  len += snprintf(line+len, MAX_LINE_LEN-len, "/ (");
795 
796  // x y z ...
797  if (numRegs <= MAX_REG_SYMBS)
798  for (int r=0; r<numRegs; r++)
799  len += snprintf(line+len, MAX_LINE_LEN-len, (r < numRegs - 1)? "%c ":"%c)", getPhaseFuncSymbol(numRegs,r));
800  else
801  len += snprintf(line+len, MAX_LINE_LEN-len, "x0 x1 x2 ...)");
802 
803  // close reciprocal brackets
804  if (funcName == INVERSE_PRODUCT || funcName == SCALED_INVERSE_PRODUCT)
805  len += snprintf(line+len, MAX_LINE_LEN-len, ")");
806  len += snprintf(line+len, MAX_LINE_LEN-len, "\n");
807  }
808  // record distance-based, like (-1.0) 1/sqrt((x1-x2)^2 + (y1-y2)^2 + ...)
809  else if (funcName == DISTANCE || funcName == SCALED_DISTANCE ||
810  funcName == INVERSE_DISTANCE || funcName == SCALED_INVERSE_DISTANCE ||
812  {
813  // coefficient
814  if (funcName == SCALED_DISTANCE || funcName == SCALED_INVERSE_DISTANCE || funcName == SCALED_INVERSE_SHIFTED_DISTANCE)
815  len += snprintf(line+len, MAX_LINE_LEN-len,
816  (params[0]>0)?
817  REAL_QASM_FORMAT " " :
818  "(" REAL_QASM_FORMAT ") ",
819  params[0]);
820 
821  // sqrt(
822  if (funcName == DISTANCE || funcName == SCALED_DISTANCE)
823  len += snprintf(line+len, MAX_LINE_LEN-len, "sqrt(");
824  else if (funcName == INVERSE_DISTANCE)
825  len += snprintf(line+len, MAX_LINE_LEN-len, "1 / sqrt(");
826  else if (funcName == SCALED_INVERSE_DISTANCE || funcName == SCALED_INVERSE_SHIFTED_DISTANCE)
827  len += snprintf(line+len, MAX_LINE_LEN-len, "/ sqrt(");
828 
829  // (x-y)^2 + (z-t)^2 + ...
830  if (numRegs <= MAX_REG_SYMBS)
831  for (int r=0; r<numRegs; r+=2) {
832  if (funcName == SCALED_INVERSE_SHIFTED_DISTANCE)
833  len += snprintf(line+len, MAX_LINE_LEN-len,
834  (params[2+r/2] < 0)?
835  "(%c-%c+" REAL_QASM_FORMAT ")^2":
836  "(%c-%c-" REAL_QASM_FORMAT ")^2",
837  getPhaseFuncSymbol(numRegs,r), getPhaseFuncSymbol(numRegs,r+1), fabs(params[2+r/2]));
838  else
839  len += snprintf(line+len, MAX_LINE_LEN-len, "(%c-%c)^2",
840  getPhaseFuncSymbol(numRegs,r), getPhaseFuncSymbol(numRegs,r+1));
841  len += snprintf(line+len, MAX_LINE_LEN-len, (r+1 < numRegs-1)? " + ":"))\n");
842  }
843  else {
844  if (funcName == SCALED_INVERSE_SHIFTED_DISTANCE)
845  len += snprintf(line+len, MAX_LINE_LEN-len, "(x0-x1-delta0)^2 + (x2-x3-delta1)^2 + ...))\n");
846  else
847  len += snprintf(line+len, MAX_LINE_LEN-len, "(x0-x1)^2 + (x2-x3)^2 + ...))\n");
848  }
849  }
850 
851  if (len >= MAX_LINE_LEN)
852  bufferOverflow();
853  addStringToQASM(qureg, line, len);
854 
855  addMultiVarRegsToQASM(qureg, qubits, numQubitsPerReg, numRegs, encoding);
856  if (numRegs > MAX_REG_SYMBS && (funcName == SCALED_INVERSE_SHIFTED_NORM || funcName == SCALED_INVERSE_SHIFTED_DISTANCE))
857  addShiftValuesToQASM(qureg, funcName, numRegs, params);
858 
859  if (numOverrides > 0)
860  addMultiVarOverridesToQASM(qureg, numRegs, overrideInds,overridePhases, numOverrides);
861 }
862 
863 
865 
866  // maintains current buffer size
867  (qureg.qasmLog->buffer)[0] = '\0';
868  qureg.qasmLog->bufferFill = 0;
869 }
870 
872  printf("%s", qureg.qasmLog->buffer);
873 }
874 
876 int qasm_writeRecordedToFile(Qureg qureg, char* filename) {
877 
878  FILE *file = fopen(filename, "w");
879  if (file == NULL)
880  return 0;
881 
882  fprintf(file, "%s", qureg.qasmLog->buffer);
883  fclose(file);
884  return 1;
885 }
886 
887 void qasm_free(Qureg qureg) {
888 
889  free(qureg.qasmLog->buffer);
890  free(qureg.qasmLog);
891 }
void qasm_printRecorded(Qureg qureg)
Definition: QuEST_qasm.c:871
@ INVERSE_PRODUCT
Definition: QuEST.h:233
Represents a 3-vector of real numbers.
Definition: QuEST.h:198
#define MEASURE_CMD
Definition: QuEST_qasm.c:30
#define MAX_LINE_LEN
Definition: QuEST_qasm.c:34
@ DISTANCE
Definition: QuEST.h:234
void qasm_recordParamGate(Qureg qureg, TargetGate gate, int targetQubit, qreal param)
Definition: QuEST_qasm.c:187
#define MESREG_LABEL
Definition: QuEST_qasm.c:28
void qasm_free(Qureg qureg)
Definition: QuEST_qasm.c:887
@ 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
char getPhaseFuncSymbol(int numSymbs, int ind)
Definition: QuEST_qasm.c:556
void qasm_recordInitZero(Qureg qureg)
Definition: QuEST_qasm.c:428
void qasm_recordMultiControlledGate(Qureg qureg, TargetGate gate, int *controlQubits, int numControlQubits, int targetQubit)
Definition: QuEST_qasm.c:317
void qasm_clearRecorded(Qureg qureg)
Definition: QuEST_qasm.c:864
void qasm_recordInitPlus(Qureg qureg)
Definition: QuEST_qasm.c:443
@ GATE_ROTATE_X
Definition: QuEST_qasm.h:27
@ TWOS_COMPLEMENT
Definition: QuEST.h:269
void qasm_recordControlledCompactUnitary(Qureg qureg, Complex alpha, Complex beta, int controlQubit, int targetQubit)
Definition: QuEST_qasm.c:265
@ GATE_ROTATE_Z
Definition: QuEST_qasm.h:29
@ GATE_SIGMA_Z
Definition: QuEST_qasm.h:23
@ NORM
Definition: QuEST.h:232
@ GATE_HADAMARD
Definition: QuEST_qasm.h:26
void qasm_startRecording(Qureg qureg)
Definition: QuEST_qasm.c:85
@ SCALED_INVERSE_DISTANCE
Definition: QuEST.h:234
#define MAX_REG_SYMBS
Definition: QuEST_qasm.c:37
@ UNSIGNED
Definition: QuEST.h:269
void getComplexPairFromRotation(qreal angle, Vector axis, Complex *alpha, Complex *beta)
Definition: QuEST_common.c:120
@ INVERSE_DISTANCE
Definition: QuEST.h:234
void qasm_recordMultiControlledMultiQubitNot(Qureg qureg, int *ctrls, int numCtrls, int *targs, int numTargs)
Definition: QuEST_qasm.c:382
#define qreal
void qasm_recordMultiStateControlledUnitary(Qureg qureg, ComplexMatrix2 u, int *controlQubits, int *controlState, int numControlQubits, int targetQubit)
Definition: QuEST_qasm.c:363
void addShiftValuesToQASM(Qureg qureg, enum phaseFunc funcName, int numRegs, qreal *params)
Definition: QuEST_qasm.c:642
void qasm_recordControlledGate(Qureg qureg, TargetGate gate, int controlQubit, int targetQubit)
Definition: QuEST_qasm.c:239
void qasm_recordAxisRotation(Qureg qureg, qreal angle, Vector axis, int targetQubit)
Definition: QuEST_qasm.c:224
@ GATE_SQRT_SWAP
Definition: QuEST_qasm.h:34
phaseFunc
Flags for specifying named phase functions.
Definition: QuEST.h:231
@ 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
#define INIT_ZERO_CMD
Definition: QuEST_qasm.c:31
@ SCALED_PRODUCT
Definition: QuEST.h:233
void qasm_recordInitClassical(Qureg qureg, long long int stateInd)
Definition: QuEST_qasm.c:471
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 qasm_recordControlledAxisRotation(Qureg qureg, qreal angle, Vector axis, int controlQubit, int targetQubit)
Definition: QuEST_qasm.c:301
@ GATE_UNITARY
Definition: QuEST_qasm.h:31
static const char * qasmGateLabels[]
Definition: QuEST_qasm.c:39
void qasm_recordComment(Qureg qureg, char *comment,...)
Definition: QuEST_qasm.c:121
@ SCALED_INVERSE_SHIFTED_NORM
Definition: QuEST.h:232
QASMLogger * qasmLog
Storage for generated QASM output.
Definition: QuEST.h:351
void bufferOverflow(void)
Definition: QuEST_qasm.c:56
void addStringToQASM(Qureg qureg, char line[], int lineLen)
Definition: QuEST_qasm.c:93
#define QUREG_LABEL
TODO.
Definition: QuEST_qasm.c:27
#define COMMENT_PREF
Definition: QuEST_qasm.c:32
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
@ INVERSE_NORM
Definition: QuEST.h:232
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
#define BUF_INIT_SIZE
Definition: QuEST_qasm.c:35
void getZYZRotAnglesFromComplexPair(Complex alpha, Complex beta, qreal *rz2, qreal *ry, qreal *rz1)
maps U(alpha, beta) to Rz(rz2) Ry(ry) Rz(rz1)
Definition: QuEST_common.c:130
void addMultiVarRegsToQASM(Qureg qureg, int *qubits, int *numQubitsPerReg, int numRegs, enum bitEncoding encoding)
Definition: QuEST_qasm.c:571
@ PRODUCT
Definition: QuEST.h:233
#define CTRL_LABEL_PREF
Definition: QuEST_qasm.c:29
void addGateToQASM(Qureg qureg, TargetGate gate, int *controlQubits, int numControlQubits, int targetQubit, qreal *params, int numParams)
Definition: QuEST_qasm.c:139
#define BUF_GROW_FAC
Definition: QuEST_qasm.c:36
int numQubitsRepresented
The number of qubits represented in either the state-vector or density matrix.
Definition: QuEST.h:327
@ SCALED_DISTANCE
Definition: QuEST.h:234
@ GATE_S
Definition: QuEST_qasm.h:25
@ GATE_SWAP
Definition: QuEST_qasm.h:33
TargetGate
! Identifiers of single-target gates
Definition: QuEST_qasm.h:20
@ 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 qasm_recordCompactUnitary(Qureg qureg, Complex alpha, Complex beta, int targetQubit)
Definition: QuEST_qasm.c:196
@ SCALED_INVERSE_SHIFTED_DISTANCE
Definition: QuEST.h:234
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
Represents one complex number.
Definition: QuEST.h:103
@ SCALED_NORM
Definition: QuEST.h:232
@ SCALED_INVERSE_PRODUCT
Definition: QuEST.h:233
void qasm_setup(Qureg *qureg)
Definition: QuEST_qasm.c:61
void qasm_recordGate(Qureg qureg, TargetGate gate, int targetQubit)
Definition: QuEST_qasm.c:179
@ GATE_ROTATE_Y
Definition: QuEST_qasm.h:28
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
bitEncoding
Flags for specifying how the bits in sub-register computational basis states are mapped to indices in...
Definition: QuEST.h:269
Represents a 2x2 matrix of complex numbers.
Definition: QuEST.h:137
void addMultiVarOverridesToQASM(Qureg qureg, int numRegs, long long int *overrideInds, qreal *overridePhases, int numOverrides)
Definition: QuEST_qasm.c:600
void getComplexPairAndPhaseFromUnitary(ComplexMatrix2 u, Complex *alpha, Complex *beta, qreal *globalPhase)
maps U(r0c0, r0c1, r1c0, r1c1) to exp(i globalPhase) U(alpha, beta)
Definition: QuEST_common.c:142
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
@ SCALED_INVERSE_NORM
Definition: QuEST.h:232