diff --git a/src/simplex.cc b/src/simplex.cc index fc47b867..9b0b2411 100644 --- a/src/simplex.cc +++ b/src/simplex.cc @@ -56,7 +56,8 @@ SimplexDecoder::SimplexDecoder(SimplexConfig _config) : config(_config) { std::vector detector_t_coords(config.dem.count_detectors(), 0); std::vector> detector_coords = get_detector_coords(config.dem); - for (size_t d = 0; d < detector_coords.size(); ++d) { + size_t num_dets = std::min(detector_coords.size(), detector_t_coords.size()); + for (size_t d = 0; d < num_dets; ++d) { if (detector_coords[d].size() > T_COORD) { detector_t_coords[d] = detector_coords[d][T_COORD]; } diff --git a/src/tesseract.test.cc b/src/tesseract.test.cc index fd0d471e..a9278aa8 100644 --- a/src/tesseract.test.cc +++ b/src/tesseract.test.cc @@ -559,3 +559,19 @@ TEST(tesseract, MoreThan64Observables) { ASSERT_EQ(flipped[i], i); } } + +TEST(utils, DuplicateDetectorCoords) { + std::string dem_str = "detector(0, 0, 1) D0\ndetector(0, 0, 2) D0\nerror(0.1) D0\n"; + stim::DetectorErrorModel dem(dem_str.c_str()); + auto coords = get_detector_coords(dem); + ASSERT_EQ(coords.size(), 1); + ASSERT_EQ(coords[0].size(), 3); + ASSERT_EQ(coords[0][2], 2.0); +} + +TEST(simplex, DuplicateDetectorCoords) { + std::string dem_str = "detector(0, 0, 1) D0\ndetector(0, 0, 2) D0\nerror(0.1) D0\n"; + stim::DetectorErrorModel dem(dem_str.c_str()); + SimplexConfig config{dem}; + EXPECT_NO_THROW({ SimplexDecoder decoder(config); }); +} diff --git a/src/utils.cc b/src/utils.cc index 56115d4b..32531c0d 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -28,7 +28,9 @@ #include "stim.h" std::vector> get_detector_coords(const stim::DetectorErrorModel& dem) { - std::vector> detector_coords; + size_t num_detectors = dem.count_detectors(); + std::vector> detector_coords(num_detectors); + bool has_any_coords = false; for (const stim::DemInstruction& instruction : dem.flattened().instructions) { switch (instruction.type) { case stim::DemInstructionType::DEM_SHIFT_DETECTORS: @@ -38,11 +40,16 @@ std::vector> get_detector_coords(const stim::DetectorErrorMo break; } case stim::DemInstructionType::DEM_DETECTOR: { - std::vector coord; - for (const double& t : instruction.arg_data) { - coord.push_back(t); + has_any_coords = true; + std::vector coord(instruction.arg_data.begin(), instruction.arg_data.end()); + for (const stim::DemTarget& target : instruction.target_data) { + if (target.is_relative_detector_id()) { + size_t det_id = target.val(); + if (det_id < num_detectors) { + detector_coords[det_id] = coord; + } + } } - detector_coords.push_back(coord); break; } case stim::DemInstructionType::DEM_LOGICAL_OBSERVABLE: @@ -52,6 +59,9 @@ std::vector> get_detector_coords(const stim::DetectorErrorMo "Unexpected DemInstructionType found in the detector error model."); } } + if (!has_any_coords) { + return {}; + } return detector_coords; } @@ -148,10 +158,13 @@ static std::vector> build_det_orders_coordinate( for (size_t i = 0; i < detector_coords.at(0).size(); ++i) { orientation_vector.push_back(dist(rng)); } - for (size_t i = 0; i < detector_coords.size(); ++i) { + size_t num_dets = std::min(detector_coords.size(), inner_products.size()); + for (size_t i = 0; i < num_dets; ++i) { inner_products[i] = 0; for (size_t j = 0; j < orientation_vector.size(); ++j) { - inner_products[i] += detector_coords[i][j] * orientation_vector[j]; + if (j < detector_coords[i].size()) { + inner_products[i] += detector_coords[i][j] * orientation_vector[j]; + } } } std::vector perm(dem.count_detectors());