Skip to content

Commit 197d9a6

Browse files
authored
Fix explain_detector_error_model_errors mixing up Y/Z of PAULI_CHANNEL_2 (#1006)
- Fix a missed XY-to-XZ encoding correction - Add a brute force unit test that verifies all 15 cases Fixes #1005
1 parent 365a1d8 commit 197d9a6

File tree

2 files changed

+309
-0
lines changed

2 files changed

+309
-0
lines changed

src/stim/simulators/error_matcher.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,10 @@ void ErrorMatcher::err_pauli_channel_2(const CircuitInstruction &op) {
222222
}
223223
bool x0 = p0 & 1;
224224
bool z0 = p0 & 2;
225+
x0 ^= z0;
225226
bool x1 = p1 & 1;
226227
bool z1 = p1 & 2;
228+
x1 ^= z1;
227229
uint32_t m0 = x0 * TARGET_PAULI_X_BIT + z0 * TARGET_PAULI_Z_BIT;
228230
uint32_t m1 = x1 * TARGET_PAULI_X_BIT + z1 * TARGET_PAULI_Z_BIT;
229231
pair[0].data = t[k].data | m0;

src/stim/simulators/error_matcher.test.cc

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,3 +609,310 @@ ExplainedError {
609609
}
610610
)RESULT");
611611
}
612+
613+
TEST(ErrorMatcher, PAULI_CHANNEL_2) {
614+
std::vector<ExplainedError> actual;
615+
616+
actual = ErrorMatcher::explain_errors_from_circuit(
617+
Circuit(R"CIRCUIT(
618+
MXX 0 2 1 3
619+
MZZ 0 2 1 3
620+
PAULI_CHANNEL_2(0.1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 0 1
621+
MXX 0 2 1 3
622+
MZZ 0 2 1 3
623+
DETECTOR rec[-1] rec[-5]
624+
DETECTOR rec[-2] rec[-6]
625+
DETECTOR rec[-3] rec[-7]
626+
DETECTOR rec[-4] rec[-8]
627+
)CIRCUIT"),
628+
nullptr,
629+
false);
630+
ASSERT_EQ(actual.size(), 1);
631+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
632+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{GateTargetWithCoords{GateTarget::x(1)}}));
633+
634+
actual = ErrorMatcher::explain_errors_from_circuit(
635+
Circuit(R"CIRCUIT(
636+
MXX 0 2 1 3
637+
MZZ 0 2 1 3
638+
PAULI_CHANNEL_2(0, 0.1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 0 1
639+
MXX 0 2 1 3
640+
MZZ 0 2 1 3
641+
DETECTOR rec[-1] rec[-5]
642+
DETECTOR rec[-2] rec[-6]
643+
DETECTOR rec[-3] rec[-7]
644+
DETECTOR rec[-4] rec[-8]
645+
)CIRCUIT"),
646+
nullptr,
647+
false);
648+
ASSERT_EQ(actual.size(), 1);
649+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
650+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{GateTargetWithCoords{GateTarget::y(1)}}));
651+
652+
actual = ErrorMatcher::explain_errors_from_circuit(
653+
Circuit(R"CIRCUIT(
654+
MXX 0 2 1 3
655+
MZZ 0 2 1 3
656+
PAULI_CHANNEL_2(0, 0, 0.1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 0 1
657+
MXX 0 2 1 3
658+
MZZ 0 2 1 3
659+
DETECTOR rec[-1] rec[-5]
660+
DETECTOR rec[-2] rec[-6]
661+
DETECTOR rec[-3] rec[-7]
662+
DETECTOR rec[-4] rec[-8]
663+
)CIRCUIT"),
664+
nullptr,
665+
false);
666+
ASSERT_EQ(actual.size(), 1);
667+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
668+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{GateTargetWithCoords{GateTarget::z(1)}}));
669+
670+
actual = ErrorMatcher::explain_errors_from_circuit(
671+
Circuit(R"CIRCUIT(
672+
MXX 0 2 1 3
673+
MZZ 0 2 1 3
674+
PAULI_CHANNEL_2(0, 0, 0, 0.1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 0 1
675+
MXX 0 2 1 3
676+
MZZ 0 2 1 3
677+
DETECTOR rec[-1] rec[-5]
678+
DETECTOR rec[-2] rec[-6]
679+
DETECTOR rec[-3] rec[-7]
680+
DETECTOR rec[-4] rec[-8]
681+
)CIRCUIT"),
682+
nullptr,
683+
false);
684+
ASSERT_EQ(actual.size(), 1);
685+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
686+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{
687+
GateTargetWithCoords{GateTarget::x(0)},
688+
}));
689+
690+
actual = ErrorMatcher::explain_errors_from_circuit(
691+
Circuit(R"CIRCUIT(
692+
MXX 0 2 1 3
693+
MZZ 0 2 1 3
694+
PAULI_CHANNEL_2(0, 0, 0, 0, 0.1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 0 1
695+
MXX 0 2 1 3
696+
MZZ 0 2 1 3
697+
DETECTOR rec[-1] rec[-5]
698+
DETECTOR rec[-2] rec[-6]
699+
DETECTOR rec[-3] rec[-7]
700+
DETECTOR rec[-4] rec[-8]
701+
)CIRCUIT"),
702+
nullptr,
703+
false);
704+
ASSERT_EQ(actual.size(), 1);
705+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
706+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{
707+
GateTargetWithCoords{GateTarget::x(0)},
708+
GateTargetWithCoords{GateTarget::x(1)},
709+
}));
710+
711+
actual = ErrorMatcher::explain_errors_from_circuit(
712+
Circuit(R"CIRCUIT(
713+
MXX 0 2 1 3
714+
MZZ 0 2 1 3
715+
PAULI_CHANNEL_2(0, 0, 0, 0, 0, 0.1, 0, 0, 0, 0, 0, 0, 0, 0, 0) 0 1
716+
MXX 0 2 1 3
717+
MZZ 0 2 1 3
718+
DETECTOR rec[-1] rec[-5]
719+
DETECTOR rec[-2] rec[-6]
720+
DETECTOR rec[-3] rec[-7]
721+
DETECTOR rec[-4] rec[-8]
722+
)CIRCUIT"),
723+
nullptr,
724+
false);
725+
ASSERT_EQ(actual.size(), 1);
726+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
727+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{
728+
GateTargetWithCoords{GateTarget::x(0)},
729+
GateTargetWithCoords{GateTarget::y(1)},
730+
}));
731+
732+
actual = ErrorMatcher::explain_errors_from_circuit(
733+
Circuit(R"CIRCUIT(
734+
MXX 0 2 1 3
735+
MZZ 0 2 1 3
736+
PAULI_CHANNEL_2(0, 0, 0, 0, 0, 0, 0.1, 0, 0, 0, 0, 0, 0, 0, 0) 0 1
737+
MXX 0 2 1 3
738+
MZZ 0 2 1 3
739+
DETECTOR rec[-1] rec[-5]
740+
DETECTOR rec[-2] rec[-6]
741+
DETECTOR rec[-3] rec[-7]
742+
DETECTOR rec[-4] rec[-8]
743+
)CIRCUIT"),
744+
nullptr,
745+
false);
746+
ASSERT_EQ(actual.size(), 1);
747+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
748+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{
749+
GateTargetWithCoords{GateTarget::x(0)},
750+
GateTargetWithCoords{GateTarget::z(1)},
751+
}));
752+
753+
actual = ErrorMatcher::explain_errors_from_circuit(
754+
Circuit(R"CIRCUIT(
755+
MXX 0 2 1 3
756+
MZZ 0 2 1 3
757+
PAULI_CHANNEL_2(0, 0, 0, 0, 0, 0, 0, 0.1, 0, 0, 0, 0, 0, 0, 0) 0 1
758+
MXX 0 2 1 3
759+
MZZ 0 2 1 3
760+
DETECTOR rec[-1] rec[-5]
761+
DETECTOR rec[-2] rec[-6]
762+
DETECTOR rec[-3] rec[-7]
763+
DETECTOR rec[-4] rec[-8]
764+
)CIRCUIT"),
765+
nullptr,
766+
false);
767+
ASSERT_EQ(actual.size(), 1);
768+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
769+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{
770+
GateTargetWithCoords{GateTarget::y(0)},
771+
}));
772+
773+
actual = ErrorMatcher::explain_errors_from_circuit(
774+
Circuit(R"CIRCUIT(
775+
MXX 0 2 1 3
776+
MZZ 0 2 1 3
777+
PAULI_CHANNEL_2(0, 0, 0, 0, 0, 0, 0, 0, 0.1, 0, 0, 0, 0, 0, 0) 0 1
778+
MXX 0 2 1 3
779+
MZZ 0 2 1 3
780+
DETECTOR rec[-1] rec[-5]
781+
DETECTOR rec[-2] rec[-6]
782+
DETECTOR rec[-3] rec[-7]
783+
DETECTOR rec[-4] rec[-8]
784+
)CIRCUIT"),
785+
nullptr,
786+
false);
787+
ASSERT_EQ(actual.size(), 1);
788+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
789+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{
790+
GateTargetWithCoords{GateTarget::y(0)},
791+
GateTargetWithCoords{GateTarget::x(1)},
792+
}));
793+
794+
actual = ErrorMatcher::explain_errors_from_circuit(
795+
Circuit(R"CIRCUIT(
796+
MXX 0 2 1 3
797+
MZZ 0 2 1 3
798+
PAULI_CHANNEL_2(0, 0, 0, 0, 0, 0, 0, 0, 0, 0.1, 0, 0, 0, 0, 0) 0 1
799+
MXX 0 2 1 3
800+
MZZ 0 2 1 3
801+
DETECTOR rec[-1] rec[-5]
802+
DETECTOR rec[-2] rec[-6]
803+
DETECTOR rec[-3] rec[-7]
804+
DETECTOR rec[-4] rec[-8]
805+
)CIRCUIT"),
806+
nullptr,
807+
false);
808+
ASSERT_EQ(actual.size(), 1);
809+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
810+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{
811+
GateTargetWithCoords{GateTarget::y(0)},
812+
GateTargetWithCoords{GateTarget::y(1)},
813+
}));
814+
815+
actual = ErrorMatcher::explain_errors_from_circuit(
816+
Circuit(R"CIRCUIT(
817+
MXX 0 2 1 3
818+
MZZ 0 2 1 3
819+
PAULI_CHANNEL_2(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.1, 0, 0, 0, 0) 0 1
820+
MXX 0 2 1 3
821+
MZZ 0 2 1 3
822+
DETECTOR rec[-1] rec[-5]
823+
DETECTOR rec[-2] rec[-6]
824+
DETECTOR rec[-3] rec[-7]
825+
DETECTOR rec[-4] rec[-8]
826+
)CIRCUIT"),
827+
nullptr,
828+
false);
829+
ASSERT_EQ(actual.size(), 1);
830+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
831+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{
832+
GateTargetWithCoords{GateTarget::y(0)},
833+
GateTargetWithCoords{GateTarget::z(1)},
834+
}));
835+
836+
actual = ErrorMatcher::explain_errors_from_circuit(
837+
Circuit(R"CIRCUIT(
838+
MXX 0 2 1 3
839+
MZZ 0 2 1 3
840+
PAULI_CHANNEL_2(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.1, 0, 0, 0) 0 1
841+
MXX 0 2 1 3
842+
MZZ 0 2 1 3
843+
DETECTOR rec[-1] rec[-5]
844+
DETECTOR rec[-2] rec[-6]
845+
DETECTOR rec[-3] rec[-7]
846+
DETECTOR rec[-4] rec[-8]
847+
)CIRCUIT"),
848+
nullptr,
849+
false);
850+
ASSERT_EQ(actual.size(), 1);
851+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
852+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{
853+
GateTargetWithCoords{GateTarget::z(0)},
854+
}));
855+
856+
actual = ErrorMatcher::explain_errors_from_circuit(
857+
Circuit(R"CIRCUIT(
858+
MXX 0 2 1 3
859+
MZZ 0 2 1 3
860+
PAULI_CHANNEL_2(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.1, 0, 0) 0 1
861+
MXX 0 2 1 3
862+
MZZ 0 2 1 3
863+
DETECTOR rec[-1] rec[-5]
864+
DETECTOR rec[-2] rec[-6]
865+
DETECTOR rec[-3] rec[-7]
866+
DETECTOR rec[-4] rec[-8]
867+
)CIRCUIT"),
868+
nullptr,
869+
false);
870+
ASSERT_EQ(actual.size(), 1);
871+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
872+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{
873+
GateTargetWithCoords{GateTarget::z(0)},
874+
GateTargetWithCoords{GateTarget::x(1)},
875+
}));
876+
877+
actual = ErrorMatcher::explain_errors_from_circuit(
878+
Circuit(R"CIRCUIT(
879+
MXX 0 2 1 3
880+
MZZ 0 2 1 3
881+
PAULI_CHANNEL_2(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.1, 0) 0 1
882+
MXX 0 2 1 3
883+
MZZ 0 2 1 3
884+
DETECTOR rec[-1] rec[-5]
885+
DETECTOR rec[-2] rec[-6]
886+
DETECTOR rec[-3] rec[-7]
887+
DETECTOR rec[-4] rec[-8]
888+
)CIRCUIT"),
889+
nullptr,
890+
false);
891+
ASSERT_EQ(actual.size(), 1);
892+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
893+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{
894+
GateTargetWithCoords{GateTarget::z(0)},
895+
GateTargetWithCoords{GateTarget::y(1)},
896+
}));
897+
898+
actual = ErrorMatcher::explain_errors_from_circuit(
899+
Circuit(R"CIRCUIT(
900+
MXX 0 2 1 3
901+
MZZ 0 2 1 3
902+
PAULI_CHANNEL_2(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.1) 0 1
903+
MXX 0 2 1 3
904+
MZZ 0 2 1 3
905+
DETECTOR rec[-1] rec[-5]
906+
DETECTOR rec[-2] rec[-6]
907+
DETECTOR rec[-3] rec[-7]
908+
DETECTOR rec[-4] rec[-8]
909+
)CIRCUIT"),
910+
nullptr,
911+
false);
912+
ASSERT_EQ(actual.size(), 1);
913+
ASSERT_EQ(actual[0].circuit_error_locations.size(), 1);
914+
ASSERT_EQ(actual[0].circuit_error_locations[0].flipped_pauli_product, (std::vector<GateTargetWithCoords>{
915+
GateTargetWithCoords{GateTarget::z(0)},
916+
GateTargetWithCoords{GateTarget::z(1)},
917+
}));
918+
}

0 commit comments

Comments
 (0)