From 5f9450fbebde1f69168e3779640045f1e9b6d65a Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 5 Jan 2022 10:43:02 +0900 Subject: [PATCH] Remove relative_finite_field_extension --- src/doc/en/reference/coding/index.rst | 7 - src/sage/coding/bch_code.py | 28 +- src/sage/coding/cyclic_code.py | 45 +- src/sage/coding/linear_code.py | 14 - .../coding/relative_finite_field_extension.py | 504 ------------------ src/sage/coding/subfield_subcode.py | 98 ++-- 6 files changed, 70 insertions(+), 626 deletions(-) delete mode 100644 src/sage/coding/relative_finite_field_extension.py diff --git a/src/doc/en/reference/coding/index.rst b/src/doc/en/reference/coding/index.rst index fd9e4de9fcd..abba3458380 100644 --- a/src/doc/en/reference/coding/index.rst +++ b/src/doc/en/reference/coding/index.rst @@ -160,11 +160,4 @@ There is at least one module in Sage for source coding in communications theory: sage/coding/source_coding/huffman -Finally an experimental module used for code constructions: - -.. toctree:: - :maxdepth: 1 - - sage/coding/relative_finite_field_extension - .. include:: ../footer.txt diff --git a/src/sage/coding/bch_code.py b/src/sage/coding/bch_code.py index 701fa6900d5..f5762c44f92 100644 --- a/src/sage/coding/bch_code.py +++ b/src/sage/coding/bch_code.py @@ -11,24 +11,6 @@ codewords `c(x) \in F[x]` satisfy `c(\alpha^{a}) = 0`, for all integers `a` in the arithmetic sequence `b, b + \ell, b + 2 \times \ell, \dots, b + (\delta - 2) \times \ell`. - -TESTS: - -This class uses the following experimental feature: -:class:`sage.coding.relative_finite_field_extension.RelativeFiniteFieldExtension`. -This test block is here only to trigger the experimental warning so it does not -interferes with doctests:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: RelativeFiniteFieldExtension(Fqm, Fq) - doctest:...: FutureWarning: This class/method/function is marked as - experimental. It, its functionality or its interface might change without a - formal deprecation. - See http://trac.sagemath.org/20284 for details. - Relative field extension between Finite Field in aa of size 2^4 and Finite - Field in a of size 2^2 """ # ***************************************************************************** # Copyright (C) 2016 David Lucas @@ -411,9 +393,8 @@ def bch_word_to_grs(self, c): sage: y in D.grs_code() True """ - mapping = self.code().field_embedding().embedding() - a = map(mapping, c) - return vector(a) + phi = self.code().field_embedding() + return vector([phi(x) for x in c]) def grs_word_to_bch(self, c): r""" @@ -431,9 +412,8 @@ def grs_word_to_bch(self, c): (0, a, 1, a, 0, 1, 1, 1, a, 0, 0, a + 1, a, 0, 1) """ C = self.code() - FE = C.field_embedding() - a = map(FE.cast_into_relative_field, c) - return vector(a) + sec = C.field_embedding().section() + return vector([sec(x) for x in c]) def decode_to_code(self, y): r""" diff --git a/src/sage/coding/cyclic_code.py b/src/sage/coding/cyclic_code.py index a6562ae199a..122a155dfa1 100644 --- a/src/sage/coding/cyclic_code.py +++ b/src/sage/coding/cyclic_code.py @@ -20,21 +20,6 @@ For now, only single-root cyclic codes (i.e. whose length `n` and field order `q` are coprimes) are implemented. - -TESTS: - -This class uses the following experimental feature: -:class:`sage.coding.relative_finite_field_extension.RelativeFiniteFieldExtension`. -This test block is here only to trigger the experimental warning so it does not -interferes with doctests:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: RelativeFiniteFieldExtension(Fqm, Fq) - doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. - See http://trac.sagemath.org/20284 for details. - Relative field extension between Finite Field in aa of size 2^4 and Finite Field in a of size 2^2 """ # ***************************************************************************** @@ -55,13 +40,12 @@ from .decoder import Decoder from copy import copy from sage.rings.integer import Integer +from sage.categories.homset import Hom from sage.arith.all import gcd from sage.modules.free_module_element import vector from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method from sage.rings.all import Zmod -from .relative_finite_field_extension import RelativeFiniteFieldExtension - def find_generator_polynomial(code, check=True): r""" @@ -437,19 +421,18 @@ def __init__(self, generator_pol=None, length=None, code=None, check=True, if primitive_root is not None: Fsplit = primitive_root.parent() try: - FE = RelativeFiniteFieldExtension(Fsplit, F) + FE = Hom(F, Fsplit)[0] except Exception: raise ValueError("primitive_root must belong to an " "extension of the base field") - if (FE.extension_degree() != s or + extension_degree = Fsplit.degree() // F.degree() + if (extension_degree != s or primitive_root.multiplicative_order() != n): raise ValueError("primitive_root must be a primitive " "n-th root of unity") alpha = primitive_root else: - Fsplit, F_to_Fsplit = F.extension(Integer(s), map=True) - FE = RelativeFiniteFieldExtension(Fsplit, F, - embedding=F_to_Fsplit) + Fsplit, FE = F.extension(Integer(s), map=True) alpha = Fsplit.zeta(n) Rsplit = Fsplit['xx'] @@ -458,12 +441,13 @@ def __init__(self, generator_pol=None, length=None, code=None, check=True, cosets = Zmod(n).cyclotomic_cosets(q, D) pows = [item for l in cosets for item in l] + sec = FE.section() g = R.one() for J in cosets: pol = Rsplit.one() for j in J: pol *= xx - alpha**j - g *= R([FE.cast_into_relative_field(coeff) for coeff in pol]) + g *= R([sec(coeff) for coeff in pol]) # we set class variables self._field_embedding = FE @@ -587,7 +571,10 @@ def field_embedding(self): sage: g = x ** 3 + x + 1 sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: C.field_embedding() - Relative field extension between Finite Field in z3 of size 2^3 and Finite Field of size 2 + Ring morphism: + From: Finite Field of size 2 + To: Finite Field in z3 of size 2^3 + Defn: 1 |--> 1 """ if not(hasattr(self, "_field_embedding")): self.defining_set() @@ -661,16 +648,13 @@ def defining_set(self, primitive_root=None): s = Zmod(n)(q).multiplicative_order() if primitive_root is None: - Fsplit, F_to_Fsplit = F.extension(Integer(s), map=True) - FE = RelativeFiniteFieldExtension(Fsplit, F, - embedding=F_to_Fsplit) + Fsplit, FE = F.extension(Integer(s), map=True) alpha = Fsplit.zeta(n) else: try: alpha = primitive_root Fsplit = alpha.parent() - FE = RelativeFiniteFieldExtension(Fsplit, F) - F_to_Fsplit = FE.embedding() + FE = Hom(Fsplit, F)[0] except ValueError: raise ValueError("primitive_root does not belong to the " "right splitting field") @@ -679,9 +663,10 @@ def defining_set(self, primitive_root=None): "order equal to the code length") Rsplit = Fsplit['xx'] - gsplit = Rsplit([F_to_Fsplit(coeff) for coeff in g]) + gsplit = Rsplit([FE(coeff) for coeff in g]) roots = gsplit.roots(multiplicities=False) D = [root.log(alpha) for root in roots] + self._field_embedding = FE self._primitive_root = alpha self._defining_set = sorted(D) diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index c335f04e1a9..befbffce9e7 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -344,20 +344,6 @@ class AbstractLinearCode(AbstractLinearCodeNoMetric): It is thus strongly recommended to set an encoder with a generator matrix implemented as a default encoder. - TESTS: - - This class uses the following experimental feature: - :class:`sage.coding.relative_finite_field_extension.RelativeFiniteFieldExtension`. - This test block is here only to trigger the experimental warning so it does not - interferes with doctests:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: RelativeFiniteFieldExtension(Fqm, Fq) - doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. - See http://trac.sagemath.org/20284 for details. - Relative field extension between Finite Field in aa of size 2^4 and Finite Field in a of size 2^2 """ _registered_encoders = {} _registered_decoders = {} diff --git a/src/sage/coding/relative_finite_field_extension.py b/src/sage/coding/relative_finite_field_extension.py deleted file mode 100644 index 1a329624cce..00000000000 --- a/src/sage/coding/relative_finite_field_extension.py +++ /dev/null @@ -1,504 +0,0 @@ -r""" -Relative finite field extensions - -Considering a *absolute field* `F_{q^m}` and a *relative_field* `F_q`, with -`q = p^s`, `p` being a prime and `s, m` being integers, this file -contains a class to take care of the representation of `F_{q^m}`-elements -as `F_q`-elements. - -.. WARNING:: - - As this code is experimental, a warning is thrown when a - relative finite field extension is created for the first time - in a session (see :class:`sage.misc.superseded.experimental`). - - TESTS:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: RelativeFiniteFieldExtension(Fqm, Fq) - doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. - See http://trac.sagemath.org/20284 for details. - Relative field extension between Finite Field in aa of size 2^4 and Finite Field in a of size 2^2 -""" - -# **************************************************************************** -# Copyright (C) 2016 David Lucas -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# https://www.gnu.org/licenses/ -# **************************************************************************** - -from sage.misc.cachefunc import cached_method -from sage.structure.sage_object import SageObject -from sage.categories.homset import Hom -from sage.matrix.constructor import column_matrix -from sage.modules.free_module_element import vector -from sage.misc.superseded import experimental - - -class RelativeFiniteFieldExtension(SageObject): - r""" - Considering `p` a prime number, n an integer and three finite fields - `F_p`, `F_q` and `F_{q^m}`, this class contains a set of methods - to manage the representation of elements of the relative extension - `F_{q^m}` over `F_q`. - - INPUT: - - - ``absolute_field``, ``relative_field`` -- two finite fields, ``relative_field`` - being a subfield of ``absolute_field`` - - - ``embedding`` -- (default: ``None``) an homomorphism from ``relative_field`` to - ``absolute_field``. If ``None`` is provided, it will default to the first - homomorphism of the list of homomorphisms Sage can build. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: RelativeFiniteFieldExtension(Fqm, Fq) - Relative field extension between Finite Field in aa of size 2^4 and Finite Field in a of size 2^2 - - It is possible to specify the embedding to use - from ``relative_field`` to ``absolute_field``:: - - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq, embedding=Hom(Fq, Fqm)[1]) - sage: FE.embedding() == Hom(Fq, Fqm)[1] - True - """ - - @experimental(trac_number=20284) - def __init__(self, absolute_field, relative_field, embedding=None): - r""" - TESTS: - - If ``absolute_field`` is not a finite field, an error is raised:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm = RR - sage: Fq. = GF(4) - sage: RelativeFiniteFieldExtension(Fqm, Fq) - Traceback (most recent call last): - ... - ValueError: absolute_field has to be a finite field - - Same for ``relative_field``:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq = RR - sage: RelativeFiniteFieldExtension(Fqm, Fq) - Traceback (most recent call last): - ... - ValueError: relative_field has to be a finite field - - If ``relative_field`` is not a subfield of ``absolute_field``, an exception - is raised:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(8) - sage: RelativeFiniteFieldExtension(Fqm, Fq) - Traceback (most recent call last): - ... - ValueError: relative_field has to be a subfield of absolute_field - """ - if not absolute_field.is_finite(): - raise ValueError("absolute_field has to be a finite field") - if not relative_field.is_finite(): - raise ValueError("relative_field has to be a finite field") - s = relative_field.degree() - sm = absolute_field.degree() - if not s.divides(sm): - raise ValueError("relative_field has to be a subfield of absolute_field") - H = Hom(relative_field, absolute_field) - if embedding is not None and embedding not in H: - raise ValueError("embedding has to be an embedding from relative_field to absolute_field") - elif embedding is not None: - self._phi = embedding - else: - self._phi = H[0] - self._prime_field = relative_field.base_ring() - self._relative_field = relative_field - self._absolute_field = absolute_field - alpha = relative_field.gen() - beta = absolute_field.gen() - self._alphas = [alpha ** i for i in range(s)] - self._betas = [beta ** i for i in range(sm)] - self._relative_field_degree = s - self._absolute_field_degree = sm - - def _repr_(self): - r""" - Returns a string representation of ``self``. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: RelativeFiniteFieldExtension(Fqm, Fq) - Relative field extension between Finite Field in aa of size 2^4 and Finite Field in a of size 2^2 - """ - return "Relative field extension between %s and %s" % (self.absolute_field(), self.relative_field()) - - def _latex_(self): - r""" - Returns a latex representation of ``self``. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: latex(RelativeFiniteFieldExtension(Fqm, Fq)) - \textnormal{Relative field extension between \Bold{F}_{2^{4}} and \Bold{F}_{2^{2}}} - """ - return "\\textnormal{Relative field extension between %s and %s}" % (self.absolute_field()._latex_(), - self.relative_field()._latex_()) - - def __eq__(self, other): - r""" - Tests equality between embeddings. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fq = GF(4) - sage: FQ = GF(4**3) - sage: H = Hom(Fq, FQ) - sage: E1 = RelativeFiniteFieldExtension(FQ, Fq) - sage: E2 = RelativeFiniteFieldExtension(FQ, Fq, H[0]) - sage: E3 = RelativeFiniteFieldExtension(FQ, Fq, H[1]) - sage: E1 == E2 - True - sage: E1 == E3 - False - """ - return isinstance(other, RelativeFiniteFieldExtension) \ - and self.embedding() == other.embedding() - - @cached_method - def _representation_matrix(self): - r""" - Returns the matrix used to represents elements of the absolute field - as vectors in the basis of the relative field over the prime field. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: FE._representation_matrix() - [1 0 0 0] - [0 0 1 1] - [0 1 1 1] - [0 0 0 1] - """ - s = self.relative_field_degree() - m = self.extension_degree() - betas = self.absolute_field_basis() - phi_alphas = [ self._phi(self._alphas[i]) for i in range(s) ] - A = column_matrix([vector(betas[i] * phi_alphas[j]) - for i in range(m) for j in range(s)]) - return A.inverse() - - def _flattened_relative_field_representation(self, b): - r""" - Returns a vector representation of ``b`` in the basis of - the relative field over the prime field. - - INPUT: - - - ``b`` -- an element of the absolute field - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: b = aa^3 + aa^2 + aa + 1 - sage: FE._flattened_relative_field_representation(b) - (1, 0, 1, 1) - """ - if b not in self.absolute_field(): - raise ValueError("The input has to be an element of the absolute field") - return self._representation_matrix() * vector(b) - - def relative_field_representation(self, b): - r""" - Returns a vector representation of the field element ``b`` in the basis - of the absolute field over the relative field. - - INPUT: - - - ``b`` -- an element of the absolute field - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: b = aa^3 + aa^2 + aa + 1 - sage: FE.relative_field_representation(b) - (1, a + 1) - """ - if b not in self.absolute_field(): - raise ValueError("The input has to be an element of the absolute field") - s = self.relative_field_degree() - if s == 1: - return vector(b) - Fq = self.relative_field() - vect = self._flattened_relative_field_representation(b) - sm = self.absolute_field_degree() - list_elts = [] - for i in range(0, sm, s): - list_elts.append(Fq(vect[i:i + s])) - return vector(Fq, list_elts) - - def absolute_field_representation(self, a): - r""" - Returns an absolute field representation of the relative field - vector ``a``. - - INPUT: - - - ``a`` -- a vector in the relative extension field - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: b = aa^3 + aa^2 + aa + 1 - sage: rel = FE.relative_field_representation(b) - sage: FE.absolute_field_representation(rel) == b - True - """ - s = self.relative_field_degree() - m = self.extension_degree() - if len(a) != m: - raise ValueError("The input has to be a vector with length equal to the order of the absolute field") - if not a.base_ring() == self.relative_field(): - raise ValueError("The input has to be over the prime field") - alphas = self.relative_field_basis() - betas = self.absolute_field_basis() - phi = self.embedding() - b = self.absolute_field().zero() - flattened_relative_field_rep_list = [] - for i in a: - tmp = vector(i).list() - for j in tmp: - flattened_relative_field_rep_list.append(j) - - flattened_relative_field_rep = vector(flattened_relative_field_rep_list) - for i in range(m): - b += betas[i] * phi(sum([flattened_relative_field_rep[j] * alphas[j%s] for j in range(i*s, i*s + s)])) - return b - - def is_in_relative_field(self, b): - r""" - Returns ``True`` if ``b`` is in the relative field. - - INPUT: - - - ``b`` -- an element of the absolute field. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: FE.is_in_relative_field(aa^2 + aa) - True - sage: FE.is_in_relative_field(aa^3) - False - """ - vect = self.relative_field_representation(b) - return vect[1:vect.length()].is_zero() - - def cast_into_relative_field(self, b, check=True): - r""" - Casts an absolute field element into the relative field (if possible). - This is the inverse function of the field embedding. - - INPUT: - - - ``b`` -- an element of the absolute field which also lies in the - relative field. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: phi = FE.embedding() - sage: b = aa^2 + aa - sage: FE.is_in_relative_field(b) - True - sage: FE.cast_into_relative_field(b) - a - sage: phi(FE.cast_into_relative_field(b)) == b - True - """ - if check: - if not self.is_in_relative_field(b): - raise ValueError("%s does not belong to the relative field" % b) - return self.relative_field_representation(b)[0] - - def embedding(self): - r""" - Returns the embedding which is used to go from the - relative field to the absolute field. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: FE.embedding() - Ring morphism: - From: Finite Field in a of size 2^2 - To: Finite Field in aa of size 2^4 - Defn: a |--> aa^2 + aa - """ - return self._phi - - def relative_field_basis(self): - r""" - Returns a basis of the relative field over the prime field. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: FE.relative_field_basis() - [1, a] - """ - return self._alphas - - def absolute_field_basis(self): - r""" - Returns a basis of the absolute field over the prime field. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: FE.absolute_field_basis() - [1, aa, aa^2, aa^3] - """ - return self._betas - - def relative_field_degree(self): - r""" - Let `F_p` be the base field of our relative field `F_q`. - Returns `s` where `p^s = q` - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: FE.relative_field_degree() - 2 - """ - return self._relative_field_degree - - def absolute_field_degree(self): - r""" - Let `F_p` be the base field of our absolute field `F_{q^m}`. - Returns `sm` where `p^{sm} = q^{m}` - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: FE.absolute_field_degree() - 4 - """ - return self._absolute_field_degree - - - def extension_degree(self): - r""" - Return `m`, the extension degree of the absolute field over - the relative field. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(64) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: FE.extension_degree() - 3 - """ - return self.absolute_field_degree() // self.relative_field_degree() - - def prime_field(self): - r""" - Returns the base field of our absolute and relative fields. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: FE.prime_field() - Finite Field of size 2 - """ - return self._prime_field - - def relative_field(self): - r""" - Returns the relative field of ``self``. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: FE.relative_field() - Finite Field in a of size 2^2 - """ - return self._relative_field - - def absolute_field(self): - r""" - Returns the absolute field of ``self``. - - EXAMPLES:: - - sage: from sage.coding.relative_finite_field_extension import * - sage: Fqm. = GF(16) - sage: Fq. = GF(4) - sage: FE = RelativeFiniteFieldExtension(Fqm, Fq) - sage: FE.absolute_field() - Finite Field in aa of size 2^4 - """ - return self._absolute_field diff --git a/src/sage/coding/subfield_subcode.py b/src/sage/coding/subfield_subcode.py index ed7b18d7a90..cb78477a8b7 100644 --- a/src/sage/coding/subfield_subcode.py +++ b/src/sage/coding/subfield_subcode.py @@ -21,7 +21,6 @@ from .linear_code import AbstractLinearCode from sage.misc.cachefunc import cached_method from sage.categories.homset import Hom -from .relative_finite_field_extension import RelativeFiniteFieldExtension from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector from .decoder import Decoder, DecodingError @@ -46,8 +45,6 @@ class SubfieldSubcode(AbstractLinearCode): sage: C = codes.random_linear_code(GF(16, 'aa'), 7, 3) sage: codes.SubfieldSubcode(C, GF(4, 'a')) - doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. - See http://trac.sagemath.org/20284 for details. Subfield subcode of [7, 3] linear code over GF(16) down to GF(4) """ _registered_encoders = {} @@ -79,20 +76,24 @@ def __init__(self, original_code, subfield, embedding=None): raise ValueError("original_code must be a linear code") if not subfield.is_finite(): raise ValueError("subfield has to be a finite field") + + super(SubfieldSubcode, self).__init__(subfield, original_code.length(), "Systematic", "Syndrome") + F = original_code.base_field() - s = subfield.degree() sm = F.degree() + s = subfield.degree() if not s.divides(sm): raise ValueError("subfield has to be a subfield of the base field of the original code") - self._original_code = original_code + H = Hom(subfield, F) if embedding is not None and embedding not in H: raise ValueError("embedding has to be an embedding from subfield to original_code's base field") - elif embedding is not None: - self._embedding = RelativeFiniteFieldExtension(F, subfield, embedding) - else: - self._embedding = RelativeFiniteFieldExtension(F, subfield, H[0]) - super(SubfieldSubcode, self).__init__(subfield, original_code.length(), "Systematic", "Syndrome") + if embedding is None: + embedding = H[0] + + self._extension_degree = sm // s + self._embedding = embedding + self._original_code = original_code def __eq__(self, other): r""" @@ -178,7 +179,7 @@ def dimension_lower_bound(self): C = self.original_code() n = C.length() k = C.dimension() - m = self.embedding().extension_degree() + m = self._extension_degree return n - m*(n-k) def original_code(self): @@ -204,7 +205,10 @@ def embedding(self): sage: C = codes.random_linear_code(GF(16, 'aa'), 7, 3) sage: Cs = codes.SubfieldSubcode(C, GF(4, 'a')) sage: Cs.embedding() - Relative field extension between Finite Field in aa of size 2^4 and Finite Field in a of size 2^2 + Ring morphism: + From: Finite Field in a of size 2^2 + To: Finite Field in aa of size 2^4 + Defn: a |--> aa^2 + aa """ return self._embedding @@ -229,21 +233,24 @@ def parity_check_matrix(self): [ 0 0 0 0 0 0 0 0 1 0 a + 1 a + 1 1] [ 0 0 0 0 0 0 0 0 0 1 a 0 a + 1] """ + F = self.base_field() + n = self.length() + C = self.original_code() - Fq = self.base_field() H_original = C.parity_check_matrix() - n = self.length() codimC = H_original.nrows() - E = self.embedding() - m = E.extension_degree() - H = matrix(Fq, codimC * m, n) + phi = self.embedding() + E = phi.codomain() + V, from_V, to_V = E.vector_space(phi, map=True) + + m = V.dimension() + H = matrix(F, codimC * m, n) for i in range(codimC): for j in range(n): - h = H_original[i][j] - h_vect = E.relative_field_representation(h) + h_vec = to_V(H_original[i][j]) for k in range(m): - H[i*m+k, j] = h_vect[k] + H[i*m+k, j] = h_vec[k] H = H.echelon_form() delete = [] @@ -255,14 +262,6 @@ def parity_check_matrix(self): return M - - - - - - - - class SubfieldSubcodeOriginalCodeDecoder(Decoder): r""" Decoder decoding through a decoder over the original code of ``code``. @@ -309,11 +308,13 @@ def __init__(self, code, original_decoder = None, **kwargs): self._original_decoder = original_decoder else: self._original_decoder = original_code.decoder(**kwargs) + + super(SubfieldSubcodeOriginalCodeDecoder, self).__init__(code, code.ambient_space(), + self._original_decoder.connected_encoder()) + self._decoder_type = copy(self._decoder_type) self._decoder_type.remove("dynamic") self._decoder_type = self._original_decoder.decoder_type() - super(SubfieldSubcodeOriginalCodeDecoder, self).__init__(code, code.ambient_space(), - self._original_decoder.connected_encoder()) def _repr_(self): r""" @@ -359,8 +360,8 @@ def original_decoder(self): return self._original_decoder def decode_to_code(self, y): - r""" - Corrects the errors in ``word`` and returns a codeword. + """ + Return an error-corrected codeword from ``y``. EXAMPLES:: @@ -375,23 +376,26 @@ def decode_to_code(self, y): """ C = self.code() D = self.original_decoder() - FE = C.embedding() - phi = FE.embedding() - y_or = vector([phi(i) for i in y]) - c_or = D.decode_to_code(y_or) + phi = C.embedding() + sec = phi.section() + + result = D.decode_to_code(vector([phi(i) for i in y])) + if 'list-decoder' in self.decoder_type(): - result = [] - for c in c_or: - if all(FE.is_in_relative_field(x) for x in c): - result.append(vector(map(FE.cast_into_relative_field, c))) - return result + l = [] + for cw in result: + try: + l.append(vector([sec(c) for c in cw])) + except ValueError: # not a codeword of this code + pass + return l else: - if all(FE.is_in_relative_field(x) for x in c_or): - return vector([FE.cast_into_relative_field(i, check=False) - for i in c_or]) - else: - raise DecodingError("Original decoder does not output a " - "subfield codeword. You may have exceeded the decoding radius.") + try: + cw = vector([sec(c) for c in result]) + except ValueError: # not a codeword of this code + raise DecodingError("Original decoder does not output a subfield codeword. " + "You may have exceeded the decoding radius.") + return cw def decoding_radius(self, **kwargs): r"""