Skip to content

Commit f90c834

Browse files
authored
Merge pull request #51 from jakewilliami/dev
Dev
2 parents 3140c5c + 35f94fe commit f90c834

File tree

11 files changed

+495
-352
lines changed

11 files changed

+495
-352
lines changed

Project.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@ version = "0.2.0"
55

66
[deps]
77
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
8-
Mods = "7475f97c-0381-53b1-977b-4c60186c8d62"
98
Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
109
Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae"
1110

1211
[compat]
13-
Mods = "1.2.4"
1412
Polynomials = "1.1.9"
1513
Primes = "0.5"
1614
julia = "1"

src/CodingTheory.jl

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,37 @@
66

77
module CodingTheory
88

9+
using Primes: isprime, primes
10+
using LinearAlgebra: I
11+
using Polynomials
12+
13+
include("utils.jl")
14+
15+
# Abstract types
916
export FinitePolynomial, AbstractCode, Alphabet, Messages, no_round
10-
export Alphabet, Messages, rate, sphere_covering_bound, sphere_packing_bound,
17+
18+
# RREF
19+
export rref, rref!
20+
21+
# Messages, Distance, and Primes
22+
export rate, sphere_covering_bound, sphere_packing_bound,
1123
construct_ham_matrix, isperfect, ishammingperfect, isgolayperfect,
1224
get_codewords_greedy, get_codewords_random, get_all_words,
1325
get_codewords
14-
export FinitePolynomial, list_polys, multiplication_table, list_span, islinear,
15-
isirreducible
1626
export hamming_distance, hamming_ball, code_distance, t_error_detecting,
1727
t_error_correcting, find_error_detection_max, find_error_correction_max
28+
export isprimepower
29+
30+
# Algebra
31+
export FinitePolynomial, list_polys, multiplication_table, list_span, islinear, isirreducible, normal_form!, normal_form, equivalent_code!, equivalent_code, generator!, generator, parity_check, syndrome, isincode
32+
33+
# Levenshtein
1834
export levenshtein, levenshtein!
19-
export normal_form!, normal_form, equivalent_code!, equivalent_code, generator!,
20-
generator, parity_check, syndrome, isincode
21-
export rref, rref!
2235

23-
include(joinpath(dirname(@__FILE__), "abstract_types.jl"))
24-
include(joinpath(dirname(@__FILE__), "messages.jl"))
25-
include(joinpath(dirname(@__FILE__), "distance.jl"))
26-
include(joinpath(dirname(@__FILE__), "fields.jl"))
27-
include(joinpath(dirname(@__FILE__), "algebra.jl"))
28-
include(joinpath(dirname(@__FILE__), "rref.jl"))
36+
include("abstract_types.jl")
37+
include("rref.jl")
38+
include("messages.jl") # implicitly exports distance.jl and primes.jl
39+
include("algebra.jl")
40+
include("levenshtein.jl")
2941

3042
end # end module

src/algebra.jl

Lines changed: 205 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,212 @@
33
exec julia --project="$(realpath $(dirname $(dirname $0)))" --color=yes --startup-file=no -e "include(popfirst!(ARGS))" \
44
"${BASH_SOURCE[0]}" "$@"
55
=#
6-
7-
include(joinpath(dirname(@__FILE__), "utils.jl"))
8-
include(joinpath(dirname(@__FILE__), "rref.jl"))
96

