/* Copyright (C) 1992 by Jeffrey S. Leon. This software may be used freely for educational and research purposes. Any other use requires permission
from the author. */
/* Highly optimized main program to compute weight distribution of a linear code The command format is
wtdist <options> <code> <weightToSave> <matrix> or wtdist <options> <code>
where in the second case all vectors of weight <weightToSave> (except scalar multiples) are saved as a matrix whose rows are the vectors. If the -1 option is coded, only one vector of this weight is saved. If there are no vectors of the given weight, the matrix is not created.
For most binary codes, bit string operations on vectors are used.
For nonbinary codes (and for binary codes whose parameters fail to meet certain constraints), several columns of each codeword are packed into a single integer in order to make computations much faster, for large codes, than would otherwise be possible. The number of columns packed into a single integer is referred to as the "packing factor". It may be specified explicitly by the -pf option (within limits) or allowed to default. Optimal choice of the packing factor can improve performance considerably.
Let the code be an (n,k) code over GF(q), where q = p^e. Let F(x) = a[0] + a[1]*x + ... + a[e]*x^e be the irreducible polynomial over GF(p) used to construct GF(q). The elements of GF(q) are represented as integers in the range 0..q-1, where field element g[0] + g[1]*x + ... + g[e-1]*x^(e-1) is represented by the integer g[0] + g[1] * q + ... + g[e-1] * q^(e-1).
Let P denote the packing factor. In order to save space and time, up to P components of a vector over GF(q) are represented as a single integer in the range 0..(q^P-1). Specifically, the sequence of components b[i],b[i+1],...,b[i+P-1] is represented by the integer b[i] + b[i+1] * q + ... + b[i+P-1] * q^(P-1).
The integer representing a sequence of field elements (components) is referred to as a "packed field sequence". The number of packed field sequences required to represent one codeword is called the "packed length" of the code; it equals ceil(n/P). The set of columns of the code corresponding to a packed field sequence is referred to as a "packed column".
The packing factor P must satisfy the constraints i) P <= MaxPackingFactor, ii) FieldSize ^ P - 1 <= MaxPackedInteger, iii) ceil(n/P) <= MaxPackedLength, where MaxPackingFactor, MaxPackedInteger, and MaxPackedLength are symbolic constant (see above).
In general, a large packing factor will increase memory requirements and will increase the time required to initialize various tables, but it will decrease the time required to compute the weight distribution, once initialization has been completed. The largest single data structure contains e * k * q^P * MaxPackedLength * r bytes, where r is the number of bytes used to represent type 0..MaxPackedInteger.
In general, a relatively small packing factor (say 8 for binary codes) is indicated for codes of moderate size. For large codes, a larger packing factor (say 12 for binary codes) leads to lower execution times, at the cost of a higher memory requirement.
The user may specify the value of the packing factor in the input, subject to the limits specified above. An input value of 0 will cause the program to choose a default value, which may not give as good performance as a user-specified value.
*/
/* Note: BINARY_CUTOFF_DIMENSION must be at least 3. */ #define BINARY_CUTOFF_DIMENSION 12 #define DEFAULT_INIT_ALLOC_SIZE 10000
/* Provide help if no arguments are specified. */ if ( argc == 1 ) {
printf( "\nUsage: wtdist [options] code [saveWeight matrix]\n"); return 0;
}
/* Check for limits option. If present in position 1, give limits and
return. */ if ( strcmp(argv[1], "-l") == 0 || strcmp(argv[1], "-L") == 0 ) {
showLimits(); return 0;
}
/* Check for verify option. If present in position 1, perform verify (Note
verifyOptions terminates program). */ if ( strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "-V") == 0 )
verifyOptions();
/* Check for exactly 1 or 3 parameters following options. */ for ( optionCountPlus1 = 1 ; optionCountPlus1 < argc &&
argv[optionCountPlus1][0] == '-' ; ++optionCountPlus1 )
;
#ifdef xxxxxx /* If a coset weight distribution is requested, check the size limits,
call cosetWeightDist if ok, and return. */ if ( cWtDistFlag ) { if ( C->fieldSize != 2 || C->length > 128 || C->length - C->dimension > 32 )
ERROR( "main (wtdist)", "Coset weight dist requires binary code, length <= 128, codimension <= 32.")
binaryCosetWeightDist( C, maxCosetWeight, oneCodeWordOnly, passes, &allocatedSize,
matrix); return 0;
} #endif
/* Decide whether to use binary or general procedure. The general
procedure is used on binary codes of small dimension. */ if ( defaultForBinaryProcedure )
useBinaryProcedure &= (C->fieldSize == 2 &&
C->length <= 128 &&
C->dimension > BINARY_CUTOFF_DIMENSION); elseif ( useBinaryProcedure && (C->fieldSize != 2 || C->length > 128 ||
C->dimension <= 3) ) {
useBinaryProcedure = FALSE; if ( options.inform )
printf( "\n\n Special binary procedure cannot be used.\n");
}
/* If the general procedure is to be used, determine the packing factor if one was not specified. Determine the packed length and the largest
packed integer. */ if ( !useBinaryProcedure ) { if ( packingFactor == 0 ) {
packingFactor = 1;
largestPackedInteger = C->fieldSize; while ( (largestPackedInteger <= 0x7fff / C->fieldSize) &&
(packingFactor <= C->dimension / 2) ) {
++packingFactor;
largestPackedInteger *= C->fieldSize;
}
--largestPackedInteger;
} else {
temp = 1;
largestPackedInteger = C->fieldSize; while ( (largestPackedInteger <= 0x7fff / C->fieldSize) &&
(temp < packingFactor) ) {
++temp;
largestPackedInteger *= C->fieldSize;
}
packingFactor = temp;
--largestPackedInteger;
}
packedLength = (C->length + packingFactor - 1) / packingFactor;
}
/* This function allocates and constructs an array of size 2^16 in which entry i contains the number of ones in the binary representation of i, 0 <= i < 2^16. It returns (a pointer to) the array. It is assumed that
type short has length 16 bits. */
/* The procedure BuildWeightArray constructs the array Weight of size 0..LargestPackedInteger. For t = 0,1,...,HighPackedInteger, Weight[t] is set to the number of nonzero field elements in the
sequence of PackingFactor field elements represented by integer t. */
char *buildWeightArray( constUnsigned fieldSize, /* Size of the field. */ constUnsigned packingFactor, /* No of cols packed into integer. */ constUnsigned largestPackedInteger)
{ Unsigned i, v; char *weight;
weight = (char *) malloc( sizeof(char) * (largestPackedInteger+1) ); if ( !weight )
ERROR( "buildWeightArray", "Out of memory.");
for ( i = 0 ; i <= largestPackedInteger ; ++i ) {
weight[i] = 0;
v = i; while ( v > 0 ) { if ( v % fieldSize )
++weight[i];
v /= fieldSize;
}
}
/* This procedure packs a codeword over a field of size greater than 2. (If the field size is 2, it works, but it returns an array of type unsigned short, whereas type unsigned would be preferable.) It returns a new packed code word which is obtained by packing the code word supplied as a parameter. If p denotes the PackingFactor, then p columns of the input codeword (Word) are packed into each integer of the output packed codeword (PackedWord). If q denotes the field size and if c(1),...,c(n) denotes the input codeword, then the output packed word will have components
c(1)+c(2)*q+...+c(p)*q**(p-1), c(p+1)+c(p+2)*q+...+c(2*p)*q**(p-1), etc. */
unsignedshort *packNonBinaryCodeWord( constUnsigned fieldSize, /* Field size for codeword. */ constUnsigned length, /* Length of codeword to pack. */ constUnsigned packingFactor, /* No of cols packed into integer. */ const FieldElement *codeWord) /* The codeword to pack. */
{ Unsigned index = 0,
offset = 0,
col,
powerOfFieldSize = 1; constUnsigned colsPerArrayElt = (length+packingFactor) / packingFactor; unsignedshort *packedCodeWord;
/* This procedure unpacks a codeword over a field of size greater than 2.
It performs the reverse of the packNonBinaryCodeword procedure above. */
void unpackNonBinaryCodeWord( constUnsigned fieldSize, /* Field size for codeword. */ constUnsigned length, /* Length of codeword to unpack. */ constUnsigned packingFactor, /* No of cols packed into integer. */ constunsignedshort *packedCodeWord, /* The codeword to unpack pack. */
FieldElement *const codeWord) /* Set to unpacked code word. */
{ Unsigned index = 0,
offset = 0,
col, temp;
/* This procedure constructs a data structure AddBasisElement which specifies how to add a a prime-basis element to an arbitrary codeword. addBasisElement[i][p][j] gives the sum of packed column j of the i'th prime basis vector and packed field sequence k, for 1 <= i <= C->dimension * C->field->exponent, 0 <= j < packedLength, 0 <= p <= largestPackedInteger.
*/
/* This procedure destructs a data structure AddBasisElement */
void destroyAddBasisElement(unsignedshort ***addBasisElement, int primeDimension, intlargestPackedInteger) { int i, j; for (i = 1; i <= primeDimension; i++) { for (j = 0; j <= largestPackedInteger; j++) {
free(addBasisElement[i][j]);
}
free(addBasisElement[i]);
}
free(addBasisElement);
}
/* Construct structure AddBasisElement, used to add a prime basis codeword
to an arbitrary codeword. */
addBasisElement = buildAddBasisElement( C, packingFactor, packedLength,
largestPackedInteger);
/* Initialize freq and saveCount. Upon termination, freq will hold the
weight distribution. */ for ( wt = 1 ; wt <= C->length ; ++wt )
freq[wt] = 0;
freq[0] = 1;
/* Traverse the code. */ for ( h = C->dimension ; h >= 1 ; --h ) {
/* Traverse codewords of form 0*basis[1] +...+ 0*basis[h-1] + 1*basis[h] + (anything) * basis[h+1] +...+ (anything) * basis[k]),
where k is the dimension. */ for ( primeRow = 0 ; primeRow <= primeDimension ; ++primeRow )
x[primeRow] = 0; for ( packedCol = 0 ; packedCol < packedLength ; ++packedCol )
currentWord[packedCol] = 0;
m = (h - 1) * fieldExponent + 1;
do {
/* Add prime basis codeword m to current word and find weight
of result. */
currentWeight = 0; for ( packedCol = 0 ; packedCol < packedLength ; ++packedCol ) {
currentWord[packedCol] =
addBasisElement[m][currentWord[packedCol]][packedCol];
currentWeight += weight[currentWord[packedCol]];
}
/* Record weight. */
freq[currentWeight] += (C->fieldSize - 1);
/* Save the codeword, if appropriate. */ if ( currentWeight == saveWeight ) {
++matrix->numberOfRows; if ( matrix->numberOfRows > *allocatedSize ) {
*allocatedSize *= 2;
matrix->entry = (FieldElement **) realloc( matrix->entry,
*allocatedSize); if ( !matrix->entry )
ERROR( "binaryWeightDist", "Out of memory.")
}
vec = matrix->entry[matrix->numberOfRows] =
malloc( (C->length+1) * sizeof(FieldElement) ); if ( !vec )
ERROR( "binaryWeightDist", "Out of memory.")
unpackNonBinaryCodeWord( C->fieldSize, C->length, packingFactor,
currentWord, vec); if ( oneCodeWordOnly )
saveWeight = UNKNOWN+1;
}
/* Find m such that prime basis codeword number X[m] is the
basis codeword to add next. */
m = primeDimension; while ( x[m] == fieldCharacteristic - 1 )
--m;
/* Adjust array X, which determines which basis codeword to add
next. */
++x[m]; for ( primeRow = m+1 ; primeRow <= primeDimension ; ++primeRow )
x[primeRow] = 0;
} while ( m > h * fieldExponent );
}
free(currentWord);
free(x);
free(weight);
destroyAddBasisElement(addBasisElement, primeDimension, largestPackedInteger);
/* Initializations. */ for ( i = 0 ; i <=C->length ; ++i )
freq[i] = 0;
cw1 = cw2 = cw3 = cw4 = 0;
for ( wt = 1 ; wt <= maxCosetWeight && cosetsFound <= goal ; ++wt ) { for ( i = 1 ; i <= wt ; ++i )
/* Write out the coset weight distribution. */
sumLess1 = 0; if ( options.inform ) {
printf( "\n\n Coset Weight Distribution of code %s", C->name);
printf( "\n\n Coset Min Wt Number Of Cosets");
printf( "\n ------------ ----------------"); for ( i = 0 ; i <= maxCosetWeight ; ++i ) if ( freq[i] != 0 ) if ( i != 0 )
sumLess1 += freq[i];
printf( "\n %2u %10lu", i, freq[i]); if ( sumLess1 < numberOfCosetsLess1 )
printf( "\n at least %2u %10lu", maxCosetWeight+1,
numberOfCosetsLess1 - sumLess1);
printf( "\n");
} #endif
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.