def guruswami_sudan_decoding_radius(C=None, n_k=None, l=None, s=None): r""" Returns the maximal decoding radius of the Guruswami-Sudan decoder and the parameter choices needed for this. If ``s`` is set but ``l`` is not it will return the best decoding radius using this ``s`` alongside with the required ``l``. Vice versa for ``l``. If both are set, it returns the decoding radius given this parameter choice. INPUT: - ``C`` -- (default: ``None``) a :class:`GeneralizedReedSolomonCode` - ``n_k`` -- (default: ``None``) a pair of integers, respectively the length and the dimension of the :class:`GeneralizedReedSolomonCode` - ``s`` -- (default: ``None``) an integer, the multiplicity parameter of Guruswami-Sudan algorithm - ``l`` -- (default: ``None``) an integer, the list size parameter .. NOTE:: One has to provide either ``C`` or ``n_k``. If none or both are given, an exception will be raised. OUTPUT: - ``(tau, (s, l))`` -- where - ``tau`` is the obtained decoding radius, and - ``s, ell`` are the multiplicity parameter, respectively list size parameter giving this radius. EXAMPLES:: sage: n, k = 250, 70 sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k)) (118, (47, 89)) One parameter can be restricted at a time:: sage: n, k = 250, 70 sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k), s=3) (109, (3, 5)) sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k), l=7) (111, (4, 7)) The function can also just compute the decoding radius given the parameters:: sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k), s=2, l=6) (92, (2, 6)) """ n, k = n_k_params(C, n_k) def get_tau(s, l): "Return the decoding radius given this s and l" if s <= 0 or l <= 0: return -1 return gilt(n - n / 2 * (s + 1) / (l + 1) - (k - 1) / 2 * l / s) if l is None and s is None: tau = gilt(johnson_radius(n, n - k + 1)) return (tau, GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k=(n, k))) if l is not None and s is not None: return (get_tau(s, l), (s, l)) # Either s or l is set, but not both. First a shared local function def find_integral_max(real_max, f): """Given a real (local) maximum of a function `f`, return that of the integers around `real_max` which gives the (local) integral maximum, and the value of at that point.""" if real_max in ZZ: int_max = Integer(real_max) return (int_max, f(int_max)) else: x_f = floor(real_max) x_c = x_f + 1 f_f, f_c = f(x_f), f(x_c) return (x_f, f_f) if f_f >= f_c else (x_c, f_c) if s is not None: # maximising tau under condition # n*(s+1 choose 2) < (ell+1)*s*(n-tau) - (ell+1 choose 2)*(k-1) # knowing n and s, we can just minimise # ( n*(s+1 choose 2) + (ell+1 choose 2)*(k-1) )/(ell+1) # Differentiating and setting to zero yields ell best choice: lmax = sqrt(n * s * (s + 1.) / (k - 1.)) - 1. #the best integral value will be (l, tau) = find_integral_max(lmax, lambda l: get_tau(s, l)) #Note that we have not proven that this ell is minimal in integral #sense! It just seems that this most often happens return (tau, (s, l)) if l is not None: # Acquired similarly to when restricting s smax = sqrt((k - 1.) / n * l * (l + 1.)) (s, tau) = find_integral_max(smax, lambda s: get_tau(s, l)) return (tau, (s, l))
def guruswami_sudan_decoding_radius(C = None, n_k = None, l = None, s = None): r""" Returns the maximal decoding radius of the Guruswami-Sudan decoder and the parameter choices needed for this. If ``s`` is set but ``l`` is not it will return the best decoding radius using this ``s`` alongside with the required ``l``. Vice versa for ``l``. If both are set, it returns the decoding radius given this parameter choice. INPUT: - ``C`` -- (default: ``None``) a :class:`GeneralizedReedSolomonCode` - ``n_k`` -- (default: ``None``) a pair of integers, respectively the length and the dimension of the :class:`GeneralizedReedSolomonCode` - ``s`` -- (default: ``None``) an integer, the multiplicity parameter of Guruswami-Sudan algorithm - ``l`` -- (default: ``None``) an integer, the list size parameter .. NOTE:: One has to provide either ``C`` or ``n_k``. If none or both are given, an exception will be raised. OUTPUT: - ``(tau, (s, l))`` -- where - ``tau`` is the obtained decoding radius, and - ``s, ell`` are the multiplicity parameter, respectively list size parameter giving this radius. EXAMPLES:: sage: n, k = 250, 70 sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k)) (118, (47, 89)) One parameter can be restricted at a time:: sage: n, k = 250, 70 sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k), s=3) (109, (3, 5)) sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k), l=7) (111, (4, 7)) The function can also just compute the decoding radius given the parameters:: sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k), s=2, l=6) (92, (2, 6)) """ n,k = n_k_params(C, n_k) def get_tau(s,l): "Return the decoding radius given this s and l" if s<=0 or l<=0: return -1 return gilt(n - n/2*(s+1)/(l+1) - (k-1)/2*l/s) if l is None and s is None: tau = gilt(johnson_radius(n, n - k + 1)) return (tau, GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k))) if l is not None and s is not None: return (get_tau(s,l), (s,l)) # Either s or l is set, but not both. First a shared local function def find_integral_max(real_max, f): """Given a real (local) maximum of a function `f`, return that of the integers around `real_max` which gives the (local) integral maximum, and the value of at that point.""" if real_max in ZZ: int_max = Integer(real_max) return (int_max, f(int_max)) else: x_f = floor(real_max) x_c = x_f + 1 f_f, f_c = f(x_f), f(x_c) return (x_f, f_f) if f_f >= f_c else (x_c, f_c) if s is not None: # maximising tau under condition # n*(s+1 choose 2) < (ell+1)*s*(n-tau) - (ell+1 choose 2)*(k-1) # knowing n and s, we can just minimise # ( n*(s+1 choose 2) + (ell+1 choose 2)*(k-1) )/(ell+1) # Differentiating and setting to zero yields ell best choice: lmax = sqrt(n*s*(s+1.)/(k-1.)) - 1. #the best integral value will be (l,tau) = find_integral_max(lmax, lambda l: get_tau(s,l)) #Note that we have not proven that this ell is minimal in integral #sense! It just seems that this most often happens return (tau,(s,l)) if l is not None: # Acquired similarly to when restricting s smax = sqrt((k-1.)/n*l*(l+1.)) (s,tau) = find_integral_max(smax, lambda s: get_tau(s,l)) return (tau, (s,l))
def parameters_given_tau(tau, C=None, n_k=None): r""" Returns the smallest possible multiplicity and list size given the given parameters of the code and decoding radius. INPUT: - ``tau`` -- an integer, number of errors one wants the Guruswami-Sudan algorithm to correct - ``C`` -- (default: ``None``) a :class:`GeneralizedReedSolomonCode` - ``n_k`` -- (default: ``None``) a pair of integers, respectively the length and the dimension of the :class:`GeneralizedReedSolomonCode` OUTPUT: - ``(s, l)`` -- a pair of integers, where: - ``s`` is the multiplicity parameter, and - ``l`` is the list size parameter. .. NOTE:: One should to provide either ``C`` or ``(n, k)``. If neither or both are given, an exception will be raised. EXAMPLES:: sage: tau, n, k = 97, 250, 70 sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) (1, 2) Another example with a bigger decoding radius:: sage: tau, n, k = 118, 250, 70 sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) (47, 89) Choosing a decoding radius which is too large results in an errors:: sage: tau = 200 sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) Traceback (most recent call last): ... ValueError: The decoding radius must be less than the Johnson radius (which is 118.66) """ n, k = n_k_params(C, n_k) johnson = johnson_radius(n, n - k + 1) if tau >= johnson: raise ValueError( "The decoding radius must be less than the Johnson radius (which is %.2f)" % float(johnson)) # We start with l=1 and check if a satisfiable s can be chosen. We keep # increasing l by 1 until this is the case. The governing equation is # s*(s+1)/2 * n < (l+1)*s*(n-tau) - l*(l+1)/2*(k-1) # See [GS1999]_ def try_l(l): (mins, maxs) = solve_degree2_to_integer_range( n, n - 2 * (l + 1) * (n - tau), (k - 1) * l * (l + 1)) if maxs > 0 and maxs >= mins: return max(1, mins) else: return None s, l = None, 0 while s is None: l += 1 s = try_l(l) return (s, l)
def parameters_given_tau(tau, C = None, n_k = None): r""" Returns the smallest possible multiplicity and list size given the given parameters of the code and decoding radius. INPUT: - ``tau`` -- an integer, number of errors one wants the Guruswami-Sudan algorithm to correct - ``C`` -- (default: ``None``) a :class:`GeneralizedReedSolomonCode` - ``n_k`` -- (default: ``None``) a pair of integers, respectively the length and the dimension of the :class:`GeneralizedReedSolomonCode` OUTPUT: - ``(s, l)`` -- a pair of integers, where: - ``s`` is the multiplicity parameter, and - ``l`` is the list size parameter. .. NOTE:: One should to provide either ``C`` or ``(n, k)``. If neither or both are given, an exception will be raised. EXAMPLES:: sage: tau, n, k = 97, 250, 70 sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) (1, 2) Another example with a bigger decoding radius:: sage: tau, n, k = 118, 250, 70 sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) (47, 89) Choosing a decoding radius which is too large results in an errors:: sage: tau = 200 sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) Traceback (most recent call last): ... ValueError: The decoding radius must be less than the Johnson radius (which is 118.66) """ n,k = n_k_params(C, n_k) johnson = johnson_radius(n, n - k + 1) if tau >= johnson: raise ValueError("The decoding radius must be less than the Johnson radius (which is %.2f)" % float(johnson)) # We start with l=1 and check if a satisfiable s can be chosen. We keep # increasing l by 1 until this is the case. The governing equation is # s*(s+1)/2 * n < (l+1)*s*(n-tau) - l*(l+1)/2*(k-1) # See [GS1999]_ def try_l(l): (mins,maxs) = solve_degree2_to_integer_range(n, n-2*(l+1)*(n-tau), (k-1)*l*(l+1)) if maxs > 0 and maxs >= mins: return max(1, mins) else: return None s, l = None, 0 while s is None: l += 1 s = try_l(l) return (s, l)