@@ -120,6 +120,8 @@ class UserGraph {
120120 Mwpm& get_mwpm ();
121121 Mwpm& get_mwpm_with_search_graph ();
122122 void handle_dem_instruction (double p, const std::vector<size_t >& detectors, const std::vector<size_t >& observables);
123+ void handle_dem_instruction_include_correlations (
124+ double p, const std::vector<size_t >& detectors, const std::vector<size_t >& observables);
123125 void get_nodes_on_shortest_path_from_source (size_t src, size_t dst, std::vector<size_t >& out_nodes);
124126 void populate_implied_edge_weights (
125127 std::map<std::pair<size_t , size_t >, std::map<std::pair<size_t , size_t >, double >>& joint_probabilites);
@@ -131,6 +133,8 @@ class UserGraph {
131133 bool _all_edges_have_error_probabilities;
132134};
133135
136+ double to_weight_for_correlations (double probability);
137+
134138template <typename EdgeCallable, typename BoundaryEdgeCallable>
135139inline double UserGraph::iter_discretized_edges (
136140 pm::weight_int num_distinct_weights,
@@ -263,7 +267,8 @@ template <typename Handler>
263267void iter_dem_instructions_include_correlations (
264268 const stim::DetectorErrorModel& detector_error_model,
265269 const Handler& handle_dem_error,
266- std::map<std::pair<size_t , size_t >, std::map<std::pair<size_t , size_t >, double >>& joint_probabilites) {
270+ std::map<std::pair<size_t , size_t >, std::map<std::pair<size_t , size_t >, double >>& joint_probabilites,
271+ bool include_decomposed_error_components_in_edge_weights = true ) {
267272 detector_error_model.iter_flatten_error_instructions ([&](const stim::DemInstruction& instruction) {
268273 double p = instruction.arg_data [0 ];
269274 pm::DecomposedDemError decomposed_err;
@@ -311,35 +316,23 @@ void iter_dem_instructions_include_correlations(
311316 component->observable_indices .push_back (target.val ());
312317 } else if (target.is_separator ()) {
313318 instruction_contains_separator = true ;
314- // If the previous error in the decomposition had 3 or more detectors, we throw an exception.
315- if (num_component_detectors > 2 ) {
316- throw std::invalid_argument (
317- " Encountered a decomposed error instruction with a hyperedge component (3 or more detectors). "
318- " This is not supported." );
319- } else if (num_component_detectors == 0 ) {
319+ // We cannot have num_component_detectors > 2 at this point, or we would have already thrown an
320+ // exception
321+ if (num_component_detectors == 0 ) {
320322 throw std::invalid_argument (
321323 " Encountered a decomposed error instruction with an undetectable component (0 detectors). "
322324 " This is not supported." );
323- } else if (num_component_detectors > 0 ) {
324- // If the previous error in the decomposition had 1 or 2 detectors, we handle it
325- handle_dem_error (p, {component->node1 , component->node2 }, component->observable_indices );
326- decomposed_err.components .push_back ({});
327- component = &decomposed_err.components .back ();
328- component->node1 = SIZE_MAX;
329- component->node2 = SIZE_MAX;
330- num_component_detectors = 0 ;
331325 }
326+ // The previous error in the decomposition must have 1 or 2 detectors
327+ decomposed_err.components .push_back ({});
328+ component = &decomposed_err.components .back ();
329+ component->node1 = SIZE_MAX;
330+ component->node2 = SIZE_MAX;
331+ num_component_detectors = 0 ;
332332 }
333333 }
334334
335- if (num_component_detectors > 2 ) {
336- // Undecomposed hyperedges are not supported
337- throw std::invalid_argument (
338- " Encountered an undecomposed error instruction with 3 or mode detectors. "
339- " This is not supported when using `enable_correlations=True`. "
340- " Did you forget to set `decompose_errors=True` when "
341- " converting the stim circuit to a detector error model?" );
342- } else if (num_component_detectors == 0 ) {
335+ if (num_component_detectors == 0 ) {
343336 if (instruction_contains_separator) {
344337 throw std::invalid_argument (
345338 " Encountered a decomposed error instruction with an undetectable component (0 detectors). "
@@ -348,12 +341,17 @@ void iter_dem_instructions_include_correlations(
348341 // Ignore errors that are undetectable, provided they are not a component of a decomposed error
349342 return ;
350343 }
344+ }
351345
352- } else if (num_component_detectors > 0 ) {
353- if (component->node2 == SIZE_MAX) {
354- handle_dem_error (p, {component->node1 }, component->observable_indices );
355- } else {
356- handle_dem_error (p, {component->node1 , component->node2 }, component->observable_indices );
346+ // If include_decomposed_error_components_in_edge_weights is False, then only add the edge into
347+ // the graph if it is not a component in a decomposed error with more than one component
348+ if (include_decomposed_error_components_in_edge_weights || decomposed_err.components .size () == 1 ) {
349+ for (pm::UserEdge& component : decomposed_err.components ) {
350+ if (component.node2 == SIZE_MAX) {
351+ handle_dem_error (p, {component.node1 }, component.observable_indices );
352+ } else {
353+ handle_dem_error (p, {component.node1 , component.node2 }, component.observable_indices );
354+ }
357355 }
358356 }
359357
0 commit comments