|
18 | 18 | from mqt.qecc import mod2 |
19 | 19 |
|
20 | 20 | from ..codes import CSSCode |
21 | | -from ..codes.core.pauli import CheckMatrix, Pauli, PauliTableau, complete_stabilizer_tableau_with_destabilizers |
22 | | -from ..codes.core.symplectic import SymplecticVector |
| 21 | +from ..codes.core.pauli import CheckMatrix, PauliTableau, complete_stabilizer_tableau_with_destabilizers |
23 | 22 | from .circuits import CliffordIsometry, CNOTCircuit |
24 | 23 | from .exact import ( |
25 | 24 | Objective, |
@@ -370,17 +369,17 @@ def synthesize_encoding_circuit( |
370 | 369 | additional_z_rows, |
371 | 370 | )) |
372 | 371 | gens_phase: npt.NDArray[np.int8] = np.hstack(( |
373 | | - code.generators.phase, |
374 | | - code.x_logicals.phase[additional_x_checks], |
375 | | - code.z_logicals.phase[additional_z_checks], |
| 372 | + code.generators.phase_exponents, |
| 373 | + code.x_logicals.phase_exponents[additional_x_checks], |
| 374 | + code.z_logicals.phase_exponents[additional_z_checks], |
376 | 375 | )) |
377 | 376 | log_mat: npt.NDArray[np.int8] = np.vstack(( |
378 | 377 | np.delete(code.x_logicals.tableau.data, additional_checks, axis=0), |
379 | 378 | np.delete(code.z_logicals.tableau.data, additional_checks, axis=0), |
380 | 379 | )) |
381 | 380 | log_phase: npt.NDArray[np.int8] = np.hstack(( |
382 | | - np.delete(code.x_logicals.phase, additional_checks, axis=0), |
383 | | - np.delete(code.z_logicals.phase, additional_checks, axis=0), |
| 381 | + np.delete(code.x_logicals.phase_exponents, additional_checks, axis=0), |
| 382 | + np.delete(code.z_logicals.phase_exponents, additional_checks, axis=0), |
384 | 383 | )) |
385 | 384 |
|
386 | 385 | return encoder_from_stabilizers_and_logicals( |
@@ -465,61 +464,33 @@ def optimize_tableau(tableau: PauliTableau, stab_rows: list[int]) -> PauliTablea |
465 | 464 | if i == j: |
466 | 465 | continue |
467 | 466 | tab = tableau.copy() |
468 | | - mat = tab.tableau.data |
469 | | - destabs = mat[:half][stab_rows] |
470 | | - stabs = mat[half:][stab_rows] |
471 | 467 |
|
472 | 468 | stab_i_abs, stab_j_abs = half + stab_rows[i], half + stab_rows[j] |
473 | 469 | destab_i_abs, destab_j_abs = stab_rows[i], stab_rows[j] |
474 | 470 |
|
475 | | - new_stab_i = Pauli(SymplecticVector(stabs[i].copy()), tab.phase[stab_i_abs]) * Pauli( |
476 | | - SymplecticVector(stabs[j].copy()), tab.phase[stab_j_abs] |
477 | | - ) |
478 | | - new_destab_j = Pauli(SymplecticVector(destabs[j].copy()), tab.phase[destab_j_abs]) * Pauli( |
479 | | - SymplecticVector(destabs[i].copy()), tab.phase[destab_i_abs] |
480 | | - ) |
481 | | - |
482 | | - stabs[i] ^= stabs[j] |
483 | | - destabs[j] ^= destabs[i] |
484 | | - mat[:half][stab_rows] = destabs |
485 | | - mat[half:][stab_rows] = stabs |
486 | | - tab.phase[stab_i_abs] = new_stab_i.phase |
487 | | - tab.phase[destab_j_abs] = new_destab_j.phase |
488 | | - |
489 | | - new_score, _ = score_symplectic(PauliTableau(mat, tab.phase.copy())) |
| 471 | + # Multiplying a stabilizer onto another must be mirrored on the |
| 472 | + # destabilizers in the opposite direction to preserve the symplectic form. |
| 473 | + tab.multiply_rows(stab_i_abs, stab_j_abs) |
| 474 | + tab.multiply_rows(destab_j_abs, destab_i_abs) |
| 475 | + |
| 476 | + new_score, _ = score_symplectic(tab) |
490 | 477 | if lexicographical_compare_np(new_score, best[1]): |
491 | 478 | best = (tab, new_score) |
492 | 479 | improved = True |
493 | 480 | for j in range(len(logical_rows)): |
494 | 481 | tab = tableau.copy() |
495 | | - mat = tab.tableau.data |
496 | | - destabs = mat[:half][stab_rows] |
497 | | - stabs = mat[half:][stab_rows] |
498 | 482 |
|
499 | | - other_log = mat[logical_rows[(j + k) % (2 * k)]] |
500 | 483 | other_log_abs = logical_rows[(j + k) % (2 * k)] |
501 | 484 | destab_i_abs = stab_rows[i] |
502 | 485 | log_j_abs = logical_rows[j] |
503 | 486 | stab_i_abs = half + stab_rows[i] |
504 | 487 |
|
505 | | - new_destab_i = Pauli(SymplecticVector(destabs[i].copy()), tab.phase[destab_i_abs]) * Pauli( |
506 | | - SymplecticVector(other_log.copy()), tab.phase[other_log_abs] |
507 | | - ) |
508 | | - |
509 | | - destabs[i] ^= other_log |
510 | | - logj = mat[logical_rows[j]] |
511 | | - |
512 | | - new_logj = Pauli(SymplecticVector(logj.copy()), tab.phase[log_j_abs]) * Pauli( |
513 | | - SymplecticVector(stabs[i].copy()), tab.phase[stab_i_abs] |
514 | | - ) |
515 | | - |
516 | | - logj ^= stabs[i] |
517 | | - mat[:half][stab_rows] = destabs |
518 | | - mat[logical_rows[j]] = logj |
519 | | - tab.phase[destab_i_abs] = new_destab_i.phase |
520 | | - tab.phase[log_j_abs] = new_logj.phase |
| 488 | + # The stabilizer row is read by the second multiplication, so it must |
| 489 | + # not be one of the rows written by the first. |
| 490 | + tab.multiply_rows(destab_i_abs, other_log_abs) |
| 491 | + tab.multiply_rows(log_j_abs, stab_i_abs) |
521 | 492 |
|
522 | | - new_score, _ = score_symplectic(PauliTableau(mat, tab.phase.copy())) |
| 493 | + new_score, _ = score_symplectic(tab) |
523 | 494 | if lexicographical_compare_np(new_score, best[1]): |
524 | 495 | best = (tab, new_score) |
525 | 496 | improved = True |
@@ -547,11 +518,11 @@ def combine_stabilizer_and_logical_tableau(stabilizers: PauliTableau, logicals: |
547 | 518 | # Combine stabilizers and logicals into a single tableau |
548 | 519 | x_logicals = logicals.tableau.data[: logicals.num_rows() // 2] |
549 | 520 | z_logicals = logicals.tableau.data[logicals.num_rows() // 2 :] |
550 | | - x_logicals_phase = logicals.phase[: logicals.num_rows() // 2] |
551 | | - z_logicals_phase = logicals.phase[logicals.num_rows() // 2 :] |
| 521 | + x_logicals_phase = logicals.phase_exponents[: logicals.num_rows() // 2] |
| 522 | + z_logicals_phase = logicals.phase_exponents[logicals.num_rows() // 2 :] |
552 | 523 | combined_matrix = np.vstack([x_logicals, z_logicals, stabilizers.tableau.data]) |
553 | 524 |
|
554 | | - combined_phase = np.hstack([x_logicals_phase, z_logicals_phase, stabilizers.phase]) |
| 525 | + combined_phase = np.hstack([x_logicals_phase, z_logicals_phase, stabilizers.phase_exponents]) |
555 | 526 | combined_tableau = PauliTableau(combined_matrix, combined_phase) |
556 | 527 |
|
557 | 528 | # Complete with destabilizers for the stabilizers only |
|
0 commit comments