Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/guava/src/ctjhai/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 1.1.2025 mit Größe 24 kB image not shown  

Quelle  minimum-weight-gf2.c   Sprache: C

 
/*
 * 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
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "minimum-weight-gf2.h"
#include "popcount.h"
#include "config.h"
#include "types.h"

/*--------- Some useful macros for updating upper-bound ---------*/
#define ROUND_0_MOD_2(d) (((int) ceil((double)d/2.0))*2) /* (singly) even code */
#define ROUND_1_MOD_2(d) ((d & 0x1) ? d : d+1)
#define ROUND_0_MOD_4(d) (((int) ceil((double)d/4.0))*4) /* doubly-even code */
#define ROUND_3_MOD_4(d) ((d & 0x11) ? ROUND_0_MOD_4(d+1) : ROUND_0_MOD_4(d))

/*-------------------- 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;
 unsigned int 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= (unsigned short *)malloc(j * sizeof(unsigned short));
 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);
  
  packedG.rank[i] = rank;
  pos += rank;
  packedG.nMatrices++;
  if (rank == G.rows) packedG.nFullRankMatrices++;
 }

 /*---------------------- 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;
  defaultbreak;
 }
 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;
 unsigned int 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= (unsigned short *)malloc(j * sizeof(unsigned short));
 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;
  defaultbreak;
 }
 fflush(stdout);
 info.matrices_req = 1;
 
 /* Obtain the first lower-bound */
 info.known_lower_bound = lower_bound;
 info.lower_bound = (unsigned int)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 ----------------------------*/

completed: 
 /* Deallocating memory */
 for (j=0; j<G.rows; j++) free(packedG.mat[0][j]);
 free(packedG.mat[0]);
 free(packedG.mat);
 
 return info.upper_bound;
}

/* 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;
 register short 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;
 register short 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 = truebreak;
   case C_1MOD2: if (ROUND_1_MOD_2(w) >= info->upper_bound) end = truebreak;
   case C_3MOD4: if (ROUND_3_MOD_4(w) >= info->upper_bound) end = truebreak;
   case C_0MOD4: if (ROUND_0_MOD_4(w) >= info->upper_bound) end = truebreak;
   defaultif (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 = (unsigned int)
  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 = (unsigned int)
   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) {
 unsigned int 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=truebreak; } }
   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=truebreak; } }
     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;
}

Messung V0.5
C=89 H=67 G=78

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.