QuEST_common.c File Reference
#include "QuEST.h"
#include "QuEST_internal.h"
#include "QuEST_precision.h"
#include "QuEST_validation.h"
#include "QuEST_qasm.h"
#include "mt19937ar.h"
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>

Go to the source code of this file.

Macros

#define M_PI   3.1415926535897932384626433832795028841971
 
#define macro_allocStackComplexMatrixN(matrix, numQubits)
 
#define macro_initialiseStackComplexMatrixN(matrix, numQubits, real, imag)
 
#define macro_populateKrausOperator(superOp, ops, numOps, opDim)
 
#define macro_setConjugateMatrix(dest, src, dim)
 

Functions

void agnostic_applyQFT (Qureg qureg, int *qubits, int numQubits)
 
void agnostic_applyTrotterCircuit (Qureg qureg, PauliHamil hamil, qreal time, int order, int reps)
 
void applyExponentiatedPauliHamil (Qureg qureg, PauliHamil hamil, qreal fac, int reverse)
 
void applySymmetrizedTrotterCircuit (Qureg qureg, PauliHamil hamil, qreal time, int order)
 
ComplexMatrixN bindArraysToStackComplexMatrixN (int numQubits, qreal re[][1<< numQubits], qreal im[][1<< numQubits], qreal **reStorage, qreal **imStorage)
 
void densmatr_applyKrausSuperoperator (Qureg qureg, int target, ComplexMatrix4 superOp)
 
void densmatr_applyMultiQubitKrausSuperoperator (Qureg qureg, int *targets, int numTargets, ComplexMatrixN superOp)
 
void densmatr_applyTwoQubitKrausSuperoperator (Qureg qureg, int target1, int target2, ComplexMatrixN superOp)
 
int densmatr_measureWithStats (Qureg qureg, int measureQubit, qreal *outcomeProb)
 
void densmatr_mixKrausMap (Qureg qureg, int target, ComplexMatrix2 *ops, int numOps)
 
void densmatr_mixMultiQubitKrausMap (Qureg qureg, int *targets, int numTargets, ComplexMatrixN *ops, int numOps)
 
void densmatr_mixPauli (Qureg qureg, int qubit, qreal probX, qreal probY, qreal probZ)
 
void densmatr_mixTwoQubitKrausMap (Qureg qureg, int target1, int target2, ComplexMatrix4 *ops, int numOps)
 
void ensureIndsIncrease (int *ind1, int *ind2)
 
int generateMeasurementOutcome (qreal zeroProb, qreal *outcomeProb)
 
void getComplexPairAndPhaseFromUnitary (ComplexMatrix2 u, Complex *alpha, Complex *beta, qreal *globalPhase)
 maps U(r0c0, r0c1, r1c0, r1c1) to exp(i globalPhase) U(alpha, beta) More...
 
void getComplexPairFromRotation (qreal angle, Vector axis, Complex *alpha, Complex *beta)
 
ComplexMatrix2 getConjugateMatrix2 (ComplexMatrix2 src)
 
ComplexMatrix4 getConjugateMatrix4 (ComplexMatrix4 src)
 
Complex getConjugateScalar (Complex scalar)
 
long long int getControlFlipMask (int *controlQubits, int *controlState, int numControlQubits)
 
long long int getQubitBitMask (int *qubits, int numQubits)
 
void getQuESTDefaultSeedKey (unsigned long int *key)
 
Vector getUnitVector (Vector vec)
 
qreal getVectorMagnitude (Vector vec)
 
void getZYZRotAnglesFromComplexPair (Complex alpha, Complex beta, qreal *rz2, qreal *ry, qreal *rz1)
 maps U(alpha, beta) to Rz(rz2) Ry(ry) Rz(rz1) More...
 
unsigned long int hashString (char *str)
 
void populateKrausSuperOperator2 (ComplexMatrix4 *superOp, ComplexMatrix2 *ops, int numOps)
 
void populateKrausSuperOperator4 (ComplexMatrixN *superOp, ComplexMatrix4 *ops, int numOps)
 
void populateKrausSuperOperatorN (ComplexMatrixN *superOp, ComplexMatrixN *ops, int numOps)
 
void reportQuregParams (Qureg qureg)
 Report metainformation about a set of qubits: number of qubits, number of probability amplitudes. More...
 
void reportState (Qureg qureg)
 Print the current state vector of probability amplitudes for a set of qubits to file. More...
 
void setConjugateMatrixN (ComplexMatrixN m)
 
void shiftIndices (int *indices, int numIndices, int shift)
 
void shiftSubregIndices (int *allInds, int *numIndsPerReg, int numRegs, int shift)
 
void statevec_applyPauliProd (Qureg workspace, int *targetQubits, enum pauliOpType *pauliCodes, int numTargets)
 
void statevec_applyPauliSum (Qureg inQureg, enum pauliOpType *allCodes, qreal *termCoeffs, int numSumTerms, Qureg outQureg)
 
qreal statevec_calcExpecPauliProd (Qureg qureg, int *targetQubits, enum pauliOpType *pauliCodes, int numTargets, Qureg workspace)
 
qreal statevec_calcExpecPauliSum (Qureg qureg, enum pauliOpType *allCodes, qreal *termCoeffs, int numSumTerms, Qureg workspace)
 
qreal statevec_calcFidelity (Qureg qureg, Qureg pureState)
 
void statevec_controlledMultiQubitUnitary (Qureg qureg, int ctrl, int *targets, int numTargets, ComplexMatrixN u)
 
void statevec_controlledRotateAroundAxis (Qureg qureg, int controlQubit, int targetQubit, qreal angle, Vector axis)
 
void statevec_controlledRotateAroundAxisConj (Qureg qureg, int controlQubit, int targetQubit, qreal angle, Vector axis)
 
void statevec_controlledRotateX (Qureg qureg, int controlQubit, int targetQubit, qreal angle)
 
void statevec_controlledRotateY (Qureg qureg, int controlQubit, int targetQubit, qreal angle)
 
void statevec_controlledRotateZ (Qureg qureg, int controlQubit, int targetQubit, qreal angle)
 
void statevec_controlledTwoQubitUnitary (Qureg qureg, int controlQubit, int targetQubit1, int targetQubit2, ComplexMatrix4 u)
 
qreal statevec_getProbAmp (Qureg qureg, long long int index)
 
int statevec_measureWithStats (Qureg qureg, int measureQubit, qreal *outcomeProb)
 
void statevec_multiControlledMultiRotatePauli (Qureg qureg, long long int ctrlMask, int *targetQubits, enum pauliOpType *targetPaulis, int numTargets, qreal angle, int applyConj)
 
void statevec_multiQubitUnitary (Qureg qureg, int *targets, int numTargets, ComplexMatrixN u)
 
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 More...
 
void statevec_pauliZ (Qureg qureg, int targetQubit)
 
void statevec_phaseShift (Qureg qureg, int targetQubit, qreal angle)
 
void statevec_rotateAroundAxis (Qureg qureg, int rotQubit, qreal angle, Vector axis)
 
void statevec_rotateAroundAxisConj (Qureg qureg, int rotQubit, qreal angle, Vector axis)
 
void statevec_rotateX (Qureg qureg, int rotQubit, qreal angle)
 
void statevec_rotateY (Qureg qureg, int rotQubit, qreal angle)
 
void statevec_rotateZ (Qureg qureg, int rotQubit, qreal angle)
 
void statevec_sGate (Qureg qureg, int targetQubit)
 
void statevec_sGateConj (Qureg qureg, int targetQubit)
 
void statevec_sqrtSwapGate (Qureg qureg, int qb1, int qb2)
 
void statevec_sqrtSwapGateConj (Qureg qureg, int qb1, int qb2)
 
void statevec_tGate (Qureg qureg, int targetQubit)
 
void statevec_tGateConj (Qureg qureg, int targetQubit)
 
void statevec_twoQubitUnitary (Qureg qureg, int targetQubit1, int targetQubit2, ComplexMatrix4 u)
 

Detailed Description

Internal and API functions which are hardware-agnostic. These must never call a front-end function in QuEST.c, which would lead to duplication of e.g. QASM logging and validation. Note that though many of these functions are prefixed with statevec_, they will be called multiple times to effect their equivalent operation on density matrices, so the passed Qureg can be assumed a statevector. Functions prefixed with densmatr_ may still explicitly call statevec_ functions, but will need to manually apply the conjugate qubit-shifted operations to satisfy the Choi–Jamiolkowski isomorphism

Author
Tyson Jones
Ania Brown (seeding, reporting)
Balint Koczor (Kraus maps, mixPauli, Windows compatibility)

Definition in file QuEST_common.c.

Macro Definition Documentation

◆ M_PI

#define M_PI   3.1415926535897932384626433832795028841971

Definition at line 41 of file QuEST_common.c.

◆ macro_allocStackComplexMatrixN

#define macro_allocStackComplexMatrixN (   matrix,
  numQubits 
)
Value:
/* reArr_, imArr_, reStorage_, and imStorage_ must not exist in calling scope */ \
qreal reArr_[1<<(numQubits)][1<<(numQubits)]; \
qreal imArr_[1<<(numQubits)][1<<(numQubits)]; \
macro_initialiseStackComplexMatrixN(matrix, (numQubits), reArr_, imArr_);

