| 2391 | |
| 2392 | template <int NumQubits> |
| 2393 | void cpu_densmatr_multiQubitProjector_sub(Qureg qureg, vector<int> qubits, vector<int> outcomes, qreal prob) { |
| 2394 | |
| 2395 | // this function is merely an optimisation to avoid calling the above |
| 2396 | // cpu_statevec_multiQubitProjector_sub() twice upon a density matrix; |
| 2397 | // pre- and post-multiply projector versions DO just call above. |
| 2398 | |
| 2399 | // qubits are unconstrained, and can include prefix qubits |
| 2400 | assert_numTargsMatchesTemplateParam(qubits.size(), NumQubits); |
| 2401 | |
| 2402 | // visit every amp, setting most to zero and multiplying the remainder by renorm |
| 2403 | qindex numIts = qureg.numAmpsPerNode; |
| 2404 | qreal renorm = 1 / prob; |
| 2405 | |
| 2406 | // binary value of targeted qubits in basis states which are to be retained |
| 2407 | qindex retainValue = getIntegerFromBits(outcomes.data(), outcomes.size()); |
| 2408 | |
| 2409 | // use template param to compile-time unroll loops in getValueOfBits() |
| 2410 | SET_VAR_AT_COMPILE_TIME(int, numBits, NumQubits, qubits.size()); |
| 2411 | |
| 2412 | #pragma omp parallel for if(qureg.isMultithreaded) |
| 2413 | for (qindex n=0; n<numIts; n++) { |
| 2414 | |
| 2415 | // i = global index of nth local amp |
| 2416 | qindex i = concatenateBits(qureg.rank, n, qureg.logNumAmpsPerNode); |
| 2417 | |
| 2418 | // r, c = global row and column indices of nth local amp |
| 2419 | qindex r = getBitsRightOfIndex(i, qureg.numQubits); |
| 2420 | qindex c = getBitsLeftOfIndex(i, qureg.numQubits-1); |
| 2421 | |
| 2422 | qindex v1 = getValueOfBits(r, qubits.data(), numBits); |
| 2423 | qindex v2 = getValueOfBits(c, qubits.data(), numBits); |
| 2424 | |
| 2425 | // multiply amp with renorm or zero if values disagree with given outcomes |
| 2426 | qcomp fac = renorm * (v1 == v2) * (retainValue == v1); |
| 2427 | qureg.cpuAmps[n] *= fac; |
| 2428 | } |
| 2429 | } |
| 2430 | |
| 2431 | |
| 2432 | INSTANTIATE_FUNC_OPTIMISED_FOR_NUM_TARGS( void, cpu_statevec_multiQubitProjector_sub, (Qureg qureg, vector<int> qubits, vector<int> outcomes, qreal prob) ) |
nothing calls this directly
no test coverage detected