@@ -1271,14 +1271,16 @@ bool CircuitSeq::to_canonical_representation(const Context *ctx) {
1271
1271
std::unique_ptr<CircuitSeq>
1272
1272
CircuitSeq::get_permuted_seq (const std::vector<int > &qubit_permutation,
1273
1273
const std::vector<int > &input_param_permutation,
1274
- Context *ctx) const {
1274
+ Context *ctx, int result_num_qubits ) const {
1275
1275
auto result = std::make_unique<CircuitSeq>(0 );
1276
1276
if (input_param_permutation.empty ()) {
1277
- result->clone_from (*this , qubit_permutation, input_param_permutation, ctx);
1277
+ result->clone_from (*this , qubit_permutation, input_param_permutation, ctx,
1278
+ result_num_qubits);
1278
1279
} else {
1279
1280
auto all_param_permutation =
1280
1281
ctx->get_param_permutation (input_param_permutation);
1281
- result->clone_from (*this , qubit_permutation, all_param_permutation, ctx);
1282
+ result->clone_from (*this , qubit_permutation, all_param_permutation, ctx,
1283
+ result_num_qubits);
1282
1284
}
1283
1285
return result;
1284
1286
}
@@ -1311,8 +1313,9 @@ CircuitSeq::get_suffix_seq(const std::unordered_set<CircuitGate *> &start_gates,
1311
1313
void CircuitSeq::clone_from (const CircuitSeq &other,
1312
1314
const std::vector<int > &qubit_permutation,
1313
1315
const std::vector<int > ¶m_permutation,
1314
- const Context *ctx) {
1315
- num_qubits = other.num_qubits ;
1316
+ const Context *ctx, int result_num_qubits) {
1317
+ num_qubits = (result_num_qubits == -1 ? other.num_qubits : result_num_qubits);
1318
+ int num_qubits_difference = other.num_qubits - num_qubits;
1316
1319
original_fingerprint_ = other.original_fingerprint_ ;
1317
1320
std::unordered_map<CircuitWire *, CircuitWire *> wires_mapping;
1318
1321
std::unordered_map<CircuitGate *, CircuitGate *> gates_mapping;
@@ -1337,28 +1340,39 @@ void CircuitSeq::clone_from(const CircuitSeq &other,
1337
1340
hash_value_valid_ = false ;
1338
1341
}
1339
1342
if (qubit_permutation.empty ()) {
1343
+ assert (result_num_qubits == -1 );
1340
1344
for (int i = 0 ; i < (int )other.wires .size (); i++) {
1341
1345
wires.emplace_back (std::make_unique<CircuitWire>(*(other.wires [i])));
1342
1346
assert (wires[i].get () !=
1343
1347
other.wires [i].get ()); // make sure we make a copy
1344
1348
wires_mapping[other.wires [i].get ()] = wires[i].get ();
1345
1349
}
1346
1350
} else {
1347
- assert (qubit_permutation.size () == num_qubits);
1348
- wires.resize (other.wires .size ());
1349
- for (int i = 0 ; i < num_qubits; i++) {
1350
- assert (qubit_permutation[i] >= 0 && qubit_permutation[i] < num_qubits);
1351
+ assert (qubit_permutation.size () == other.num_qubits );
1352
+ wires.resize (other.wires .size () - num_qubits_difference);
1353
+ for (int i = 0 ; i < other.num_qubits ; i++) {
1354
+ if (result_num_qubits == -1 ) {
1355
+ assert (qubit_permutation[i] >= 0 && qubit_permutation[i] < num_qubits);
1356
+ } else {
1357
+ if (qubit_permutation[i] < 0 || qubit_permutation[i] >= num_qubits) {
1358
+ continue ;
1359
+ }
1360
+ }
1351
1361
wires[qubit_permutation[i]] =
1352
1362
std::make_unique<CircuitWire>(*(other.wires [i]));
1353
1363
wires[qubit_permutation[i]]->index =
1354
1364
qubit_permutation[i]; // update index
1355
1365
assert (wires[qubit_permutation[i]].get () != other.wires [i].get ());
1356
1366
wires_mapping[other.wires [i].get ()] = wires[qubit_permutation[i]].get ();
1357
1367
}
1358
- for (int i = num_qubits; i < (int )other.wires .size (); i++) {
1359
- wires[i] = std::make_unique<CircuitWire>(*(other.wires [i]));
1360
- wires[i]->index = qubit_permutation[wires[i]->index ]; // update index
1361
- wires_mapping[other.wires [i].get ()] = wires[i].get ();
1368
+ for (int i = other.num_qubits ; i < (int )other.wires .size (); i++) {
1369
+ wires[i - num_qubits_difference] =
1370
+ std::make_unique<CircuitWire>(*(other.wires [i]));
1371
+ // update index
1372
+ wires[i - num_qubits_difference]->index =
1373
+ qubit_permutation[wires[i - num_qubits_difference]->index ];
1374
+ wires_mapping[other.wires [i].get ()] =
1375
+ wires[i - num_qubits_difference].get ();
1362
1376
}
1363
1377
}
1364
1378
if (!param_permutation.empty ()) {
@@ -1392,8 +1406,19 @@ void CircuitSeq::clone_from(const CircuitSeq &other,
1392
1406
wire = wires_mapping[wire];
1393
1407
}
1394
1408
}
1395
- for (auto &wire : other.outputs ) {
1396
- outputs.emplace_back (wires_mapping[wire]);
1409
+ if (qubit_permutation.empty ()) {
1410
+ for (auto &wire : other.outputs ) {
1411
+ outputs.emplace_back (wires_mapping[wire]);
1412
+ }
1413
+ } else {
1414
+ outputs.resize (num_qubits);
1415
+ for (auto &wire : other.outputs ) {
1416
+ if (wires_mapping.count (wire) > 0 ) {
1417
+ assert (qubit_permutation[wire->index ] >= 0 &&
1418
+ qubit_permutation[wire->index ] < num_qubits);
1419
+ outputs[qubit_permutation[wire->index ]] = wires_mapping[wire];
1420
+ }
1421
+ }
1397
1422
}
1398
1423
}
1399
1424
0 commit comments