| 2362 | |
| 2363 | template <int NumQubits> |
| 2364 | void cpu_statevec_multiQubitProjector_sub(Qureg qureg, vector<int> qubits, vector<int> outcomes, qreal prob) { |
| 2365 | |
| 2366 | // all qubits are in suffix |
| 2367 | assert_numTargsMatchesTemplateParam(qubits.size(), NumQubits); |
| 2368 | |
| 2369 | // visit every amp, setting to zero or multiplying it by renorm |
| 2370 | qindex numIts = qureg.numAmpsPerNode; |
| 2371 | qreal renorm = 1 / std::sqrt(prob); |
| 2372 | |
| 2373 | // binary value of targeted qubits in basis states which are to be retained |
| 2374 | qindex retainValue = getIntegerFromBits(outcomes.data(), outcomes.size()); |
| 2375 | |
| 2376 | // use template param to compile-time unroll loop in getValueOfBits() |
| 2377 | SET_VAR_AT_COMPILE_TIME(int, numBits, NumQubits, qubits.size()); |
| 2378 | |
| 2379 | #pragma omp parallel for if(qureg.isMultithreaded) |
| 2380 | for (qindex n=0; n<numIts; n++) { |
| 2381 | |
| 2382 | // val = outcomes corresponding to n-th local amp (all qubits are in suffix) |
| 2383 | qindex val = getValueOfBits(n, qubits.data(), numBits); |
| 2384 | |
| 2385 | // multiply amp with renorm or zero, if qubit value matches or disagrees |
| 2386 | qcomp fac = renorm * (val == retainValue); |
| 2387 | qureg.cpuAmps[n] *= fac; |
| 2388 | } |
| 2389 | } |
| 2390 | |
| 2391 | |
| 2392 | template <int NumQubits> |
nothing calls this directly
no test coverage detected