@@ -323,7 +323,6 @@ function information_sets(G::CTMatrixTypes, alg::Symbol = :Edmonds; permute::Boo
323323 if permute
324324 # permute identities to the front
325325 pivots = collect (start_ind: (i + 1 ) * nr)
326- @assert det (Gi[:, pivots]) != 0
327326 σ = [pivots; setdiff (1 : nc, pivots)]
328327 Gi = Gi[:, σ]
329328 Pi = Pi[:, σ]
@@ -424,8 +423,12 @@ Return the minimum distance of `C` using a deterministic algorithm based on enum
424423constant weight codewords of the binary reflected Gray code. If a word of minimum weight
425424is found before the lower and upper bounds cross, it is returned; otherwise, the zero vector
426425is returned.
426+
427+ show_progress will display a progress meter for each iteration of a weight that takes longer than
428+ a second
427429"""
428- function minimum_distance_Gray (C:: AbstractLinearCode ; alg:: Symbol = :auto , v:: Bool = false , show_progress= true )
430+ function minimum_distance_Gray (C:: AbstractLinearCode ; alg:: Symbol = :auto , v:: Bool = false ,
431+ show_progress = true )
429432
430433 ord_F = Int (order (C. F))
431434 ord_F == 2 || throw (ArgumentError (" Currently only implemented for binary codes." ))
@@ -451,9 +454,9 @@ function minimum_distance_Gray(C::AbstractLinearCode; alg::Symbol = :auto, v::Bo
451454 alg = :Zimmermann
452455 end
453456 end
454- alg == :auto || throw (ErrorException (" Could not determine minimum distance algo automatically" ))
457+ alg == :auto && throw (ErrorException (" Could not determine minimum distance algo automatically" ))
455458
456- if alg in (:Brouwer , :Zimmermann ) ||
459+ if alg in (:Brouwer , :Zimmermann )
457460 return _minimum_distance_BZ (C:: AbstractLinearCode ; info_set_alg = alg, verbose = v, show_progress = show_progress)
458461 end
459462 println (" Warning: old enumeration algorithm selected. Performance will be slow" ) # TODO remove when all code updated
462465
463466function _minimum_distance_BZ (C:: AbstractLinearCode ; info_set_alg:: Symbol = :Zimmermann ,
464467 verbose:: Bool = false , dbg = Dict (), show_progress= false )
468+ dbg_key_exit_r = " exit_r"
465469
466470 ord_F = Int (order (C. F))
467471 ord_F == 2 || throw (ArgumentError (" Currently only implemented for binary codes." ))
@@ -488,16 +492,10 @@ function _minimum_distance_BZ(C::AbstractLinearCode; info_set_alg::Symbol = :Zim
488492 if length (keys (dbg)) > 0
489493 println (" Debug mode ON" )
490494 end
491- dbg_key_found = " found_codewords"
492- dbg_key_exit_r = " exit_r"
493495
494496 if haskey (dbg, dbg_key_exit_r)
495- verbose && println (" dbg Dict: Storing the largest message weight reached @key=$dbg_key_found " )
496- dbg[" exit_r" ] = - 1
497- end
498- store_found_codewords = haskey (dbg, dbg_key_found)
499- if store_found_codewords
500- verbose && println (" dbg Dict: Storing the codewords in the debug dictionary @key=$dbg_key_found " )
497+ verbose && println (" dbg Dict: largest message weight searched stored @key=$dbg_key_exit_r " )
498+ dbg[dbg_key_exit_r] = - 1
501499 end
502500
503501 k, n = size (C. G)
@@ -539,12 +537,6 @@ function _minimum_distance_BZ(C::AbstractLinearCode; info_set_alg::Symbol = :Zim
539537 # following loop is the r=1 case of the enumeration. We do this case here because we want to make a good guess at the terminating r before we start multiple threads
540538 for (j, g) in enumerate (A_mats) # loop over the A_mats rather than the original G because it would add another case to deal with later
541539 # can make this faster with dots and views
542- if store_found_codewords
543- for a in 1 : size (g, 2 )
544- output_vec = Int .(perms_mats[j] * g[:, a])
545- push! (dbg[" found_codewords" ], (1 , [], output_vec))
546- end
547- end
548540 w, i = _min_wt_col (g)
549541 if w <= C. u_bound
550542 found = g[:, i]
@@ -554,7 +546,6 @@ function _minimum_distance_BZ(C::AbstractLinearCode; info_set_alg::Symbol = :Zim
554546 end
555547
556548 verbose && println (" Current upper bound: $(C. u_bound) " )
557- verbose && ! iszero (found) && println (" Found element matching upper bound." )
558549 found = A_mats[1 ][:, 1 ]
559550
560551 l = 0
@@ -595,30 +586,27 @@ function _minimum_distance_BZ(C::AbstractLinearCode; info_set_alg::Symbol = :Zim
595586 verbose && println (" Number of threads " , num_thrds)
596587 for r in 2 : k
597588 if r > 2 ^ 16
598- verbose && println (" Reached an r larger than 2^16" )
589+ verbose && println (" Warning: Reached an r larger than 2^16" )
599590 end
600591 C. l_bound < lower_bounds[r] && (C. l_bound = lower_bounds[r];)
601592 # an even code can't have have an odd minimum weight
602593 # (!triply_even_flag && !doubly_even_flag && even_flag) && (C.l_bound += C.l_bound % 2;)
603594 # (!triply_even_flag && doubly_even_flag) && (C.l_bound += 4 - C.l_bound % 4;)
604595 # triply_even_flag && (C.l_bound += 8 - C.l_bound % 8;)
605596 if C. l_bound >= C. u_bound
606- C. d = C. u_bound
607- y = matrix (C. F, 1 , n, perms_mats[initial_perm_ind] * found)
608- dbg[dbg_key_exit_r] = r
609- show_progress && ProgressMeter. finish! (prog_bar)
610- return C. u_bound, y
597+ dbg[dbg_key_exit_r] = r- 1
598+ break
611599 end
612600 verbose && println (" r: $r " )
613601 verbose && println (" Lower bound: $(C. l_bound) " )
614602 verbose && println (" Upper bound: $(C. u_bound) " )
615603
616604 if verbose
617- count = 0
605+ i_count = 0
618606 for i in 1 : h
619- r - rank_defs[i] ≤ 0 && (count += 1 ;)
607+ r - rank_defs[i] ≤ 0 && (i_count += 1 ;)
620608 end
621- count > 0 && println (" $count of the original $h information sets no longer contribute to the lower bound" )
609+ i_count > 0 && println (" $i_count of the original $h information sets no longer contribute to the lower bound" )
622610 end
623611 p = Int (characteristic (C. F))
624612
@@ -645,7 +633,7 @@ function _minimum_distance_BZ(C::AbstractLinearCode; info_set_alg::Symbol = :Zim
645633 CodingTheory. _subset_unrank_to_vec! (init_rank, UInt64 (r), first_vec)
646634 end
647635
648- # as in White Algo 7.1 we loop over matrices first so that we can update the lower bound more often
636+ # as in White Algo 7.1 we loop over matrices first
649637 for i in 1 : h
650638 if keep_going[] == false
651639 verbose && println (thrd_stop_msg)
@@ -655,6 +643,8 @@ function _minimum_distance_BZ(C::AbstractLinearCode; info_set_alg::Symbol = :Zim
655643 c_itr = zeros (UInt16, C. n - C. k)
656644 is_first = true
657645 curr_mat = A_mats_trunc[i]
646+ count = UInt128 (0 )
647+
658648 for u in SubsetGrayCode (k, r, len, init_rank)
659649 if keep_going[] == false
660650 println (thrd_stop_msg)
@@ -678,18 +668,11 @@ function _minimum_distance_BZ(C::AbstractLinearCode; info_set_alg::Symbol = :Zim
678668 end
679669 end
680670
681- if store_found_codewords
682- subset_vec_full = zeros (Int, k)
683- CodingTheory. _subset_unrank_to_vec! (UInt128 (init_rank + count), UInt64 (r), subset_vec_full)
684- output_vec = Int .(perms_mats[exit_thread_indicator_vec[ind]] * vcat (subset_vec_full, c_itr))
685- push! (dbg[" found_codewords" ], (r, [], Int .(output_vec)))
686- end
687-
688671 partial_weight = r + sum (view (c_itr, 1 : weight_sum_bound))
689672
690673 if uppers[ind] > partial_weight
691674 w = r + sum (c_itr)
692- verbose && @assert w = = 0
675+ verbose && @assert w ! = 0
693676 if uppers[ind] > w
694677 subset_vec_full = zeros (Int, k)
695678 CodingTheory. _subset_unrank_to_vec! (UInt128 (init_rank + count), UInt64 (r), subset_vec_full)
@@ -699,7 +682,7 @@ function _minimum_distance_BZ(C::AbstractLinearCode; info_set_alg::Symbol = :Zim
699682 verbose && @assert size (founds[ind], 1 ) == C. n " found vector has length $(size (founds[ind], 1 )) but should be n=$(C. n) "
700683 exit_thread_indicator_vec[ind] = i
701684
702- verbose && println (" Adjusting (local) upper bound: $w for c_itr=$(c_itr) " )
685+ println (" Adjusting (local) upper bound: $w for c_itr=$(Int .( c_itr) ) " )
703686 if C. l_bound == uppers[ind]
704687 println (" early exit" )
705688 Threads. atomic_cas! (keep_going, true , false )
@@ -719,12 +702,15 @@ function _minimum_distance_BZ(C::AbstractLinearCode; info_set_alg::Symbol = :Zim
719702 initial_perm_ind = exit_thread_indicator_vec[loc]
720703 end
721704 end
722- show_progress && ProgressMeter. finish! (prog_bar)
723705
724- # at this point we are guaranteed to have found the code's distance
725706 C. d = C. u_bound
726- y = matrix (C. F, 1 , n, perms_mats[initial_perm_ind] * found) # weight(y) >= C.d with equality not being the typical case
707+ y = matrix (C. F, 1 , n, perms_mats[initial_perm_ind] * found) # weight(y) >= C.d, with equality not being the typical case
727708 verbose && @assert iszero (C. H * transpose (y))
709+ if dbg[dbg_key_exit_r] == - 1
710+ dbg[dbg_key_exit_r] = r
711+ end
712+ show_progress && ProgressMeter. finish! (prog_bar)
713+ verbose && println (" Computation complete" )
728714 return C. u_bound, y
729715end
730716
@@ -827,7 +813,6 @@ function _minimum_distance_enumeration_with_matrix_multiply(C::AbstractLinearCod
827813 if C. l_bound >= C. u_bound
828814 C. d = C. u_bound
829815 y = perms_mats[initial_perm_ind] * found
830- # @assert in(y, C)
831816 return C. u_bound, (C. F). (y)
832817 end
833818
0 commit comments