Skip to content

Commit 34fb5fc

Browse files
committed
patched shifted phase functions
which slightly differed to documentation. - Previously, SCALED_INVERSE_SHIFTED_DISTANCE computed coeff/sqrt( (x2-x1-dx)^2 + ... ), but now computes coeff/sqrt( (x1-x2-dx)^2 + ... (x1 and x2 have swapped) - Previously, SCALED_INVERSE_SHIFTED_NORM and SCALED_INVERSE_SHIFTED_DISTANCE used their divergence parameter when their denominators were precisely zero. Now, the divergence parameter is used whenever the denominator is within REAL_EPS to zero.
1 parent 840fa4e commit 34fb5fc

File tree

4 files changed

+28
-19
lines changed

4 files changed

+28
-19
lines changed

QuEST/include/QuEST.h

+5
Original file line numberDiff line numberDiff line change
@@ -6176,6 +6176,11 @@ void applyNamedPhaseFuncOverrides(Qureg qureg, int* qubits, int* numQubitsPerReg
61766176
* \f[
61776177
* f(\vec{r}, \theta)|_{\theta=0.5} \; = \; \begin{cases} \pi & \;\;\; \vec{r}=\vec{0} \\ \displaystyle 0.5 \left[ \sum_j^{\text{numRegs}} {r_j}^2 \right]^{-1/2} & \;\;\;\text{otherwise} \end{cases}.
61786178
* \f]
6179+
* Notice the order of the parameters matches the order of the words in the \p phaseFunc.
6180+
* > Functions \p SCALED_INVERSE_SHIFTED_NORM and \p SCALED_INVERSE_SHIFTED_DISTANCE,
6181+
* > which can have denominators arbitrarily close to zero, will invoke the
6182+
* > divergence parameter whenever the denominator is smaller than (or equal to)
6183+
* > machine precision `REAL_EPS`.
61796184
*
61806185
* - Functions allowing the shifting of sub-register values, which are \p SCALED_INVERSE_SHIFTED_NORM
61816186
* and \p SCALED_INVERSE_SHIFTED_DISTANCE, need these shift values to be passed in the \p params

QuEST/src/CPU/QuEST_cpu.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -4529,15 +4529,15 @@ void statevec_applyParamNamedPhaseFuncOverrides(
45294529
for (r=0; r<numRegs; r++)
45304530
norm += phaseInds[r]*phaseInds[r];
45314531
norm = sqrt(norm);
4532-
4532+
45334533
if (phaseFuncName == NORM)
45344534
phase = norm;
45354535
else if (phaseFuncName == INVERSE_NORM)
4536-
phase = (norm == 0.)? params[0] : 1/norm;
4536+
phase = (norm == 0.)? params[0] : 1/norm; // smallest non-zero norm is 1
45374537
else if (phaseFuncName == SCALED_NORM)
45384538
phase = params[0] * norm;
45394539
else if (phaseFuncName == SCALED_INVERSE_NORM || phaseFuncName == SCALED_INVERSE_SHIFTED_NORM)
4540-
phase = (norm == 0.)? params[1] : params[0] / norm;
4540+
phase = (norm <= REAL_EPS)? params[1] : params[0] / norm; // unless shifted closer to zero
45414541
}
45424542
// compute product related phases
45434543
else if (phaseFuncName == PRODUCT || phaseFuncName == INVERSE_PRODUCT ||
@@ -4550,7 +4550,7 @@ void statevec_applyParamNamedPhaseFuncOverrides(
45504550
if (phaseFuncName == PRODUCT)
45514551
phase = prod;
45524552
else if (phaseFuncName == INVERSE_PRODUCT)
4553-
phase = (prod == 0.)? params[0] : 1/prod;
4553+
phase = (prod == 0.)? params[0] : 1/prod; // smallest non-zero product norm is +- 1
45544554
else if (phaseFuncName == SCALED_PRODUCT)
45554555
phase = params[0] * prod;
45564556
else if (phaseFuncName == SCALED_INVERSE_PRODUCT)
@@ -4564,7 +4564,7 @@ void statevec_applyParamNamedPhaseFuncOverrides(
45644564
dist = 0;
45654565
if (phaseFuncName == SCALED_INVERSE_SHIFTED_DISTANCE) {
45664566
for (r=0; r<numRegs; r+=2)
4567-
dist += (phaseInds[r+1] - phaseInds[r] - params[2+r/2])*(phaseInds[r+1] - phaseInds[r] - params[2+r/2]);
4567+
dist += (phaseInds[r] - phaseInds[r+1] - params[2+r/2])*(phaseInds[r] - phaseInds[r+1] - params[2+r/2]);
45684568
}
45694569
else
45704570
for (r=0; r<numRegs; r+=2)
@@ -4574,11 +4574,11 @@ void statevec_applyParamNamedPhaseFuncOverrides(
45744574
if (phaseFuncName == DISTANCE)
45754575
phase = dist;
45764576
else if (phaseFuncName == INVERSE_DISTANCE)
4577-
phase = (dist == 0.)? params[0] : 1/dist;
4577+
phase = (dist == 0.)? params[0] : 1/dist; // smallest non-zero dist is 1
45784578
else if (phaseFuncName == SCALED_DISTANCE)
45794579
phase = params[0] * dist;
45804580
else if (phaseFuncName == SCALED_INVERSE_DISTANCE || phaseFuncName == SCALED_INVERSE_SHIFTED_DISTANCE)
4581-
phase = (dist == 0.)? params[1] : params[0] / dist;
4581+
phase = (dist <= REAL_EPS)? params[1] : params[0] / dist; // unless shifted closer to 0
45824582
}
45834583
}
45844584

QuEST/src/GPU/QuEST_gpu.cu

+6-6
Original file line numberDiff line numberDiff line change
@@ -3835,11 +3835,11 @@ __global__ void statevec_applyParamNamedPhaseFuncOverridesKernel(
38353835
if (phaseFuncName == NORM)
38363836
phase = norm;
38373837
else if (phaseFuncName == INVERSE_NORM)
3838-
phase = (norm == 0.)? params[0] : 1/norm;
3838+
phase = (norm == 0.)? params[0] : 1/norm; // smallest non-zero norm is 1
38393839
else if (phaseFuncName == SCALED_NORM)
38403840
phase = params[0] * norm;
38413841
else if (phaseFuncName == SCALED_INVERSE_NORM || phaseFuncName == SCALED_INVERSE_SHIFTED_NORM)
3842-
phase = (norm == 0.)? params[1] : params[0] / norm;
3842+
phase = (norm <= REAL_EPS)? params[1] : params[0] / norm; // unless shifted closer to zero
38433843
}
38443844
// compute product related phases
38453845
else if (phaseFuncName == PRODUCT || phaseFuncName == INVERSE_PRODUCT ||
@@ -3852,7 +3852,7 @@ __global__ void statevec_applyParamNamedPhaseFuncOverridesKernel(
38523852
if (phaseFuncName == PRODUCT)
38533853
phase = prod;
38543854
else if (phaseFuncName == INVERSE_PRODUCT)
3855-
phase = (prod == 0.)? params[0] : 1/prod;
3855+
phase = (prod == 0.)? params[0] : 1/prod; // smallest non-zero prod is +- 1
38563856
else if (phaseFuncName == SCALED_PRODUCT)
38573857
phase = params[0] * prod;
38583858
else if (phaseFuncName == SCALED_INVERSE_PRODUCT)
@@ -3866,7 +3866,7 @@ __global__ void statevec_applyParamNamedPhaseFuncOverridesKernel(
38663866
qreal dist = 0;
38673867
if (phaseFuncName == SCALED_INVERSE_SHIFTED_DISTANCE) {
38683868
for (int r=0; r<numRegs; r+=2) {
3869-
qreal dif = (phaseInds[(r+1)*stride+offset] - phaseInds[r*stride+offset] - params[2+r/2]);
3869+
qreal dif = (phaseInds[r*stride+offset] - phaseInds[(r+1)*stride+offset] - params[2+r/2]);
38703870
dist += dif*dif;
38713871
}
38723872
}
@@ -3880,11 +3880,11 @@ __global__ void statevec_applyParamNamedPhaseFuncOverridesKernel(
38803880
if (phaseFuncName == DISTANCE)
38813881
phase = dist;
38823882
else if (phaseFuncName == INVERSE_DISTANCE)
3883-
phase = (dist == 0.)? params[0] : 1/dist;
3883+
phase = (dist == 0.)? params[0] : 1/dist; // smallest non-zero dist is 1
38843884
else if (phaseFuncName == SCALED_DISTANCE)
38853885
phase = params[0] * dist;
38863886
else if (phaseFuncName == SCALED_INVERSE_DISTANCE || phaseFuncName == SCALED_INVERSE_SHIFTED_DISTANCE)
3887-
phase = (dist == 0.)? params[1] : params[0] / dist;
3887+
phase = (dist <= REAL_EPS)? params[1] : params[0] / dist; // unless shifted closer
38883888
}
38893889
}
38903890

tests/test_operators.cpp

+10-6
Original file line numberDiff line numberDiff line change
@@ -1723,7 +1723,8 @@ TEST_CASE( "applyParamNamedPhaseFunc", "[operators]" ) {
17231723
qreal phase = 0;
17241724
for (int r=0; r<numRegs; r++)
17251725
phase += pow(regVals[i][r] - params[2+r], 2);
1726-
phase = (phase == 0.)? params[1] : params[0]/sqrt(phase);
1726+
phase = sqrt(phase);
1727+
phase = (phase <= REAL_EPS)? params[1] : params[0]/phase;
17271728
diagMatr[i][i] = expI(phase);
17281729
}
17291730

@@ -1952,8 +1953,9 @@ TEST_CASE( "applyParamNamedPhaseFunc", "[operators]" ) {
19521953
for (size_t i=0; i<diagMatr.size(); i++) {
19531954
qreal phase = 0;
19541955
for (int r=0; r<numRegs; r+=2)
1955-
phase += pow(regVals[i][r+1]-regVals[i][r]-params[2+r/2], 2);
1956-
phase = (phase == 0.)? params[1] : params[0]/sqrt(phase);
1956+
phase += pow(regVals[i][r]-regVals[i][r+1]-params[2+r/2], 2);
1957+
phase = sqrt(phase);
1958+
phase = (phase <= REAL_EPS)? params[1] : params[0]/phase;
19571959
diagMatr[i][i] = expI(phase);
19581960
}
19591961
}
@@ -2271,7 +2273,8 @@ TEST_CASE( "applyParamNamedPhaseFuncOverrides", "[operators]" ) {
22712273
qreal phase = 0;
22722274
for (int r=0; r<numRegs; r++)
22732275
phase += pow(regVals[i][r] - params[2+r], 2);
2274-
phase = (phase == 0.)? params[1] : params[0]/sqrt(phase);
2276+
phase = sqrt(phase);
2277+
phase = (phase <= REAL_EPS)? params[1] : params[0]/phase;
22752278
diagMatr[i][i] = expI(phase);
22762279
}
22772280
setDiagMatrixOverrides(diagMatr, numQubitsPerReg, numRegs, encoding, overrideInds, overridePhases, numOverrides);
@@ -2505,8 +2508,9 @@ TEST_CASE( "applyParamNamedPhaseFuncOverrides", "[operators]" ) {
25052508
for (size_t i=0; i<diagMatr.size(); i++) {
25062509
qreal phase = 0;
25072510
for (int r=0; r<numRegs; r+=2)
2508-
phase += pow(regVals[i][r+1]-regVals[i][r]-params[2+r/2], 2);
2509-
phase = (phase == 0.)? params[1] : params[0]/sqrt(phase);
2511+
phase += pow(regVals[i][r]-regVals[i][r+1]-params[2+r/2], 2);
2512+
phase = sqrt(phase);
2513+
phase = (phase <= REAL_EPS)? params[1] : params[0]/phase;
25102514
diagMatr[i][i] = expI(phase);
25112515
}
25122516

0 commit comments

Comments
 (0)