Definition at line 675 of file QuEST_common.c.

◆ macro_initialiseStackComplexMatrixN

#define macro_initialiseStackComplexMatrixN (   matrix,
  numQubits,
  real,
  imag 
)
Value:
/* reStorage_ and imStorage_ must not exist in calling scope */ \
qreal* reStorage_[1<<(numQubits)]; \
qreal* imStorage_[1<<(numQubits)]; \
matrix = bindArraysToStackComplexMatrixN((numQubits), real, imag, reStorage_, imStorage_);

Definition at line 669 of file QuEST_common.c.

◆ macro_populateKrausOperator

#define macro_populateKrausOperator (   superOp,
  ops,
  numOps,
  opDim 
)
Value:
/* clear the superop */ \
for (int r=0; r < (opDim)*(opDim); r++) \
for (int c=0; c < (opDim)*(opDim); c++) { \
superOp->real[r][c] = 0; \
superOp->imag[r][c] = 0; \
} \
/* add each op's contribution to the superop */ \
for (int n=0; n<(numOps); n++) \
/* superop += conjugate(op) (x) op, where (x) is a tensor product */ \
for (int i = 0; i < (opDim); i++) \
for (int j = 0; j < (opDim); j++) \
for (int k = 0; k < (opDim); k++) \
for (int l = 0; l < (opDim); l++) { \
superOp->real[i*(opDim) + k][j*(opDim) + l] += \
ops[n].real[i][j]*ops[n].real[k][l] + \
ops[n].imag[i][j]*ops[n].imag[k][l]; \
superOp->imag[i*(opDim) + k][j*(opDim) + l] += \
ops[n].real[i][j]*ops[n].imag[k][l] - \
ops[n].imag[i][j]*ops[n].real[k][l]; \
}

Definition at line 585 of file QuEST_common.c.

◆ macro_setConjugateMatrix

#define macro_setConjugateMatrix (   dest,
  src,
  dim 
)
Value:
for (int i=0; i<dim; i++) \
for (int j=0; j<dim; j++) { \
dest.real[i][j] = src.real[i][j]; \
dest.imag[i][j] = - src.imag[i][j]; /* negative for conjugate */ \
}

Definition at line 99 of file QuEST_common.c.

Function Documentation

◆ agnostic_applyQFT()

void agnostic_applyQFT ( Qureg  qureg,
int *  qubits,
int  numQubits 
)

Definition at line 849 of file QuEST_common.c.

849  {
850 
851  int densShift = qureg.numQubitsRepresented;
852 
853  // start with top/left-most qubit, work down
854  for (int q=numQubits-1; q >= 0; q--) {
855 
856  // H
857  statevec_hadamard(qureg, qubits[q]);
858  if (qureg.isDensityMatrix)
859  statevec_hadamard(qureg, qubits[q] + densShift);
860  qasm_recordGate(qureg, GATE_HADAMARD, qubits[q]);
861 
862  if (q == 0)
863  break;
864 
865  // succession of C-phases, control on qubits[q], targeting each of
866  // qubits[q-1], qubits[q-1], ... qubits[0]. This can be expressed by
867  // a single invocation of applyNamedPhaseFunc product
868 
869  int numRegs = 2;
870  int numQubitsPerReg[2] = {q, 1};
871  int regs[100]; // [q+1];
872  for (int i=0; i<q+1; i++)
873  regs[i] = qubits[i]; // qubits[q] is in own register
874 
875  int numParams = 1;
876  qreal params[1] = { M_PI / (1 << q) };
877 
878  int conj = 0;
880  qureg, regs, numQubitsPerReg, numRegs,
881  UNSIGNED, SCALED_PRODUCT, params, numParams,
882  NULL, NULL, 0,
883  conj);
884  if (qureg.isDensityMatrix) {
885  conj = 1;
886  shiftSubregIndices(regs, numQubitsPerReg, numRegs, densShift);
888  qureg, regs, numQubitsPerReg, numRegs,
889  UNSIGNED, SCALED_PRODUCT, params, numParams,
890  NULL, NULL, 0,
891  conj);
892  shiftSubregIndices(regs, numQubitsPerReg, numRegs, - densShift);
893  }
895  qureg, regs, numQubitsPerReg, numRegs,
896  UNSIGNED, SCALED_PRODUCT, params, numParams,
897  NULL, NULL, 0);
898  }
899 
900  // final swaps
901  for (int i=0; i<(numQubits/2); i++) {
902 
903  int qb1 = qubits[i];
904  int qb2 = qubits[numQubits-i-1];
905 
906  statevec_swapQubitAmps(qureg, qb1, qb2);
907  if (qureg.isDensityMatrix)
908  statevec_swapQubitAmps(qureg, qb1 + densShift, qb2 + densShift);
909  qasm_recordControlledGate(qureg, GATE_SWAP, qb1, qb2);
910  }
911 }

References GATE_HADAMARD, GATE_SWAP, Qureg::isDensityMatrix, M_PI, Qureg::numQubitsRepresented, qasm_recordControlledGate(), qasm_recordGate(), qasm_recordNamedPhaseFunc(), qreal, SCALED_PRODUCT, shiftSubregIndices(), statevec_applyParamNamedPhaseFuncOverrides(), statevec_hadamard(), statevec_swapQubitAmps(), and UNSIGNED.

Referenced by applyFullQFT(), and applyQFT().

◆ agnostic_applyTrotterCircuit()

void agnostic_applyTrotterCircuit ( Qureg  qureg,
PauliHamil  hamil,
qreal  time,
int  order,
int  reps 
)

Definition at line 840 of file QuEST_common.c.

840  {
841 
842  if (time == 0)
843  return;
844 
845  for (int r=0; r<reps; r++)
846  applySymmetrizedTrotterCircuit(qureg, hamil, time/reps, order);
847 }

References applySymmetrizedTrotterCircuit().

Referenced by applyTrotterCircuit().

◆ applyExponentiatedPauliHamil()

void applyExponentiatedPauliHamil ( Qureg  qureg,
PauliHamil  hamil,
qreal  fac,
int  reverse 
)

Definition at line 765 of file QuEST_common.c.

765  {
766 
767  /* applies a first-order one-repetition approximation of exp(-i fac H)
768  * to qureg. Letting H = sum_j c_j h_j, it does this via
769  * exp(-i fac H) ~ prod_j exp(-i fac c_j h_j), where each inner exp
770  * is performed with multiRotatePauli (with pre-factor 2).
771  */
772 
773  // prepare targets for multiRotatePauli
774  // (all qubits; actual targets are determined by Pauli codes)
775  int vecTargs[100]; // [hamil.numQubits];
776  int densTargs[100]; // [hamil.numQubits];
777  for (int q=0; q<hamil.numQubits; q++) {
778  vecTargs[q] = q;
779  densTargs[q] = q + hamil.numQubits;
780  }
781 
782  for (int i=0; i<hamil.numSumTerms; i++) {
783 
784  int t=i;
785  if (reverse)
786  t=hamil.numSumTerms-1-i;
787 
788  qreal angle = 2*fac*hamil.termCoeffs[t];
789 
791  qureg, vecTargs, &(hamil.pauliCodes[t*hamil.numQubits]),
792  hamil.numQubits, angle, 0);
793 
794  if (qureg.isDensityMatrix)
796  qureg, densTargs, &(hamil.pauliCodes[t*hamil.numQubits]),
797  hamil.numQubits, angle, 1);
798 
799  // record qasm
800  char buff[1024];
801  int b=0;
802  for (int q=0; q<hamil.numQubits; q++) {
803  enum pauliOpType op = hamil.pauliCodes[q + t*hamil.numQubits];
804 
805  char p = 'I';
806  if (op == PAULI_X) p = 'X';
807  if (op == PAULI_Y) p = 'Y';
808  if (op == PAULI_Z) p = 'Z';
809  buff[b++] = p;
810  buff[b++] = ' ';
811  }
812  buff[b] = '\0';
813 
814  qasm_recordComment(qureg,
815  "Here, a multiRotatePauli with angle %g and paulis %s was applied.",
816  angle, buff);
817  }
818 }

References Qureg::isDensityMatrix, PauliHamil::numQubits, PauliHamil::numSumTerms, PAULI_X, PAULI_Y, PAULI_Z, PauliHamil::pauliCodes, qasm_recordComment(), qreal, statevec_multiRotatePauli(), and PauliHamil::termCoeffs.

Referenced by applySymmetrizedTrotterCircuit().

◆ applySymmetrizedTrotterCircuit()

void applySymmetrizedTrotterCircuit ( Qureg  qureg,
PauliHamil  hamil,
qreal  time,
int  order 
)

Definition at line 820 of file QuEST_common.c.

820  {
821 
822  if (order == 1) {
823  applyExponentiatedPauliHamil(qureg, hamil, time, 0);
824  }
825  else if (order == 2) {
826  applyExponentiatedPauliHamil(qureg, hamil, time/2., 0);
827  applyExponentiatedPauliHamil(qureg, hamil, time/2., 1);
828  }
829  else {
830  qreal p = 1. / (4 - pow(4, 1./(order-1)));
831  int lower = order-2;
832  applySymmetrizedTrotterCircuit(qureg, hamil, p*time, lower);
833  applySymmetrizedTrotterCircuit(qureg, hamil, p*time, lower);
834  applySymmetrizedTrotterCircuit(qureg, hamil, (1-4*p)*time, lower);
835  applySymmetrizedTrotterCircuit(qureg, hamil, p*time, lower);
836  applySymmetrizedTrotterCircuit(qureg, hamil, p*time, lower);
837  }
838 }

