/* * minimum-weight-gf2.c * * Minimum Hamming weight computation for codes over GF(2) * The core of computation is in this src file * * NOTES: * - The GF(2) vectors are represented in packed long integer * format. This long integer is either 32-bit or 64-bit, * depending on the machine architecture, see config.h * * - To efficiently generate combination patterns, revolving door * algorithm is used here. This algorithm has the property that * in going to the next combination pattern, there is only one * position that is exchanged, i.e. one 'In' and one 'Out'. The * implementation here follows the third algorithm in the paper * by * * Clement W.H. Lam and Leonard H. Soicher, "Three new combination * algorithms with minimal change property", Communications * of the ACM, vol. 25, no. 8, August 1982 * * - The code here is not yet optimized, your contributions in this * respect are greatly appreciated. * * Version Log: * 0.1 18 March 2008 (first released to public -- GUAVA 3.3) * * CJ, Tjhai * email: ctjhai@plymouth.ac.uk * Homepage: www.plymouth.ac.uk/staff/ctjhai *
*/
/*-------------------- Function prototypes ----------------------*/
packed_t **to_packed_integer_gf2(MATRIX *G, int nBlocks); int gf2_gauss_jordan(MATRIX *M, int start); void mat_packed_print_gf2(packed_t **M, int nBlocks, int dim, int length); void update_info_gf2(PACKED_MATRIX_GF2 *G, INFO *info); void cyclic_update_info_gf2(PACKED_MATRIX_GF2 *G, INFO *info); void __mindist_gf2(PACKED_MATRIX_GF2 *G, INFO *info); void __cyclic_mindist_gf2(PACKED_MATRIX_GF2 *G, INFO *info); /*---------------------------------------------------------------*/
/* Return the minimum weight of a general binary linear code */ int mindist_gf2(MATRIX G, mod_t m_mod, int lower_bound) { int i, j, l, rank, pos; double steps; unsignedint sum=0;
PACKED_MATRIX_GF2 packedG;
INFO info;
/* * Knowing G, now build an array of generator matrices with * disjoint information sets. These matrices are stored in * packed integer format *
*/
j = (G.cols - G.rows) + 1; /* maximum possible number of matrices */
packedG.mat = (packed_t ***)malloc(j * sizeof(packed_t **));
packedG.rank= (unsignedshort *)malloc(j * sizeof(unsignedshort));
packedG.dimension = G.rows;
packedG.block_length = G.cols;
packedG.nMatrices = packedG.nFullRankMatrices = 0;
packedG.nBlocks = (!(G.cols % BITSIZE)) ? (G.cols / BITSIZE) : (G.cols / BITSIZE)+1; for (i=0,pos=0;;i++) { if (pos >= G.cols) break;
rank = gf2_gauss_jordan(&G, pos); /* what is the rank at column 'pos'? */ if (!rank) {
pos++; continue;
}
/* Convert the reduced echelon matrix into packed integer format */
packedG.mat[i] = to_packed_integer_gf2(&G, packedG.nBlocks);
/*---------------------- core computation starts here -------------------------*/
printf("[%d,%d] linear code over GF(2) - minimum weight evaluation\n", G.cols, G.rows);
printf("Known lower-bound: %d\n", lower_bound);
printf("There are %d generator matrices, ranks : ", packedG.nMatrices); for (i=0; i<packedG.nMatrices; i++) printf("%d ", packedG.rank[i]); printf("\n");
info.weight_constraint = m_mod; switch (m_mod) { case C_0MOD2:
printf("The weight of the minimum weight codeword satisfies 0 mod 2 congruence\n"); break; case C_1MOD2:
printf("The weight of the minimum weight codeword satisfies 1 mod 2 congruence\n"); break; case C_3MOD4:
printf("The weight of the minimum weight codeword satisfies 3 mod 4 congruence\n"); break; case C_0MOD4:
printf("The weight of the minimum weight codeword satisfies 0 mod 4 congruence\n"); break; default: break;
}
fflush(stdout);
/* Obtain the first lower-bound */
info.known_lower_bound = lower_bound;
info.lower_bound = 2 * packedG.nFullRankMatrices; for (i=packedG.nFullRankMatrices; i<packedG.nMatrices; i++) {
j = 2 - (G.rows - packedG.rank[i]); if (j>0) info.lower_bound += j;
}
/* Information weight 1 */
printf("Enumerating codewords with information weight 1 (w=1)\n"); fflush(stdout);
steps = 0; info.upper_bound = G.cols; i = packedG.nMatrices; do { --i;
j = packedG.dimension; do { --j;
steps++;
sum = 0; l = packedG.nBlocks; do { --l;
sum += popcount(packedG.mat[i][j][l]);
} while (l); if (sum < info.upper_bound) {
info.upper_bound = sum;
printf(" Found new minimum weight %d\n", info.upper_bound); fflush(stdout); if (info.upper_bound <= info.known_lower_bound) break;
}
} while (j); if (sum <= info.known_lower_bound) {
printf("The known lower-bound is met, enumeration completed.\n");
info.upper_bound = sum; goto completed;
}
} while(i);
/* Update progress information */
info.info_weight_completed = 1;
update_info_gf2(&packedG, &info);
printf("Number of matrices required for codeword enumeration %d\n", info.matrices_req);
printf("Completed w= 1, %.0lf codewords enumerated, lower-bound %d, upper-bound %d\n",
steps, info.displayed_lower_bound, info.upper_bound); fflush(stdout); if (info.displayed_lower_bound >= info.upper_bound) goto completed;
printf("Termination expected with information weight %d at matrix %d\n",
info.max_info_weight_req, info.ith_matrix);
printf("-----------------------------------------------------------------------------\n");
/* The following function is executed for higher minimum weight */
__mindist_gf2(&packedG, &info);
/*------------------------ end of core computation ----------------------------*/
completed: /* Deallocating memory */ for (i=0; i<packedG.nMatrices; i++) { for (j=0; j<G.rows; j++) free(packedG.mat[i][j]);
free(packedG.mat[i]);
}
free(packedG.mat);
return info.upper_bound;
}
/* Return the minimum weight of a binary cyclic code */ int cyclic_mindist_gf2(MATRIX G, mod_t m_mod, int lower_bound) { int j, l, rank; unsignedint sum=0;
PACKED_MATRIX_GF2 packedG;
INFO info;
/* * For cyclic code, only one information set is required, so * only one generator matrix (in packed integer format) is * needed. *
*/
j = 1; /* only one generator matrix */
packedG.mat = (packed_t ***)malloc(j * sizeof(packed_t **));
packedG.rank= (unsignedshort *)malloc(j * sizeof(unsignedshort));
packedG.dimension = G.rows;
packedG.block_length = G.cols;
packedG.nMatrices = j;
packedG.nFullRankMatrices = 1 + ((G.cols - G.rows)/G.rows);
packedG.nBlocks = (!(G.cols % BITSIZE)) ? (G.cols / BITSIZE) : (G.cols / BITSIZE)+1;
rank = gf2_gauss_jordan(&G, 0); if (!rank) {
fprintf(stderr, "ERROR: rank is 0\n\n"); return -1;
}
/* Convert the reduced echelon matrix into packed integer format */
packedG.mat[0] = to_packed_integer_gf2(&G, packedG.nBlocks);
packedG.rank[0] = rank; if (rank != G.rows) {
fprintf(stderr, "ERROR: full rank generator matrix cannot be obtained.\n");
fprintf(stderr, " Please provide a full-rank generator matrix as an input.\n\n"); return -1;
}
/*---------------------- core computation starts here -------------------------*/
printf("[%d,%d] cyclic code over GF(2) - minimum weight evaluation\n", G.cols, G.rows);
printf("Known lower-bound: %d\n", lower_bound);
info.weight_constraint = m_mod; switch (m_mod) { case C_0MOD2:
printf("The weight of the minimum weight codeword satisfies 0 mod 2 congruence\n"); break; case C_1MOD2:
printf("The weight of the minimum weight codeword satisfies 1 mod 2 congruence\n"); break; case C_3MOD4:
printf("The weight of the minimum weight codeword satisfies 3 mod 4 congruence\n"); break; case C_0MOD4:
printf("The weight of the minimum weight codeword satisfies 0 mod 4 congruence\n"); break; default: break;
}
fflush(stdout);
info.matrices_req = 1;
/* Obtain the first lower-bound */
info.known_lower_bound = lower_bound;
info.lower_bound = (unsignedint)ceil(((double)G.cols/(double)G.rows)*2.0);
/* Information weight 1 */
printf("Enumerating codewords with information weight 1 (w=1)\n"); fflush(stdout);
info.upper_bound = G.cols;
j = packedG.dimension; do { --j;
sum = 0; l = packedG.nBlocks; do { --l;
sum += popcount(packedG.mat[0][j][l]);
} while (l); if (sum < info.upper_bound) {
info.upper_bound = sum;
printf(" Found new minimum weight %d\n", info.upper_bound); fflush(stdout); if (info.upper_bound <= info.known_lower_bound) break;
}
} while (j); if (sum <= info.known_lower_bound) {
printf("The known lower-bound is met, enumeration completed.\n");
info.upper_bound = sum; goto completed;
}
/* Update progress information */
info.info_weight_completed = 1;
cyclic_update_info_gf2(&packedG, &info);
printf("Number of matrices required for codeword enumeration %d\n", info.matrices_req);
printf("Completed w= 1, %d codewords enumerated, lower-bound %d, upper-bound %d\n",
packedG.dimension, info.displayed_lower_bound, info.upper_bound); fflush(stdout); if (info.displayed_lower_bound >= info.upper_bound) goto completed;
printf("Termination expected with information weight %d\n", info.max_info_weight_req);
printf("-----------------------------------------------------------------------------\n");
/* The following function is executed for higher minimum weight */
__cyclic_mindist_gf2(&packedG, &info);
/*------------------------ end of core computation ----------------------------*/
/* Minimum weight enumeration function for information weight >= 2 */ void __mindist_gf2(PACKED_MATRIX_GF2 *G, INFO *info) { #define EVALUATE_MINIMUM_WEIGHT1 {\
l=info->matrices_req; do { --l;\
steps++;\
i = G->nBlocks; w = 0;\ do { --i;\
c[l][i] = G->mat[l][v[1]][i];\
j = m; do { --j; c[l][i] ^= G->mat[l][v[j+2]][i]; } while (j);\
w += popcount(c[l][i]);\
} while (i);\ if (w < info->upper_bound) {\
info->upper_bound = w;\
printf(" Found new minimum weight %d\n", w); fflush(stdout);\ if (w <= info->known_lower_bound) goto lower_bound_met;\
}\
} while (l);\
} #define EVALUATE_MINIMUM_WEIGHT {\
l=info->matrices_req; do { --l;\
steps++;\
i = G->nBlocks; w = 0;\ do { --i;\ /* Property of revolving door algorithm: */\ /* In two consecutive combination pattern, */\ /* exactly one element In and one element Out. */\
c[l][i] ^= (G->mat[l][ Out ][i] ^ G->mat[l][ In ][i]);\
w += popcount(c[l][i]);\
} while (i);\ if (w < info->upper_bound) {\
info->upper_bound = w;\
printf(" Found new minimum weight %d\n", w); fflush(stdout);\ if (w <= info->known_lower_bound) goto lower_bound_met;\
}\
} while (l);\
} double steps; short m, iw, top, In, Out, nMat; registershort i, j, l, w; register packed_t **c; short *v, *s;
w = top = 0;
nMat = info->matrices_req;
c = (packed_t **)malloc(nMat * sizeof(packed_t*));
l = nMat; do { --l;
c[l] = (packed_t *)malloc(G->nBlocks * sizeof(packed_t));
} while (l); for (iw=2;;iw++) { /* starting from information weight 2 */ if (iw == info->max_info_weight_req) info->matrices_req = info->ith_matrix;
printf("Enumerating codewords with information weight %d (w=%d) using %d matrices\n",
iw, iw, info->matrices_req);
fflush(stdout);
steps = 0;
m = iw - 1;
v = (short *) malloc((iw+2)*sizeof(short));
s = (short *) malloc((iw+2)*sizeof(short));
if ( !(iw & 1) ) {
v[iw + 1] = G->dimension; v[iw] = iw - 1; if (iw < G->dimension) top = iw;
} else {
v[iw] = G->dimension - 1; if (iw < G->dimension) top = iw - 1;
}
v[1] = s[iw] = 0; for (i=2; i<iw; ++i) { v[i] = i-1; s[i] = i+1; }
/* first combination */
EVALUATE_MINIMUM_WEIGHT1;
/* main loop to generate all other combinations */ while (top != 0) { if (top == 2) { /* special handling far v[1] and v[2] */
top = s[2]; s[2] = 3; do {
Out = v[1];
v[1] = v[2]; ++v[2];
In = v[2];
EVALUATE_MINIMUM_WEIGHT; do {
Out = v[1];
--v[1];
In = v[1];
EVALUATE_MINIMUM_WEIGHT;
} while (v[1]);
} while ( !(v[2] == v[3] - 1) );
} else { if (top & 0x1) {
Out = v[top];
--v[top]; if (v[top] > top - 1) {
top = top - 1; v[top] = top - 1;
In = v[top];
} else {
v[top-1] = top - 2; i = top;
In = v[top-1];
top = s[top]; s[i] = i + 1;
}
} else {
Out = v[top-1];
v[top-1] = v[top]; ++v[top];
In = v[top]; if (v[top] == v[top+1] - 1) {
s[top-1] = s[top]; s[top] = top + 1;
}
top -= 2;
}
EVALUATE_MINIMUM_WEIGHT;
}
}
/* Update progress information */
info->info_weight_completed = iw;
update_info_gf2(G, info);
printf("Completed w=%2d, %.0lf codewords enumerated, lower-bound %d, upper-bound %d\n",
iw, steps, info->displayed_lower_bound, info->upper_bound); fflush(stdout);
lower_bound_met:
free(v);
free(s); if (w <= info->known_lower_bound) {
printf("The known lower-bound is met, enumeration completed.\n");
printf("-----------------------------------------------------------------------------\n");
info->upper_bound = w; for (l=0; l<nMat; l++) free(c[l]);
free(c); return;
} if (info->displayed_lower_bound >= info->upper_bound) break;
printf("Termination expected with information weight %d at matrix %d\n",
info->max_info_weight_req, info->ith_matrix);
printf("-----------------------------------------------------------------------------\n");
}
printf("-----------------------------------------------------------------------------\n"); for (l=0; l<nMat; l++) free(c[l]);
free(c);
}
/* Cyclic code: minimum weight enumeration function for information weight >= 2 */ void __cyclic_mindist_gf2(PACKED_MATRIX_GF2 *G, INFO *info) { #define EVALUATE_CYCLIC_MINIMUM_WEIGHT1 {\
steps++;\
i = G->nBlocks; w = 0;\ do { --i;\
c[i] = G->mat[0][v[1]][i];\
j = m; do { --j; c[i] ^= G->mat[0][v[j+2]][i]; } while (j);\
w += popcount(c[i]);\
} while (i);\ if (w < info->upper_bound) {\
info->upper_bound = w;\
printf(" Found new minimum weight %d\n", w); fflush(stdout);\ if (w <= info->known_lower_bound) goto lower_bound_met;\
}\
} #define EVALUATE_CYCLIC_MINIMUM_WEIGHT {\
steps++;\
i = G->nBlocks; w = 0;\ do { --i;\ /* Property of revolving door algorithm: */\ /* In two consecutive combination pattern, */\ /* exactly one element In and one element Out. */\
c[i] ^= (G->mat[0][ Out ][i] ^ G->mat[0][ In ][i]);\
w += popcount(c[i]);\
} while (i);\ if (w < info->upper_bound) {\
info->upper_bound = w;\
printf(" Found new minimum weight %d\n", w); fflush(stdout);\ if (w <= info->known_lower_bound) goto lower_bound_met;\
}\
} double steps; short m, iw, top, In, Out; registershort i, j, w; register packed_t *c; short *v, *s;
w = top = 0;
c = (packed_t *)malloc(G->nBlocks * sizeof(packed_t)); for (iw=2;;iw++) { /* starting from information weight 2 */
printf("Enumerating codewords with information weight %d (w=%d) using 1 matrix\n",
iw, iw);
fflush(stdout);
steps = 0;
m = iw - 1;
v = (short *) malloc((iw+2)*sizeof(short));
s = (short *) malloc((iw+2)*sizeof(short));
if ( !(iw & 1) ) {
v[iw + 1] = G->dimension; v[iw] = iw - 1; if (iw < G->dimension) top = iw;
} else {
v[iw] = G->dimension - 1; if (iw < G->dimension) top = iw - 1;
}
v[1] = s[iw] = 0; for (i=2; i<iw; ++i) { v[i] = i-1; s[i] = i+1; }
/* first combination */
EVALUATE_CYCLIC_MINIMUM_WEIGHT1;
/* main loop to generate all other combinations */ while (top != 0) { if (top == 2) { /* special handling far v[1] and v[2] */
top = s[2]; s[2] = 3; do {
Out = v[1];
v[1] = v[2]; ++v[2];
In = v[2];
EVALUATE_CYCLIC_MINIMUM_WEIGHT; do {
Out = v[1];
--v[1];
In = v[1];
EVALUATE_CYCLIC_MINIMUM_WEIGHT;
} while (v[1]);
} while ( !(v[2] == v[3] - 1) );
} else { if (top & 0x1) {
Out = v[top];
--v[top]; if (v[top] > top - 1) {
top = top - 1; v[top] = top - 1;
In = v[top];
} else {
v[top-1] = top - 2; i = top;
In = v[top-1];
top = s[top]; s[i] = i + 1;
}
} else {
Out = v[top-1];
v[top-1] = v[top]; ++v[top];
In = v[top]; if (v[top] == v[top+1] - 1) {
s[top-1] = s[top]; s[top] = top + 1;
}
top -= 2;
}
EVALUATE_CYCLIC_MINIMUM_WEIGHT;
}
}
/* Update progress information */
info->info_weight_completed = iw;
cyclic_update_info_gf2(G, info);
printf("Completed w=%2d, %.0lf codewords enumerated, lower-bound %d, upper-bound %d\n",
iw, steps, info->displayed_lower_bound, info->upper_bound); fflush(stdout);
lower_bound_met:
free(v);
free(s); if (w <= info->known_lower_bound) {
printf("The known lower-bound is met, enumeration completed.\n");
printf("-----------------------------------------------------------------------------\n");
info->upper_bound = w;
free(c); return;
} if (info->displayed_lower_bound >= info->upper_bound) break;
printf("Termination expected with information weight %d\n",
info->max_info_weight_req);
printf("-----------------------------------------------------------------------------\n");
}
printf("-----------------------------------------------------------------------------\n");
free(c);
}
/* Update INFO structure, which contains various information on the */ /* current progress of enumeration. */ void update_info_gf2(PACKED_MATRIX_GF2 *G, INFO *info) { bool end; short i, j, l, d, w;
/* Estimate the number of matrices required to complete enumeration */
info->matrices_req = 0; for (w=0,i=1;;i++) {
w = (i+1) * G->nFullRankMatrices;
info->matrices_req = G->nFullRankMatrices; for (j=G->nFullRankMatrices; j<G->nMatrices; j++) {
l = i - (G->dimension - G->rank[j]) + 1; if (l > 0) { w += l; info->matrices_req++; }
}
end = false; switch (info->weight_constraint) { case C_0MOD2: if (ROUND_0_MOD_2(w) >= info->upper_bound) end = true; break; case C_1MOD2: if (ROUND_1_MOD_2(w) >= info->upper_bound) end = true; break; case C_3MOD4: if (ROUND_3_MOD_4(w) >= info->upper_bound) end = true; break; case C_0MOD4: if (ROUND_0_MOD_4(w) >= info->upper_bound) end = true; break; default: if (w >= info->upper_bound) end = true;
} if (end) break;
}
/* Estimate the minimum distance lower bound after current enumeration */ if (info->info_weight_completed == 1) /* required for safety */
info->max_info_weight_req = G->dimension; if (info->info_weight_completed < info->max_info_weight_req) {
info->lower_bound = (info->info_weight_completed + 1) * G->nFullRankMatrices; for (j=G->nFullRankMatrices; j<G->nMatrices; j++) {
l = info->info_weight_completed - (G->dimension - G->rank[j]) + 1; if (l > 0) info->lower_bound += l;
}
} else { /* last information weight in enumeration */ for (j=0; j<info->ith_matrix; j++) { if (j < G->nFullRankMatrices) info->lower_bound++; else {
l = i - (G->dimension - G->rank[j]) + 1; if (l > 0) info->lower_bound++;
}
}
}
/* lower-bound information to display, this value could be different */ /* from the actual lower-bound if the code satisfies some weight */ /* constraint such as 0 mod 2, 1 mod 2, 3 mod 4 or 0 mod 4. */ switch (info->weight_constraint) { case C_0MOD2: info->displayed_lower_bound = ROUND_0_MOD_2(info->lower_bound); break; case C_1MOD2: info->displayed_lower_bound = ROUND_1_MOD_2(info->lower_bound); break; case C_3MOD4: info->displayed_lower_bound = ROUND_3_MOD_4(info->lower_bound); break; case C_0MOD4: info->displayed_lower_bound = ROUND_0_MOD_4(info->lower_bound); break; default: info->displayed_lower_bound = info->lower_bound;
}
/* Estimate the maximum information weight required */
d = 0;
w = info->lower_bound; for (i=info->info_weight_completed+1;;i++) { for (j=0; j<G->nMatrices; j++) { if (j < G->nFullRankMatrices)
l = 1; /* this is a trick to reduce the number of lines of codes */ else
l = i - (G->dimension - G->rank[j]) + 1; if (l > 0) {
w++; switch (info->weight_constraint) { case C_0MOD2: d = ROUND_0_MOD_2(w); break; case C_1MOD2: d = ROUND_1_MOD_2(w); break; case C_3MOD4: d = ROUND_3_MOD_4(w); break; case C_0MOD4: d = ROUND_0_MOD_4(w); break; default: d = w;
} if (d >= info->upper_bound) { info->ith_matrix = j + 1; break; }
}
} if (d >= info->upper_bound) { info->max_info_weight_req = i; break; }
}
}
/* Update INFO structure, which contains various information on the */ /* current progress of enumeration. */ void cyclic_update_info_gf2(PACKED_MATRIX_GF2 *G, INFO *info) { short i, d, w;
/* Estimate the minimum distance lower bound after current enumeration */
info->lower_bound = (info->info_weight_completed + 1) * G->nFullRankMatrices;
info->lower_bound = (unsignedint)
ceil(((double)G->block_length/(double)G->dimension)*((double)info->info_weight_completed+1.0));
/* lower-bound information to display, this value could be different */ /* from the actual lower-bound if the code satisfies some weight */ /* constraint such as 0 mod 2, 1 mod 2, 3 mod 4, 0 mod 4. */ switch (info->weight_constraint) { case C_0MOD2: info->displayed_lower_bound = ROUND_0_MOD_2(info->lower_bound); break; case C_1MOD2: info->displayed_lower_bound = ROUND_1_MOD_2(info->lower_bound); break; case C_3MOD4: info->displayed_lower_bound = ROUND_3_MOD_4(info->lower_bound); break; case C_0MOD4: info->displayed_lower_bound = ROUND_0_MOD_4(info->lower_bound); break; default: info->displayed_lower_bound = info->lower_bound;
}
/* Estimate the maximum information weight required */
d = 0; for (i=info->info_weight_completed+1;;i++) {
w = (unsignedint)
ceil(((double)G->block_length/(double)G->dimension)*((double)i+1.0)); switch (info->weight_constraint) { case C_0MOD2: d = ROUND_0_MOD_2(w); break; case C_1MOD2: d = ROUND_1_MOD_2(w); break; case C_3MOD4: d = ROUND_3_MOD_4(w); break; case C_0MOD4: d = ROUND_0_MOD_4(w); break; default: d = w;
} if (d >= info->upper_bound) { info->max_info_weight_req = i; break; }
}
}
/* Convert a binary matrix into packed integer format */
packed_t **to_packed_integer_gf2(MATRIX *G, int nBlocks) { int i, j;
packed_t **M;
M = (packed_t **)malloc(G->rows * sizeof(packed_t *)); for (i=0; i<G->rows; i++) {
M[i] = (packed_t *)malloc(nBlocks * sizeof(packed_t));
memset(M[i], 0, nBlocks * sizeof(packed_t)); for (j=0; j<G->cols; j++) { if (G->m[i][j]) M[i][j >> LOG2] |= (ONE << (j & MOD));
}
} return M;
}
/* Print out a packed GF2 matrix in unpacked format */ void mat_packed_print_gf2(packed_t **M, int nBlocks, int dim, int length) { unsignedint r, i, j; for (r=0; r<dim; r++) { for (i=0; i<nBlocks-1; i++) { for (j=0; j<BITSIZE; j++) {
printf("%d", (M[r][i] & (ONE << j)) ? 1 : 0);
}
} for (i=nBlocks-1,j=0; j<length-(BITSIZE*(nBlocks-1)); j++) {
printf("%d", (M[r][i] & (ONE << j)) ? 1 : 0);
}
printf("\n");
}
}
/* gauss jordan - turn matrix 'M' into reduced-echelon format at position 'start' */ int gf2_gauss_jordan(MATRIX *M, int start) { bool found; int i, r, c, pivot, swap; for (c=0; c<M->rows; ++c) { /* diagonalise the element from col=1 to rows */ if (c+start >= M->cols) return c; if (!M->m[c][c+start]) { /* pivot is zero, do row swapping */ for (found=false,r=c+1; r<M->rows; ++r) { if (M->m[r][c+start]) { found=true; break; } } if (found) { for (i=0; i<M->cols; ++i) { swap=M->m[r][i]; M->m[r][i]=M->m[c][i]; M->m[c][i]=swap; }
} else { /* row swapping failed, do column swapping */ for (found=false,i=start+c+1; i<M->cols; ++i) { for (r=c; r<M->rows; ++r) { if (M->m[r][i]) { found=true; break; } } if (found) break;
} if (!found) return c; for (pivot=i,i=0; i<M->cols; ++i) { swap=M->m[r][i]; M->m[r][i]=M->m[c][i]; M->m[c][i]=swap; } for (r=0; r<M->rows; ++r) {
swap=M->m[r][pivot]; M->m[r][pivot]=M->m[r][c+start]; M->m[r][c+start]=swap;
}
}
} for (r=0; r<M->rows; ++r) { /* zero the whole rows at column c, except at row c (diagonalisation) */ if (r==c) continue; if (M->m[r][c+start]) {
pivot = M->m[r][c+start]; for (i=0; i<M->cols; ++i)
M->m[r][i] = (M->m[r][i] - M->m[c][i]) & 0x1;
}
}
} return c;
}
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.