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)
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)
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))