Skip to content

Commit 5fa4f60

Browse files
added non-unitary Pauli gadgets (#637)
as part of unitaryHACK 2025, challenge issue #594 --------- Co-authored-by: Tyson Jones <[email protected]>
1 parent cd5120c commit 5fa4f60

File tree

13 files changed

+82
-8
lines changed

13 files changed

+82
-8
lines changed

AUTHORS.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ Dr Ian Bush [consultant]
4444
HPC
4545

4646
External contributors:
47+
Diogo Pratas Maia
48+
added non-unitary Pauli gadget (for unitaryHACK issue #594)
4749
Mai Đức Khang
4850
implemented RAM probe (for unitaryHACK issue #600)
4951
James Richings

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ See the [docs](docs/README.md) for enabling acceleration and running the unit te
257257

258258
In addition to QuEST's [authors](AUTHORS.txt), we sincerely thank the following external contributors to QuEST.
259259

260+
- [Diogo Pratas Maia](https://github.com/diogomaia00) for implementing non-unitary Pauli gadgets (unitaryHACK 2025 [#594](https://github.com/QuEST-Kit/QuEST/issues/594)).
260261
- [Mai Đức Khang](https://github.com/Roll249) for implementing a RAM probe (unitaryHACK 2025 [#600](https://github.com/QuEST-Kit/QuEST/issues/600)).
261262
- [James Richings](https://github.com/JPRichings) for patching a v4 overflow bug.
262263
- [Luc Jaulmes](https://github.com/lucjaulmes) for patching v4's CMake installation.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include "quest.h"
2+
3+
int main() {
4+
initQuESTEnv();
5+
6+
Qureg qureg = createQureg(3);
7+
PauliStr str = getInlinePauliStr("XYZ", {0,1,2});
8+
qcomp angle = getQcomp(.4, .8);
9+
10+
initPlusState(qureg);
11+
applyNonUnitaryPauliGadget(qureg, str, angle);
12+
13+
qreal norm = calcTotalProb(qureg);
14+
reportScalar("norm", norm);
15+
16+
finalizeQuESTEnv();
17+
return 0;
18+
}

quest/include/operations.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* instead exposed in decoherence.h
66
*
77
* @author Tyson Jones
8+
* @author Diogo Pratas Maia (non-unitary Pauli gadget)
89
*
910
* @defgroup operations Operations
1011
* @ingroup api
@@ -1853,6 +1854,8 @@ void multiplyPauliGadget(Qureg qureg, PauliStr str, qreal angle);
18531854
*/
18541855
void applyPauliGadget(Qureg qureg, PauliStr str, qreal angle);
18551856

1857+
/// @notyetdoced
1858+
void applyNonUnitaryPauliGadget(Qureg qureg, PauliStr str, qcomp angle);
18561859

18571860
/// @notyetdoced
18581861
void applyControlledPauliGadget(Qureg qureg, int control, PauliStr str, qreal angle);

quest/src/api/operations.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,6 +1432,22 @@ void applyPauliGadget(Qureg qureg, PauliStr str, qreal angle) {
14321432
applyMultiStateControlledPauliGadget(qureg, nullptr, nullptr, 0, str, angle);
14331433
}
14341434

1435+
void applyNonUnitaryPauliGadget(Qureg qureg, PauliStr str, qcomp angle) {
1436+
validate_quregFields(qureg, __func__);
1437+
validate_pauliStrTargets(qureg, str, __func__);
1438+
1439+
qcomp phase = util_getPhaseFromGateAngle(angle);
1440+
localiser_statevec_anyCtrlPauliGadget(qureg, {}, {}, str, phase);
1441+
1442+
if (!qureg.isDensityMatrix)
1443+
return;
1444+
1445+
// conj(e^i(a)XZ) = e^(-i conj(a)XZ) but conj(Y)=-Y, so odd-Y undoes phase negation
1446+
phase = std::conj(phase) * (paulis_hasOddNumY(str) ? 1 : -1);
1447+
str = paulis_getShiftedPauliStr(str, qureg.numQubits);
1448+
localiser_statevec_anyCtrlPauliGadget(qureg, {}, {}, str, phase);
1449+
}
1450+
14351451
void applyControlledPauliGadget(Qureg qureg, int control, PauliStr str, qreal angle) {
14361452
validate_quregFields(qureg, __func__);
14371453
validate_controlAndPauliStrTargets(qureg, control, str, __func__);

quest/src/core/localiser.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,7 @@ extern int paulis_getPrefixZSign(Qureg qureg, vector<int> prefixZ) ;
12441244
extern qcomp paulis_getPrefixPaulisElem(Qureg qureg, vector<int> prefixY, vector<int> prefixZ);
12451245

12461246

1247-
void anyCtrlZTensorOrGadget(Qureg qureg, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, bool isGadget, qreal phase) {
1247+
void anyCtrlZTensorOrGadget(Qureg qureg, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, bool isGadget, qcomp phase) {
12481248
assertValidCtrlStates(ctrls, ctrlStates);
12491249
setDefaultCtrlStates(ctrls, ctrlStates);
12501250

@@ -1339,14 +1339,14 @@ void localiser_statevec_anyCtrlPauliTensor(Qureg qureg, vector<int> ctrls, vecto
13391339
}
13401340

13411341

1342-
void localiser_statevec_anyCtrlPhaseGadget(Qureg qureg, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qreal phase) {
1342+
void localiser_statevec_anyCtrlPhaseGadget(Qureg qureg, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qcomp phase) {
13431343

13441344
bool isGadget = true;
1345-
anyCtrlZTensorOrGadget(qureg, ctrls, ctrlStates, targs, isGadget, phase);
1345+
anyCtrlZTensorOrGadget(qureg, ctrls, ctrlStates, targs, isGadget, phase);
13461346
}
13471347

13481348

1349-
void localiser_statevec_anyCtrlPauliGadget(Qureg qureg, vector<int> ctrls, vector<int> ctrlStates, PauliStr str, qreal phase) {
1349+
void localiser_statevec_anyCtrlPauliGadget(Qureg qureg, vector<int> ctrls, vector<int> ctrlStates, PauliStr str, qcomp phase) {
13501350

13511351
// when str=IZ, we must use the above bespoke algorithm
13521352
if (!paulis_containsXOrY(str)) {

quest/src/core/localiser.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ void localiser_statevec_anyCtrlAnyTargAnyMatr(Qureg qureg, vector<int> ctrls, ve
118118

119119
void localiser_statevec_anyCtrlPauliTensor(Qureg qureg, vector<int> ctrls, vector<int> ctrlStates, PauliStr str, qcomp globalFactor=1);
120120

121-
void localiser_statevec_anyCtrlPauliGadget(Qureg qureg, vector<int> ctrls, vector<int> ctrlStates, PauliStr str, qreal phase);
121+
void localiser_statevec_anyCtrlPauliGadget(Qureg qureg, vector<int> ctrls, vector<int> ctrlStates, PauliStr str, qcomp phase);
122122

123-
void localiser_statevec_anyCtrlPhaseGadget(Qureg qureg, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qreal phase);
123+
void localiser_statevec_anyCtrlPhaseGadget(Qureg qureg, vector<int> ctrls, vector<int> ctrlStates, vector<int> targs, qcomp phase);
124124

125125

126126
/*

quest/src/core/memory.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* allocators in gpu_config.cpp, and use NUMA strategies.
1111
*
1212
* @author Tyson Jones
13+
* @author Mai Đức Khang (CPU memory query)
1314
*/
1415

1516
#include "quest/include/types.h"

quest/src/core/utilities.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,10 @@ qreal util_getPhaseFromGateAngle(qreal angle) {
913913
return - angle / 2;
914914
}
915915

916+
qcomp util_getPhaseFromGateAngle(qcomp angle) {
916917

918+
return -angle / qcomp(2.0, 0.0);
919+
}
917920

918921
/*
919922
* DECOHERENCE FACTORS

quest/src/core/utilities.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ util_VectorIndexRange util_getLocalIndRangeOfVectorElemsWithinNode(int rank, qin
350350

351351
qreal util_getPhaseFromGateAngle(qreal angle);
352352

353+
qcomp util_getPhaseFromGateAngle(qcomp angle);
353354

354355

355356
/*

0 commit comments

Comments
 (0)