The Quantum Exact Simulation Toolkit v4.2.0
Loading...
Searching...
No Matches
PauliStr gadgets

Functions for applying many-qubit rotations around arbitrary PauliStr. More...

Functions

void applyControlledPauliGadget (Qureg qureg, int control, PauliStr str, qreal angle)
 
void applyMultiControlledPauliGadget (Qureg qureg, int *controls, int numControls, PauliStr str, qreal angle)
 
void applyMultiStateControlledPauliGadget (Qureg qureg, int *controls, int *states, int numControls, PauliStr str, qreal angle)
 
void applyNonUnitaryPauliGadget (Qureg qureg, PauliStr str, qcomp angle)
 
void applyPauliGadget (Qureg qureg, PauliStr str, qreal angle)
 

Detailed Description

Functions for applying many-qubit rotations around arbitrary PauliStr.

Function Documentation

◆ applyControlledPauliGadget()

void applyControlledPauliGadget ( Qureg qureg,
int control,
PauliStr str,
qreal angle )
Note
Documentation for this function or struct is under construction!

Definition at line 1264 of file operations.cpp.

1264 {
1265 validate_quregFields(qureg, __func__);
1266 validate_controlAndPauliStrTargets(qureg, control, str, __func__);
1267
1268 applyMultiStateControlledPauliGadget(qureg, &control, nullptr, 1, str, angle);
1269}
void applyMultiStateControlledPauliGadget(Qureg qureg, int *controls, int *states, int numControls, PauliStr str, qreal angle)

◆ applyMultiControlledPauliGadget()

void applyMultiControlledPauliGadget ( Qureg qureg,
int * controls,
int numControls,
PauliStr str,
qreal angle )
Note
Documentation for this function or struct is under construction!

Definition at line 1271 of file operations.cpp.

1271 {
1272 validate_quregFields(qureg, __func__);
1273 validate_controlsAndPauliStrTargets(qureg, controls, numControls, str, __func__);
1274
1275 applyMultiStateControlledPauliGadget(qureg, controls, nullptr, numControls, str, angle);
1276}

Referenced by applyMultiControlledPauliGadget().

◆ applyMultiStateControlledPauliGadget()

void applyMultiStateControlledPauliGadget ( Qureg qureg,
int * controls,
int * states,
int numControls,
PauliStr str,
qreal angle )
Note
Documentation for this function or struct is under construction!
See also

Definition at line 1278 of file operations.cpp.

1278 {
1279 validate_quregFields(qureg, __func__);
1280 validate_controlsAndPauliStrTargets(qureg, controls, numControls, str, __func__);
1281 validate_controlStates(states, numControls, __func__); // permits states==nullptr
1282
1283 // a non-controlled str=I effects a global phase change (of -angle/2) which does not
1284 // at all change a density matrix; the subsequent dagger operation would undo it,
1285 // which we avoid to preserve numerical accuracy
1286 if (paulis_isIdentity(str) && numControls == 0 && qureg.isDensityMatrix)
1287 return;
1288
1289 // when numControls >= 1, all amps satisfying the control condition undergo a phase
1290 // change of -angle/2, as if all non-control-qubits were targeted by exp(-angle/2)I,
1291 // which is sufficiently efficient using the existing gadget backend function
1292
1293 qreal phase = util_getPhaseFromGateAngle(angle);
1294 auto ctrlVec = util_getVector(controls, numControls);
1295 auto stateVec = util_getVector(states, numControls); // empty if states==nullptr
1296 localiser_statevec_anyCtrlPauliGadget(qureg, ctrlVec, stateVec, str, phase);
1297
1298 if (!qureg.isDensityMatrix)
1299 return;
1300
1301 // conj(e^(i a P)) = e^(-i s a P)
1302 phase *= - paulis_getSignOfPauliStrConj(str);
1303 ctrlVec = util_getBraQubits(ctrlVec, qureg);
1304 str = paulis_getShiftedPauliStr(str, qureg.numQubits);
1305 localiser_statevec_anyCtrlPauliGadget(qureg, ctrlVec, stateVec, str, phase);
1306}

Referenced by applyControlledPauliGadget(), applyMultiControlledPauliGadget(), applyMultiStateControlledPauliGadget(), and applyPauliGadget().

◆ applyNonUnitaryPauliGadget()

