Skip to content

Commit ca162df

Browse files
committed
Temp TRS Update
1 parent 6dbcb64 commit ca162df

File tree

14 files changed

+640
-178
lines changed

14 files changed

+640
-178
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Copyright (c) 2024 Eric Sabo
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
#############################
8+
# constructors
9+
#############################
10+
11+
"""
12+
TwistedReedSolomonCode(k::Int, α::Vector{T}, t::Vector{Int}, h::Vector{Int}, η::Vector{T}) where T <: CTFieldElem
13+
14+
Return the twisted Reed-Solomon code defined in `https://arxiv.org/abs/2107.06945`.
15+
"""
16+
function TwistedReedSolomonCode(k::Int, α::Vector{T}, t::Vector{Int}, h::Vector{Int}, η::Vector{T}) where T <: CTFieldElem
17+
18+
l = length(t)
19+
l == length(h) || throw(ArgumentError("Input vectors `t`, `h`, and `η` must have the same length"))
20+
l == length(η) || throw(ArgumentError("Input vectors `t`, `h`, and `η` must have the same length"))
21+
length(unique(collect(zip(h, t)))) == l || throw(ArgumentError("The tuples `(h[i], t[i])` must be distinct"))
22+
n = length(α)
23+
length(unique(α)) == n || throw(ArgumentError("The elements of `α` must be distinct"))
24+
1 k n || throw(DomainError(k, "The dimension of the code must satisfy `1 ≤ k ≤ length(α)`"))
25+
all(1 x n - k for x in t) || throw(DomainError(t, "Elements of `t` must satsify `1 ≤ t[i] ≤ n - k`"))
26+
all(0 x k - 1 for x in h) || throw(DomainError(h, "Elements of `h` must satsify `0 ≤ h[i] ≤ k - 1`"))
27+
F = parent(α[1])
28+
all(parent(x) == F for x in α) || throw(DomainError(α, "All elements of `α` must be over the same base ring"))
29+
all(parent(x) == F for x in η) || throw(DomainError(η, "All elements of `η` must be over the same base ring as the elements of `α`"))
30+
31+
_, x = polynomial_ring(F, :x)
32+
G = zero_matrix(F, k, n)
33+
for i in 0:k - 1
34+
g_i = x^i
35+
for j in 1:l
36+
h[j] == i && (g_i += η[j] * x^(k - 1 + t[j]);)
37+
end
38+
39+
for c in 1:n
40+
G[i + 1, c] = g_i(α[c])
41+
end
42+
end
43+
display(G)
44+
45+
t_dual = k .- h
46+
h_dual = (n - k) .- t
47+
H = zero_matrix(F, n - k, n)
48+
for i in 0:n - k - 1
49+
g_i = x^i
50+
for j in 1:l
51+
h_dual[j] == i && (g_i += -η[j] * x^(n - k - 1 + t_dual[j]);)
52+
end
53+
54+
for c in 1:n
55+
H[i + 1, c] = g_i(α[c])
56+
end
57+
end
58+
println(" ")
59+
display(H)
60+
61+
println(" ")
62+
display(G * transpose(H))
63+
64+
C = LinearCode(G, H, false)
65+
return TwistedReedSolomonCode(C.F, C.n, C.k, C.d, C.l_bound, C.u_bound, C.G, C.H, C.G_stand, C.H_stand, C.P_stand, C.weight_enum, α, t, h, η, l)
66+
end
67+
68+
#############################
69+
# getter functions
70+
#############################
71+
72+
"""
73+
twist_vector(C::AbstractTwistedReedSolomonCode)
74+
75+
Return the twist vector of `C`.
76+
"""
77+
twist_vector(C::AbstractTwistedReedSolomonCode) = C.t
78+
79+
"""
80+
hook_vector(C::AbstractTwistedReedSolomonCode)
81+
82+
Return the hook vector of `C`.
83+
"""
84+
hook_vector(C::AbstractTwistedReedSolomonCode) = C.h
85+
86+
"""
87+
coefficient_vector(C::AbstractTwistedReedSolomonCode)
88+
89+
Return the coefficient vector of `C`.
90+
"""
91+
coefficient_vector(C::AbstractTwistedReedSolomonCode) = C.η
92+
93+
"""
94+
number_of_twists(C::AbstractTwistedReedSolomonCode)
95+
96+
Return the number of twists of `C`.
97+
"""
98+
number_of_twists(C::AbstractTwistedReedSolomonCode) = C.l
99+
100+
#############################
101+
# setter functions
102+
#############################
103+
104+
#############################
105+
# general functions
106+
#############################
107+
108+
# TODO check if all of these are in linear_code and branches on type
109+
# TODO can do better wrt d, bounds, and weight enumerator
110+
function dual(C::AbstractTwistedReedSolomonCode)
111+
return TwistedReedSolomonCode(C.F, C.n, C.n - C.k, missing, 1, C.n, C.H, C.G, C.H_stand, C.G_stand, C.P_stand, missing, C.α, C.k .- C.h, (C.n - C.k) .- C.t, -C.η, C.l)
112+
end

