Skip to content

Commit

Permalink
Merge pull request #51 from jakewilliami/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
jakewilliami authored Nov 3, 2020
2 parents 3140c5c + 35f94fe commit f90c834
Show file tree
Hide file tree
Showing 11 changed files with 495 additions and 352 deletions.
2 changes: 0 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ version = "0.2.0"

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

[compat]
Mods = "1.2.4"
Polynomials = "1.1.9"
Primes = "0.5"
julia = "1"
Expand Down
36 changes: 24 additions & 12 deletions src/CodingTheory.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,37 @@

module CodingTheory

using Primes: isprime, primes
using LinearAlgebra: I
using Polynomials

include("utils.jl")

# Abstract types
export FinitePolynomial, AbstractCode, Alphabet, Messages, no_round
export Alphabet, Messages, rate, sphere_covering_bound, sphere_packing_bound,

# RREF
export rref, rref!

# Messages, Distance, and Primes
export rate, sphere_covering_bound, sphere_packing_bound,
construct_ham_matrix, isperfect, ishammingperfect, isgolayperfect,
get_codewords_greedy, get_codewords_random, get_all_words,
get_codewords
export FinitePolynomial, list_polys, multiplication_table, list_span, islinear,
isirreducible
export hamming_distance, hamming_ball, code_distance, t_error_detecting,
t_error_correcting, find_error_detection_max, find_error_correction_max
export isprimepower

# Algebra
export FinitePolynomial, list_polys, multiplication_table, list_span, islinear, isirreducible, normal_form!, normal_form, equivalent_code!, equivalent_code, generator!, generator, parity_check, syndrome, isincode

# Levenshtein
export levenshtein, levenshtein!
export normal_form!, normal_form, equivalent_code!, equivalent_code, generator!,
generator, parity_check, syndrome, isincode
export rref, rref!

include(joinpath(dirname(@__FILE__), "abstract_types.jl"))
include(joinpath(dirname(@__FILE__), "messages.jl"))
include(joinpath(dirname(@__FILE__), "distance.jl"))
include(joinpath(dirname(@__FILE__), "fields.jl"))
include(joinpath(dirname(@__FILE__), "algebra.jl"))
include(joinpath(dirname(@__FILE__), "rref.jl"))
include("abstract_types.jl")
include("rref.jl")
include("messages.jl") # implicitly exports distance.jl and primes.jl
include("algebra.jl")
include("levenshtein.jl")

end # end module
209 changes: 205 additions & 4 deletions src/algebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,212 @@
exec julia --project="$(realpath $(dirname $(dirname $0)))" --color=yes --startup-file=no -e "include(popfirst!(ARGS))" \
"${BASH_SOURCE[0]}" "$@"
=#

include(joinpath(dirname(@__FILE__), "utils.jl"))
include(joinpath(dirname(@__FILE__), "rref.jl"))

using LinearAlgebra: I
"""
struct FinitePolynomial <: FiniteField
Has parameters `p`, which is an abstract polynomial, and `n` which is the modulus of the field under which the molynomial is defined.
---
FinitePolynomial(p::AbstractPolynomial, n::Integer)
A constructor method for `FinitePolynomial`. Takes in a polynomial `p` and a number `n`, and constructs a polynomial under modulo n.
"""
struct FinitePolynomial <: FiniteField
p::AbstractPolynomial
n::Integer

function FinitePolynomial(p::AbstractPolynomial, n::Integer)
p = Polynomial(mod.(p.coeffs, n))
new(p, n)
end
end

"""
mod(p::Polynomial, n::Integer) -> Polynomial
Uses the FinitePolynomial constructor to return a polynomial `p` under modulus `n`.
Parameters:
- p::Polynomial: The input polynomial.
- n::Integer: The modulus of the field.
Returns
- Polynomial: A polynomial modulo n.
"""
Base.mod(p::Polynomial, n::Integer) = FinitePolynomial(p, n).p

"""
Polynomial(A::Union{Tuple, AbstractArray}, n::Integer) -> Polynomial
Constructs a polynomial under modulo `n`.
Parameters:
- A::Union{Tuple, AbstractArrau}: The polynomial coefficients.
- n::Integer: The modulus of the field.
Returns
- Polynomial: A polynomial modulo n.
"""
Polynomial(A::Union{Tuple, AbstractArray}, n::Integer) = mod(Polynomial(A), n)

"""
list_polys(n::Integer, m::Integer) -> Array
Lists all polynomials of degree less than to `n` under modulo `m`.
Parameters:
- n::Integer: Highest degree of polynomial.
- m::Integer: The modulus of the field.
Returns:
- Array: An array of polynomials of degree less than n, under modulo m.
"""
function list_polys(n::Integer, m::Integer)
return collect(Polynomial(collect(t)) for t in Iterators.product([0:(m-1) for i in 1:n]...))
end

