@@ -641,7 +641,7 @@ function random_information_set_minimum_distance_bound!(S::T, which::Symbol = :f
641641 dressed:: Bool = true , max_iters:: Int = 10000 , verbose:: Bool = false ) where T <: AbstractSubsystemCode
642642
643643 which ∈ (:full , :X , :Z ) || throw (DomainError (which, " Must choose `:full`, `:X` or `:Z`." ))
644- # order(field(S)) == 2 || throw(DomainError(S, "Currently only implemented for binary codes."))
644+ order (field (S)) == 2 || throw (DomainError (S, " Currently only implemented for binary codes." ))
645645 is_positive (max_iters) || throw (DomainError (max_iters, " The number of iterations must be a positive integer." ))
646646
647647 return random_information_set_minimum_distance_bound! (GaugeTrait (T), CSSTrait (T),
@@ -658,28 +658,37 @@ function random_information_set_minimum_distance_bound!(::HasGauges, ::IsCSS, ::
658658
659659 n = S. n
660660 if which == :full
661- upperx, foundx = random_information_set_minimum_distance_bound! (HasGauges (), IsCSS (), HasLogicals (), S, :X , dressed, max_iters, verbose)
662- upperz, foundz = random_information_set_minimum_distance_bound! (HasGauges (), IsCSS (), HasLogicals (), S, :Z , dressed, max_iters, verbose)
663- if upperx <= upperz
664- if dressed
665- S. u_bound_dressed = min (upperx, S. u_bound_dressed)
666- else
667- S. u_bound_bare = min (upperx, S. u_bound_bare)
668- end
669- return upperx, foundx
661+ ! ismissing (S. d_dressed) && (println (" Dressed distance already known" ); return S. d_dressed;)
662+ verbose && println (" Bounding the full dressed distance" )
663+ stabs = _Flint_matrix_to_Julia_T_matrix (stabilizers (S), UInt8)
664+ if dressed
665+ gauges = _Flint_matrix_to_Julia_T_matrix (gauges_matrix (S), UInt8)
666+ stabs = vcat (stabs, gauges)
667+ end
668+ _rref_no_col_swap_binary! (stabs)
669+ stabs = _remove_empty (stabs, :rows )
670+ logs = _Flint_matrix_to_Julia_T_matrix (logicals_matrix (S), UInt8)
671+ operators_to_reduce = vcat (stabs, logs)
672+ check_against = permutedims (logs[:, [n + 1 : 2 n; 1 : n]])
673+ curr_l_bound = if dressed
674+ S. l_bound_dressed
670675 else
671- if dressed
672- S. u_bound_dressed = min (upperz, S. u_bound_dressed)
673- else
674- S. u_bound_bare = min (upperz, S. u_bound_bare)
675- end
676- return upperz, foundz
676+ S. l_bound_bare
677677 end
678+ verbose && println (" Starting lower bound: $curr_l_bound " )
679+
680+ # this is done in the constructor but the logical is not stored at the time
681+ # so must redo here
682+ mat = _rref_no_col_swap_binary (operators_to_reduce)
683+ anti = mat * check_against
684+ curr_u_bound, index = findmin (row_wts_symplectic (mat[findall (! iszero (anti[i, :]) for i in axes (anti, 1 )), :]))
685+ found = operators_to_reduce[index, :]
686+ verbose && println (" Starting upper bound: $curr_u_bound " )
678687 else
679688 stabs = _Flint_matrix_to_Julia_T_matrix (stabilizers (S)[:, (which == :X ? (1 : n) : (n + 1 : 2 n))], UInt8)
680689 if dressed
681690 gauges = _Flint_matrix_to_Julia_T_matrix (gauge_operators_matrix (S)[:, (which == :X ? (1 : n) : (n + 1 : 2 n))], UInt8)
682- stabs = [ stabs; gauges]
691+ stabs = vcat ( stabs, gauges)
683692 end
684693 _rref_no_col_swap_binary! (stabs)
685694 stabs = _remove_empty (stabs, :rows )
@@ -702,49 +711,56 @@ function random_information_set_minimum_distance_bound!(::HasGauges, ::IsCSS, ::
702711 uppers, founds = _RIS_bound_loop! (operators_to_reduce, check_against, curr_l_bound,
703712 curr_u_bound, found, max_iters, n, verbose)
704713 loc = argmin (uppers)
714+ verbose && println (" Ending $max_iters iterations with an upper bound of $(uppers[loc]) " )
705715 if dressed
706716 if which == :full
707717 S. u_bound_dressed = uppers[loc]
718+ flint_mat_found = matrix (field (S), permutedims (founds[loc]))
708719 elseif which == :X
709720 S. u_bound_dx_dressed = uppers[loc]
721+ flint_mat_found = matrix (field (S), [permutedims (founds[loc]) zeros (Int, 1 , n)])
710722 else
711723 S. u_bound_dz_dressed = uppers[loc]
724+ flint_mat_found = matrix (field (S), [zeros (Int, 1 , n) permutedims (founds[loc])])
712725 end
713726 else
714727 if which == :full
715728 S. u_bound_bare = uppers[loc]
729+ flint_mat_found = matrix (field (S), permutedims (founds[loc]))
716730 elseif which == :X
717731 S. u_bound_dx_bare = uppers[loc]
732+ flint_mat_found = matrix (field (S), [permutedims (founds[loc]) zeros (Int, 1 , n)])
718733 else
719734 S. u_bound_dz_bare = uppers[loc]
735+ flint_mat_found = matrix (field (S), [zeros (Int, 1 , n) permutedims (founds[loc])])
720736 end
721737 end
722- verbose && println (" Ending $max_iters iterations with an upper bound of $(uppers[loc]) " )
723- flint_mat_found = if which == :full
724- matrix (field (S), permutedims (founds[loc]))
725- elseif which == :X
726- matrix (field (S), [permutedims (founds[loc]) zeros (Int, 1 , n)])
727- else
728- matrix (field (S), [zeros (Int, 1 , n) permutedims (founds[loc])])
729- end
738+
730739 return uppers[loc], flint_mat_found
731740end
732741
742+ # TODO
743+ # 2. check changes to other cases
744+
733745function random_information_set_minimum_distance_bound! (:: HasNoGauges , :: IsCSS , :: HasLogicals ,
734746 S:: AbstractSubsystemCode , which:: Symbol , dressed:: Bool , max_iters:: Int , verbose:: Bool )
735747 # CSS stabilizer code
736748
737749 n = S. n
738750 if which == :full
739- upperx, foundx = random_information_set_minimum_distance_bound! (HasNoGauges (), IsCSS (), HasLogicals (), S, :X , dressed, max_iters, verbose)
740- upperz, foundz = random_information_set_minimum_distance_bound! (HasNoGauges (), IsCSS (), HasLogicals (), S, :Z , dressed, max_iters, verbose)
741- if upperx <= upperz
742- S. u_bound = upperx
743- return upperx, foundx
744- else
745- S. u_bound = upperz
746- return upperz, foundz
747- end
751+ ! ismissing (S. d) && (println (" Distance already known" ); return S. d;)
752+ stabs = _Flint_matrix_to_Julia_T_matrix (stabilizers (S), UInt8)
753+ _rref_no_col_swap_binary! (stabs)
754+ stabs = _remove_empty (stabs, :rows )
755+ logs = _Flint_matrix_to_Julia_T_matrix (logicals_matrix (S), UInt8)
756+ operators_to_reduce = vcat (stabs, logs)
757+ println (size (operators_to_reduce))
758+ check_against = permutedims (logs)
759+ curr_l_bound = S. l_bound
760+ verbose && println (" Starting lower bound: $curr_l_bound " )
761+ curr_u_bound, index = findmin (count (! iszero, logs[i, :]) for i in 1 : size (logs, 1 ))
762+ found = logs[index, :]
763+ verbose && println (" Starting upper bound: $curr_u_bound " )
748764 else
749765 if verbose && which == :X
750766 verbose && println (" Bounding the X-distance" )
@@ -759,7 +775,7 @@ function random_information_set_minimum_distance_bound!(::HasNoGauges, ::IsCSS,
759775 operators_to_reduce = vcat (stabs, logs)
760776 check_against = _Flint_matrix_to_Julia_T_matrix (logicals_matrix (S)[:, (which == :X ? (n + 1 : 2 n) : (1 : n))], UInt8)
761777 check_against = permutedims (_remove_empty (check_against, :rows ))
762- curr_l_bound = S. l_bound_dx
778+ which == :X ? ( curr_l_bound = S. l_bound_dx;) : (curr_l_bound = S . l_bound_dz;)
763779 verbose && println (" Starting lower bound: $curr_l_bound " )
764780 curr_u_bound, index = findmin (count (! iszero, logs[i, :]) for i in 1 : size (logs, 1 ))
765781 found = logs[index, :]
@@ -774,21 +790,20 @@ function random_information_set_minimum_distance_bound!(::HasNoGauges, ::IsCSS,
774790 curr_u_bound, found, max_iters, n, verbose)
775791 end
776792 loc = argmin (uppers)
793+ verbose && println (" Ending $max_iters iterations with an upper bound of $(uppers[loc]) " )
777794 if which == :full
778795 S. u_bound = uppers[loc]
796+ flint_mat_found = matrix (field (S), permutedims (founds[loc]))
779797 elseif which == :X
780798 S. u_bound_dx = uppers[loc]
799+ S. u_bound = min (S. u_bound_dx, S. u_bound_dz)
800+ flint_mat_found = matrix (field (S), [permutedims (founds[loc]) zeros (Int, 1 , n)])
781801 else
782802 S. u_bound_dz = uppers[loc]
803+ S. u_bound = min (S. u_bound_dx, S. u_bound_dz)
804+ flint_mat_found = matrix (field (S), [zeros (Int, 1 , n) permutedims (founds[loc])])
783805 end
784- verbose && println (" Ending $max_iters iterations with an upper bound of $(uppers[loc]) " )
785- flint_mat_found = if which == :full
786- matrix (field (S), permutedims (founds[loc]))
787- elseif which == :X
788- matrix (field (S), [permutedims (founds[loc]) zeros (Int, 1 , n)])
789- else
790- matrix (field (S), [zeros (Int, 1 , n) permutedims (founds[loc])])
791- end
806+
792807 return uppers[loc], flint_mat_found
793808end
794809
@@ -799,44 +814,34 @@ function random_information_set_minimum_distance_bound!(::HasGauges, ::IsNotCSS,
799814 which == :full || throw (ArguementError (which, " Parameter is not valid for non-CSS codes." ))
800815
801816 n = S. n
817+ ! ismissing (S. d_dressed) && (println (" Dressed distance already known" ); return S. d_dressed;)
818+ stabs = _Flint_matrix_to_Julia_T_matrix (stabilizers (S), Int)
819+ _rref_no_col_swap_binary! (stabs)
820+ stabs = _remove_empty (stabs, :rows )
802821 if dressed
803822 verbose && println (" Bounding the full dressed distance" )
804- stabs = _Flint_matrix_to_Julia_T_matrix (stabilizers (S), Int)
805- _rref_no_col_swap_binary! (stabs)
806- stabs = _remove_empty (stabs, :rows )
807- gauges = _Flint_matrix_to_Julia_T_matrix (gauges_matrix (S), Int)
808- logs = _Flint_matrix_to_Julia_T_matrix (logicals_matrix (S), Int)
809- operators_to_reduce = vcat (stabs, gauges, logs)
810- check_against = permutedims (logs[:, [n + 1 : 2 n; 1 : n]])
811- curr_l_bound = S. l_bound_dressed
812- verbose && println (" Starting lower bound: $curr_l_bound " )
813-
814- # this is done in the constructor but the logical is not stored at the time
815- # so must redo here
816- mat = _rref_no_col_swap_binary (operators_to_reduce)
817- anti = mat * check_against
818- curr_u_bound, index = findmin (row_wts_symplectic (mat[findall (! iszero (anti[i, :]) for i in axes (anti, 1 )), :]))
819- found = operators_to_reduce[index, :]
820- verbose && println (" Starting upper bound: $curr_u_bound " )
823+ gauges = _Flint_matrix_to_Julia_T_matrix (gauge_operators_matrix (S), UInt8)
824+ stabs = vcat (stabs, gauges)
821825 else
822826 verbose && println (" Bounding the full bare distance" )
823- stabs = _Flint_matrix_to_Julia_T_matrix (stabilizers (S), Int)
824- _rref_no_col_swap_binary! (stabs)
825- stabs = _remove_empty (stabs, :rows )
826- logs = _Flint_matrix_to_Julia_T_matrix (logicals_matrix (S), Int)
827- operators_to_reduce = vcat (stabs, logs)
828- check_against = permutedims (logs[:, [n + 1 : 2 n; 1 : n]])
829- curr_l_bound = S. l_bound_bare
830- verbose && println (" Starting lower bound: $curr_l_bound " )
831-
832- # this is done in the constructor but the logical is not stored at the time
833- # so must redo here
834- mat = _rref_no_col_swap_binary (operators_to_reduce)
835- anti = mat * check_against
836- curr_u_bound, index = findmin (row_wts_symplectic (mat[findall (! iszero (anti[i, :]) for i in axes (anti, 1 )), :]))
837- found = operators_to_reduce[index, :]
838- verbose && println (" Starting upper bound: $curr_u_bound " )
839827 end
828+ logs = _Flint_matrix_to_Julia_T_matrix (logicals_matrix (S), Int)
829+ operators_to_reduce = vcat (stabs, logs)
830+ check_against = permutedims (logs[:, [n + 1 : 2 n; 1 : n]])
831+ curr_l_bound = if dressed
832+ S. l_bound_dressed
833+ else
834+ S. l_bound_bare
835+ end
836+ verbose && println (" Starting lower bound: $curr_l_bound " )
837+
838+ # this is done in the constructor but the logical is not stored at the time
839+ # so must redo here
840+ mat = _rref_no_col_swap_binary (operators_to_reduce)
841+ anti = mat * check_against
842+ curr_u_bound, index = findmin (row_wts_symplectic (mat[findall (! iszero (anti[i, :]) for i in axes (anti, 1 )), :]))
843+ found = operators_to_reduce[index, :]
844+ verbose && println (" Starting upper bound: $curr_u_bound " )
840845
841846 uppers, founds = _RIS_bound_loop_symp! (operators_to_reduce, check_against, curr_l_bound,
842847 curr_u_bound, found, max_iters, n, verbose)
@@ -847,7 +852,7 @@ function random_information_set_minimum_distance_bound!(::HasGauges, ::IsNotCSS,
847852 S. u_bound_bare = uppers[loc]
848853 end
849854 verbose && println (" Ending $max_iters iterations with an upper bound of $(uppers[loc]) " )
850- return uppers[loc], founds[loc]
855+ return uppers[loc], matrix ( field (S), permutedims ( founds[loc]))
851856end
852857
853858function random_information_set_minimum_distance_bound! (:: HasNoGauges , :: IsNotCSS , :: HasLogicals ,
@@ -857,6 +862,7 @@ function random_information_set_minimum_distance_bound!(::HasNoGauges, ::IsNotCS
857862 which == :full || throw (ArguementError (which, " Parameter is not valid for non-CSS codes." ))
858863
859864 n = S. n
865+ ! ismissing (S. d) && (println (" Distance already known" ); return S. d;)
860866 verbose && println (" Bounding the full distance" )
861867 stabs = _Flint_matrix_to_Julia_T_matrix (stabilizers (S), Int)
862868 _rref_no_col_swap_binary! (stabs)
891897# end
892898
893899function _RIS_bound_loop_symp! (operators_to_reduce, check_against, curr_l_bound:: Int , curr_u_bound:: Int , found, max_iters:: Int , n:: Int , verbose:: Bool )
900+
894901 num_thrds = Threads. nthreads ()
895902 verbose && println (" Detected $num_thrds threads." )
896903
@@ -906,9 +913,12 @@ function _RIS_bound_loop_symp!(operators_to_reduce, check_against, curr_l_bound:
906913 perm_ops = similar (orig_ops)
907914 ops = similar (orig_ops)
908915 perm = collect (1 : n)
916+ # perm2 = [perm; perm]
909917 for _ in 1 : (thread_load + (t <= remaining ? 1 : 0 ))
910918 if flag[]
911919 shuffle! (perm)
920+ # perm2[1:n] .= perm
921+ # perm2[n + 1:end] .= (perm .+ n)
912922 _col_permutation_symp! (perm_ops, orig_ops, perm)
913923 # modifying this in place is not thread safe (apparently)
914924 # perm_ops = _rref_no_col_swap_binary(perm_ops)
@@ -943,6 +953,7 @@ function _RIS_bound_loop_symp!(operators_to_reduce, check_against, curr_l_bound:
943953end
944954
945955function _RIS_bound_loop! (operators_to_reduce, check_against, curr_l_bound:: Int , curr_u_bound:: Int , found, max_iters:: Int , n:: Int , verbose:: Bool )
956+
946957 num_thrds = Threads. nthreads ()
947958 verbose && println (" Detected $num_thrds threads." )
948959
0 commit comments