src/Classical/cyclic_code.jl

Lines changed: 81 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,14 @@ function CyclicCode(q::Int, n::Int, cosets::Vector{Vector{Int}})
9494
H, G_stand, H_stand, P, missing)
9595
end
9696

97+
# TODO should define this instead over a residue ring such that n is already defined?
9798
"""
98-
CyclicCode(n::Int, g::FqPolyRingElem)
99+
CyclicCode(n::Int, g::Union{fpPolyRingElem, FqPolyRingElem})
99100
100101
Return the length `n` cyclic code generated by the polynomial `g`.
101102
"""
102-
function CyclicCode(n::Int, g::FqPolyRingElem)
103-
n <= 1 && throw(DomainError("Invalid parameters passed to CyclicCode constructor: n = $n."))
103+
function CyclicCode(n::Int, g::Union{fpPolyRingElem, FqPolyRingElem})
104+
is_positive(n) || throw(DomainError("Invalid parameters passed to CyclicCode constructor: n = $n."))
104105
R = parent(g)
105106
flag, h = divides(gen(R)^n - 1, g)
106107
flag || throw(ArgumentError("Given polynomial does not divide x^$n - 1."))
@@ -119,13 +120,19 @@ function CyclicCode(n::Int, g::FqPolyRingElem)
119120
β = α^(div(q^deg - 1, n))
120121
ord_E = Int(order(E))
121122
R_E, y = polynomial_ring(E, :y)
122-
g_E = R_E([E(i) for i in collect(coefficients(g))])
123+
if t == 1 && typeof(g) == fpPolyRingElem
124+
g_E = R_E(E.(lift.(Ref(ZZ), collect(coefficients(g)))))
125+
else
126+
g_E = R_E([E(i) for i in collect(coefficients(g))])
127+
end
123128
# _, h = divides(gen(R_E)^n - 1, g_E)
124129

130+
# TODO doesn't work for large fields
125131
dic = Dict{FqFieldElem, Int}()
126132
for i in 0:ord_E - 1
127133
dic[β^i] = i
128134
end
135+
129136
cosets = defining_set(sort!([dic[rt] for rt in roots(g_E)]), q, n, false)
130137
def_set = sort!(reduce(vcat, cosets))
131138
k = n - length(def_set)
@@ -145,7 +152,7 @@ function CyclicCode(n::Int, g::FqPolyRingElem)
145152
iszero(G * tr_H) || error("Generator and parity check matrices are not transpose orthogonal.")
146153

147154
if t == 1
148-
F = GF(p)
155+
F = Oscar.Nemo.Native.GF(p)
149156
G = change_base_ring(F, G)
150157
H = change_base_ring(F, H)
151158
G_stand = change_base_ring(F, G_stand)
@@ -378,6 +385,29 @@ Return the cyclic code whose roots are the quadratic residues of `q`, `n`.
378385
"""
379386
QuadraticResidueCode(q::Int, n::Int) = CyclicCode(q, n, [quadratic_residues(q, n)])
380387

388+
"""
389+
FireCode(p::Union{fpPolyRingElem, FqPolyRingElem}, l::Int)
390+
391+
Return the fire code with generator polynomial `(x^(2l - 1) + 1) * p`.
392+
"""
393+
function FireCode(p::Union{fpPolyRingElem, FqPolyRingElem}, l::Int)
394+
# F = base_ring(p)
395+
# Int(order(F)) == 2 || throw(ArgumentError("Fire codes are only defined over `GF(2)`."))
396+
Oscar.is_irreducible(p) || throw(ArgumentError("The polynomial `p` must be irreducible over `GF(2)`."))
397+
m = degree(p)
398+
x = gen(parent(p))
399+
1 l m || throw(DomainError(l, "This construction requires 1 ≤ l ≤ degree(p)."))
400+
isone(gcd(p, x^(2l - 1) + 1)) || throw(ArgumentError("This construction requires `gcd(p, x^(2l - 1) + 1) = 1`."))
401+
g = (x^(2l - 1) + 1) * p
402+
403+
n = -1
404+
for i in 1:3000
405+
flag, _ = divides(x^i - 1, g)
406+
flag && (n = i; break)
407+
end
408+
n == -1 && error("Unable to find the period of the generator polynomial in 3000 iterations.")
409+
return CyclicCode(n, g)
410+
end
381411
#TODO: cyclic code constructors from zeros and nonzeros
382412

383413
#############################
@@ -487,52 +517,6 @@ BCH_bound(C::AbstractCyclicCode) = C.δ
487517
# """
488518
# HT_bound(C::AbstractCyclicCode) = C.HT
489519