"""
multiplication_table(degree::Integer, modulo::Integer) -> Matrix
Returns a table (matrix) of the multiplication of all combinations of polynomials for degree less than `degree`, under modulo `modulo`.
Parameters:
- degree::Integer: Highest degree of polynomial.
- modulo::Integer: The modulus of the field.
Returns:
- Matrix: A multiplication table of all polynomials with degree less than n, under modulus.
"""
function multiplication_table(degree::Integer, modulo::Integer)
polys = list_polys(degree, modulo)
number_of_polys = length(polys)
poly_matrix = Matrix{Polynomial}(undef, number_of_polys, number_of_polys)

for i in 1:number_of_polys, j in 1:number_of_polys
poly_matrix[i,j] = mod(polys[i]*polys[j], modulo)
end

return poly_matrix
end

"""
list_span(u̲::Vector, v̲::Vector, modulo::Integer) -> Array
Given two vectors `u̲` and `v̲`, 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.
Parameters:
- u̲::Vector: One vector.
- v̲::Vector: Another vector.
- modulo::Integer: The modulus of the field.
Returns:
- Array: All vectors in the span of u̲ and v̲, under modulo.
"""
function list_span(u̲::Vector, v̲::Vector, modulo::Integer)::Array{Array{Int, 1}}
span = Vector[]

for λ in 0:modulo-1, γ in 0:modulo-1
= mod.(λ*+ γ*v̲, modulo)
if span
push!(span, w̲)
end
end

return span
end

function list_span(u̲::Vector, v̲::Vector, t̲::Vector, modulo::Integer)::Array{Array{Int, 1}}
span = Vector[]

for λ in 0:modulo-1, γ in 0:modulo-1, α in 0:modulo-1
= mod.(λ*+ γ*+ α*t̲, modulo)
if span
push!(span, w̲)
end
end

return span
end

"""
islinear(C::Vector, modulo::Integer; verbose::Bool=false) -> Bool
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).
Parameters:
- C::Vector: A code, typically consisting of multiple vectors or strings.
- modulo::Integer: The modulus of the field under which you are working.
- verbose::Bool (kwarg): print the point at which C fails, if it does.
Returns:
- Bool: Whether or not the code `C` is linear (true or false).
"""
function islinear(C::Vector, modulo::Integer; verbose::Bool=false)
allequal_length(C) || return false # not all codes are of the same length
block_length = length(C[1])
𝟎 = fill(0, block_length)

if 𝟎 C
if verbose
println("The zero vector 0̲ is not in C.\n")
end
return false # the zero vector is not in the code
end

for C
for λ in 0:modulo-1
if mod.(λ*c̲, modulo) C
if verbose
println(λ, "", c̲, " = ", mod.(λ*c̲, modulo), " ∉ C\n")
end
return false # this code isn't closed under scalar multiplication
end
end

for C, c̲′ C
if c̲′
if mod.(c̲ + c̲′, modulo) C
if verbose
println(c̲, " + ", c̲′, " = ", mod.(c̲ + c̲′, modulo), " ∉ C\n")
end
return false # this code isn't closed under addition
end
end
end
end

if verbose
println()
end

return true
end

"""
isirreducible(f::AbstractPolynomial, modulo::Integer) -> Bool
Checks if a polynomial is irreducible.
Parameters:
- f::Polynomial: The polynomial you need to check.
- modulo::Integer: The modulus under which you are working.
Returns:
- Bool: Whether or not the polynomial is irreducible (true or false).
"""
function isirreducible(f::AbstractPolynomial, modulo::Integer)
deg = length(f.coeffs) - 1
f = mod(f, deg)
polys = list_polys(deg, modulo)

for a in polys, b in polys
isequal(f, mod(a*b, modulo)) && return false
end

return true
end

"""
normal_form!(M::AbstractArray, n::Integer) -> Matrix{Integer}
Expand Down
4 changes: 1 addition & 3 deletions src/distance.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
"${BASH_SOURCE[0]}" "$@"
=#

include(joinpath(dirname(@__FILE__), "utils.jl"))

"""
hamming_distance(w₁, w₂) -> Integer
Expand Down Expand Up @@ -62,7 +60,7 @@ Returns:
- AbstractArray: The list of words in Σⁿ whose distance from w is less than or equal to e. Returns an array of array of symbols.
"""
hamming_ball(Σⁿ::AbstractArray{T}, w::AbstractArray, e::Integer) where T =
__hamming_space(lessthanorequal, Σⁿ, w, e)
__hamming_space(, Σⁿ, w, e)

"""
hamming_sphere(Σⁿ::AbstractArray, w::AbstractArray, e::Integer) -> Vector{Vector}
Expand Down
Loading

0 comments on commit f90c834

Please sign in to comment.