void applyNonUnitaryPauliGadget ( Qureg qureg,
PauliStr str,
qcomp angle )
Note
Documentation for this function or struct is under construction!

This function generalises applyPauliGadget() to accept a complex angle.

Definition at line 1248 of file operations.cpp.

1248 {
1249 validate_quregFields(qureg, __func__);
1250 validate_pauliStrTargets(qureg, str, __func__);
1251
1252 qcomp phase = util_getPhaseFromGateAngle(angle);
1253 localiser_statevec_anyCtrlPauliGadget(qureg, {}, {}, str, phase);
1254
1255 if (!qureg.isDensityMatrix)
1256 return;
1257
1258 // conj(e^i(a)P) = e^(-i s conj(a) P)
1259 phase = - std::conj(phase) * paulis_getSignOfPauliStrConj(str);
1260 str = paulis_getShiftedPauliStr(str, qureg.numQubits);
1261 localiser_statevec_anyCtrlPauliGadget(qureg, {}, {}, str, phase);
1262}

Referenced by TEST_CASE().

◆ applyPauliGadget()

void applyPauliGadget ( Qureg qureg,
PauliStr str,
qreal angle )
Note
Documentation for this function or struct is under construction!
Formulae

Let \( \hat{\sigma} = \) str and \( \theta = \) angle.

This function effects unitary

\[ R_{\hat{\sigma}}(\theta) = \exp \left( - \iu \, \frac{\theta}{2} \, \hat{\sigma} \right), \]

which affects only the qubits for which \( \hat{\sigma} \) is not the identity Pauli. As such, this effects a multi-qubit rotation around an arbitrary Pauli string.

Equivalences
  • Because \( R_{\hat{\sigma}}(\theta) \) satisfies

    \[ R_{\hat{\sigma}}(\theta) \equiv \cos\left( \frac{\theta}{2} \right) \, \id - \iu \sin\left( \frac{\theta}{2} \right) \, \hat{\sigma}, \]

    this function is equivalent to (but much faster than) effecting \( \hat{\sigma} \) upon a clone which is subsequently combined.
    // prepare |temp> = str |qureg>
    Qureg temp = createCloneQureg(qureg);
    applyPauliStr(temp, str);
    // set |qureg> = cos(theta/2) |qureg> - i sin(theta/2) str |qureg>
    qcomp coeffs[] = {cos(theta/2), -1i * sin(theta/2)};
    Qureg quregs[] = {qureg, temp};
    setQuregToWeightedSum(qureg, coeffs, quregs, 2);
    void setQuregToWeightedSum(Qureg out, qcomp *coeffs, Qureg *in, int numIn)
    void applyPauliStr(Qureg qureg, PauliStr str)
    Qureg createCloneQureg(Qureg qureg)
    Definition qureg.cpp:319
    Definition qureg.h:49
  • When str contains only \( \hat{Z} \) or \( \id \) Paulis, this function will automatically invoke applyPhaseGadget() which leverages an optimised implementation.
  • When str contains only \( \id \) Paulis, this function merely effects a change of global phase upon statevectors of \( -\theta/2 \), leaving density matrices unchanged.
    qcomp factor = cexp(- theta / 2 * 1.i);
    setQuregToWeightedSum(qureg, &factor, &qureg, 1);
  • Passing angle=0 is equivalent to effecting the identity, leaving the state unchanged.
Example
Qureg qureg = createQureg(10);
qreal theta = 3.14;
// verbosely
int numPaulis = 4;
char* paulis = "XYIZ";
int targets[] = {0,1,5,7};
PauliStr str = getPauliStr(paulis, targets, numPaulis);
applyPauliGadget(qureg, str, angle);
// concisely
applyPauliGadget(qureg, getInlinePauliStr("XYZ",{0,1,7}), theta);
void applyPauliGadget(Qureg qureg, PauliStr str, qreal angle)
PauliStr getInlinePauliStr(const char *paulis, { list })
PauliStr getPauliStr(const char *paulis, int *indices, int numPaulis)
Definition paulis.cpp:76
Qureg createQureg(int numQubits)
Definition qureg.cpp:283
See also

Definition at line 1241 of file operations.cpp.

1241 {
1242 validate_quregFields(qureg, __func__);
1243 validate_pauliStrTargets(qureg, str, __func__);
1244
1245 applyMultiStateControlledPauliGadget(qureg, nullptr, nullptr, 0, str, angle);
1246}