14namespace layer1_foundations {
15namespace coding_theory {
46static void print_matrix(
MINDIST *MD,
int **G);
47static int min_weight(
MINDIST *MD);
48static void create_systematic_generator_matrices(
MINDIST *MD);
49static int weight_of_linear_combinations(
MINDIST *MD,
int t);
50static int weight(
int *v,
int n,
int idx_zero);
51static void padic(
int ind,
int *v,
int L,
int A);
52static int nextsub(
int k,
int l,
int *sub);
53static void vmmult(
MINDIST *MD,
int *v,
int **mx,
int *cv);
56 int verbose_level,
int idx_zero,
int idx_one,
57 int *add_table,
int *mult_table)
71 MD.
f_v = (verbose_level >= 1);
72 MD.
f_vv = (verbose_level >= 2);
82 MD.
ff_mult = (
int *) malloc(
sizeof(
int) * q * q);
83 MD.
ff_add = (
int *) malloc(
sizeof(
int) * q * q);
84 MD.
ff_inv = (
int *) malloc(
sizeof(
int) * q);
88 cout <<
"multiplication table:" << endl;
90 for (i = 0; i < q; i++) {
91 for (j = 0; j < q; j++) {
92 a = (int) mult_table[i * q + j];
109 cout <<
"addition table:" << endl;
111 for (i = 0; i < q; i++) {
112 for (j = 0; j < q; j++) {
113 a = (int) add_table[i * q + j];
126 cout <<
"multiplication table:" << endl;
128 for (i = 0; i < q; i++) {
129 for (j = 0; j < q; j++) {
146 cout <<
"addition table:" << endl;
148 for (i = 0; i < q; i++) {
149 for (j = 0; j < q; j++) {
162 cout <<
"the field: GF(" << MD.
q <<
") = GF(" << MD.
p <<
"^" << MD.
f <<
")" << endl;
163 cout <<
"idx_zero = " << MD.
idx_zero <<
", idx_one = " << MD.
idx_one <<
", idx_mone = " << MD.
idx_mone << endl;
167 cout <<
"at the moment, we assume that idx_zero == 0" << endl;
171 MD.
G = (
int **) malloc((
sizeof (
int *))*(k+2));
172 for (i = 1; i <= k; i++) {
173 MD.
G[i] = (
int *)calloc(n+2,
sizeof(
int));
176 for (i = 0; i < k; i++) {
178 for (j = 0; j < n; j++) {
185 for (i = 1; i <= k; i++) {
186 for (j = 1; j <= n; j++) {
187 a = G[(i-1)*n + j - 1];
192 cout <<
"(" << n <<
"," << k <<
") code over GF(" << q <<
"), generated by" << endl;
193 print_matrix(&MD, MD.
G);
200 cout <<
"the minimum distance is " << d << endl;
201 cout <<
"This was determined by looking at "
203 <<
" codewords\n(rather than "
204 << NT.
i_power_j(q, k) <<
" codewords)" << endl;
209 cout <<
"min weight = " << d <<
210 " is less than the weight of the vectors in "
211 "the rows, which is " << wt_rows << endl;
212 print_matrix(&MD, MD.
G);
217 for (i = 1; i <= k; i++) {
227static void print_matrix(
MINDIST *MD,
int **G)
231 for (i = 1; i <= MD->
k; i++) {
232 for (j = 1; j <= MD->
n; j++) {
242static int min_weight(
MINDIST *MD)
256 MD->S = (
int ***)malloc((
sizeof (
int **))*(n+2));
257 create_systematic_generator_matrices(MD);
260 for (i = 1; i <= MD->M; i++) {
261 size = size + MD->Size[i];
266 while (w_c > w_r && t < k) {
271 w_t = weight_of_linear_combinations(MD, t);
278 cout <<
"\\bar{d}_" << t <<
"=" << w_t << endl;
282 cout <<
"mindist(C_{\\le " << t <<
"})=" << w_c << endl;
286 cout <<
"\\bar{d}_" << t <<
"=";
289 for (i = 1; i <= MD->M; i++) {
296 cout <<
" +" << t + 1 <<
"-(" << k <<
"-" << MD->Size[i] <<
")" << endl;
300 cout <<
"=" << w_r << endl;
306 cout <<
"min weight = " << w_c <<
307 " is less than the weight of the vectors in the rows, which is " << w_1 << endl;
308 print_matrix(MD, MD->G);
309 for (i = 1; i <= MD->M; i++) {
310 cout << i <<
"-th matrix:" << endl;
311 print_matrix(MD, MD->S[MD->M]);
316 for (i = 1; i <= MD->M; i++){
317 for (j = 1; j <= k; j++) {
328static void create_systematic_generator_matrices(
MINDIST *MD)
343 int i, I = 0, j, J, l;
344 int P, h, h1, h2, h3, pivot, pivot_inv;
349 MD->S[1] = (
int **)calloc(k+2,
sizeof(
int *));
350 for (i = 1; i <= k; i++) {
351 MD->S[1][i] = (
int *)calloc(n+2,
sizeof(
int));
355 for (i = 1; i <= k; i++) {
356 for (j = 1; j <= n; j++) {
357 MD->S[1][i][j] = MD->G[i][j];
361 MD->Size = (
int *)calloc(n+1,
sizeof(
int ));
369 cout <<
"loop with M = " << M <<
", P = " << P <<
" K = " << K << endl;
374 for (i = 1; i <= K; i++) {
376 cout <<
"i = " << i <<
" ";
377 cout <<
" (M = " << M <<
", P = " << P <<
" K = " << K << endl;
386 for (J = P + i; J <= n; J++) {
387 for (I = i; I <= K; I++) {
388 if (MD->S[M][I][J] != MD->idx_zero) {
398 cout <<
"I=" << I <<
", J=" << J << endl;
402 if ((I <= K) && (J == n)) {
404 cout <<
"end reached, I = " << I << endl;
411 cout <<
"pivot in I=" << I <<
" J=" << J << endl;
416 if (I > K && J > n) {
419 cout <<
"no pivot" << endl;
427 cout << endl <<
"swapping rows: " << i <<
"<->" << I << endl;
429 for (j = 1; j <= n; j++) {
431 MD->S[M][i][j] = MD->S[M][I][j];
439 cout << endl <<
"swapping columns: " << P + i <<
"<->" << J << endl;
441 for (j = 1; j <= k; j++) {
442 h = MD->S[M][j][i+P];
443 MD->S[M][j][i+P] = MD->S[M][j][J];
448 pivot = MD->S[M][i][P + i];
449 if (pivot == MD->idx_zero) {
450 cout <<
"pivot is 0, exiting!" << endl;
452 pivot_inv = MD->ff_inv[pivot];
454 cout <<
"pivot = " << pivot <<
", pivot_inv = " << pivot_inv << endl;
457 if (MD->S[M][i][P+i] != MD->idx_one) {
458 for (j = 1; j <= n; j++) {
459 MD->S[M][i][j] = MD->ff_mult[MD->S[M][i][j] * q + pivot_inv];
463 cout <<
"pivot row normalized" << endl;
468 for (l = 1; l <= k; l++) {
470 if ((h = MD->S[M][l][i+P]) != MD->idx_zero)
471 for (j = 1; j <= n; j++) {
472 h1 = MD->ff_mult[MD->S[M][i][j] * q + h];
473 h2 = MD->ff_mult[h1 * q + MD->idx_mone];
474 h3 = MD->ff_add[MD->S[M][l][j] * q + h2];
480 mod_p(MD->S[M][l][j] - MD->S[M][i][j] * h);
486 cout <<
"pivot col normalized" << endl;
492 cout << endl <<
"systematic generator matrix s[" << M <<
"]:" << endl;
493 print_matrix(MD, MD->S[M]);
500 cout <<
"K = 0, the generator matrix has " << n - P <<
" zero columns" << endl;
503 if (P + K >= n || K == 0) {
515 MD->S[M] = (
int **)calloc(k+2,
sizeof(
int *));
517 for (i = 1; i <= k; i++) {
518 MD->S[M][i] = (
int *)calloc(n+2,
sizeof(
int));
522 for (i = 1; i <= k; i++) {
523 for (j = 1; j <= n; j++) {
524 MD->S[M][i][j] = MD->S[M-1][i][j];
532 cout <<
"size of information subsets:" << endl;
533 for (i = 1; i <= M; i++) {
534 cout << MD->Size[i] <<
" ";
542static int weight_of_linear_combinations(
MINDIST *MD,
int l)
568 number_theory::number_theory_domain NT;
574 sub = (
int *)calloc(k+1,
sizeof (
int));
578 for (z = 1; z <= M; z++) {
579 for (i = 1; i <= k; i++) {
581 if (MD->Size[z] > 0) {
582 d1 = weight(MD->S[z][i], n, MD->idx_zero);
583 MD->weight_computations++;
587 cout <<
"matrix " << z <<
" row " << i <<
" is ";
588 for (j = 1; j <= n; j++) {
589 cout << MD->S[z][i][j] <<
" ";
591 cout <<
" of weight " << d1 <<
" minimum is " << d_l << endl;
605 v = (
int*)calloc(l+2,
sizeof(
int));
606 linc = (
int*)calloc(k+2,
sizeof(
int));
607 lcv = (
int*)calloc(n+2,
sizeof(
int));
609 lc = NT.i_power_j(q-1, l);
617 for (dec = 1; dec <= lc; dec++) {
618 padic(dec, v, l, q-1);
621 for (z = 1; z <= M; z++) {
628 for (i = 1; i <= l; i++) {
637 for (j = 1; j <= K; j++) {
649 vmmult(MD, linc, MD->S[z], lcv);
652 w = weight(lcv, n, MD->idx_zero);
654 MD->weight_computations++;
658 for (i = 1; i <= k; i++) {
659 cout << linc[i] <<
" ";
662 for (i = 1; i <= n; i++) {
663 cout << lcv[i] <<
" ";
665 cout <<
" of weight " << w <<
" minimum is " << d_l << endl;
667 }
while (nextsub(K,l,sub));
679static int weight(
int *v,
int n,
int idx_zero)
686 for (i = 1; i <= n; i++) {
687 if (v[i] != idx_zero) {
694static void padic(
int ind,
int *v,
int L,
int A)
699 for (i = 0; i < L; i++) {
706static int nextsub(
int k,
int l,
int *sub)
717 while (i < l && sub[l - i] == k-i) {
722 for (j = l - i; j <= l; j++) {
723 sub[j] = a + 1 + j - (l - i);
735static void vmmult(
MINDIST *MD,
int *v,
int **mx,
int *cv)
743 for (j = 1; j <= MD->n; j++) {
745 for (i = 1; i <= k; i++) {
746 h1 = MD->ff_mult[v[i] * q + mx[i][j]];
747 h2 = MD->ff_add[cv[j] * q + h1];
int mindist(int n, int k, int q, int *G, int f_verbose_level, int idx_zero, int idx_one, int *add_table, int *mult_table)
basic number theoretic functions
int i_power_j(int i, int j)
void factor_prime_power(int q, int &p, int &e)
the orbiter library for the classification of combinatorial objects
internal class for the algorithm to compute the minimum distance of a linear code