@@ -276,50 +276,38 @@ bool QTensorNetwork::ForceM(bitLenInt qubit, bool result, bool doForce, bool doA
276
276
// Insert terminal measurement.
277
277
measurements[layerId][qubit] = toRet;
278
278
279
- // If no qubit in this layer is target of a non-phase gate, it can be completely telescoped into classical state
280
- // preparation.
281
- while (layerId) {
282
- std::vector<bitLenInt> nonMeasuredQubits;
283
- nonMeasuredQubits.reserve (qubitCount);
284
- for (size_t i = 0U ; i < qubitCount; ++i) {
285
- nonMeasuredQubits.push_back (i);
286
- }
287
- std::map<bitLenInt, bool >& m = measurements[layerId];
288
- for (const auto & b : m) {
289
- nonMeasuredQubits.erase (std::find (nonMeasuredQubits.begin (), nonMeasuredQubits.end (), b.first ));
290
- }
279
+ // If no qubit in this layer is unmeasured, we can completely telescope into classical state preparation.
280
+ std::vector<bitLenInt> nonMeasuredQubits;
281
+ nonMeasuredQubits.reserve (qubitCount);
282
+ for (size_t i = 0U ; i < qubitCount; ++i) {
283
+ nonMeasuredQubits.push_back (i);
284
+ }
285
+ std::map<bitLenInt, bool >& m = measurements[layerId];
286
+ for (const auto & b : m) {
287
+ nonMeasuredQubits.erase (std::find (nonMeasuredQubits.begin (), nonMeasuredQubits.end (), b.first ));
288
+ }
291
289
292
- const QCircuitPtr& c = circuit[layerId];
293
- for (const bitLenInt& q : nonMeasuredQubits) {
294
- if (c->IsNonPhaseTarget (q)) {
295
- // Nothing more to do; tell the user the result.
296
- return toRet;
297
- }
290
+ if (nonMeasuredQubits.empty ()) {
291
+ // All bits have been measured in this layer.
292
+ // None of the previous layers matter.
293
+
294
+ // Erase all of the previous layers.
295
+ std::map<bitLenInt, bool > m = measurements[layerId];
296
+ for (size_t i = 1U ; i < layerId; ++i) {
297
+ circuit.erase (circuit.end () - 1U );
298
+ measurements.erase (measurements.end () - 1U );
298
299
}
300
+ circuit[0U ] = std::make_shared<QCircuit>();
301
+ measurements[0U ] = m;
299
302
300
- // If we did not return, this circuit layer is fully collapsed.
303
+ // Sync layer 0U as state preparation for deterministic measurement.
304
+ std::map<bitLenInt, bool > m0 = measurements[0U ];
301
305
QRACK_CONST complex pauliX[4U ]{ ZERO_CMPLX, ONE_CMPLX, ONE_CMPLX, ZERO_CMPLX };
302
-
303
- const size_t layerIdMin1 = layerId - 1U ;
304
- std::map<bitLenInt, bool >& mMin1 = measurements[layerIdMin1];
305
- for (const auto & b : m) {
306
- const auto it = mMin1 .find (b.first );
307
- if ((it != mMin1 .end ()) && (it->second != b.second )) {
308
- // If the last measurement and this measurement do not agree, insert an X gate between.
309
- circuit[layerIdMin1]->AppendGate (std::make_shared<QCircuitGate>(b.first , pauliX));
306
+ for (const auto & b : m0) {
307
+ if (b.second ) {
308
+ circuit[0U ]->AppendGate (std::make_shared<QCircuitGate>(b.first , pauliX));
310
309
}
311
- // Collapse the measurements into the previous layer.
312
- mMin1 [b.first ] = b.second ;
313
310
}
314
- // Combine any remaining gates into the previous layer
315
- circuit[layerIdMin1]->Combine (circuit[layerId]);
316
- // The circuit layer is effectively empty.
317
- circuit.erase (circuit.begin () + layerId);
318
- // The measurement layer is effectively empty.
319
- measurements.erase (measurements.begin () + layerId);
320
-
321
- // ...Repeat until we reach the terminal layer.
322
- --layerId;
323
311
}
324
312
325
313
// Tell the user the result.
0 commit comments