References applyExponentiatedPauliHamil(), and qreal.

Referenced by agnostic_applyTrotterCircuit().

◆ bindArraysToStackComplexMatrixN()

ComplexMatrixN bindArraysToStackComplexMatrixN ( int  numQubits,
qreal  re[][1<< numQubits],
qreal  im[][1<< numQubits],
qreal **  reStorage,
qreal **  imStorage 
)

Definition at line 652 of file QuEST_common.c.

655  {
656  ComplexMatrixN m;
657  m.numQubits = numQubits;
658  m.real = reStorage;
659  m.imag = imStorage;
660 
661  int len = 1<<numQubits;
662  for (int i=0; i<len; i++) {
663  m.real[i] = re[i];
664  m.imag[i] = im[i];
665  }
666  return m;
667 }

References ComplexMatrixN::imag, ComplexMatrixN::numQubits, and ComplexMatrixN::real.

◆ densmatr_applyKrausSuperoperator()

void densmatr_applyKrausSuperoperator ( Qureg  qureg,
int  target,
ComplexMatrix4  superOp 
)

Definition at line 620 of file QuEST_common.c.

620  {
621 
622  long long int ctrlMask = 0;
623  statevec_multiControlledTwoQubitUnitary(qureg, ctrlMask, target, target + qureg.numQubitsRepresented, superOp);
624 }

References Qureg::numQubitsRepresented, and statevec_multiControlledTwoQubitUnitary().

Referenced by densmatr_mixKrausMap().

◆ densmatr_applyMultiQubitKrausSuperoperator()

void densmatr_applyMultiQubitKrausSuperoperator ( Qureg  qureg,
int *  targets,
int  numTargets,
ComplexMatrixN  superOp 
)

Definition at line 634 of file QuEST_common.c.

634  {
635  long long int ctrlMask = 0;
636  int allTargets[200]; // [2*numTargets];
637  for (int t=0; t < numTargets; t++) {
638  allTargets[t] = targets[t];
639  allTargets[t+numTargets] = targets[t] + qureg.numQubitsRepresented;
640  }
641  statevec_multiControlledMultiQubitUnitary(qureg, ctrlMask, allTargets, 2*numTargets, superOp);
642 }

References Qureg::numQubitsRepresented, and statevec_multiControlledMultiQubitUnitary().

Referenced by densmatr_mixMultiQubitKrausMap().

◆ densmatr_applyTwoQubitKrausSuperoperator()

void densmatr_applyTwoQubitKrausSuperoperator ( Qureg  qureg,
int  target1,
int  target2,
ComplexMatrixN  superOp 
)

Definition at line 626 of file QuEST_common.c.

626  {
627 
628  long long int ctrlMask = 0;
629  int numQb = qureg.numQubitsRepresented;
630  int allTargets[4] = {target1, target2, target1+numQb, target2+numQb};
631  statevec_multiControlledMultiQubitUnitary(qureg, ctrlMask, allTargets, 4, superOp);
632 }

References Qureg::numQubitsRepresented, and statevec_multiControlledMultiQubitUnitary().

Referenced by densmatr_mixTwoQubitKrausMap().

◆ densmatr_measureWithStats()

int densmatr_measureWithStats ( Qureg  qureg,
int  measureQubit,
qreal outcomeProb 
)

Definition at line 372 of file QuEST_common.c.

372  {
373 
374  qreal zeroProb = densmatr_calcProbOfOutcome(qureg, measureQubit, 0);
375  int outcome = generateMeasurementOutcome(zeroProb, outcomeProb);
376  densmatr_collapseToKnownProbOutcome(qureg, measureQubit, outcome, *outcomeProb);
377  return outcome;
378 }

References densmatr_calcProbOfOutcome(), densmatr_collapseToKnownProbOutcome(), generateMeasurementOutcome(), and qreal.

Referenced by measure(), and measureWithStats().

◆ densmatr_mixKrausMap()

void densmatr_mixKrausMap ( Qureg  qureg,
int  target,
ComplexMatrix2 ops,
int  numOps 
)

Definition at line 644 of file QuEST_common.c.

644  {
645 
646  ComplexMatrix4 superOp;
647  populateKrausSuperOperator2(&superOp, ops, numOps);
648  densmatr_applyKrausSuperoperator(qureg, target, superOp);
649 }

References densmatr_applyKrausSuperoperator(), and populateKrausSuperOperator2().

Referenced by densmatr_mixPauli(), and mixKrausMap().

◆ densmatr_mixMultiQubitKrausMap()

void densmatr_mixMultiQubitKrausMap ( Qureg  qureg,
int *  targets,
int  numTargets,
ComplexMatrixN ops,
int  numOps 
)

Definition at line 701 of file QuEST_common.c.

701  {
702 
703  ComplexMatrixN superOp;
704 
705  /* superOp will contain 2^(4 numTargets) complex numbers.
706  * At double precision, superOp will cost additional memory:
707  * numTargs=1 -> 0.25 KiB
708  * numTargs=2 -> 4 KiB
709  * numTargs=3 -> 64 KiB
710  * numTargs=4 -> 1 MiB
711  * numTargs=5 -> 16 MiB.
712  * At quad precision (usually 10 B per number, but possibly 16 B due to alignment),
713  * this costs at most double.
714  *
715  * Hence, if superOp is kept in the stack, numTargs >= 4 would exceed Windows' 1 MB
716  * maximum stack-space allocation (numTargs >= 5 exceeding Linux' 8 MB). Therefore,
717  * for numTargets < 4, superOp will be kept in the stack, else in the heap
718  */
719 
720  // if NOT on Windows, allocate ComplexN on stack depending on size
721  #ifndef _WIN32
722  if (numTargets < 4) {
723  // everything must live in 'if' since this macro declares local vars
724  macro_allocStackComplexMatrixN(superOp, 2*numTargets);
725  populateKrausSuperOperatorN(&superOp, ops, numOps);
726  densmatr_applyMultiQubitKrausSuperoperator(qureg, targets, numTargets, superOp);
727  }
728  else {
729  superOp = createComplexMatrixN(2*numTargets);
730  populateKrausSuperOperatorN(&superOp, ops, numOps);
731  densmatr_applyMultiQubitKrausSuperoperator(qureg, targets, numTargets, superOp);
732  destroyComplexMatrixN(superOp);
733  }
734  // on Windows, we must always create in heap
735  #else
736  superOp = createComplexMatrixN(2*numTargets);
737  populateKrausSuperOperatorN(&superOp, ops, numOps);
738  densmatr_applyMultiQubitKrausSuperoperator(qureg, targets, numTargets, superOp);
739  destroyComplexMatrixN(superOp);
740  #endif
741 }

References createComplexMatrixN(), densmatr_applyMultiQubitKrausSuperoperator(), destroyComplexMatrixN(), macro_allocStackComplexMatrixN, and populateKrausSuperOperatorN().

Referenced by mixMultiQubitKrausMap().

◆ densmatr_mixPauli()

void densmatr_mixPauli ( Qureg  qureg,
int  qubit,
qreal  probX,
qreal  probY,
qreal  probZ 
)

Definition at line 743 of file QuEST_common.c.

743  {
744 
745  // convert pauli probabilities into Kraus map
746  const int numOps = 4;
747  ComplexMatrix2 ops[4]; // [numOps];
748  for (int n=0; n < numOps; n++)
749  ops[n] = (ComplexMatrix2) {.real={{0}}, .imag={{0}}};
750 
751  qreal facs[4] = { // literal numOps=4 for valid initialisation
752  sqrt(1-(probX + probY + probZ)),
753  sqrt(probX),
754  sqrt(probY),
755  sqrt(probZ)
756  };
757  ops[0].real[0][0] = facs[0]; ops[0].real[1][1] = facs[0];
758  ops[1].real[0][1] = facs[1]; ops[1].real[1][0] = facs[1];
759  ops[2].imag[0][1] = -facs[2]; ops[2].imag[1][0] = facs[2];
760  ops[3].real[0][0] = facs[3]; ops[3].real[1][1] = -facs[3];
761 
762  densmatr_mixKrausMap(qureg, qubit, ops, numOps);
763 }

References densmatr_mixKrausMap(), ComplexMatrix2::imag, qreal, and ComplexMatrix2::real.

Referenced by mixPauli().

◆ densmatr_mixTwoQubitKrausMap()

void densmatr_mixTwoQubitKrausMap ( Qureg  qureg,
int  target1,
int  target2,
ComplexMatrix4 ops,
int  numOps 
)

Definition at line 682 of file QuEST_common.c.

