| 1661 | } |
| 1662 | |
| 1663 | qindex applyMultiQubitMeasurementAndGetProb(Qureg qureg, int* qubits, int numQubits, qreal* probability) { |
| 1664 | validate_quregFields(qureg, __func__); |
| 1665 | validate_targets(qureg, qubits, numQubits, __func__); |
| 1666 | |
| 1667 | // find the probability of all possible outcomes... |
| 1668 | qindex numProbs = powerOf2(numQubits); |
| 1669 | |
| 1670 | // by allocating a temp vector, and validating successful (since exponentially big!) |
| 1671 | vector<qreal> probs; |
| 1672 | auto callback = [&]() { validate_tempAllocSucceeded(false, numProbs, sizeof(qreal), __func__); }; |
| 1673 | util_tryAllocVector(probs, numProbs, callback); |
| 1674 | |
| 1675 | // populate probs |
| 1676 | calcProbsOfAllMultiQubitOutcomes(probs.data(), qureg, qubits, numQubits); // harmlessly re-validates |
| 1677 | |
| 1678 | // we cannot meaningfully sample these probs if not normalised |
| 1679 | validate_measurementProbsAreNormalised(probs, __func__); |
| 1680 | |
| 1681 | // randomly choose an outcome |
| 1682 | qindex outcome = rand_getRandomMultiQubitOutcome(probs); |
| 1683 | *probability = probs[outcome]; |
| 1684 | |
| 1685 | // map outcome to individual qubit outcomes |
| 1686 | auto qubitVec = util_getVector(qubits, numQubits); |
| 1687 | auto outcomeVec = vector<int>(numQubits); |
| 1688 | getBitsFromInteger(outcomeVec.data(), outcome, numQubits); |
| 1689 | |
| 1690 | // project to the outcomes, renormalising the surviving states |
| 1691 | (qureg.isDensityMatrix)? |
| 1692 | localiser_densmatr_multiQubitProjector(qureg, qubitVec, outcomeVec, *probability): |
| 1693 | localiser_statevec_multiQubitProjector(qureg, qubitVec, outcomeVec, *probability); |
| 1694 | |
| 1695 | return outcome; |
| 1696 | } |
| 1697 | |
| 1698 | qreal applyForcedMultiQubitMeasurement(Qureg qureg, int* qubits, int* outcomes, int numQubits) { |
| 1699 | validate_quregFields(qureg, __func__); |
no test coverage detected