The Quantum Exact Simulation Toolkit v4.3.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!

Applies a singly-controlled many-qubit rotation upon qureg, generated by tensor product of Pauli operators str.

‍- See applyPauliGadget() for information about the base operation, angle, and str.

Author
Tyson Jones

Definition at line 1265 of file operations.cpp.

1265 {
1266 validate_quregFields(qureg, __func__);
1267 validate_controlAndPauliStrTargets(qureg, control, str, __func__);
1268
1269 applyMultiStateControlledPauliGadget(qureg, &control, nullptr, 1, str, angle);
1270}
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!

Applies a multiply-controlled many-qubit rotation upon qureg, generated by tensor product of Pauli operators str.

‍- See applyPauliGadget() for information about the base operation, angle, and str.

Author
Tyson Jones

Definition at line 1272 of file operations.cpp.

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

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!

Applies an arbitrarily-controlled many-qubit rotation upon qureg, generated by tensor product of Pauli operators str, and conditioned upon controls being in the corresponding states.

‍- See applyPauliGadget() for information about the base operation, angle, and str.

Author
Tyson Jones

Definition at line 1279 of file operations.cpp.

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

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 auto none = lists_getEmptyList64();
1254 localiser_statevec_anyCtrlPauliGadget(qureg, none, none, str, phase);
1255
1256 if (!qureg.isDensityMatrix)
1257 return;
1258
1259 // conj(e^i(a)P) = e^(-i s conj(a) P)
1260 phase = - std::conj(phase) * paulis_getSignOfPauliStrConj(str);
1261 str = paulis_getShiftedPauliStr(str, qureg.numQubits);
1262 localiser_statevec_anyCtrlPauliGadget(qureg, none, none, str, phase);
1263}

Referenced by TEST_CASE().

◆ applyPauliGadget()

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

Applies a many-qubit rotation upon qureg, generated by tensor product of Pauli operators str.

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:325
    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:289
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}