682  {
683 
684  // if NOT on Windows, allocate ComplexN on stack
685  #ifndef _WIN32
686  ComplexMatrixN superOp;
687  macro_allocStackComplexMatrixN(superOp, 4);
688  populateKrausSuperOperator4(&superOp, ops, numOps);
689  densmatr_applyTwoQubitKrausSuperoperator(qureg, target1, target2, superOp);
690 
691  // but on Windows, we MUST allocated dynamically
692  #else
694  populateKrausSuperOperator4(&superOp, ops, numOps);
695  densmatr_applyTwoQubitKrausSuperoperator(qureg, target1, target2, superOp);
696  destroyComplexMatrixN(superOp);
697 
698  #endif
699 }

References createComplexMatrixN(), densmatr_applyTwoQubitKrausSuperoperator(), destroyComplexMatrixN(), macro_allocStackComplexMatrixN, and populateKrausSuperOperator4().

Referenced by mixTwoQubitKrausMap().

◆ ensureIndsIncrease()

void ensureIndsIncrease ( int *  ind1,
int *  ind2 
)

Definition at line 70 of file QuEST_common.c.

70  {
71 
72  if (*ind1 > *ind2) {
73  int copy = *ind1;
74  *ind1 = *ind2;
75  *ind2 = copy;
76  }
77 }

Referenced by mixTwoQubitDephasing(), and mixTwoQubitDepolarising().

◆ generateMeasurementOutcome()

int generateMeasurementOutcome ( qreal  zeroProb,
qreal outcomeProb 
)

Definition at line 168 of file QuEST_common.c.

168  {
169 
170  // randomly choose outcome
171  int outcome;
172  if (zeroProb < REAL_EPS)
173  outcome = 1;
174  else if (1-zeroProb < REAL_EPS)
175  outcome = 0;
176  else
177  outcome = (genrand_real1() > zeroProb);
178 
179  // set probability of outcome
180  *outcomeProb = (outcome==0)? zeroProb : 1-zeroProb;
181 
182  return outcome;
183 }

References genrand_real1().

Referenced by densmatr_measureWithStats(), and statevec_measureWithStats().

◆ getComplexPairAndPhaseFromUnitary()

void getComplexPairAndPhaseFromUnitary ( ComplexMatrix2  u,
Complex alpha,
Complex beta,
qreal globalPhase 
)

maps U(r0c0, r0c1, r1c0, r1c1) to exp(i globalPhase) U(alpha, beta)

Definition at line 142 of file QuEST_common.c.

142  {
143 
144  qreal r0c0Phase = atan2(u.imag[0][0], u.real[0][0]);
145  qreal r1c1Phase = atan2(u.imag[1][1], u.real[1][1]);
146  *globalPhase = (r0c0Phase + r1c1Phase)/2.0;
147 
148  qreal cosPhase = cos(*globalPhase);
149  qreal sinPhase = sin(*globalPhase);
150  alpha->real = u.real[0][0]*cosPhase + u.imag[0][0]*sinPhase;
151  alpha->imag = u.imag[0][0]*cosPhase - u.real[0][0]*sinPhase;
152  beta->real = u.real[1][0]*cosPhase + u.imag[1][0]*sinPhase;
153  beta->imag = u.imag[1][0]*cosPhase - u.real[1][0]*sinPhase;
154 }

References Complex::imag, ComplexMatrix2::imag, qreal, Complex::real, and ComplexMatrix2::real.

Referenced by qasm_recordControlledUnitary(), qasm_recordMultiControlledUnitary(), and qasm_recordUnitary().

◆ getComplexPairFromRotation()

void getComplexPairFromRotation ( qreal  angle,
Vector  axis,
Complex alpha,
Complex beta 
)

Definition at line 120 of file QuEST_common.c.

120  {
121 
122  Vector unitAxis = getUnitVector(axis);
123  alpha->real = cos(angle/2.0);
124  alpha->imag = - sin(angle/2.0)*unitAxis.z;
125  beta->real = sin(angle/2.0)*unitAxis.y;
126  beta->imag = - sin(angle/2.0)*unitAxis.x;
127 }

References getUnitVector(), Complex::imag, Complex::real, Vector::x, Vector::y, and Vector::z.

Referenced by qasm_recordAxisRotation(), qasm_recordControlledAxisRotation(), statevec_controlledRotateAroundAxis(), statevec_controlledRotateAroundAxisConj(), statevec_rotateAroundAxis(), and statevec_rotateAroundAxisConj().

◆ getConjugateMatrix2()

ComplexMatrix2 getConjugateMatrix2 ( ComplexMatrix2  src)

Definition at line 105 of file QuEST_common.c.

105  {
106  ComplexMatrix2 conj;
107  macro_setConjugateMatrix(conj, src, 2);
108  return conj;
109 }

References macro_setConjugateMatrix.

Referenced by controlledUnitary(), multiControlledUnitary(), multiStateControlledUnitary(), and unitary().

◆ getConjugateMatrix4()

ComplexMatrix4 getConjugateMatrix4 ( ComplexMatrix4  src)

Definition at line 110 of file QuEST_common.c.

110  {
111  ComplexMatrix4 conj;
112  macro_setConjugateMatrix(conj, src, 4);
113  return conj;
114 }

References macro_setConjugateMatrix.

Referenced by controlledTwoQubitUnitary(), multiControlledTwoQubitUnitary(), and twoQubitUnitary().

◆ getConjugateScalar()

Complex getConjugateScalar ( Complex  scalar)

Definition at line 91 of file QuEST_common.c.

91  {
92 
93  Complex conjScalar;
94  conjScalar.real = scalar.real;
95  conjScalar.imag = - scalar.imag;
96  return conjScalar;
97 }

References Complex::imag, and Complex::real.

Referenced by compactUnitary(), and controlledCompactUnitary().

◆ getControlFlipMask()

long long int getControlFlipMask ( int *  controlQubits,
int *  controlState,
int  numControlQubits 
)

Definition at line 60 of file QuEST_common.c.

60  {
61 
62  long long int mask=0;
63  for (int i=0; i<numControlQubits; i++)
64  if (controlState[i] == 0)
65  mask = mask | (1LL << controlQubits[i]);
66 
67  return mask;
68 }

Referenced by multiStateControlledUnitary().

◆ getQubitBitMask()

◆ getQuESTDefaultSeedKey()

void getQuESTDefaultSeedKey ( unsigned long int *  key)

Definition at line 195 of file QuEST_common.c.

