Quelle codecr.gi
Sprache: unbekannt
|
|
Spracherkennung für: .gi vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen] #############################################################################
##
#A codecr.gi GUAVA library Reinald Baart
#A Jasper Cramwinckel
#A Erik Roijackers
#A Eric Minkes
##
## This file contains functions for calculating with code covering radii
##
## changes 10-2004:
## 1. CalculateLinearCodeCoveringRadius changed to a slightly faster
## algorithm.
## 2. minor bug fix for ExhaustiveSearchCoveringRadius
## 2. minor bug fix for IncreaseCoveringRadiusLowerBound
##
########################################################################
##
#F CoveringRadius( <code> )
##
## Return the covering radius of <code>
## In case a special algorithm for this code exist, call
## it first.
##
## Not useful for large codes.
##
## That's why I changed it, see the manual for more details
## -- eric minkes.
##
## Calculation is done in this function, instead of in the method, so that
## users can override the redundancy restriction if desired. Note that
## this does not check the trivial cases checked in the method,
CalculateLinearCodeCoveringRadius := function( code )
local H, wts,CLs,i,rho;
if Redundancy(code) = 0 then
return 0;
else
#
#return Maximum( List( SyndromeTable( code ), i -> Weight( i[ 1 ] ) ) );
# (old version had line above in place of next 5)
H:=CheckMat(code);
CLs:=GuavaCosetLeadersMatFFE(H,LeftActingDomain(code));
wts:=List([1..Length(CLs)],i->WeightVecFFE(CLs[i]));
rho:=Maximum(wts);
return rho;
fi;
end;
InstallMethod(CoveringRadius, "method for linear code", true,
[IsLinearCode], 0,
function( code )
# call the special algorithm for this code, if it exists
if HasSpecialCoveringRadius( code ) then
code!.boundsCoveringRadius :=
SpecialCoveringRadius( code ) ( code );
fi;
if Length( BoundsCoveringRadius( code ) ) = 1 then
return code!.boundsCoveringRadius[ 1 ];
else
if Redundancy( code ) < 20 then
code!.boundsCoveringRadius :=
[ CalculateLinearCodeCoveringRadius( code ) ];
else
##LR - this sets CR to an interval
InfoCoveringRadius(
"CoveringRadius: warning, the covering radius of \n",
"this code cannot be computed straightforward. \n",
"Try to use IncreaseCoveringRadiusLowerBound( <code> ).\n",
"(see the manual for more details).\n",
"The covering radius of <code> lies in the interval:\n" );
return BoundsCoveringRadius( code );
fi;
fi;
return code!.boundsCoveringRadius[ 1 ];
end);
# For small codes in large spaces, this may take a very long time
InstallMethod(CoveringRadius, "method for unrestricted code", true,
[IsCode], 0,
function( code )
local Code, vector, d, curmax, n, q, one, count, size, t, i, j,
zero, large, gen;
if IsLinearCode( code ) then
return CoveringRadius( code );
elif Length(code!.boundsCoveringRadius) = 1 then
return code!.boundsCoveringRadius[1];
elif HasSpecialCoveringRadius( code ) then
code!.boundsCoveringRadius := SpecialCoveringRadius( code ) ( code );
else
q := Size(LeftActingDomain(code));
n := WordLength(code);
size := Size(code);
one := One(LeftActingDomain(code));
zero := Zero(LeftActingDomain(code));
Code := VectorCodeword(AsSSortedList(code));
vector := List([1..n], i-> zero);
large := one;
gen := Z(q);
curmax := n;
for t in Code do
d := DistanceVecFFE(t, vector);
if d < curmax then
curmax := d;
fi;
od;
for count in [2..q^n] do
t := n;
while vector[t] = large do
vector[t] := zero;
t := t - 1;
od;
if vector[t] = zero then
vector[t] := gen;
else
vector[t] := vector[t] * gen;
fi;
t := 1;
repeat
d := DistanceVecFFE(Code[t], vector);
t := t + 1;
until d <= curmax or t > size;
if d > curmax then
curmax := n;
for t in Code do
d := DistanceVecFFE(t, vector);
if d < curmax then
curmax := d;
fi;
od;
fi;
od;
code!.boundsCoveringRadius := [curmax];
fi;
return code!.boundsCoveringRadius[1];
end);
########################################################################
##
#F BoundsCoveringRadius( <code> )
##
## Find a lower and an upper bound for the covering radius of code.
##
InstallMethod(BoundsCoveringRadius, "method for unrestricted code", true,
[IsCode], 0,
function(code)
local bcr;
if HasCoveringRadius(code) then
code!.boundsCoveringRadius := [CoveringRadius(code)];
elif not IsBound(code!.boundsCoveringRadius) then
bcr := [GeneralLowerBoundCoveringRadius(code) ..
GeneralUpperBoundCoveringRadius(code)];
if Length(bcr) = 0 then
code!.boundsCoveringRadius := [0,WordLength(code)];
else
code!.boundsCoveringRadius := bcr;
fi;
fi;
return code!.boundsCoveringRadius;
end);
########################################################################
##
#F SetBoundsCoveringRadius( <code>, <cr> )
## SetBoundsCoveringRadius( <code>, <interval> )
##
## Enable the user to set the covering radius (or bounds) him/herself.
## Used to be SetCoveringRadius, before GAP4.
InstallOtherMethod(SetBoundsCoveringRadius,
"method for unrestricted code, integer",
true, [IsCode, IsInt], 0,
function(code, cr)
SetCoveringRadius(code, cr);
code!.boundsCoveringRadius := [cr];
end);
InstallMethod(SetBoundsCoveringRadius,
"method for unrestricted code, interval",
true, [IsCode, IsVector], 0,
function(code, cr)
code!.boundsCoveringRadius := IntersectionSet(
BoundsCoveringRadius( code ), cr );
if Length( code!.boundsCoveringRadius ) = 0 then
code!.boundsCoveringRadius := cr;
fi;
IsRange( code!.boundsCoveringRadius );
if Length(code!.boundsCoveringRadius) = 1 then
SetCoveringRadius(code, code!.boundsCoveringRadius[1]);
fi;
end);
########################################################################
##
#F IncreaseCoveringRadiusLowerBound(
## <code> [, <stopdistance> ] [, <startword> ] )
##
## small bug fix 10-2004
##
InstallMethod(IncreaseCoveringRadiusLowerBound,
"method for unrestricted code, stop distance, start vector",
true, [IsCode, IsInt, IsVector], 0,
function ( code, stopdistance, startvector )
local
n, # length of the code
k, # dimension of the code
genmat, # generator matrix of the code
field, # field of the code
q, # the size of field
fieldels, # elements of field
fieldzero, # zero element of field
nonzeroels, # non-zero elements of field
boundscr, # current bounds on the covering radius
lb, # current achieved lower bound
current, # the element of field^n that we are
# currently checking
cwcurrent, # current in Codeword form
distcurrenttocode, # the distance of current to the code
currentchanged, # did we change current during the loop ?
counterchanged, # number of changes we have made so far
countertotal, # number of iterations we have made so far
h, i, j, # indexes to make the first slice
slice, # the number of the current slice
numberofslices, # the elements of the code are handled in
# slices of 2^10 elements
slicedim, # the dimension of a slice
slicesize, # the size of a slice ( q^slicedim )
index, # to enumerate the codewords, the
# correct generator must be added
# index contains the generator number
satisfied, # are we satisfied with the results ?
words, # a list of codewords in the current slice
wordslist0, # a list of codewords with distance
# distcurrentocode + 0 from current
wordslist1, # a list of codewords with distance
# distcurrentocode + 1 from current
word, # a index for wordslist*
coord, # the coordinate where current will
# be changed
staychance, # chance that we stay at the same distance
downchance, # chance that we move closer to the code
bestdist, # best distance reached so far
bestword, # the corresponding word
newelement, # the new element for current[ coord ]
newdist; # the new distance of the changed current
# to the code
# extract some code parameters
n := WordLength( code );
if IsLinearCode( code ) then
k := Dimension( code );
fi;
field := LeftActingDomain( code );
q := Size( field );
# if we cannot compute the minimum distance of the code,
# this algorithm will not be of much help either.
# <lb> is a safe place to start searching
lb := IntFloor( MinimumDistance( code ) / 2 );
boundscr := BoundsCoveringRadius( code );
if lb > boundscr[ 1 ] then
code!.boundsCoveringRadius := Filtered( boundscr, n -> lb <= n );
IsRange( code!.boundsCoveringRadius );
boundscr := code!.boundsCoveringRadius;
fi;
if Length( boundscr ) = 1 then
# if there is nothing to compute,
# then just return the covering radius
return boundscr[ 1 ];
fi;
# starting vector
#
current := ShallowCopy(VectorCodeword( Codeword( startvector ) ));
# (old version has above in place of below)
# current := Codeword( startvector );
distcurrenttocode := MinimumDistance( code, Codeword( current) );
bestdist := distcurrenttocode;
bestword := ShallowCopy( current );
# initialise some parameters and useful variables
fieldels := AsSSortedList( field );
fieldzero := Zero(field);
nonzeroels := Difference( fieldels, [ fieldzero ] );
if IsLinearCode( code ) then
genmat := GeneratorMat( code );
# try to make the size of a group codewords to be about
# CRMemSize
slicedim := LogInt( CRMemSize, q );
numberofslices := Maximum( 1, q^( k-slicedim ) );
slicesize := q^slicedim;
fi;
satisfied := false;
currentchanged := true;
counterchanged := 0;
countertotal := 0;
staychance := 10; # maybe make arguments of these
downchance := 1;
# the words array contains all codewords generated by
# genmat[ 1 ] ... genmat[ slicedim ] ( or genmat[ k ], if
# slicedim > k )
if IsLinearCode( code ) then
words := [ NullVector( n, field ) ];
for i in [ 1 .. Minimum( slicedim, k ) ] do
for j in [ 1 .. q^( i-1 ) ] do
for h in [ 1 .. q-1 ] do
Add( words, words[ j ] + genmat[ i ] * nonzeroels[ h ] );
od;
od;
od;
else
# if the code is non-linear, the
# elements field is obligatory,
# so it fits in memory.
# no need for all the hassle as in the linear case,
# but the disadvantage is that we can't handle
# large non-linear codes.
# but then again, GUAVA can't handle these anyway.
words := VectorCodeword( AsSSortedList( code ) );
fi;
# start algorithm, stop when we are satisfied with the results
# (either we have a coset leader of weight <stopweigth>,
# or lb = ub)
while not satisfied do
countertotal := countertotal + 1;
if countertotal mod 1000 = 0 then
InfoCoveringRadius( "Number of runs: ",
countertotal,
" best distance so far: ", bestdist, "\n" );
fi;
if currentchanged then
# current word has changed, generate three lists of
# codewords that have distance distcurrenttocode,
# distcurrenttocode + 1 and distcurrenttocode + 2
cwcurrent := Codeword( current );
if distcurrenttocode > bestdist then
bestdist := distcurrenttocode;
bestword := ShallowCopy( current );
InfoCoveringRadius(
"New best distance: ", bestdist, "\n" );
fi;
wordslist0 := [];
wordslist1 := [];
if IsLinearCode( code ) then
for slice in [ 0 .. numberofslices-1 ] do
if slice > 0 then
i := k - slicedim - 1;
while EuclideanRemainder( slice, q^i ) <> 0 do
i := i - 1;
od;
index := slicedim + i + 1;
words := List( words, x -> x + genmat[ index ] );
fi;
Append( wordslist0,
Filtered( words, x ->
DistanceVecFFE( x, current )
= distcurrenttocode ) );
Append( wordslist1,
Filtered( words, x ->
DistanceVecFFE( x, current )
= distcurrenttocode + 1 ) );
od;
else
wordslist0 := Filtered( words, x->
DistanceVecFFE( x, current )
= distcurrenttocode );
wordslist1 := Filtered( words, x->
DistanceVecFFE( x, current )
= distcurrenttocode + 1 );
fi;
currentchanged := false;
counterchanged := counterchanged + 1;
if EuclideanRemainder( counterchanged, 100 ) = 0 then
InfoCoveringRadius( "Number of changes: ",
counterchanged, "\n" );
fi;
fi;
# pick a coordinate
# the algorithm will look what happens if we change this coordinate
coord := Random( [ 1 .. n ] );
# the possible new element for this coordinate
# is picked at random from the field elements
newelement := Random( Difference( fieldels,
[ current[ coord ] ] ) );
# check the new word against the codewords that are
# at distance distcurrenttocode + 0 from current
# the result can be:
# 1) the distance to all words in wordslist0 is
# one more than distcurrenttocode
# (this is the situation that we hope for)
# 2) there is at least one word in wordslist0 that
# has distance distcurrenttocode - 1 to the
# new current
# 3) if the field is not GF(2):
# there is a word in wordslist0 that stays
# at the same distance
newdist := distcurrenttocode + 1;
for word in wordslist0 do
if word[ coord ] <> current[ coord ] then
if word[ coord ] = newelement then
newdist := distcurrenttocode - 1;
else
newdist := distcurrenttocode;
fi;
fi;
od;
# only check against other words if the previous tests
# did not fail
if newdist > distcurrenttocode then
# check the new word against the codewords that are at
# distance distcurrenttocode + 1 from current
# again, two results are possible
# 1) all words in wordslist1 are at distance
# distcurrenttocode + 1 or + 2 (this is good)
# 2) there is a word in wordslist1 that now has
# distance distcurrenttocode to current
# this means we did not find an improvement
for word in wordslist1 do
if word[ coord ] = newelement then
newdist := distcurrenttocode;
fi;
od;
fi;
if newdist > distcurrenttocode then
# we found a new coset leader with larger weight
# now change current
current[ coord ] := newelement;
currentchanged := true;
distcurrenttocode := newdist;
# also check whether the covering radius lower bound
# can be increased, this is what the whole
# algorithm is about !
if distcurrenttocode > boundscr[ 1 ] then
# write directly to the code to make the change
# permanent, even if the user interrupted us
code!.boundsCoveringRadius :=
Filtered( boundscr, x -> x >= distcurrenttocode );
# make it a range together if possible
IsRange( code!.boundsCoveringRadius );
boundscr := code!.boundsCoveringRadius;
# maybe we have reached the upper bound
# then we can stop altogether !
if Length( boundscr ) = 1 then
satisfied := true;
fi;
fi;
elif newdist = distcurrenttocode then
# the change to the word did not change the
# distance to the code
if Random( [ 1 .. 100 ] ) <= staychance then
current[ coord ] := newelement;
currentchanged := true;
fi;
else
# make it a 1 in 100 chance to get closer anyway
# because we do not want to get stuck in a
# suboptimal coset
if Random( [ 1 .. 100 ] ) <= downchance then
current[ coord ] := newelement;
currentchanged := true;
distcurrenttocode := newdist;
fi;
fi;
# maybe the distance of current to the code
# is high enough for the user
# then we should stop
if distcurrenttocode = stopdistance then
satisfied := true;
fi;
od;
# return the new covering radius bounds, and a coset leader
# that has weight equal to the lower bound
return rec( boundsCoveringRadius := code!.boundsCoveringRadius,
cosetLeader := Codeword( current ) );
end);
InstallOtherMethod(IncreaseCoveringRadiusLowerBound,
"method for unrestricted code, starting vector",
true, [IsCode, IsVector], 0,
function( code, startvector )
# stopdistance = -1 is the default: never stop, unless the lower
# bound meets the upper bound
return IncreaseCoveringRadiusLowerBound( code, -1, startvector );
end);
InstallOtherMethod(IncreaseCoveringRadiusLowerBound,
"method for unrestricted code, stopdistance",
true, [IsCode, IsInt], 0,
function( code, stopdistance )
local lb, current, distcurrenttocode;
lb := IntFloor( MinimumDistance( code ) / 2 );
current := RandomVector( WordLength( code ),
Random( [0..WordLength( code )] ),
LeftActingDomain( code ));
distcurrenttocode := MinimumDistance( code, Codeword(current) );
while distcurrenttocode < lb do
current := RandomVector( WordLength( code ),
Random( [0..WordLength( code )] ),
LeftActingDomain( code ));
distcurrenttocode := MinimumDistance( code, Codeword(current) );
od;
return IncreaseCoveringRadiusLowerBound( code, -1, current);
end);
InstallOtherMethod(IncreaseCoveringRadiusLowerBound,
"method for unrestricted code", true, [IsCode], 0,
function( code )
local lb, current, distcurrenttocode;
lb := IntFloor( MinimumDistance( code ) / 2 );
current := RandomVector( WordLength( code ),
Random( [0..WordLength( code )] ),
LeftActingDomain( code ));
# distcurrenttocode := MinimumDistance( code, current );
# (old version had above line)
distcurrenttocode := MinimumDistance( code, Codeword(current) );
while distcurrenttocode < lb do
current := RandomVector( WordLength( code ),
Random( [0..WordLength( code )] ),
LeftActingDomain( code ));
distcurrenttocode := MinimumDistance( code, Codeword(current) );
od;
return IncreaseCoveringRadiusLowerBound( code, -1, current);
end);
########################################################################
##
#F ExhaustiveSearchCoveringRadius( <code> )
##
## Try to compute the covering radius. Don't compute all coset
## leaders, but increment the lower bound as soon as a coset leader
## is found.
##
InstallMethod(ExhaustiveSearchCoveringRadius,
"unrestricted code, boolean stopsoon",
true, [IsCode,IsBool], 0,
function(C, stopsoon)
if IsLinearCode(C) then
return ExhaustiveSearchCoveringRadius(C, stopsoon);
else
Error("ExhaustiveSearchCoveringRadius: <code> must be a linear code");
fi;
end);
InstallMethod(ExhaustiveSearchCoveringRadius, "linear code, boolean stopsoon",
true, [IsLinearCode, IsBool], 0,
function(code, stopsoon)
local k, n, i, j, lastone, zerofound, IsCosetLeader,
lb, we, wd, vc, cont, codewords,
leaderfound, allexamined, supp, elmsC, elms, len, one, zero,
boundscr;
IsCosetLeader := function( codewords, len, word, wt, one )
local i, check, cw, wcw, j;
check := true;
i := 1;
while i <= len and check do
cw := codewords[ i ] + word;
wcw := 0;
for j in [ 1 .. Length( cw ) ] do
if cw[ j ] = one then
wcw := wcw + 1;
fi;
od;
if wcw < wt then
check := false;
fi;
i := i + 1;
od;
return check;
end;
if Size( LeftActingDomain( code ) ) <> 2 then
Error( "CoveringRadiusSearch: <code> must be a binary code" );
fi;
boundscr := BoundsCoveringRadius( code );
if Length( boundscr ) = 1 then
return boundscr[ 1 ];
fi;
lb := boundscr[ 1 ];
n := WordLength( code );
wd := WeightDistribution( code );
elms := [];
for i in [ 0 .. n ] do
if wd[ i + 1 ] > 0 then
elms[ i + 1 ] := ShallowCopy(AsSSortedList(
ConstantWeightSubcode( code, i ) ));
fi;
od;
for i in [ 1 .. n+1 ] do
if IsBound( elms[ i ] ) then
for j in [ 1 .. Length( elms[ i ] ) ] do
elms[ i ][ j ] := VectorCodeword( elms[ i ][ j ] );
#mutable error on:
# C:=RandomLinearCode(10,5,GF(2));
# ExhaustiveSearchCoveringRadius(C,true);
od;
fi;
od;
# try to find a coset leader with weight > lb
# if found, increase lb
one := One(GF(2));
zero := Zero(GF(2));
cont := true;
while cont do
k := BoundsCoveringRadius(code)[ 1 ] + 1;
InfoCoveringRadius( "Trying ", k, " ...\n" );
codewords := [ NullVector(n, GF(2) ) ];
for i in [ 1 .. Minimum( n, 2 * k - 1) ] do
if wd[ i + 1 ] <> 0 then
Append( codewords, elms[ i + 1 ] );
fi;
od;
len := Length( codewords );
vc := NullVector( n, GF(2) );
for i in [ 1 .. k ] do
vc[ i ] := one;
od;
lastone := k;
allexamined := false;
leaderfound := false;
while not leaderfound and not allexamined do
if not IsCosetLeader( codewords, len, vc, k, one ) then
if lastone = n then
zerofound := false;
i := lastone - 1;
while i > n - k and vc[ i ] = one do
i := i - 1;
od;
if i = n - k then
allexamined := true;
else
j := i;
i := i + 1;
while vc[ j ] = zero do
j := j - 1;
od;
vc[ j ] := zero;
vc[ j + 1 ] := one;
j := j + 2;
if i <> j then
while i <= lastone do
vc[ j ] := one;
vc[ i ] := zero;
i := i + 1;
j := j + 1;
od;
lastone := j - 1;
else
lastone := n;
fi;
fi;
else
vc[ lastone ] := zero;
lastone := lastone + 1;
vc[ lastone ] := one;
fi;
else
leaderfound := true;
fi;
od;
if leaderfound then
code!.boundsCoveringRadius :=
Filtered( code!.boundsCoveringRadius, x -> x >= k );
if stopsoon then
cont := false;
fi;
else
code!.boundsCoveringRadius :=
[ code!.boundsCoveringRadius[ 1 ] ];
cont := false;
fi;
od;
IsRange( code!.boundsCoveringRadius );
return( code!.boundsCoveringRadius );
end);
InstallOtherMethod(ExhaustiveSearchCoveringRadius, "unrestricted code", true,
[IsCode], 0,
function(C)
return ExhaustiveSearchCoveringRadius(C, true);
end);
########################################################################
##
#F CoveringRadiusLowerBoundTable
##
CoveringRadiusLowerBoundTable := [
[ 3, 2, , , , , , , , , # n = 13
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 3, 3, , , , , , , , , # n = 14
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 4, 3, 3, , , , , , , , # n = 15
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 4, 4, 3, 3, , , , , , , # n = 16
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 4, 4, 3, 3, 3, , , , , , # n = 17
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 5, 4, 4, 3, 3, 3, , , , , # n = 18
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 5, 4, 4, 4, 3, 3, 2, , , , # n = 19
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 6, 5, 4, 4, 4, 3, 3, 2, , , # n = 20
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 6, 5, 5, 4, 4, 3, 3, 3, , , # n = 21
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 6, 6, 5, 5, 4, 4, 3, 3, 3, , # n = 22
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 7, 6, 5, 5, 4, 4, 3, 3, 3, 3, # n = 23
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 7, 6, 6, 5, 5, 4, 4, 3, 3, 3, # n = 24
3, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, # n = 25
3, 2, , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, # n = 26
3, 3, 2, , , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 8, 8, 7, 6, 6, 5, 5, 4, 4, 4, # n = 27
3, 3, 3, 2, , , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 9, 8, 7, 7, 6, 6, 5, 5, 4, 4, # n = 28
4, 3, 3, 3, 2, , , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, # n = 29
4, 4, 3, 3, 3, 2, , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 9, 9, 8, 7, 7, 6, 6, 5, 5, 5, # n = 30
4, 4, 4, 3, 3, 3, , , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 10, 9, 8, 8, 7, 7, 6, 6, 5, 5, # n = 31
5, 4, 4, 3, 3, 3, 3, , , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, # n = 32
5, 4, 4, 4, 3, 3, 3, 3, , ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 11, 10, 9, 9, 8, 7, 7, 6, 6, 6, # n = 33
5, 5, 4, 4, 4, 3, 3, 3, 3, ,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 11, 10, 10, 9, 8, 8, 7, 7, 6, 6, # n = 34
5, 5, 5, 4, 4, 4, 3, 3, 3, 2,
, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 11, 11, 10, 9, 9, 8, 8, 7, 7, 6, # n = 35
6, 5, 5, 5, 4, 4, 4, 3, 3, 3,
2, , , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 12, 11, 10, 10, 9, 9, 8, 8, 7, 7, # n = 36
6, 6, 5, 5, 5, 4, 4, 4, 3, 3,
3, 2, , , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 12, 11, 11, 10, 9, 9, 8, 8, 7, 7, # n = 37
6, 6, 6, 5, 5, 4, 4, 4, 4, 3,
3, 3, 2, , , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 13, 12, 11, 10, 10, 9, 9, 8, 8, 7, # n = 38
7, 6, 6, 6, 5, 5, 4, 4, 4, 3,
3, 3, 3, 2, , , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 13, 12, 12, 11, 10, 10, 9, 9, 8, 8, # n = 39
7, 7, 6, 6, 5, 5, 5, 4, 4, 4,
3, 3, 3, 3, 2, , , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 14, 13, 12, 11, 11, 10, 9, 9, 8, 8, # n = 40
7, 7, 7, 6, 6, 5, 5, 5, 4, 4,
4, 3, 3, 3, 3, 2, , , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 14, 13, 12, 12, 11, 10, 10, 9, 9, 8, # n = 41
8, 7, 7, 6, 6, 6, 5, 5, 5, 4,
4, 4, 3, 3, 3, 3, 2, , , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 14, 14, 13, 12, 11, 11, 10, 10, 9, 9, # n = 42
8, 8, 7, 7, 6, 6, 6, 5, 5, 5,
4, 4, 4, 3, 3, 3, 3, 2, , ,
, , , , , , , , , ,
, , , , , , , , ],
[ 15, 14, 13, 12, 12, 11, 10, 10, 9, 9, # n = 43
8, 8, 7, 7, 7, 6, 6, 6, 5, 5,
5, 4, 4, 4, 3, 3, 3, 3, 2, ,
, , , , , , , , , ,
, , , , , , , , ],
[ 15, 14, 14, 13, 12, 11, 11, 10, 10, 9, # n = 44
9, 8, 8, 7, 7, 7, 6, 6, 5, 5,
5, 4, 4, 4, 4, 3, 3, 3, 3, ,
, , , , , , , , , ,
, , , , , , , , ],
[ 16, 15, 14, 13, 12, 12, 11, 11, 10, 10, # n = 45
9, 9, 8, 8, 7, 7, 7, 6, 6, 5,
5, 5, 4, 4, 4, 4, 3, 3, 3, 3,
, , , , , , , , , ,
, , , , , , , , ],
[ 16, 15, 14, 14, 13, 12, 12, 11, 11, 10, # n = 46
9, 9, 8, 8, 8, 7, 7, 6, 6, 6,
5, 5, 5, 4, 4, 4, 4, 3, 3, 3,
3, , , , , , , , , ,
, , , , , , , , ],
[ 16, 16, 15, 14, 13, 13, 12, 11, 11, 10, # n = 47
10, 9, 9, 8, 8, 8, 7, 7, 6, 6,
6, 5, 5, 5, 4, 4, 4, 3, 3, 3,
3, 2, , , , , , , , ,
, , , , , , , , ],
[ 17, 16, 15, 14, 14, 13, 12, 12, 11, 11, # n = 48
10, 10, 9, 9, 8, 8, 7, 7, 7, 6,
6, 6, 5, 5, 5, 4, 4, 4, 3, 3,
3, 3, 2, , , , , , , ,
, , , , , , , , ],
[ 17, 16, 16, 15, 14, 13, 13, 12, 12, 11, # n = 49
11, 10, 9, 9, 9, 8, 8, 7, 7, 7,
6, 6, 6, 5, 5, 5, 4, 4, 4, 3,
3, 3, 3, 2, , , , , , ,
, , , , , , , , ],
[ 18, 17, 16, 15, 14, 14, 13, 13, 12, 11, # n = 50
11, 10, 10, 9, 9, 8, 8, 8, 7, 7,
7, 6, 6, 6, 5, 5, 5, 4, 4, 4,
3, 3, 3, 3, 2, , , , , ,
, , , , , , , , ],
[ 18, 17, 16, 16, 15, 14, 13, 13, 12, 12, # n = 51
11, 11, 10, 10, 9, 9, 8, 8, 8, 7,
7, 6, 6, 6, 5, 5, 5, 5, 4, 4,
4, 3, 3, 3, 3, 2, , , , ,
, , , , , , , , ],
[ 19, 18, 17, 16, 15, 15, 14, 13, 13, 12, # n = 52
12, 11, 11, 10, 10, 9, 9, 8, 8, 8,
7, 7, 6, 6, 6, 5, 5, 5, 5, 4,
4, 4, 3, 3, 3, 3, 2, , , ,
, , , , , , , , ],
[ 19, 18, 17, 16, 16, 15, 14, 14, 13, 12, # n = 53
12, 11, 11, 10, 10, 9, 9, 9, 8, 8,
7, 7, 7, 6, 6, 6, 5, 5, 5, 4,
4, 4, 4, 3, 3, 3, 3, 2, , ,
, , , , , , , , ],
[ 19, 18, 18, 17, 16, 15, 15, 14, 13, 13, # n = 54
12, 12, 11, 11, 10, 10, 9, 9, 9, 8,
8, 7, 7, 7, 6, 6, 6, 5, 5, 5,
4, 4, 4, 4, 3, 3, 3, 3, 2, ,
, , , , , , , , ],
[ 20, 19, 18, 17, 16, 16, 15, 14, 14, 13, # n = 55
13, 12, 12, 11, 11, 10, 10, 9, 9, 8,
8, 8, 7, 7, 7, 6, 6, 6, 5, 5,
5, 4, 4, 4, 4, 3, 3, 3, 3, 2,
, , , , , , , , ],
[ 20, 19, 18, 18, 17, 16, 15, 15, 14, 14, # n = 56
13, 12, 12, 11, 11, 10, 10, 10, 9, 9,
8, 8, 8, 7, 7, 7, 6, 6, 6, 5,
5, 5, 4, 4, 4, 4, 3, 3, 3, 3,
2, , , , , , , , ],
[ 21, 20, 19, 18, 17, 16, 16, 15, 14, 14, # n = 57
13, 13, 12, 12, 11, 11, 10, 10, 9, 9,
9, 8, 8, 7, 7, 7, 6, 6, 6, 5,
5, 5, 5, 4, 4, 4, 4, 3, 3, 3,
3, 2, , , , , , , ],
[ 21, 20, 19, 18, 18, 17, 16, 15, 15, 14, # n = 58
14, 13, 13, 12, 12, 11, 11, 10, 10, 9,
9, 9, 8, 8, 7, 7, 7, 6, 6, 6,
5, 5, 5, 5, 4, 4, 4, 4, 3, 3,
3, 3, 2, , , , , , ],
[ 22, 21, 20, 19, 18, 17, 17, 16, 15, 15, # n = 59
14, 14, 13, 12, 12, 11, 11, 11, 10, 10,
9, 9, 8, 8, 8, 7, 7, 7, 6, 6,
6, 5, 5, 5, 5, 4, 4, 4, 4, 3,
3, 3, 3, 2, , , , , ],
[ 22, 21, 20, 19, 18, 18, 17, 16, 16, 15, # n = 60
14, 14, 13, 13, 12, 12, 11, 11, 10, 10,
10, 9, 9, 8, 8, 8, 7, 7, 7, 6,
6, 6, 5, 5, 5, 5, 4, 4, 4, 3,
3, 3, 3, 3, 2, , , , ],
[ 23, 21, 20, 20, 19, 18, 17, 17, 16, 15, # n = 61
15, 14, 14, 13, 13, 12, 12, 11, 11, 10,
10, 10, 9, 9, 8, 8, 8, 7, 7, 7,
6, 6, 6, 5, 5, 5, 5, 4, 4, 4,
3, 3, 3, 3, 3, 2, , , ],
[ 23, 22, 21, 20, 19, 18, 18, 17, 16, 16, # n = 62
15, 15, 14, 14, 13, 12, 12, 12, 11, 11,
10, 10, 9, 9, 9, 8, 8, 8, 7, 7,
7, 6, 6, 6, 5, 5, 5, 4, 4, 4,
4, 3, 3, 3, 3, 3, 2, , ],
[ 23, 22, 21, 20, 20, 19, 18, 17, 17, 16, # n = 63
16, 15, 14, 14, 13, 13, 12, 12, 11, 11,
11, 10, 10, 9, 9, 9, 8, 8, 7, 7,
7, 6, 6, 6, 6, 5, 5, 5, 4, 4,
4, 4, 3, 3, 3, 3, 3, 2, ],
[ 24, 23, 22, 21, 20, 19, 18, 18, 17, 16, # n = 64
16, 15, 15, 14, 14, 13, 13, 12, 12, 11,
11, 10, 10, 10, 9, 9, 8, 8, 8, 7,
7, 7, 6, 6, 6, 6, 5, 5, 5, 4,
4, 4, 4, 3, 3, 3, 3, 3, 2 ]
];
########################################################################
##
#F GeneralLowerBoundCoveringRadius( <n>, <size> [, <F> ] )
## GeneralLowerBoundCoveringRadius( <code> )
##
InstallMethod(GeneralLowerBoundCoveringRadius, "unrestricted code", true,
[IsCode], 0,
function(code)
local n, size, field, listofbounds, max;
if IsLinearCode(code) then
return GeneralLowerBoundCoveringRadius(code);
fi;
n := WordLength( code );
size := Size( code );
field := LeftActingDomain( code );
listofbounds := [
LowerBoundCoveringRadiusSphereCovering( n, size, field, false ),
];
if field = GF(2) then
Append( listofbounds, [
LowerBoundCoveringRadiusVanWee1( n, size, field, false ),
LowerBoundCoveringRadiusVanWee2( n, size, false ),
LowerBoundCoveringRadiusCountingExcess( n, size, false )
] );
if n <= 200 then
Append( listofbounds, [
LowerBoundCoveringRadiusEmbedded1( n, size, field, false ),
LowerBoundCoveringRadiusEmbedded2( n, size, field, false )
] );
fi;
fi;
max := Maximum( listofbounds );
if IsBound(code!.boundsCoveringRadius) then
return Maximum ([ max, code!.boundsCoveringRadius[1] ]);
else
return max;
fi;
end);
InstallMethod(GeneralLowerBoundCoveringRadius, "linear code", true,
[IsLinearCode], 0,
function (code)
local n, size, field, k, listofbounds, return_value;
n := WordLength(code);
size := Size(code);
field := LeftActingDomain(code);
listofbounds := [
LowerBoundCoveringRadiusSphereCovering( n, size, field, false ),
];
return_value := -99; # Allows to check whether next set of if
# statements actually assign a value
if field = GF(2) then
k := Dimension( code );
# small codimensions (n-k)
if k = n then
return_value := 0;
elif k = n - 1 then
return_value := 1;
elif k = n - 2 then
return_value := 1;
elif k = n - 3 and n >= 7 then
return_value := 1;
elif k = n - 4 and n >= 5 then
if n >= 15 then
return_value := 1;
else
return_value := 2;
fi;
elif k = n - 5 and n >= 9 then
if n >= 31 then
return_value := 1;
else
return_value := 2;
fi;
elif k = n - 6 then
if n >= 63 then
return_value := 1;
elif n >= 14 then
return_value := 2;
elif n = 12 then
return_value := 3;
fi;
elif k = n - 7 and n >= 21 and n <= 64 then
return_value := 2;
elif k = n - 8 and n >= 30 and n <= 64 then
return_value := 2;
elif k = n - 9 and n >= 44 and n <= 64 then
return_value := 2;
elif k = 1 then
return_value := IntFloor( n/2 );
elif k = 2 then
return_value := IntFloor( (n-1)/2 );
elif k = 3 then
return_value := IntFloor( (n-2)/2 );
elif k = 4 then
return_value := IntFloor( (n-4)/2 );
elif k = 5 then
return_value := IntFloor( (n-5)/2 );
fi;
# use the table of Cohen, Litsyn, Lobstein and Mattson
if return_value < 0 and n >= 13 and n <= 64 and k>=6 and k<= 64 then
if IsBound(
CoveringRadiusLowerBoundTable[ n - 12 ][ k - 5 ] ) then
return_value :=
CoveringRadiusLowerBoundTable[ n - 12 ][ k - 5 ];
fi;
fi;
if return_value < 0 then
# not in the table. use the bounds
listofbounds := [
LowerBoundCoveringRadiusSphereCovering( n, size, field, false ),
LowerBoundCoveringRadiusVanWee1( n, size, field, false ),
LowerBoundCoveringRadiusVanWee2( n, size, false ),
LowerBoundCoveringRadiusCountingExcess( n, size, false )
];
if n <= 200 then
Append( listofbounds, [
LowerBoundCoveringRadiusEmbedded1( n, size, field, false ),
LowerBoundCoveringRadiusEmbedded2( n, size, field, false ),
] );
fi;
return_value := Maximum( listofbounds );
fi;
else # field is not GF(2)
listofbounds := [
LowerBoundCoveringRadiusSphereCovering( n, size, field, false ),
];
return_value := Maximum( listofbounds );
fi;
if IsBound(code!.boundsCoveringRadius) then
return Maximum([return_value, code!.boundsCoveringRadius[1]]);
else
return return_value;
fi;
end);
InstallOtherMethod(GeneralLowerBoundCoveringRadius, "n, k, field", true,
[IsInt, IsInt, IsField], 0,
function(n, size, field)
local listofbounds;
if n < 1 or size < 1 then
Error("GeneralLBCR: <n> and <size> must be positive");
fi;
listofbounds := [
LowerBoundCoveringRadiusSphereCovering( n, size, field, false ),
LowerBoundCoveringRadiusVanWee1( n, size, field, false ),
LowerBoundCoveringRadiusEmbedded1( n, size, field, false ),
LowerBoundCoveringRadiusEmbedded2( n, size, field, false )
];
if field = GF(2) then
Append( listofbounds, [
LowerBoundCoveringRadiusVanWee2( n, size, false ),
LowerBoundCoveringRadiusCountingExcess( n, size, false )
] );
fi;
return Maximum( listofbounds );
end);
InstallOtherMethod(GeneralLowerBoundCoveringRadius, "n, size", true,
[IsInt, IsInt], 0,
function(n, size)
return GeneralLowerBoundCoveringRadius(n, size, GF(2));
end);
########################################################################
##
#F LowerBoundCoveringRadiusSphereCovering( <n>, <r> [, <F> ] [, true ] )
##
InstallMethod(LowerBoundCoveringRadiusSphereCovering,
"n, r, fieldsize, usage",
true, [IsInt, IsInt, IsInt, IsBool], 0,
function(n, r, q, usage)
local m, lb, ub, tmpcr, tmpsize, t;
if n <= 0 then
Error("LBCRSphereCovering: <n> must be positive");
fi;
if usage = false then
# last argument is false, try to find a lower bound for
# the covering radius, given length and size of the code, and field
m := r;
if m <= 0 or m > q^n then
Error( "LBCRSphereCovering: <m> must be > 0 and <= q^n" );
fi;
# everything is set up. now compute the bound
lb := 0;
ub := n;
while lb <> ub do
tmpcr := IntFloor( ( lb + ub ) / 2 );
tmpsize := IntCeiling( q^n / SphereContent( n, tmpcr, q ) );
if tmpsize > m then
lb := tmpcr + 1;
else
ub := tmpcr;
fi;
od;
return ub;
else
# the last argument is not false
# now it is assumed that the first argument is the length
# of the code and the second argument is the covering radius
# of the code. a lower bound for the minimal size of the
# code is returned
t := r;
if t < 0 or t > n then
Error( "LBCRSphereCovering: <t> must be >= 0 and <= <n>" );
fi;
return IntCeiling( q^n / SphereContent( n, t, q ) );
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusSphereCovering,
"n, r, field, usage", true,
[IsInt, IsInt, IsField, IsBool], 0,
function(n, r, F, usage)
if not IsFinite(F) then
Error("LBCRSphereCovering: <F> must be a finite field");
else
return LowerBoundCoveringRadiusSphereCovering(n, r, Size(F), usage);
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusSphereCovering,
"n, r, fieldsize", true, [IsInt, IsInt, IsInt], 0,
function(n, r, q)
return LowerBoundCoveringRadiusSphereCovering(n, r, q, true);
end);
InstallOtherMethod(LowerBoundCoveringRadiusSphereCovering,
"n, r, field", true, [IsInt, IsInt, IsField], 0,
function(n, r, F)
if not IsFinite(F) then
Error("LBCRSphereCovering: <F> must be a finite field");
else
return LowerBoundCoveringRadiusSphereCovering(n, r, Size(F), true);
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusSphereCovering,
"n, r, usage", true, [IsInt, IsInt, IsBool], 0,
function(n, r, usage)
return LowerBoundCoveringRadiusSphereCovering(n, r, 2, usage);
end);
InstallOtherMethod(LowerBoundCoveringRadiusSphereCovering, "n, r", true,
[IsInt, IsInt], 0,
function(n, r)
return LowerBoundCoveringRadiusSphereCovering(n, r, 2, true);
end);
########################################################################
##
#F LowerBoundCoveringRadiusVanWee1( ... )
##
InstallMethod(LowerBoundCoveringRadiusVanWee1,
"n, r, fieldsize, usage", true, [IsInt, IsInt, IsInt, IsBool], 0,
function(n, r, q, usage)
local m, lb, ub, tmpcr, tmpsize, t, tmp;
if n <= 0 then
Error("LBCRVanWee1: <n> must be positive");
fi;
if usage = false then
# last argument is false, try to find a lower bound for
# the covering radius, given length and size of the code, and field
m := r;
if m <= 0 or m > q^n then
Error( "LBCRVanWee1: <m> must be > 0 and <= q^n" );
fi;
# everything is set up. now compute the bound
lb := 0;
ub := n;
while lb <> ub do
tmpcr := IntFloor( (ub+lb) / 2 );
tmpsize := LowerBoundCoveringRadiusVanWee1( n, tmpcr, q );
if tmpsize > m then
lb := tmpcr + 1;
else
ub := tmpcr;
fi;
od;
return ub;
else
# the last argument is not false
# now it is assumed that the first argument is the length
# of the code and the second argument is the covering radius
# of the code. a lower bound for the minimal size of the
# code is returned
t := r;
if t < 0 or t > n then
Error( "LBCRVanWee1: <t> must be >= 0 and <= <n>" );
fi;
if t = n then
return 1;
fi;
tmp := (Binomial(n,t))/(IntCeiling((n-t)/(t+1)));
tmp := tmp * (IntCeiling((t+1)/(t+1)) - (t+1)/(t+1));
tmp := SphereContent( n, t, q ) - tmp;
return IntCeiling( q^n / tmp );
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusVanWee1,
"n, r, field, usage", true, [IsInt, IsInt, IsField, IsBool], 0,
function(n, r, F, usage)
if not IsFinite(F) then
Error("LBCRVanWee1: <F> must be a finite field");
else
return LowerBoundCoveringRadiusVanWee1(n, r, Size(F), usage);
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusVanWee1, "n,r,fieldsize",
true, [IsInt, IsInt, IsInt], 0,
function(n, r, q)
return LowerBoundCoveringRadiusVanWee1(n, r, q, true);
end);
InstallOtherMethod(LowerBoundCoveringRadiusVanWee1, "n, r, field",
true, [IsInt, IsInt, IsField], 0,
function(n, r, F)
if not IsFinite(F) then
Error("LBCRVanWee1: <F> must be a finite field");
else
return LowerBoundCoveringRadiusVanWee1(n, r, Size(F), true);
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusVanWee1,
"n, r, usage", true, [IsInt, IsInt, IsBool], 0,
function(n, r, usage)
return LowerBoundCoveringRadiusVanWee1(n, r, 2, usage);
end);
InstallOtherMethod(LowerBoundCoveringRadiusVanWee1,
"n, r", true, [IsInt, IsInt], 0,
function(n, r)
return LowerBoundCoveringRadiusVanWee1(n, r, 2, true);
end);
#############################################################################
##
#F LowerBoundCoveringRadiusVanWee2( <n>, <r> ) Counting Excess bound
##
InstallMethod(LowerBoundCoveringRadiusVanWee2,
"code length, code size or covering radius, usage",
true, [IsInt, IsInt, IsBool], 0,
function(n, r, usage)
local m, lb, ub, tmpcr, eps, tmpsize, t, tmpb1, tmpb2;
if n<=0 then
Error( "LBCRVanWee2: <n> must be positive" );
fi;
if usage = false then
m := r;
if m <= 0 or m > 2^n then
Error( "LBCRVanWee2: <m> must be > 0 and <= 2^n" );
fi;
lb := 0;
ub := IntFloor( n/2 );
while lb <> ub do
tmpcr := IntFloor( ( ub + lb ) / 2 );
tmpb1 := (tmpcr+2)*(tmpcr+1)/2; # Binomial(tmpcr+2,2)
tmpb2 := (n-tmpcr+1)*(n-tmpcr)/2; # Binomial(n-tmpcr+1,2)
eps := tmpb1 * IntCeiling( tmpb2/tmpb1 ) - tmpb2;
tmpsize := 2^n * ( SphereContent( n, 2, 2 ) + eps
- 1/2*( tmpcr + 2 )*( tmpcr - 1 ) );
tmpsize := tmpsize / ( SphereContent( n, tmpcr, 2 ) *
( SphereContent( n, 2, 2 )
- 1/2*( tmpcr + 2 )*( tmpcr - 1 ) )
+ eps * SphereContent( n, tmpcr - 2 ) );
if tmpsize > m then
lb := tmpcr + 1;
else
ub := tmpcr;
fi;
od;
return ub;
else
t := r;
if t < 0 or t > n then
Error( "LBCRVanWee2: <t> must be >= 0 and <= <n>" );
fi;
if 2 * t > n then
return 0;
fi;
tmpb1 := (t+2)*(t+1)/2;
tmpb2 := (n-t+1)*(n-t)/2;
eps := tmpb1 * IntCeiling( tmpb2/tmpb1 ) - tmpb2;
tmpsize := 2^n * ( SphereContent( n, 2, 2 ) + eps
- 1/2*( t + 2 )*( t - 1 ) );
tmpsize := tmpsize / ( SphereContent( n, t, 2 )
* ( SphereContent( n, 2, 2 )
- 1/2*( t + 2 )*( t - 1 ) )
+ eps * SphereContent( n, t-2, 2 ) );
return IntCeiling(tmpsize);
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusVanWee2,
"code length, code covering radius",
true, [IsInt, IsInt], 0,
function(n, r)
return LowerBoundCoveringRadiusVanWee2(n, r, true);
end);
#############################################################################
##
#F LowerBoundCoveringRadiusCountingExcess( <n>, <r> )
##
InstallMethod(LowerBoundCoveringRadiusCountingExcess,
"code length, code size or covering radius, usage", true,
[IsInt, IsInt, IsBool], 0,
function(n, r, usage)
local m, lb, ub, tmpcr, tmpsize, t, rho, eps;
if n<=0 then
Error( "LBCRCountingExcess: <n> must be positive" );
fi;
if usage = false then
m := r;
if m<=0 or m > 2^n then
Error( "LBCRCountingExcess: <m> must be > 0 and <= 2^n" );
fi;
lb := 0;
ub := IntFloor( ( n-1 ) / 2 );
while lb <> ub do
tmpcr := IntFloor( ( ub + lb ) / 2 );
tmpsize := LowerBoundCoveringRadiusCountingExcess(
n, tmpcr, true );
if tmpsize > m then
lb := tmpcr + 1;
else
ub := tmpcr;
fi;
od;
return ub;
else
t := r;
if t < 0 or t > n then
Error( "LBCRCountingExcess: <t> must be >=0 and <= <n>" );
fi;
if t < 2 or 2 * t + 1 > n then
return 0;
fi;
if t = 2 then
rho := n - 3 + 2/n;
else
rho := n - t - 1;
fi;
eps := ( t+1 ) * IntCeiling( ( n+1 ) / ( t+1 ) ) - ( n+1 );
if eps > t then
return 0;
fi;
tmpsize := 2^n * ( rho + eps );
tmpsize := tmpsize / ( rho * SphereContent( n, t )
+ eps * SphereContent( n, t-1 ) );
return IntCeiling( tmpsize );
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusCountingExcess,
"code length, code covering radius", true,
[IsInt, IsInt], 0,
function(n, r)
return LowerBoundCoveringRadiusCountingExcess(n, r, true);
end);
########################################################################
##
#F LowerBoundCoveringRadiusEmbedded1( <n>, <r> [, <givesize> ] )
##
InstallMethod(LowerBoundCoveringRadiusEmbedded1,
"code length, code size or covering radius, field size, usage",
true, [IsInt, IsInt, IsInt, IsBool], 0,
function(n, r, q, usage)
local m, lb, ub, tmpcr, tmpsize, t, upperb;
if n <= 0 then
Error("LBCREmbedded1: <n> must be positive");
fi;
if usage = false then
# last argument is false, try to find a lower bound for
# the covering radius, given length and size of the code, and field
m := r;
if m <= 0 or m > q^n then
Error( "LBCREmbedded1: <m> must be > 0 and <= q^n" );
fi;
# everything is set up. now compute the bound
if m = q^n then
return 0;
fi;
if n = 1 then
return 0;
fi;
lb := 1;
ub := n;
while lb <> ub do
tmpcr := IntFloor( (ub+lb) / 2 );
tmpsize := SphereContent( n, tmpcr, q )
- Binomial( 2*tmpcr, tmpcr );
if tmpsize = 0 then
lb := lb + 1;
elif tmpsize < 0 then
ub := tmpcr;
else
if 2*tmpcr+1 > n then
upperb := 1;
else
upperb := UpperBound( n, 2*tmpcr+1, q );
fi;
tmpsize := IntCeiling( ( q^n - upperb
* Binomial( 2 * tmpcr, tmpcr ) )
/ tmpsize );
if tmpsize > m then
lb := tmpcr + 1;
else
ub := tmpcr;
fi;
fi;
od;
return ub;
else
# the last argument is not false
# now it is assumed that the first argument is the length
# of the code and the second argument is the covering radius
# of the code. a lower bound for the minimal size of the
# code is returned
t := r;
if t < 0 or t > n then
Error( "LBCREmbedded1: <t> must be >= 0 and <= <n>" );
fi;
tmpsize := SphereContent( n, t, q ) - Binomial( 2*t, t );
if tmpsize <= 0 then
return 0;
else
if 2 * t + 1 > n then
upperb := 1;
else
upperb := UpperBound( n, 2*t+1, q );
fi;
return IntCeiling( ( q^n - upperb
* Binomial( 2*t, t ) ) / tmpsize );
fi;
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusEmbedded1,
"code length, code size or covering radius, field, usage",
true, [IsInt, IsInt, IsField, IsBool], 0,
function(n, r, F, usage)
if not IsFinite(F) then
Error("LBCREmbedded1: <F> must be a finite field");
else
return LowerBoundCoveringRadiusEmbedded1(n, r, Size(F), usage);
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusEmbedded1,
"code length, code size or covering radius, usage",
true, [IsInt, IsInt, IsBool], 0,
function(n, r, usage)
return LowerBoundCoveringRadiusEmbedded1(n, r, 2, usage);
end);
InstallOtherMethod(LowerBoundCoveringRadiusEmbedded1,
"code length, code covering radius, field size", true,
[IsInt, IsInt, IsInt], 0,
function(n, r, q)
return LowerBoundCoveringRadiusEmbedded1(n, r, q, true);
end);
InstallOtherMethod(LowerBoundCoveringRadiusEmbedded1,
"code length, code covering radius, field", true,
[IsInt, IsInt, IsField], 0,
function(n, r, F)
if not IsFinite(F) then
Error("LBCREmbedded1: <F> must be a finite field");
else
return LowerBoundCoveringRadiusEmbedded1(n, r, Size(F), true);
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusEmbedded1,
"code length, code covering radius", true, [IsInt, IsInt], 0,
function(n, r)
return LowerBoundCoveringRadiusEmbedded1(n, r, 2, true);
end);
########################################################################
##
#F LowerBoundCoveringRadiusEmbedded2( <n>, <r> [, <givesize> ] )
##
InstallMethod(LowerBoundCoveringRadiusEmbedded2,
"code length, code size or covering radius, field size, usage",
true, [IsInt, IsInt, IsInt, IsBool], 0,
function(n, r, q, usage)
local m, lb, ub, tmpcr, tmpsize, t, upperb;
if n <= 0 then
Error("LBCREmbedded2: <n> must be positive");
fi;
if usage = false then
# last argument is false, try to find a lower bound for
# the covering radius, given length and size of the code, and field
m := r;
if m <= 0 or m > q^n then
Error( "LBCREmbedded2: <m> must be > 0 and <= q^n" );
fi;
# everything is set up. now compute the bound
if m = q^n then
return 0;
fi;
if n = 1 or n = 2 then
return 0;
fi;
lb := 1;
ub := n;
while lb <> ub do
tmpcr := IntFloor( (ub+lb) / 2 );
tmpsize := SphereContent( n, tmpcr, q )
- 3/2 * Binomial( 2*tmpcr, tmpcr );
if tmpsize = -1/2 then
lb := lb + 1;
elif tmpsize <= 0 then
ub := tmpcr;
else
if 2*tmpcr+1 > n then
upperb := 1;
else
upperb := UpperBound( n, 2*tmpcr+1, q );
fi;
tmpsize := IntCeiling( ( q^n - 2 * upperb
* Binomial( 2*tmpcr, tmpcr ) )
/ tmpsize );
if tmpsize > m then
lb := tmpcr + 1;
else
ub := tmpcr;
fi;
fi;
od;
return ub;
else
# the last argument is not false
# now it is assumed that the first argument is the length
# of the code and the second argument is the covering radius
# of the code. a lower bound for the minimal size of the
# code is returned
t := r;
if t < 0 or t > n then
Error( "LBCREmbedded2: <t> must be >= 0 and <= <n>" );
fi;
tmpsize := SphereContent( n, t, q ) - 3/2*Binomial( 2*t, t );
if tmpsize <= 0 then
return 0;
else
if 2*t+1 > n then
upperb := 1;
else
upperb := UpperBound( n, 2*t+1, q );
fi;
return IntCeiling( ( q^n - 2*upperb
* Binomial( 2*t, t ) ) / tmpsize );
fi;
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusEmbedded2,
"code length, code size or covering radius, field, usage",
true, [IsInt, IsInt, IsField, IsBool], 0,
function(n, r, F, usage)
if not IsFinite(F) then
Error("LBCREmbedded2: <F> must be a finite field");
else
return LowerBoundCoveringRadiusEmbedded2(n, r, Size(F), usage);
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusEmbedded2,
"code length, code size or covering radius, usage",
true, [IsInt, IsInt, IsBool], 0,
function(n, r, usage)
return LowerBoundCoveringRadiusEmbedded2(n, r, 2, usage);
end);
InstallOtherMethod(LowerBoundCoveringRadiusEmbedded2,
"code length, code covering radius, field size",
true, [IsInt, IsInt, IsInt], 0,
function(n, r, q)
return LowerBoundCoveringRadiusEmbedded2(n, r, q, true);
end);
InstallOtherMethod(LowerBoundCoveringRadiusEmbedded2,
"code length, code covering radius, field",
true, [IsInt, IsInt, IsField], 0,
function(n, r, F)
if not IsFinite(F) then
Error("LBCREmbedded2: <F> must be a finite field");
else
return LowerBoundCoveringRadiusEmbedded2(n, r, Size(F), true);
fi;
end);
InstallOtherMethod(LowerBoundCoveringRadiusEmbedded2,
"code length, code covering radius",
true, [IsInt, IsInt], 0,
function(n, r)
return LowerBoundCoveringRadiusEmbedded2(n, r, 2, true);
end);
#############################################################################
##
#F LowerBoundCoveringRadiusInduction( <n>, <r> ) Induction bound
##
InstallMethod(LowerBoundCoveringRadiusInduction,
"method for two integers", true, [IsInt, IsInt], 0,
function(n, t)
if n <= 0 then
Error( "LBCRInduction: <n> must be positive" );
fi;
if t < 0 or t > n then
Error( "LBCRInduction: <t> must be >= 0 and <= <n>" );
fi;
if n = 2 * t + 2 and t >= 1 then
return 4;
elif n = 2 * t + 3 and t >= 1 then
return 7;
elif n = 2 * t + 4 and t >= 4 then
return 8;
else
return 0;
fi;
end);
########################################################################
##
#F GeneralUpperBoundCoveringRadius( <code> )
##
InstallMethod(GeneralUpperBoundCoveringRadius, "unrestricted code", true,
[IsCode], 0,
function(code)
local listofbounds;
listofbounds := [ UpperBoundCoveringRadiusStrength( code ) ];
if WordLength( code ) <= 100 then
Append( listofbounds, [
UpperBoundCoveringRadiusDelsarte( code )
] );
fi;
if IsLinearCode( code ) then
Append( listofbounds, [
UpperBoundCoveringRadiusRedundancy( code ),
] );
if LeftActingDomain( code ) = GF(2) then
if ( IsBound( code!.lowerBoundMinimumDistance ) and
IsBound( code!.upperBoundMinimumDistance ) ) and
LowerBoundMinimumDistance( code ) =
UpperBoundMinimumDistance (code )
then
Append( listofbounds, [
UpperBoundCoveringRadiusGriesmerLike( code )
] );
fi;
fi;
fi;
if IsCyclicCode( code ) and LeftActingDomain( code ) = GF(2) then
Append( listofbounds, [
UpperBoundCoveringRadiusCyclicCode( code )
] );
fi;
if IsBound( code!.boundsCoveringRadius ) then
Add( listofbounds, Maximum( code!.boundsCoveringRadius ) );
fi;
return Minimum( listofbounds );
end);
########################################################################
##
#F UpperBoundCoveringRadiusRedundancy( <code> )
##
## Return the redundancy of the code as an upper bound for
## the covering radius.
##
## Only for linear codes.
##
InstallMethod(UpperBoundCoveringRadiusRedundancy, "unrestricted code", true,
[IsCode], 0,
function( code )
if IsLinearCode( code ) then
return UpperBoundCoveringRadiusRedundancy( code );
else
Error("UBCRRedundancy: <code> must be a linear code");
fi;
end);
InstallMethod(UpperBoundCoveringRadiusRedundancy, "linear code", true,
[IsLinearCode], 0,
function( code)
return Redundancy(code);
end);
########################################################################
##
#F UpperBoundCoveringRadiusDelsarte( <code> )
##
InstallMethod(UpperBoundCoveringRadiusDelsarte, "method for unrestricted codes", true, [IsCode], 0,
function(code)
local p;
p := CodeMacWilliamsTransform(code);
p := CoefficientsOfLaurentPolynomial(p);
p := ShiftedCoeffs(p[1], p[2]);
return WeightVector(p) - 1;
end);
InstallMethod(UpperBoundCoveringRadiusDelsarte, "method for linear codes",
true, [IsLinearCode], 0,
function(code)
local dual, wddual;
if not IsBound(code!.boundsCoveringRadius) then
# avoid recursion
code!.boundsCoveringRadius := [ 0 .. WordLength( code ) ];
fi;
dual := DualCode( code );
wddual := WeightDistribution( dual );
--> --------------------
--> maximum size reached
--> --------------------
[ Dauer der Verarbeitung: 0.155 Sekunden
]
|
2026-03-28
|