490-
"""
491-
is_narrow_sense(C::AbstractBCHCode)
492-
493-
Return `true` if the BCH code is narrowsense.
494-
"""
495-
is_narrowsense(C::AbstractBCHCode) = iszero(C.b) # should we define this as b = 1 instead?
496-
497-
"""
498-
is_reversible(C::AbstractCyclicCode)
499-
500-
Return `true` if the cyclic code is reversible.
501-
"""
502-
is_reversible(C::AbstractCyclicCode) = [C.n - i for i in C.def_set] C.def_set
503-
504-
"""
505-
is_degenerate(C::AbstractCyclicCode)
506-
507-
Return `true` if the cyclic code is degenerate.
508-
509-
# Notes
510-
* A cyclic code is degenerate if the parity-check polynomial divides `x^r - 1` for
511-
some `r` less than the length of the code.
512-
"""
513-
function is_degenerate(C::AbstractCyclicCode)
514-
x = gen(C.R)
515-
for r in 1:C.n - 1
516-
flag, _ = divides(x^r - 1, C.h)
517-
flag && return true
518-
end
519-
return false
520-
end
521-
522-
"""
523-
is_primitive(C::AbstractBCHCode)
524-
525-
Return `true` if the BCH code is primitive.
526-
"""
527-
is_primitive(C::AbstractBCHCode) = C.n == Int(order(C.F)) - 1
528-
529-
"""
530-
is_antiprimitive(C::AbstractBCHCode)
531-
532-
Return `true` if the BCH code is antiprimitive.
533-
"""
534-
is_antiprimitive(C::AbstractBCHCode) = C.n == Int(order(C.F)) + 1
535-
536520
#############################
537521
# setter functions
538522
#############################
@@ -814,6 +798,52 @@ function +(C1::AbstractCyclicCode, C2::AbstractCyclicCode)
814798
end
815799
end
816800

801+
"""
802+
is_narrow_sense(C::AbstractBCHCode)
803+
804+
Return `true` if the BCH code is narrowsense.
805+
"""
806+
is_narrowsense(C::AbstractBCHCode) = iszero(C.b) # should we define this as b = 1 instead?
807+
808+
"""
809+
is_reversible(C::AbstractCyclicCode)
810+
811+
Return `true` if the cyclic code is reversible.
812+
"""
813+
is_reversible(C::AbstractCyclicCode) = [C.n - i for i in C.def_set] C.def_set
814+
815+
"""
816+
is_degenerate(C::AbstractCyclicCode)
817+
818+
Return `true` if the cyclic code is degenerate.
819+
820+
# Notes
821+
* A cyclic code is degenerate if the parity-check polynomial divides `x^r - 1` for
822+
some `r` less than the length of the code.
823+
"""
824+
function is_degenerate(C::AbstractCyclicCode)
825+
x = gen(C.R)
826+
for r in 1:C.n - 1
827+
flag, _ = divides(x^r - 1, C.h)
828+
flag && return true
829+
end
830+
return false
831+
end
832+
833+
"""
834+
is_primitive(C::AbstractBCHCode)
835+
836+
Return `true` if the BCH code is primitive.
837+
"""
838+
is_primitive(C::AbstractBCHCode) = C.n == Int(order(C.F)) - 1
839+
840+
"""
841+
is_antiprimitive(C::AbstractBCHCode)
842+
843+
Return `true` if the BCH code is antiprimitive.
844+
"""
845+
is_antiprimitive(C::AbstractBCHCode) = C.n == Int(order(C.F)) + 1
846+
817847
# "Schur products of linear codes: a study of parameters"
818848
# Diego Mirandola
819849
# """

0 commit comments

Comments
 (0)