10-
using LinearAlgebra: I
7+
"""
8+
struct FinitePolynomial <: FiniteField
9+
10+
Has parameters `p`, which is an abstract polynomial, and `n` which is the modulus of the field under which the molynomial is defined.
11+
12+
---
13+
14+
FinitePolynomial(p::AbstractPolynomial, n::Integer)
15+
16+
A constructor method for `FinitePolynomial`. Takes in a polynomial `p` and a number `n`, and constructs a polynomial under modulo n.
17+
"""
18+
struct FinitePolynomial <: FiniteField
19+
p::AbstractPolynomial
20+
n::Integer
21+
22+
function FinitePolynomial(p::AbstractPolynomial, n::Integer)
23+
p = Polynomial(mod.(p.coeffs, n))
24+
new(p, n)
25+
end
26+
end
27+
28+
"""
29+
mod(p::Polynomial, n::Integer) -> Polynomial
30+
31+
Uses the FinitePolynomial constructor to return a polynomial `p` under modulus `n`.
32+
33+
Parameters:
34+
- p::Polynomial: The input polynomial.
35+
- n::Integer: The modulus of the field.
36+
37+
Returns
38+
- Polynomial: A polynomial modulo n.
39+
"""
40+
Base.mod(p::Polynomial, n::Integer) = FinitePolynomial(p, n).p
41+
42+
"""
43+
Polynomial(A::Union{Tuple, AbstractArray}, n::Integer) -> Polynomial
44+
45+
Constructs a polynomial under modulo `n`.
46+
47+
Parameters:
48+
- A::Union{Tuple, AbstractArrau}: The polynomial coefficients.
49+
- n::Integer: The modulus of the field.
50+
51+
Returns
52+
- Polynomial: A polynomial modulo n.
53+
"""
54+
Polynomial(A::Union{Tuple, AbstractArray}, n::Integer) = mod(Polynomial(A), n)
55+
56+
"""
57+
list_polys(n::Integer, m::Integer) -> Array
58+
59+
Lists all polynomials of degree less than to `n` under modulo `m`.
60+
61+
Parameters:
62+
- n::Integer: Highest degree of polynomial.
63+
- m::Integer: The modulus of the field.
64+
65+
Returns:
66+
- Array: An array of polynomials of degree less than n, under modulo m.
67+
"""
68+
function list_polys(n::Integer, m::Integer)
69+
return collect(Polynomial(collect(t)) for t in Iterators.product([0:(m-1) for i in 1:n]...))
70+
end
71+
72+
"""
73+
multiplication_table(degree::Integer, modulo::Integer) -> Matrix
74+
75+
Returns a table (matrix) of the multiplication of all combinations of polynomials for degree less than `degree`, under modulo `modulo`.
76+
77+
Parameters:
78+
- degree::Integer: Highest degree of polynomial.
79+
- modulo::Integer: The modulus of the field.
80+
81+
Returns:
82+
- Matrix: A multiplication table of all polynomials with degree less than n, under modulus.
83+
"""
84+
function multiplication_table(degree::Integer, modulo::Integer)
85+
polys = list_polys(degree, modulo)
86+
number_of_polys = length(polys)
87+
poly_matrix = Matrix{Polynomial}(undef, number_of_polys, number_of_polys)
88+
89+
for i in 1:number_of_polys, j in 1:number_of_polys
90+
poly_matrix[i,j] = mod(polys[i]*polys[j], modulo)
91+
end
92+
93+
return poly_matrix
94+
end
95+
96+
"""
97+
list_span(u̲::Vector, v̲::Vector, modulo::Integer) -> Array
98+
99+
Given two vectors `` and ``, prints all linear combinations of those vectors, modulo `modulo`. NB: this function can take in another vector, but is not yet generalised to more than three.
100+
101+
Parameters:
102+
- u̲::Vector: One vector.
103+
- v̲::Vector: Another vector.
104+
- modulo::Integer: The modulus of the field.
105+
106+
Returns:
107+
- Array: All vectors in the span of u̲ and v̲, under modulo.
108+
"""
109+
function list_span(u̲::Vector, v̲::Vector, modulo::Integer)::Array{Array{Int, 1}}
110+
span = Vector[]
111+
112+
for λ in 0:modulo-1, γ in 0:modulo-1
113+
w̲ = mod.(λ*u̲ + γ*v̲, modulo)
114+
if w̲ ∉ span
115+
push!(span, w̲)
116+
end
117+
end
118+
119+
return span
120+
end
121+
122+
function list_span(u̲::Vector, v̲::Vector, t̲::Vector, modulo::Integer)::Array{Array{Int, 1}}
123+
span = Vector[]
124+
125+
for λ in 0:modulo-1, γ in 0:modulo-1, α in 0:modulo-1
126+
w̲ = mod.(λ*u̲ + γ*v̲ + α*t̲, modulo)
127+
if w̲ ∉ span
128+
push!(span, w̲)
129+
end
130+
end
131+
132+
return span
133+
end
134+
135+
"""
136+
islinear(C::Vector, modulo::Integer; verbose::Bool=false) -> Bool
137+
138+
Determines whether a code `C` is a linear code (i.e., if it is closed under addition, scalar multiplication, and has the zero vector in it).
139+
140+
Parameters:
141+
- C::Vector: A code, typically consisting of multiple vectors or strings.
142+
- modulo::Integer: The modulus of the field under which you are working.
143+
- verbose::Bool (kwarg): print the point at which C fails, if it does.
144+
145+
Returns:
146+
- Bool: Whether or not the code `C` is linear (true or false).
147+
"""
148+
function islinear(C::Vector, modulo::Integer; verbose::Bool=false)
149+
allequal_length(C) || return false # not all codes are of the same length
150+
block_length = length(C[1])
151+
𝟎 = fill(0, block_length)
152+
153+
if 𝟎 ∉ C
154+
if verbose
155+
println("The zero vector 0̲ is not in C.\n")
156+
end
157+
return false # the zero vector is not in the code
158+
end
159+
160+
for c̲ ∈ C
161+
for λ in 0:modulo-1
162+
if mod.(λ*c̲, modulo) ∉ C
163+
if verbose
164+
println(λ, "", c̲, " = ", mod.(λ*c̲, modulo), " ∉ C\n")
165+
end
166+
return false # this code isn't closed under scalar multiplication
167+
end
168+
end
169+
170+
for c̲ ∈ C, c̲′ ∈ C
171+
if c̲ ≠ c̲′
172+
if mod.(c̲ + c̲′, modulo) ∉ C
173+
if verbose
174+
println(c̲, " + ", c̲′, " = ", mod.(c̲ + c̲′, modulo), " ∉ C\n")
175+
end
176+
return false # this code isn't closed under addition
177+
end
178+
end
179+
end
180+
end
181+
182+
if verbose
183+
println()
184+
end
185+
186+
return true
187+
end
188+
189+
"""
190+
isirreducible(f::AbstractPolynomial, modulo::Integer) -> Bool
191+
192+
Checks if a polynomial is irreducible.
193+
194+
Parameters:
195+
- f::Polynomial: The polynomial you need to check.
196+
- modulo::Integer: The modulus under which you are working.
197+
198+
Returns:
199+
- Bool: Whether or not the polynomial is irreducible (true or false).
200+
"""
201+
function isirreducible(f::AbstractPolynomial, modulo::Integer)
202+
deg = length(f.coeffs) - 1
203+
f = mod(f, deg)
204+
polys = list_polys(deg, modulo)
205+
206+
for a in polys, b in polys
207+
isequal(f, mod(a*b, modulo)) && return false
208+
end
209+
210+
return true
211+
end
11212

12213
"""
13214
normal_form!(M::AbstractArray, n::Integer) -> Matrix{Integer}

src/distance.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
"${BASH_SOURCE[0]}" "$@"
66
=#
77

8-
include(joinpath(dirname(@__FILE__), "utils.jl"))
9-
108
"""
119
hamming_distance(w₁, w₂) -> Integer
1210
@@ -62,7 +60,7 @@ Returns:
6260
- AbstractArray: The list of words in Σⁿ whose distance from w is less than or equal to e. Returns an array of array of symbols.
6361
"""
6462
hamming_ball(Σⁿ::AbstractArray{T}, w::AbstractArray, e::Integer) where T =
65-
__hamming_space(lessthanorequal, Σⁿ, w, e)
63+
__hamming_space(, Σⁿ, w, e)
6664

6765
"""
6866
hamming_sphere(Σⁿ::AbstractArray, w::AbstractArray, e::Integer) -> Vector{Vector}

0 commit comments

Comments
 (0)