195  {
196  // init MT random number generator with two keys -- time and pid
197  // for the MPI version, it is ok that all procs will get the same seed as random numbers will only be
198  // used by the master process
199 #if defined(_WIN32) && ! defined(__MINGW32__)
200 
201  unsigned long int pid = (unsigned long int) _getpid();
202  unsigned long int msecs = (unsigned long int) GetTickCount64();
203 
204  key[0] = msecs; key[1] = pid;
205 #else
206  struct timeval tv;
207  gettimeofday(&tv, NULL);
208 
209  double time_in_mill =
210  (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000 ; // convert tv_sec & tv_usec to millisecond
211 
212  unsigned long int pid = getpid();
213  unsigned long int msecs = (unsigned long int) time_in_mill;
214 
215  key[0] = msecs; key[1] = pid;
216 #endif
217 }

Referenced by seedQuESTDefault().

◆ getUnitVector()

Vector getUnitVector ( Vector  vec)

Definition at line 84 of file QuEST_common.c.

84  {
85 
86  qreal mag = getVectorMagnitude(vec);
87  Vector unitVec = (Vector) {.x=vec.x/mag, .y=vec.y/mag, .z=vec.z/mag};
88  return unitVec;
89 }

References getVectorMagnitude(), qreal, Vector::x, Vector::y, and Vector::z.

Referenced by getComplexPairFromRotation().

◆ getVectorMagnitude()

qreal getVectorMagnitude ( Vector  vec)

Definition at line 79 of file QuEST_common.c.

79  {
80 
81  return sqrt(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z);
82 }

References Vector::x, Vector::y, and Vector::z.

Referenced by getUnitVector(), and validateVector().

◆ getZYZRotAnglesFromComplexPair()

void getZYZRotAnglesFromComplexPair ( Complex  alpha,
Complex  beta,
qreal rz2,
qreal ry,
qreal rz1 
)

maps U(alpha, beta) to Rz(rz2) Ry(ry) Rz(rz1)

Definition at line 130 of file QuEST_common.c.

130  {
131 
132  qreal alphaMag = sqrt(alpha.real*alpha.real + alpha.imag*alpha.imag);
133  *ry = 2.0 * acos(alphaMag);
134 
135  qreal alphaPhase = atan2(alpha.imag, alpha.real);
136  qreal betaPhase = atan2(beta.imag, beta.real);
137  *rz2 = - alphaPhase + betaPhase;
138  *rz1 = - alphaPhase - betaPhase;
139 }

References Complex::imag, qreal, and Complex::real.

Referenced by qasm_recordAxisRotation(), qasm_recordCompactUnitary(), qasm_recordControlledAxisRotation(), qasm_recordControlledCompactUnitary(), qasm_recordControlledUnitary(), qasm_recordMultiControlledUnitary(), and qasm_recordUnitary().

◆ hashString()

unsigned long int hashString ( char *  str)

Definition at line 185 of file QuEST_common.c.

185  {
186  unsigned long int hash = 5381;
187  int c;
188 
189  while ((c = *str++))
190  hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
191 
192  return hash;
193 }

◆ populateKrausSuperOperator2()

void populateKrausSuperOperator2 ( ComplexMatrix4 superOp,
ComplexMatrix2 ops,
int  numOps 
)

Definition at line 607 of file QuEST_common.c.

607  {
608  int opDim = 2;
609  macro_populateKrausOperator(superOp, ops, numOps, opDim);
610 }

References macro_populateKrausOperator.

Referenced by densmatr_mixKrausMap().

◆ populateKrausSuperOperator4()

void populateKrausSuperOperator4 ( ComplexMatrixN superOp,
ComplexMatrix4 ops,
int  numOps 
)

Definition at line 611 of file QuEST_common.c.

611  {
612  int opDim = 4;
613  macro_populateKrausOperator(superOp, ops, numOps, opDim);
614 }

References macro_populateKrausOperator.

Referenced by densmatr_mixTwoQubitKrausMap().

◆ populateKrausSuperOperatorN()

void populateKrausSuperOperatorN ( ComplexMatrixN superOp,
ComplexMatrixN ops,
int  numOps 
)

Definition at line 615 of file QuEST_common.c.

615  {
616  int opDim = 1 << ops[0].numQubits;
617  macro_populateKrausOperator(superOp, ops, numOps, opDim);
618 }

References macro_populateKrausOperator, and ComplexMatrixN::numQubits.

Referenced by densmatr_mixMultiQubitKrausMap().

◆ setConjugateMatrixN()

void setConjugateMatrixN ( ComplexMatrixN  m)

Definition at line 115 of file QuEST_common.c.

115  {
116  int len = 1 << m.numQubits;
117  macro_setConjugateMatrix(m, m, len);
118 }

References macro_setConjugateMatrix, and ComplexMatrixN::numQubits.

Referenced by controlledMultiQubitUnitary(), multiControlledMultiQubitUnitary(), and multiQubitUnitary().

◆ shiftIndices()

void shiftIndices ( int *  indices,
int  numIndices,
int  shift 
)

◆ shiftSubregIndices()

void shiftSubregIndices ( int *  allInds,
int *  numIndsPerReg,
int  numRegs,
int  shift 
)

Definition at line 161 of file QuEST_common.c.

161  {
162  int i=0;
163  for (int r=0; r<numRegs; r++)
164  for (int j=0; j<numIndsPerReg[r]; j++)
165  allInds[i++] += shift;
166 }

Referenced by agnostic_applyQFT(), applyMultiVarPhaseFunc(), applyMultiVarPhaseFuncOverrides(), applyNamedPhaseFunc(), applyNamedPhaseFuncOverrides(), applyParamNamedPhaseFunc(), and applyParamNamedPhaseFuncOverrides().

◆ statevec_applyPauliProd()

void statevec_applyPauliProd ( Qureg  workspace,
int *  targetQubits,
enum pauliOpType pauliCodes,
int  numTargets 
)

Definition at line 495 of file QuEST_common.c.

495  {
496 
497  for (int i=0; i < numTargets; i++) {
498  // (pauliCodes[i] == PAULI_I) applies no operation
499  if (pauliCodes[i] == PAULI_X)
500  statevec_pauliX(workspace, targetQubits[i]);
501  if (pauliCodes[i] == PAULI_Y)
502  statevec_pauliY(workspace, targetQubits[i]);
503  if (pauliCodes[i] == PAULI_Z)
504  statevec_pauliZ(workspace, targetQubits[i]);
505  }
506 }

References PAULI_X, PAULI_Y, PAULI_Z, statevec_pauliX(), statevec_pauliY(), and statevec_pauliZ().

Referenced by statevec_applyPauliSum(), and statevec_calcExpecPauliProd().

◆ statevec_applyPauliSum()

void statevec_applyPauliSum ( Qureg  inQureg,
enum pauliOpType allCodes,
qreal termCoeffs,
int  numSumTerms,
Qureg  outQureg 
)

Definition at line 538 of file QuEST_common.c.

538  {
539 
540  int numQb = inQureg.numQubitsRepresented;
541  int targs[100]; // [numQb];
542  for (int q=0; q < numQb; q++)
543  targs[q] = q;
544 
545  statevec_initBlankState(outQureg);
546 
547  for (int t=0; t < numSumTerms; t++) {
548  Complex coef = (Complex) {.real=termCoeffs[t], .imag=0};
549  Complex iden = (Complex) {.real=1, .imag=0};
550  Complex zero = (Complex) {.real=0, .imag=0};
551 
552  // outQureg += coef paulis(inQureg)
553  statevec_applyPauliProd(inQureg, targs, &allCodes[t*numQb], numQb);
554  statevec_setWeightedQureg(coef, inQureg, iden, outQureg, zero, outQureg);
555 
556  // undero paulis(inQureg), exploiting XX=YY=ZZ=I
557  statevec_applyPauliProd(inQureg, targs, &allCodes[t*numQb], numQb);
558  }
559 }

References Qureg::numQubitsRepresented, Complex::real, statevec_applyPauliProd(), statevec_initBlankState(), and statevec_setWeightedQureg().

Referenced by applyPauliHamil(), and applyPauliSum().

◆ statevec_calcExpecPauliProd()

qreal statevec_calcExpecPauliProd ( Qureg  qureg,
int *  targetQubits,
enum pauliOpType pauliCodes,
int  numTargets,
Qureg  workspace 
)

Definition at line 509 of file QuEST_common.c.

509  {
510 
511  statevec_cloneQureg(workspace, qureg);
512  statevec_applyPauliProd(workspace, targetQubits, pauliCodes, numTargets);
513 
514  // compute the expected value
515  qreal value;
516  if (qureg.isDensityMatrix)
517  value = densmatr_calcTotalProb(workspace); // Trace(ops qureg)
518  else
519  value = statevec_calcInnerProduct(workspace, qureg).real; // <qureg|ops|qureg>
520 
521  return value;
522 }

References densmatr_calcTotalProb(), Qureg::isDensityMatrix, qreal, Complex::real, statevec_applyPauliProd(), statevec_calcInnerProduct(), and statevec_cloneQureg().

Referenced by calcExpecPauliProd(), and statevec_calcExpecPauliSum().

◆ statevec_calcExpecPauliSum()

qreal statevec_calcExpecPauliSum ( Qureg  qureg,
enum pauliOpType allCodes,
qreal termCoeffs,
int  numSumTerms,
Qureg  workspace 
)

Definition at line 524 of file QuEST_common.c.

524  {
525 
526  int numQb = qureg.numQubitsRepresented;
527  int targs[100]; // [numQb];
528  for (int q=0; q < numQb; q++)
529  targs[q] = q;
530 
531  qreal value = 0;
532  for (int t=0; t < numSumTerms; t++)
533  value += termCoeffs[t] * statevec_calcExpecPauliProd(qureg, targs, &allCodes[t*numQb], numQb, workspace);
534 
535  return value;
536 }

References Qureg::numQubitsRepresented, qreal, and statevec_calcExpecPauliProd().

Referenced by calcExpecPauliHamil(), and calcExpecPauliSum().

◆ statevec_calcFidelity()

qreal statevec_calcFidelity ( Qureg  qureg,
Qureg  pureState 
)

Definition at line 380 of file QuEST_common.c.

380  {
381 
382  Complex innerProd = statevec_calcInnerProduct(qureg, pureState);
383  qreal innerProdMag = innerProd.real*innerProd.real + innerProd.imag*innerProd.imag;
384  return innerProdMag;
385 }

References Complex::imag, qreal, Complex::real, and statevec_calcInnerProduct().

Referenced by calcFidelity().

◆ statevec_controlledMultiQubitUnitary()

void statevec_controlledMultiQubitUnitary ( Qureg  qureg,
int  ctrl,
int *  targets,
int  numTargets,
ComplexMatrixN  u 
)

Definition at line 579 of file QuEST_common.c.

579  {
580 
581  long long int ctrlMask = 1LL << ctrl;
582  statevec_multiControlledMultiQubitUnitary(qureg, ctrlMask, targets, numTargets, u);
583 }

References statevec_multiControlledMultiQubitUnitary().

Referenced by controlledMultiQubitUnitary().

◆ statevec_controlledRotateAroundAxis()

void statevec_controlledRotateAroundAxis ( Qureg  qureg,
int  controlQubit,
int  targetQubit,
qreal  angle,
Vector  axis 
)

Definition at line 330 of file QuEST_common.c.

330  {
331 
332  Complex alpha, beta;
333  getComplexPairFromRotation(angle, axis, &alpha, &beta);
334  statevec_controlledCompactUnitary(qureg, controlQubit, targetQubit, alpha, beta);
335 }

References getComplexPairFromRotation(), and statevec_controlledCompactUnitary().

Referenced by controlledRotateAroundAxis(), statevec_controlledRotateX(), statevec_controlledRotateY(), and statevec_controlledRotateZ().

◆ statevec_controlledRotateAroundAxisConj()

void statevec_controlledRotateAroundAxisConj ( Qureg  qureg,
int  controlQubit,
int  targetQubit,
qreal  angle,
Vector  axis 
)

Definition at line 337 of file QuEST_common.c.

337  {
338 
339  Complex alpha, beta;
340  getComplexPairFromRotation(angle, axis, &alpha, &beta);
341  alpha.imag *= -1;
342  beta.imag *= -1;
343  statevec_controlledCompactUnitary(qureg, controlQubit, targetQubit, alpha, beta);
344 }

References getComplexPairFromRotation(), Complex::imag, and statevec_controlledCompactUnitary().

Referenced by controlledRotateAroundAxis().

◆ statevec_controlledRotateX()

void statevec_controlledRotateX ( Qureg  qureg,
int  controlQubit,
int  targetQubit,
qreal  angle 
)

Definition at line 346 of file QuEST_common.c.

346  {
347 
348  Vector unitAxis = {1, 0, 0};
349  statevec_controlledRotateAroundAxis(qureg, controlQubit, targetQubit, angle, unitAxis);
350 }

References statevec_controlledRotateAroundAxis().

Referenced by controlledRotateX().

◆ statevec_controlledRotateY()

void statevec_controlledRotateY ( Qureg  qureg,
int  controlQubit,
int  targetQubit,
qreal  angle 
)

Definition at line 352 of file QuEST_common.c.

352  {
353 
354  Vector unitAxis = {0, 1, 0};
355  statevec_controlledRotateAroundAxis(qureg, controlQubit, targetQubit, angle, unitAxis);
356 }

References statevec_controlledRotateAroundAxis().

Referenced by controlledRotateY().

◆ statevec_controlledRotateZ()

void statevec_controlledRotateZ ( Qureg  qureg,
int  controlQubit,
int  targetQubit,
qreal  angle 
)

Definition at line 358 of file QuEST_common.c.

358  {
359 
360  Vector unitAxis = {0, 0, 1};
361  statevec_controlledRotateAroundAxis(qureg, controlQubit, targetQubit, angle, unitAxis);
362 }

References statevec_controlledRotateAroundAxis().

Referenced by controlledRotateZ().

◆ statevec_controlledTwoQubitUnitary()

void statevec_controlledTwoQubitUnitary ( Qureg  qureg,
int  controlQubit,
int  targetQubit1,
int  targetQubit2,
ComplexMatrix4  u 
)

Definition at line 567 of file QuEST_common.c.

567  {
568 
569  long long int ctrlMask = 1LL << controlQubit;
570  statevec_multiControlledTwoQubitUnitary(qureg, ctrlMask, targetQubit1, targetQubit2, u);
571 }

References statevec_multiControlledTwoQubitUnitary().

Referenced by controlledTwoQubitUnitary().

◆ statevec_getProbAmp()

qreal statevec_getProbAmp ( Qureg  qureg,
long long int  index 
)

Definition at line 248 of file QuEST_common.c.

248  {
249  qreal real = statevec_getRealAmp(qureg, index);
250  qreal imag = statevec_getImagAmp(qureg, index);
251  return real*real + imag*imag;
252 }

References qreal, statevec_getImagAmp(), and statevec_getRealAmp().

Referenced by getProbAmp().

◆ statevec_measureWithStats()

int statevec_measureWithStats ( Qureg  qureg,
int  measureQubit,
qreal outcomeProb 
)

Definition at line 364 of file QuEST_common.c.

364  {
365 
366  qreal zeroProb = statevec_calcProbOfOutcome(qureg, measureQubit, 0);
367  int outcome = generateMeasurementOutcome(zeroProb, outcomeProb);
368  statevec_collapseToKnownProbOutcome(qureg, measureQubit, outcome, *outcomeProb);
369  return outcome;
370 }

References generateMeasurementOutcome(), qreal, statevec_calcProbOfOutcome(), and statevec_collapseToKnownProbOutcome().

Referenced by measure(), and measureWithStats().

◆ statevec_multiControlledMultiRotatePauli()

void statevec_multiControlledMultiRotatePauli ( Qureg  qureg,
long long int  ctrlMask,
int *  targetQubits,
enum pauliOpType targetPaulis,
int  numTargets,
qreal  angle,
int  applyConj 
)

Definition at line 453 of file QuEST_common.c.

456  {
457  qreal fac = 1/sqrt(2);
458  qreal sgn = (applyConj)? 1 : -1;
459  ComplexMatrix2 uRx = {.real={{fac,0},{0,fac}}, .imag={{0,sgn*fac},{sgn*fac,0}}}; // Rx(pi/2)* rotates Z -> Y
460  ComplexMatrix2 uRy = {.real={{fac,fac},{-fac,fac}}, .imag={{0,0},{0,0}}}; // Ry(-pi/2) rotates Z -> X
461 
462  // this function is controlled on the all-one state, so no ctrl flips
463  long long int ctrlFlipMask = 0;
464 
465  // mask may be modified to remove superfluous Identity ops
466  long long int targMask = getQubitBitMask(targetQubits, numTargets);
467 
468  // rotate basis so that exp(Z) will effect exp(Y) and exp(X)
469  for (int t=0; t < numTargets; t++) {
470  if (targetPaulis[t] == PAULI_I)
471  targMask -= 1LL << targetQubits[t]; // remove target from mask
472  if (targetPaulis[t] == PAULI_X)
473  statevec_multiControlledUnitary(qureg, ctrlMask, ctrlFlipMask, targetQubits[t], uRy);
474  if (targetPaulis[t] == PAULI_Y)
475  statevec_multiControlledUnitary(qureg, ctrlMask, ctrlFlipMask, targetQubits[t], uRx);
476  // (targetPaulis[t] == 3) is Z basis
477  }
478 
479  // does nothing if there are no qubits to 'rotate'
480  if (targMask != 0)
481  statevec_multiControlledMultiRotateZ(qureg, ctrlMask, targMask, (applyConj)? -angle : angle);
482 
483  // undo X and Y basis rotations
484  uRx.imag[0][1] *= -1; uRx.imag[1][0] *= -1;
485  uRy.real[0][1] *= -1; uRy.real[1][0] *= -1;
486  for (int t=0; t < numTargets; t++) {
487  if (targetPaulis[t] == PAULI_X)
488  statevec_multiControlledUnitary(qureg, ctrlMask, ctrlFlipMask, targetQubits[t], uRy);
489  if (targetPaulis[t] == PAULI_Y)
490  statevec_multiControlledUnitary(qureg, ctrlMask, ctrlFlipMask, targetQubits[t], uRx);
491  }
492 }

References getQubitBitMask(), ComplexMatrix2::imag, PAULI_I, PAULI_X, PAULI_Y, qreal, ComplexMatrix2::real, statevec_multiControlledMultiRotateZ(), and statevec_multiControlledUnitary().

Referenced by multiControlledMultiRotatePauli().

◆ statevec_multiQubitUnitary()

void statevec_multiQubitUnitary ( Qureg  qureg,
int *  targets,
int  numTargets,
ComplexMatrixN  u 
)

Definition at line 573 of file QuEST_common.c.

573  {
574 
575  long long int ctrlMask = 0;
576  statevec_multiControlledMultiQubitUnitary(qureg, ctrlMask, targets, numTargets, u);
577 }

References statevec_multiControlledMultiQubitUnitary().

Referenced by applyMatrixN(), and multiQubitUnitary().

◆ statevec_multiRotatePauli()

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 at line 414 of file QuEST_common.c.

417  {
418  qreal fac = 1/sqrt(2);
419  Complex uRxAlpha = {.real = fac, .imag = 0}; // Rx(pi/2)* rotates Z -> Y
420  Complex uRxBeta = {.real = 0, .imag = (applyConj)? fac : -fac};
421  Complex uRyAlpha = {.real = fac, .imag = 0}; // Ry(-pi/2) rotates Z -> X
422  Complex uRyBeta = {.real = -fac, .imag = 0};
423 
424  // mask may be modified to remove superfluous Identity ops
425  long long int mask = getQubitBitMask(targetQubits, numTargets);
426 
427  // rotate basis so that exp(Z) will effect exp(Y) and exp(X)
428  for (int t=0; t < numTargets; t++) {
429  if (targetPaulis[t] == PAULI_I)
430  mask -= 1LL << targetQubits[t]; // remove target from mask
431  if (targetPaulis[t] == PAULI_X)
432  statevec_compactUnitary(qureg, targetQubits[t], uRyAlpha, uRyBeta);
433  if (targetPaulis[t] == PAULI_Y)
434  statevec_compactUnitary(qureg, targetQubits[t], uRxAlpha, uRxBeta);
435  // (targetPaulis[t] == 3) is Z basis
436  }
437 
438  // does nothing if there are no qubits to 'rotate'
439  if (mask != 0)
440  statevec_multiRotateZ(qureg, mask, (applyConj)? -angle : angle);
441 
442  // undo X and Y basis rotations
443  uRxBeta.imag *= -1;
444  uRyBeta.real *= -1;
445  for (int t=0; t < numTargets; t++) {
446  if (targetPaulis[t] == PAULI_X)
447  statevec_compactUnitary(qureg, targetQubits[t], uRyAlpha, uRyBeta);
448  if (targetPaulis[t] == PAULI_Y)
449  statevec_compactUnitary(qureg, targetQubits[t], uRxAlpha, uRxBeta);
450  }
451 }

References getQubitBitMask(), Complex::imag, PAULI_I, PAULI_X, PAULI_Y, qreal, Complex::real, statevec_compactUnitary(), and statevec_multiRotateZ().

Referenced by applyExponentiatedPauliHamil(), and multiRotatePauli().

◆ statevec_pauliZ()

void statevec_pauliZ ( Qureg  qureg,
int  targetQubit 
)

Definition at line 261 of file QuEST_common.c.

261  {
262  Complex term;
263  term.real = -1;
264  term.imag = 0;
265  statevec_phaseShiftByTerm(qureg, targetQubit, term);
266 }

References Complex::imag, Complex::real, and statevec_phaseShiftByTerm().

Referenced by pauliZ(), and statevec_applyPauliProd().

◆ statevec_phaseShift()

void statevec_phaseShift ( Qureg  qureg,
int  targetQubit,
qreal  angle 
)

Definition at line 254 of file QuEST_common.c.

254  {
255  Complex term;
256  term.real = cos(angle);
257  term.imag = sin(angle);
258  statevec_phaseShiftByTerm(qureg, targetQubit, term);
259 }

References Complex::imag, Complex::real, and statevec_phaseShiftByTerm().

Referenced by phaseShift().

◆ statevec_rotateAroundAxis()

void statevec_rotateAroundAxis ( Qureg  qureg,
int  rotQubit,
qreal  angle,
Vector  axis 
)

Definition at line 314 of file QuEST_common.c.

314  {
315 
316  Complex alpha, beta;
317  getComplexPairFromRotation(angle, axis, &alpha, &beta);
318  statevec_compactUnitary(qureg, rotQubit, alpha, beta);
319 }

References getComplexPairFromRotation(), and statevec_compactUnitary().

Referenced by rotateAroundAxis(), statevec_rotateX(), statevec_rotateY(), and statevec_rotateZ().

◆ statevec_rotateAroundAxisConj()

void statevec_rotateAroundAxisConj ( Qureg  qureg,
int  rotQubit,
qreal  angle,
Vector  axis 
)

Definition at line 321 of file QuEST_common.c.

321  {
322 
323  Complex alpha, beta;
324  getComplexPairFromRotation(angle, axis, &alpha, &beta);
325  alpha.imag *= -1;
326  beta.imag *= -1;
327  statevec_compactUnitary(qureg, rotQubit, alpha, beta);
328 }

References getComplexPairFromRotation(), Complex::imag, and statevec_compactUnitary().

Referenced by rotateAroundAxis().

◆ statevec_rotateX()

void statevec_rotateX ( Qureg  qureg,
int  rotQubit,
qreal  angle 
)

Definition at line 296 of file QuEST_common.c.

296  {
297 
298  Vector unitAxis = {1, 0, 0};
299  statevec_rotateAroundAxis(qureg, rotQubit, angle, unitAxis);
300 }

References statevec_rotateAroundAxis().

Referenced by rotateX().

◆ statevec_rotateY()

void statevec_rotateY ( Qureg  qureg,
int  rotQubit,
qreal  angle 
)

Definition at line 302 of file QuEST_common.c.

302  {
303 
304  Vector unitAxis = {0, 1, 0};
305  statevec_rotateAroundAxis(qureg, rotQubit, angle, unitAxis);
306 }

References statevec_rotateAroundAxis().

Referenced by rotateY().

◆ statevec_rotateZ()

void statevec_rotateZ ( Qureg  qureg,
int  rotQubit,
qreal  angle 
)

Definition at line 308 of file QuEST_common.c.

308  {
309 
310  Vector unitAxis = {0, 0, 1};
311  statevec_rotateAroundAxis(qureg, rotQubit, angle, unitAxis);
312 }

References statevec_rotateAroundAxis().

Referenced by rotateZ().

◆ statevec_sGate()

void statevec_sGate ( Qureg  qureg,
int  targetQubit 
)

Definition at line 268 of file QuEST_common.c.

268  {
269  Complex term;
270  term.real = 0;
271  term.imag = 1;
272  statevec_phaseShiftByTerm(qureg, targetQubit, term);
273 }

References Complex::imag, Complex::real, and statevec_phaseShiftByTerm().

Referenced by sGate().

◆ statevec_sGateConj()

void statevec_sGateConj ( Qureg  qureg,
int  targetQubit 
)

Definition at line 282 of file QuEST_common.c.

282  {
283  Complex term;
284  term.real = 0;
285  term.imag = -1;
286  statevec_phaseShiftByTerm(qureg, targetQubit, term);
287 }

References Complex::imag, Complex::real, and statevec_phaseShiftByTerm().

Referenced by sGate().

◆ statevec_sqrtSwapGate()

void statevec_sqrtSwapGate ( Qureg  qureg,
int  qb1,
int  qb2 
)

Definition at line 387 of file QuEST_common.c.

387  {
388 
389  ComplexMatrix4 u = (ComplexMatrix4) {.real={{0}}, .imag={{0}}};
390  u.real[0][0]=1;
391  u.real[3][3]=1;
392  u.real[1][1] = .5; u.imag[1][1] = .5;
393  u.real[1][2] = .5; u.imag[1][2] =-.5;
394  u.real[2][1] = .5; u.imag[2][1] =-.5;
395  u.real[2][2] = .5; u.imag[2][2] = .5;
396 
397  statevec_twoQubitUnitary(qureg, qb1, qb2, u);
398 }

References ComplexMatrix4::imag, ComplexMatrix4::real, and statevec_twoQubitUnitary().

Referenced by sqrtSwapGate().

◆ statevec_sqrtSwapGateConj()

void statevec_sqrtSwapGateConj ( Qureg  qureg,
int  qb1,
int  qb2 
)

Definition at line 400 of file QuEST_common.c.

400  {
401 
402  ComplexMatrix4 u = (ComplexMatrix4) {.real={{0}}, .imag={{0}}};
403  u.real[0][0]=1;
404  u.real[3][3]=1;
405  u.real[1][1] = .5; u.imag[1][1] =-.5;
406  u.real[1][2] = .5; u.imag[1][2] = .5;
407  u.real[2][1] = .5; u.imag[2][1] = .5;
408  u.real[2][2] = .5; u.imag[2][2] =-.5;
409 
410  statevec_twoQubitUnitary(qureg, qb1, qb2, u);
411 }

References ComplexMatrix4::imag, ComplexMatrix4::real, and statevec_twoQubitUnitary().

Referenced by sqrtSwapGate().

◆ statevec_tGate()

void statevec_tGate ( Qureg  qureg,
int  targetQubit 
)

Definition at line 275 of file QuEST_common.c.

275  {
276  Complex term;
277  term.real = 1/sqrt(2);
278  term.imag = 1/sqrt(2);
279  statevec_phaseShiftByTerm(qureg, targetQubit, term);
280 }

References Complex::imag, Complex::real, and statevec_phaseShiftByTerm().

Referenced by tGate().

◆ statevec_tGateConj()

void statevec_tGateConj ( Qureg  qureg,
int  targetQubit 
)

Definition at line 289 of file QuEST_common.c.

289  {
290  Complex term;
291  term.real = 1/sqrt(2);
292  term.imag = -1/sqrt(2);
293  statevec_phaseShiftByTerm(qureg, targetQubit, term);
294 }

References Complex::imag, Complex::real, and statevec_phaseShiftByTerm().

Referenced by tGate().

◆ statevec_twoQubitUnitary()

void statevec_twoQubitUnitary ( Qureg  qureg,
int  targetQubit1,
int  targetQubit2,
ComplexMatrix4  u 
)

Definition at line 561 of file QuEST_common.c.

561  {
562 
563  long long int ctrlMask = 0;
564  statevec_multiControlledTwoQubitUnitary(qureg, ctrlMask, targetQubit1, targetQubit2, u);
565 }

References statevec_multiControlledTwoQubitUnitary().

Referenced by applyMatrix4(), statevec_sqrtSwapGate(), statevec_sqrtSwapGateConj(), and twoQubitUnitary().

Represents a 3-vector of real numbers.
Definition: QuEST.h:198
void statevec_pauliZ(Qureg qureg, int targetQubit)
Definition: QuEST_common.c:261
pauliOpType
Codes for specifying Pauli operators.
Definition: QuEST.h:96
#define macro_setConjugateMatrix(dest, src, dim)
Definition: QuEST_common.c:99
qreal real[4][4]
Definition: QuEST.h:177
void densmatr_mixKrausMap(Qureg qureg, int target, ComplexMatrix2 *ops, int numOps)
Definition: QuEST_common.c:644
@ PAULI_Z
Definition: QuEST.h:96
void applyExponentiatedPauliHamil(Qureg qureg, PauliHamil hamil, qreal fac, int reverse)
Definition: QuEST_common.c:765
void populateKrausSuperOperator4(ComplexMatrixN *superOp, ComplexMatrix4 *ops, int numOps)
Definition: QuEST_common.c:611
void populateKrausSuperOperatorN(ComplexMatrixN *superOp, ComplexMatrixN *ops, int numOps)
Definition: QuEST_common.c:615
void destroyComplexMatrixN(ComplexMatrixN m)
Destroy a ComplexMatrixN instance created with createComplexMatrixN()
Definition: QuEST.c:1369
qreal statevec_calcExpecPauliProd(Qureg qureg, int *targetQubits, enum pauliOpType *pauliCodes, int numTargets, Qureg workspace)
Definition: QuEST_common.c:509
@ PAULI_I
Definition: QuEST.h:96
ComplexMatrixN createComplexMatrixN(int numQubits)
Allocate dynamic memory for a square complex matrix of any size, which can be passed to functions lik...
Definition: QuEST.c:1348
void statevec_twoQubitUnitary(Qureg qureg, int targetQubit1, int targetQubit2, ComplexMatrix4 u)
Definition: QuEST_common.c:561
qreal z
Definition: QuEST.h:200
void statevec_applyPauliProd(Qureg workspace, int *targetQubits, enum pauliOpType *pauliCodes, int numTargets)
Definition: QuEST_common.c:495
void statevec_multiControlledMultiQubitUnitary(Qureg qureg, long long int ctrlMask, int *targs, int numTargs, ComplexMatrixN u)
This calls swapQubitAmps only when it would involve a distributed communication; if the qubit chunks ...
void statevec_multiRotateZ(Qureg qureg, long long int mask, qreal angle)
Definition: QuEST_cpu.c:3316
qreal statevec_calcProbOfOutcome(Qureg qureg, int measureQubit, int outcome)
@ GATE_HADAMARD
Definition: QuEST_qasm.h:26
Vector getUnitVector(Vector vec)
Definition: QuEST_common.c:84
Represents a 4x4 matrix of complex numbers.
Definition: QuEST.h:175
@ UNSIGNED
Definition: QuEST.h:269
void getComplexPairFromRotation(qreal angle, Vector axis, Complex *alpha, Complex *beta)
Definition: QuEST_common.c:120
void statevec_pauliY(Qureg qureg, int targetQubit)
ComplexMatrixN bindArraysToStackComplexMatrixN(int numQubits, qreal re[][1<< numQubits], qreal im[][1<< numQubits], qreal **reStorage, qreal **imStorage)
Definition: QuEST_common.c:652
Represents a general 2^N by 2^N matrix of complex numbers.
Definition: QuEST.h:186
#define qreal
#define macro_allocStackComplexMatrixN(matrix, numQubits)
Definition: QuEST_common.c:675
@ PAULI_X
Definition: QuEST.h:96
void statevec_swapQubitAmps(Qureg qureg, int qb1, int qb2)
qreal densmatr_calcTotalProb(Qureg qureg)
void densmatr_collapseToKnownProbOutcome(Qureg qureg, int measureQubit, int outcome, qreal outcomeProb)
Renorms (/prob) every | * outcome * >< * outcome * | state, setting all others to zero.
Definition: QuEST_cpu.c:791
void qasm_recordControlledGate(Qureg qureg, TargetGate gate, int controlQubit, int targetQubit)
Definition: QuEST_qasm.c:239
qreal y
Definition: QuEST.h:200
qreal imag[2][2]
Definition: QuEST.h:140
void statevec_applyParamNamedPhaseFuncOverrides(Qureg qureg, int *qubits, int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, enum phaseFunc functionNameCode, qreal *params, int numParams, long long int *overrideInds, qreal *overridePhases, int numOverrides, int conj)
Definition: QuEST_cpu.c:4446
void statevec_multiControlledMultiRotateZ(Qureg qureg, long long int ctrlMask, long long int targMask, qreal angle)
Definition: QuEST_cpu.c:3358
qreal x
Definition: QuEST.h:200
int generateMeasurementOutcome(qreal zeroProb, qreal *outcomeProb)
Definition: QuEST_common.c:168
qreal * termCoeffs
The real coefficient of each Pauli product. This is an array of length PauliHamil....
Definition: QuEST.h:283
void densmatr_applyKrausSuperoperator(Qureg qureg, int target, ComplexMatrix4 superOp)
Definition: QuEST_common.c:620
enum pauliOpType * pauliCodes
The Pauli operators acting on each qubit, flattened over every operator.
Definition: QuEST.h:281
void statevec_initBlankState(Qureg qureg)
Definition: QuEST_cpu.c:1464
void populateKrausSuperOperator2(ComplexMatrix4 *superOp, ComplexMatrix2 *ops, int numOps)
Definition: QuEST_common.c:607
@ SCALED_PRODUCT
Definition: QuEST.h:233
void statevec_cloneQureg(Qureg targetQureg, Qureg copyQureg)
works for both statevectors and density matrices
Definition: QuEST_cpu.c:1572
void statevec_rotateAroundAxis(Qureg qureg, int rotQubit, qreal angle, Vector axis)
Definition: QuEST_common.c:314
qreal imag[4][4]
Definition: QuEST.h:178
void statevec_multiControlledTwoQubitUnitary(Qureg qureg, long long int ctrlMask, int targetQubit1, int targetQubit2, ComplexMatrix4 u)
This calls swapQubitAmps only when it would involve a distributed communication; if the qubit chunks ...
int numSumTerms
The number of terms in the weighted sum, or the number of Pauli products.
Definition: QuEST.h:285
long long int getQubitBitMask(int *qubits, int numQubits)
Definition: QuEST_common.c:50
void statevec_compactUnitary(Qureg qureg, int targetQubit, Complex alpha, Complex beta)
@ PAULI_Y
Definition: QuEST.h:96
double genrand_real1(void)
Definition: mt19937ar.c:150
void statevec_multiRotatePauli(Qureg qureg, int *targetQubits, enum pauliOpType *targetPaulis, int numTargets, qreal angle, int applyConj)
applyConj=1 will apply conjugate operation, else applyConj=0
Definition: QuEST_common.c:414
void qasm_recordComment(Qureg qureg, char *comment,...)
Definition: QuEST_qasm.c:121
qreal ** real
Definition: QuEST.h:189
void statevec_controlledRotateAroundAxis(Qureg qureg, int controlQubit, int targetQubit, qreal angle, Vector axis)
Definition: QuEST_common.c:330
Complex statevec_calcInnerProduct(Qureg bra, Qureg ket)
Terrible code which unnecessarily individually computes and sums the real and imaginary components of...
void statevec_setWeightedQureg(Complex fac1, Qureg qureg1, Complex fac2, Qureg qureg2, Complex facOut, Qureg out)
Definition: QuEST_cpu.c:4005
void statevec_collapseToKnownProbOutcome(Qureg qureg, int measureQubit, int outcome, qreal outcomeProb)
void shiftSubregIndices(int *allInds, int *numIndsPerReg, int numRegs, int shift)
Definition: QuEST_common.c:161
qreal statevec_getImagAmp(Qureg qureg, long long int index)
qreal ** imag
Definition: QuEST.h:190
qreal real[2][2]
Definition: QuEST.h:139
int isDensityMatrix
Whether this instance is a density-state representation.
Definition: QuEST.h:325
void statevec_hadamard(Qureg qureg, int targetQubit)
int numQubits
Definition: QuEST.h:188
void statevec_multiControlledUnitary(Qureg qureg, long long int ctrlQubitsMask, long long int ctrlFlipMask, int targetQubit, ComplexMatrix2 u)
qreal getVectorMagnitude(Vector vec)
Definition: QuEST_common.c:79
void densmatr_applyTwoQubitKrausSuperoperator(Qureg qureg, int target1, int target2, ComplexMatrixN superOp)
Definition: QuEST_common.c:626
void statevec_phaseShiftByTerm(Qureg qureg, int targetQubit, Complex term)
Definition: QuEST_cpu.c:3185
int numQubits
The number of qubits informing the Hilbert dimension of the Hamiltonian.
Definition: QuEST.h:287
int numQubitsRepresented
The number of qubits represented in either the state-vector or density matrix.
Definition: QuEST.h:327
void statevec_pauliX(Qureg qureg, int targetQubit)
@ GATE_SWAP
Definition: QuEST_qasm.h:33
qreal real
Definition: QuEST.h:105
void densmatr_applyMultiQubitKrausSuperoperator(Qureg qureg, int *targets, int numTargets, ComplexMatrixN superOp)
Definition: QuEST_common.c:634
qreal imag
Definition: QuEST.h:106
Represents one complex number.
Definition: QuEST.h:103
#define macro_populateKrausOperator(superOp, ops, numOps, opDim)
Definition: QuEST_common.c:585
void qasm_recordGate(Qureg qureg, TargetGate gate, int targetQubit)
Definition: QuEST_qasm.c:179
qreal densmatr_calcProbOfOutcome(Qureg qureg, int measureQubit, int outcome)
#define M_PI
Definition: QuEST_common.c:41
void applySymmetrizedTrotterCircuit(Qureg qureg, PauliHamil hamil, qreal time, int order)
Definition: QuEST_common.c:820
void qasm_recordNamedPhaseFunc(Qureg qureg, int *qubits, int *numQubitsPerReg, int numRegs, enum bitEncoding encoding, enum phaseFunc funcName, qreal *params, int numParams, long long int *overrideInds, qreal *overridePhases, int numOverrides)
Definition: QuEST_qasm.c:726
void statevec_controlledCompactUnitary(Qureg qureg, int controlQubit, int targetQubit, Complex alpha, Complex beta)
qreal statevec_getRealAmp(Qureg qureg, long long int index)
Represents a 2x2 matrix of complex numbers.
Definition: QuEST.h:137