@@ -72,7 +72,7 @@ std::string Node::str() {
7272 std::stringstream ss;
7373 auto & self = *this ;
7474 ss << " Node(" ;
75- ss << " errors =" << self.errors << " , " ;
75+ ss << " error_chain_idx =" << self.error_chain_idx << " , " ;
7676 ss << " cost=" << self.cost << " , " ;
7777 ss << " num_dets=" << self.num_dets << " , " ;
7878 return ss.str ();
@@ -243,16 +243,13 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections)
243243}
244244
245245void TesseractDecoder::flip_detectors_and_block_errors (
246- size_t detector_order, const std::vector< size_t >& errors , boost::dynamic_bitset<>& detectors,
246+ size_t detector_order, int64_t error_chain_idx , boost::dynamic_bitset<>& detectors,
247247 std::vector<DetectorCostTuple>& detector_cost_tuples) const {
248- for (size_t ei : errors) {
249- size_t min_detector = std::numeric_limits<size_t >::max ();
250- for (size_t d = 0 ; d < num_detectors; ++d) {
251- if (detectors[config.det_orders [detector_order][d]]) {
252- min_detector = config.det_orders [detector_order][d];
253- break ;
254- }
255- }
248+ int64_t walker_idx = error_chain_idx;
249+ while (walker_idx != -1 ) {
250+ const auto & node = error_chain_arena[walker_idx];
251+ size_t ei = node.error_index ;
252+ size_t min_detector = node.min_detector ;
256253
257254 for (int oei : d2e[min_detector]) {
258255 detector_cost_tuples[oei].error_blocked = 1 ;
@@ -262,13 +259,18 @@ void TesseractDecoder::flip_detectors_and_block_errors(
262259 for (int d : edets[ei]) {
263260 detectors[d] = !detectors[d];
264261 }
262+ walker_idx = node.parent_idx ;
265263 }
266264}
267265
268266void TesseractDecoder::decode_to_errors (const std::vector<uint64_t >& detections,
269267 size_t detector_order, size_t detector_beam) {
270268 predicted_errors_buffer.clear ();
271269 low_confidence_flag = false ;
270+ error_chain_arena.clear ();
271+ // Can technically be larger than pqlimit, but we need an initial guess on how many nodes we
272+ // will process from the queue.
273+ error_chain_arena.reserve (config.pqlimit );
272274
273275 std::priority_queue<Node, std::vector<Node>, std::greater<Node>> pq;
274276 std::unordered_map<size_t , std::unordered_set<boost::dynamic_bitset<>>> visited_detectors;
@@ -296,11 +298,10 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections,
296298 size_t min_num_dets = detections.size ();
297299 size_t max_num_dets = min_num_dets + detector_beam;
298300
299- std::vector<size_t > next_errors;
300301 boost::dynamic_bitset<> next_detectors;
301302 std::vector<DetectorCostTuple> next_detector_cost_tuples;
302303
303- pq.push ({initial_cost, min_num_dets, std::vector< size_t >() });
304+ pq.push ({initial_cost, min_num_dets, 0 , - 1 });
304305 size_t num_pq_pushed = 1 ;
305306
306307 while (!pq.empty ()) {
@@ -311,17 +312,20 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections,
311312
312313 boost::dynamic_bitset<> detectors = initial_detectors;
313314 std::vector<DetectorCostTuple> detector_cost_tuples (num_errors);
314- flip_detectors_and_block_errors (detector_order, node.errors , detectors, detector_cost_tuples);
315+ flip_detectors_and_block_errors (detector_order, node.error_chain_idx , detectors,
316+ detector_cost_tuples);
315317
316318 if (node.num_dets == 0 ) {
317319 if (config.create_visualization ) {
318- visualizer.add_activated_errors (node.errors );
320+ visualizer.add_activated_errors (node.error_chain_idx , error_chain_arena );
319321 visualizer.add_activated_detectors (detectors, num_detectors);
320322 }
321323 if (config.verbose ) {
322324 std::cout << " activated_errors = " ;
323- for (size_t oei : node.errors ) {
324- std::cout << oei << " , " ;
325+ int64_t walker_idx = node.error_chain_idx ;
326+ while (walker_idx != -1 ) {
327+ std::cout << error_chain_arena[walker_idx].error_index << " , " ;
328+ walker_idx = error_chain_arena[walker_idx].parent_idx ;
325329 }
326330 std::cout << std::endl;
327331 std::cout << " activated_detectors = " ;
@@ -335,15 +339,20 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections,
335339 std::cout << " Decoding complete. Cost: " << node.cost
336340 << " num_pq_pushed = " << num_pq_pushed << std::endl;
337341 }
338- predicted_errors_buffer = node.errors ;
342+ predicted_errors_buffer.resize (node.depth );
343+ int64_t walker_idx = node.error_chain_idx ;
344+ for (size_t i = 0 ; i < node.depth ; ++i) {
345+ predicted_errors_buffer[node.depth - 1 - i] = error_chain_arena[walker_idx].error_index ;
346+ walker_idx = error_chain_arena[walker_idx].parent_idx ;
347+ }
339348 return ;
340349 }
341350
342351 if (config.no_revisit_dets && !visited_detectors[node.num_dets ].insert (detectors).second )
343352 continue ;
344353
345354 if (config.create_visualization ) {
346- visualizer.add_activated_errors (node.errors );
355+ visualizer.add_activated_errors (node.error_chain_idx , error_chain_arena );
347356 visualizer.add_activated_detectors (detectors, num_detectors);
348357 }
349358 if (config.verbose ) {
@@ -352,8 +361,10 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections,
352361 std::cout << " num_dets = " << node.num_dets << " max_num_dets = " << max_num_dets
353362 << " cost = " << node.cost << std::endl;
354363 std::cout << " activated_errors = " ;
355- for (size_t oei : node.errors ) {
356- std::cout << oei << " , " ;
364+ int64_t walker_idx = node.error_chain_idx ;
365+ while (walker_idx != -1 ) {
366+ std::cout << error_chain_arena[walker_idx].error_index << " , " ;
367+ walker_idx = error_chain_arena[walker_idx].parent_idx ;
357368 }
358369 std::cout << std::endl;
359370 std::cout << " activated_detectors = " ;
@@ -408,8 +419,13 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections,
408419 }
409420 prev_ei = ei;
410421
411- next_errors = node.errors ;
412- next_errors.push_back (ei);
422+ // Create the error chain node for this candidate.
423+ error_chain_arena.emplace_back ();
424+ auto & next_node = error_chain_arena.back ();
425+ next_node.error_index = ei;
426+ next_node.min_detector = min_detector;
427+ next_node.parent_idx = node.error_chain_idx ;
428+
413429 next_detectors = detectors;
414430 next_detector_cost_tuples[ei].error_blocked = 1 ;
415431
@@ -453,7 +469,7 @@ void TesseractDecoder::decode_to_errors(const std::vector<uint64_t>& detections,
453469
454470 if (next_cost == INF) continue ;
455471
456- pq.push ({next_cost, next_num_dets, next_errors });
472+ pq.push ({next_cost, next_num_dets, node. depth + 1 , ( int64_t )(error_chain_arena. size () - 1 ) });
457473 ++num_pq_pushed;
458474
459475 if (num_pq_pushed > config.pqlimit ) {
0 commit comments