Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/stim/dem/detector_error_model.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@

#include "stim/dem/detector_error_model.h"

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <limits>
#include <numeric>

#include "stim/util_bot/str_util.h"

Expand Down Expand Up @@ -793,3 +795,30 @@ DetectorErrorModel DetectorErrorModel::without_tags() const {
}
return result;
}

bool DetectorErrorModel::equal_up_to_instruction_ordering(const DetectorErrorModel &other) const {
if (instructions.size() != other.instructions.size()) {
return false;
}

auto get_sorted_indices = [](const std::vector<DemInstruction> &ins) {
std::vector<size_t> indices(ins.size());
std::iota(indices.begin(), indices.end(), 0);
std::sort(indices.begin(), indices.end(), [&ins](size_t i, size_t j) {
return ins[i] < ins[j];
});
return indices;
};

// sort the indices to avoid copying instructions
auto sorted_lhs_indices = get_sorted_indices(instructions);
auto sorted_rhs_indices = get_sorted_indices(other.instructions);

for (size_t i = 0; i < sorted_lhs_indices.size(); i++) {
if (!(instructions[sorted_lhs_indices[i]] == other.instructions[sorted_rhs_indices[i]])) {
return false;
}
}

return true;
}
7 changes: 7 additions & 0 deletions src/stim/dem/detector_error_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ struct DetectorErrorModel {

/// Returns an equivalent detector error model with no repeat blocks or detector_shift instructions.
DetectorErrorModel flattened() const;

/// Returns true if the detector error model is equal to the other detector error model up to instruction ordering.
///
/// For example, error(0.01) D0 error(0.002) D1 L0 is considered the same as error(0.002) D1 L0 error(0.01) D0.
///
/// Note: requires O(n log n) time due to sorting. Prefer `==` when you know the instructions are in the same order.
bool equal_up_to_instruction_ordering(const DetectorErrorModel &other) const;
};

void print_detector_error_model(std::ostream &out, const DetectorErrorModel &v, size_t indent);
Expand Down
18 changes: 18 additions & 0 deletions src/stim/dem/detector_error_model.test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -894,3 +894,21 @@ TEST(detector_error_model, parse_windows_newlines) {
DetectorErrorModel("error(0.125) D0\r\ndetector(5) D10\r\n"),
DetectorErrorModel("error(0.125) D0\r\ndetector(5) D10\r\n"));
}

TEST(detector_error_model, equal_up_to_instruction_ordering) {
DetectorErrorModel lhs(R"MODEL(
error(0.01) D0
error(0.002) D1 L0
detector(5, 10) D0
detector(5, 15) D1
logical_observable L0
)MODEL");
DetectorErrorModel rhs(R"MODEL(
error(0.002) D1 L0
error(0.01) D0
detector(5, 15) D1
detector(5, 10) D0
logical_observable L0
)MODEL");
EXPECT_TRUE(lhs.equal_up_to_instruction_ordering(rhs));
}
Loading