18namespace layer1_foundations {
19namespace number_theory {
22static void ntt4_forward(
int *input,
int *output, field_theory::finite_field *F);
23static void ntt4_backward(
int *input,
int *output, field_theory::finite_field *F);
69 int k,
int q,
int verbose_level)
71 int f_v = (verbose_level >= 1);
73 int nb_m10, nb_m11, nb_a10, nb_a11;
74 int nb_m20, nb_m21, nb_a20, nb_a21;
82 cout <<
"number_theoretic_transform::init" << endl;
83 cout <<
"number_theoretic_transform::init k = " <<
k <<
" q=" <<
q << endl;
93 sprintf(str,
"k%d_q%d.cpp",
k,
q);
104 cout <<
"alpha = " <<
alpha << endl;
112 for (h = 0; h <=
k; h++) {
116 cout <<
"N[]:" << endl;
119 idx = (
q - 1) /
N[
k];
122 cout <<
"idx = " << idx << endl;
123 cout <<
"omega = " <<
omega << endl;
131 for (h =
k; h >= 1; h--) {
136 sprintf(str,
"Fourier_q%d_N%d.csv",
q,
N[h]);
153 for (i = 1; i <
N[
k]; i++) {
158 cout <<
"alphaQ=" <<
alphaQ << endl;
159 cout <<
"psi=" <<
psi << endl;
160 cout <<
"Psi_powers:" << endl;
168 cout <<
"Omega:" << endl;
172 cout <<
"h : N[h] : Omega[h] : multiplicative_order : Omega[h]^2" << endl;
173 for (h =
k; h >= 1; h--) {
174 cout << setw(3) << h <<
" : ";
175 cout << setw(3) <<
N[h] <<
" : ";
176 cout << setw(3) <<
Omega[h] <<
" : ";
183 for (h =
k; h >= 0; h--) {
185 for (i = 0; i <
N[h]; i++) {
186 for (j = 0; j <
N[h]; j++) {
190 cout <<
"A_" <<
N[h] <<
" using logarithms (+1):" << endl;
203 for (i = 0; i <
N[
k]; i++) {
206 cout <<
"X:" << endl;
219 nb_m1 = nb_m11 - nb_m10;
220 nb_a1 = nb_a11 - nb_a10;
222 cout <<
"nb_m1 = " << nb_m1 <<
" nb_a1 = " << nb_a1 << endl;
225 cout <<
"Y:" << endl;
235 for (i = 0; i <
N[
k - 1]; i++) {
236 X1[i] =
X[2 * i + 0];
237 X2[i] =
X[2 * i + 1];
247 for (i = 0; i <
N[
k - 1]; i++) {
258 nb_m2 = nb_m21 - nb_m20;
259 nb_a2 = nb_a21 - nb_a20;
261 cout <<
"nb_m2 = " << nb_m2 <<
" nb_a2 = " << nb_a2 << endl;
264 cout <<
"Z:" << endl;
268 for (i = 0; i <
N[
k]; i++) {
270 cout <<
"problem in component " << i << endl;
314 cout <<
"G[k-1]:" << endl;
317 cout <<
"D[k-1]:" << endl;
320 cout <<
"T[k-1]:" << endl;
323 cout <<
"Tv[k-1]:" << endl;
326 cout <<
"P[k-1]:" << endl;
341 sprintf(str,
"ntt_F_k%d.csv",
k);
343 sprintf(str,
"ntt_Fv_k%d.csv",
k);
344 fname_Fv.assign(str);
345 sprintf(str,
"ntt_G_k%d.csv",
k);
347 sprintf(str,
"ntt_D_k%d.csv",
k);
349 sprintf(str,
"ntt_Dv_k%d.csv",
k);
350 fname_Dv.assign(str);
351 sprintf(str,
"ntt_T_k%d.csv",
k);
353 sprintf(str,
"ntt_Tv_k%d.csv",
k);
354 fname_Tv.assign(str);
355 sprintf(str,
"ntt_P_k%d.csv",
k);
366 cout <<
"Written file " << fname_F <<
" of size " << Fio.
file_size(fname_F) << endl;
367 cout <<
"Written file " << fname_Fv <<
" of size " << Fio.
file_size(fname_Fv) << endl;
368 cout <<
"Written file " << fname_G <<
" of size " << Fio.
file_size(fname_G) << endl;
369 cout <<
"Written file " << fname_D <<
" of size " << Fio.
file_size(fname_D) << endl;
370 cout <<
"Written file " << fname_Dv <<
" of size " << Fio.
file_size(fname_Dv) << endl;
371 cout <<
"Written file " << fname_T <<
" of size " << Fio.
file_size(fname_T) << endl;
372 cout <<
"Written file " << fname_Tv <<
" of size " << Fio.
file_size(fname_Tv) << endl;
373 cout <<
"Written file " << fname_P <<
" of size " << Fio.
file_size(fname_P) << endl;
382 for (i = 0; i <
N[
k] *
N[
k]; i++) {
384 cout <<
"matrix product differs from the Fourier matrix, problem in component " << i << endl;
392 cout <<
"number_theoretic_transform::init before make_level(k - 2)" << endl;
398 cout <<
"number_theoretic_transform::init before make_level(k - 3)" << endl;
414 Stack[2] =
Pr[
k - 1];
417 cout <<
"the_P:" << endl;
421 sprintf(str,
"ntt_the_P_k%d.csv",
k);
424 cout <<
"Written file " << fname_P <<
" of size " << Fio.
file_size(fname_P) << endl;
428 for (i = 0; i <
N[
k]; i++) {
429 for (j = 0; j <
N[
k]; j++) {
430 if (the_P[i *
N[
k] + j]) {
436 cout <<
"bit_reversal:" << endl;
441 Stack[0] =
Gr[
k - 1];
442 Stack[1] =
Dr[
k - 1];
451 cout <<
"the_L:" << endl;
457 sprintf(str,
"ntt_L_k%d.csv",
k);
460 cout <<
"Written file " << fname_L <<
" of size " << Fio.
file_size(fname_L) << endl;
473 cout <<
"G[2]*D[2]*T[2]*P[2]=" << endl;
478 for (i = 0; i <
N[3] *
N[3]; i++) {
479 if (
A[3][i] != the_L[i]) {
480 cout <<
"matrix product differs from the Fourier matrix, problem in component " << i << endl;
493 cout <<
"A*Av=" << endl;
499 sprintf(str,
"ntt_AAv_k%d.csv",
k);
500 fname_AAv.assign(str);
502 cout <<
"Written file " << fname_AAv <<
" of size " << Fio.
file_size(fname_AAv) << endl;
522 cout <<
"Hom->get_nb_monomials() != N[k]" << endl;
537 for (i = 0; i <
N[
k]; i++) {
541 cout <<
"poly_A:" << endl;
546 for (i = 0; i <
N[
k]; i++) {
550 cout <<
"poly_B:" << endl;
557 cout <<
"poly_C:" << endl;
562 ntt4_forward(poly_A, poly_Ap,
F);
563 ntt4_forward(poly_B, poly_Bp,
F);
565 for (i = 0; i <
N[
k]; i++) {
566 poly_Cp[i] =
F->
mult(poly_Ap[i], poly_Bp[i]);
568 ntt4_backward(poly_Cp, poly_C,
F);
570 cout <<
"poly_C:" << endl;
575 cout <<
"negatively wrapped convolution:" << endl;
579 cout <<
"poly_C:" << endl;
583 for (i = 0; i <
N[
k]; i++) {
586 for (i = 0; i <
N[
k]; i++) {
589 ntt4_forward(poly_A, poly_Ap,
FQ);
590 ntt4_forward(poly_B, poly_Bp,
FQ);
592 for (i = 0; i <
N[
k]; i++) {
593 poly_Cp[i] =
FQ->
mult(poly_Ap[i], poly_Bp[i]);
595 ntt4_backward(poly_Cp, poly_C,
FQ);
596 for (i = 0; i <
N[
k]; i++) {
599 cout <<
"poly_C:" << endl;
607 cout <<
"number_theoretic_transform::init done" << endl;
617 int f_v = (verbose_level = 1);
621 cout <<
"number_theoretic_transform::write_code" << endl;
645 int &nb_add,
int &nb_negate,
int &nb_mult,
648 int f_v = (verbose_level = 1);
649 int i, j1, j2, a, b, c, d;
652 cout <<
"number_theoretic_transform::write_code2" << endl;
658 ost <<
"void ntt" <<
k <<
"_forward(int *input, int *output, finite_field *F)" << endl;
661 ost <<
"void ntt" <<
k <<
"_backward(int *input, int *output, finite_field *F)" << endl;
664 ost <<
"\tint t0[" <<
N[
k] <<
"];" << endl;
665 ost <<
"\tint t1[" <<
N[
k] <<
"];" << endl;
666 ost <<
"\tint t2[" <<
N[
k] <<
"];" << endl;
667 ost <<
"\tint t3[" <<
N[
k] <<
"];" << endl;
668 ost <<
"\tint t4[" <<
N[
k] <<
"];" << endl;
669 ost <<
"\tint t5[" <<
N[
k] <<
"];" << endl;
671 for (i = 0; i <
N[
k]; i += 2) {
672 a =
T[
k - 3][i *
N[
k] + i];
673 b =
T[
k - 3][i *
N[
k] + i + 1];
674 c =
T[
k - 3][(i + 1) *
N[
k] + i];
675 d =
T[
k - 3][(i + 1) *
N[
k] + i + 1];
677 cout <<
"a != 1" << endl;
681 cout <<
"b != 1" << endl;
685 cout <<
"c != 1" << endl;
689 cout <<
"d != -1" << endl;
692 ost <<
"\tt0[" << i <<
"] = F->add(input[" <<
bit_reversal[i] <<
"], input[" <<
bit_reversal[i + 1] <<
"]);" << endl;
693 ost <<
"\tt0[" << i + 1 <<
"] = F->add(input[" <<
bit_reversal[i] <<
"], F->negate(input[" <<
bit_reversal[i + 1] <<
"]));" << endl;
698 for (i = 0; i <
N[
k]; i++) {
700 d =
D[
k - 3][i *
N[
k] + i];
703 d =
Dv[
k - 3][i *
N[
k] + i];
706 ost <<
"\tt1[" << i <<
"] = t0[" << i <<
"];" << endl;
709 ost <<
"\tt1[" << i <<
"] = F->negate(t0[" << i <<
"]);" << endl;
713 ost <<
"\tt1[" << i <<
"] = F->mult(" << d <<
", t0[" << i <<
"]);" << endl;
718 for (i = 0; i <
N[
k]; i++) {
719 for (j1 = 0; j1 <
N[
k]; j1++) {
720 a =
G[
k - 3][i *
N[
k] + j1];
725 for (j2 = j1 + 1; j2 <
N[
k]; j2++) {
726 b =
G[
k - 3][i *
N[
k] + j2];
731 ost <<
"\tt2[" << i <<
"] = F->add(";
735 ost <<
"t1[" << j1 <<
"]";
738 ost <<
"F->negate(t1[" << j1 <<
"])";
742 ost <<
"F->mult(" << a <<
", t1[" << j1 <<
"])";
747 ost <<
"t1[" << j2 <<
"]";
750 ost <<
"F->negate(t1[" << j2 <<
"])";
754 ost <<
"F->mult(" << b <<
", t1[" << j2 <<
"])";
762 for (i = 0; i <
N[
k]; i++) {
764 d =
D[
k - 2][i *
N[
k] + i];
767 d =
Dv[
k - 2][i *
N[
k] + i];
770 ost <<
"\tt3[" << i <<
"] = t2[" << i <<
"];" << endl;
773 ost <<
"\tt3[" << i <<
"] = F->negate(t2[" << i <<
"]);" << endl;
777 ost <<
"\tt3[" << i <<
"] = F->mult(" << d <<
", t2[" << i <<
"]);" << endl;
782 for (i = 0; i <
N[
k]; i++) {
783 for (j1 = 0; j1 <
N[
k]; j1++) {
784 a =
G[
k - 2][i *
N[
k] + j1];
789 for (j2 = j1 + 1; j2 <
N[
k]; j2++) {
790 b =
G[
k - 2][i *
N[
k] + j2];
795 ost <<
"\tt4[" << i <<
"] = F->add(";
799 ost <<
"t3[" << j1 <<
"]";
802 ost <<
"F->negate(t3[" << j1 <<
"])";
806 ost <<
"F->mult(" << a <<
", t3[" << j1 <<
"])";
811 ost <<
"t3[" << j2 <<
"]";
814 ost <<
"F->negate(t3[" << j2 <<
"])";
818 ost <<
"F->mult(" << b <<
", t3[" << j2 <<
"])";
825 for (i = 0; i <
N[
k]; i++) {
827 d =
Dr[
k - 1][i *
N[
k] + i];
830 d =
Dvr[
k - 1][i *
N[
k] + i];
833 ost <<
"\tt5[" << i <<
"] = t4[" << i <<
"];" << endl;
836 ost <<
"\tt5[" << i <<
"] = F->negate(t4[" << i <<
"]);" << endl;
840 ost <<
"\tt5[" << i <<
"] = F->mult(" << d <<
", t4[" << i <<
"]);" << endl;
846 for (i = 0; i <
N[
k]; i++) {
847 for (j1 = 0; j1 <
N[
k]; j1++) {
848 a =
Gr[
k - 1][i *
N[
k] + j1];
853 for (j2 = j1 + 1; j2 <
N[
k]; j2++) {
854 b =
Gr[
k - 1][i *
N[
k] + j2];
859 ost <<
"\toutput[" << i <<
"] = ";
860 if (f_forward ==
FALSE) {
868 ost <<
"t5[" << j1 <<
"]";
871 ost <<
"F->negate(t5[" << j1 <<
"])";
875 ost <<
"F->mult(" << a <<
", t5[" << j1 <<
"])";
880 ost <<
"t5[" << j2 <<
"]";
883 ost <<
"F->negate(t5[" << j2 <<
"])";
887 ost <<
"F->mult(" << b <<
", t5[" << j2 <<
"])";
891 if (f_forward ==
FALSE) {
897 ost <<
"// nb_add = " << nb_add << endl;
898 ost <<
"// nb_negate = " << nb_negate << endl;
899 ost <<
"// nb_mult = " << nb_mult << endl;
904 cout <<
"number_theoretic_transform::write_code done" << endl;
919 ost <<
" * Created on: " << str << endl;
920 ost <<
" * Author: Orbiter" << endl;
921 ost <<
" */" << endl;
923 ost <<
"#include \"orbiter.h\"" << endl;
925 ost <<
"using namespace std;" << endl;
926 ost <<
"using namespace orbiter;" << endl;
928 ost <<
"void ntt" <<
k <<
"_forward(int *input, int *output, finite_field *F);" << endl;
929 ost <<
"void ntt" <<
k <<
"_backward(int *input, int *output, finite_field *F);" << endl;
931 ost <<
"int main(int argc, char **argv)" << endl;
933 ost <<
"\torbiter::top_level::orbiter_top_level_session Top_level_session;" << endl;
934 ost <<
"\torbiter::top_level::The_Orbiter_top_level_session = &Top_level_session;" << endl;
935 ost <<
"\torbiter::top_level::The_Orbiter_top_level_session->Orbiter_session = new orbiter_session;" << endl;
936 ost <<
"\tfinite_field *F;" << endl;
937 ost <<
"\tos_interface Os;" << endl;
938 ost <<
"\tint q = " <<
q <<
";" << endl;
939 ost <<
"\tint n = " <<
N[
k] <<
";" << endl;
940 ost <<
"\tint i;" << endl;
942 ost <<
"\tF = NEW_OBJECT(finite_field);" << endl;
943 ost <<
"\tF->finite_field_init(q, FALSE /*f_without_tables*/, 0 /*verbose_level*/);" << endl;
945 ost <<
"\tint *input;" << endl;
946 ost <<
"\tint *output;" << endl;
948 ost <<
"\tinput = NEW_int(n);" << endl;
949 ost <<
"\toutput = NEW_int(n);" << endl;
951 ost <<
"\tfor (i = 0; i < n; i++) {" << endl;
952 ost <<
"\t\tinput[i] = Os.random_integer(q);" << endl;
953 ost <<
"\t}" << endl;
954 ost <<
"\tcout << \"input:\" << endl;" << endl;
955 ost <<
"\tOrbiter->Int_vec.matrix_print(input, 1, n);" << endl;
956 ost <<
"\tcout << endl;" << endl;
958 ost <<
"\tntt" <<
k <<
"_forward(input, output, F);" << endl;
960 ost <<
"\tcout << \"output:\" << endl;" << endl;
961 ost <<
"\tOrbiter->Int_vec.matrix_print(output, 1, n);" << endl;
962 ost <<
"\tcout << endl;" << endl;
964 ost <<
"\tFREE_OBJECT(F);" << endl;
973 int f_v = (verbose_level = 1);
978 cout <<
"number_theoretic_transform::make_level s=" << s << endl;
984 cout <<
"making k - 2 matrices:" << endl;
1000 cout <<
"Gr[" << s <<
"]:" << endl;
1003 cout <<
"Dr[" << s <<
"]:" << endl;
1006 cout <<
"Dvr[" << s <<
"]:" << endl;
1009 cout <<
"Tr[" << s <<
"]:" << endl;
1012 cout <<
"Tvr[" << s <<
"]:" << endl;
1015 cout <<
"Pr[" << s <<
"]:" << endl;
1021 char fname_Fv[1000];
1024 char fname_Dv[1000];
1026 char fname_Tv[1000];
1029 snprintf(fname_F, 1000,
"ntt_F_k%d.csv", s + 1);
1030 snprintf(fname_Fv, 1000,
"ntt_Fv_k%d.csv", s + 1);
1031 snprintf(fname_G, 1000,
"ntt_Gr_k%d.csv", s + 1);
1032 snprintf(fname_D, 1000,
"ntt_Dr_k%d.csv", s + 1);
1033 snprintf(fname_Dv, 1000,
"ntt_Dvr_k%d.csv", s + 1);
1034 snprintf(fname_T, 1000,
"ntt_Tr_k%d.csv", s + 1);
1035 snprintf(fname_Tv, 1000,
"ntt_Tvr_k%d.csv", s + 1);
1036 snprintf(fname_P, 1000,
"ntt_Pr_k%d.csv", s + 1);
1048 sprintf(str,
"ntt_F_k%d.csv", s + 1);
1049 fname_F.assign(str);
1050 sprintf(str,
"ntt_Fv_k%d.csv", s + 1);
1051 fname_Fv.assign(str);
1052 sprintf(str,
"ntt_Gr_k%d.csv", s + 1);
1053 fname_G.assign(str);
1054 sprintf(str,
"ntt_Dr_k%d.csv", s + 1);
1055 fname_D.assign(str);
1056 sprintf(str,
"ntt_Dvr_k%d.csv", s + 1);
1057 fname_Dv.assign(str);
1058 sprintf(str,
"ntt_Tr_k%d.csv", s + 1);
1059 fname_T.assign(str);
1060 sprintf(str,
"ntt_Tvr_k%d.csv", s + 1);
1061 fname_Tv.assign(str);
1062 sprintf(str,
"ntt_Pr_k%d.csv", s + 1);
1063 fname_P.assign(str);
1074 cout <<
"Written file " << fname_F <<
" of size " << Fio.
file_size(fname_F) << endl;
1075 cout <<
"Written file " << fname_Fv <<
" of size " << Fio.
file_size(fname_Fv) << endl;
1076 cout <<
"Written file " << fname_G <<
" of size " << Fio.
file_size(fname_G) << endl;
1077 cout <<
"Written file " << fname_D <<
" of size " << Fio.
file_size(fname_D) << endl;
1078 cout <<
"Written file " << fname_Dv <<
" of size " << Fio.
file_size(fname_Dv) << endl;
1079 cout <<
"Written file " << fname_T <<
" of size " << Fio.
file_size(fname_T) << endl;
1080 cout <<
"Written file " << fname_Tv <<
" of size " << Fio.
file_size(fname_Tv) << endl;
1081 cout <<
"Written file " << fname_P <<
" of size " << Fio.
file_size(fname_P) << endl;
1088 for (i = 0; i <
N[s + 1] *
N[s + 1]; i++) {
1089 if (
A[s + 1][i] !=
Tmp1[i]) {
1090 cout <<
"matrix product differs from the Fourier matrix, problem in component " << i << endl;
1102 cout <<
"G[" << s <<
"]:" << endl;
1105 cout <<
"D[" << s <<
"]:" << endl;
1108 cout <<
"Dv[" << s <<
"]:" << endl;
1111 cout <<
"T[" << s <<
"]:" << endl;
1114 cout <<
"Tv[" << s <<
"]:" << endl;
1117 cout <<
"P[" << s <<
"]:" << endl;
1123 snprintf(fname_G, 1000,
"ntt_G_k%d.csv", s + 1);
1124 snprintf(fname_D, 1000,
"ntt_D_k%d.csv", s + 1);
1125 snprintf(fname_Dv, 1000,
"ntt_Dv_k%d.csv", s + 1);
1126 snprintf(fname_T, 1000,
"ntt_T_k%d.csv", s + 1);
1127 snprintf(fname_Tv, 1000,
"ntt_Tv_k%d.csv", s + 1);
1128 snprintf(fname_P, 1000,
"ntt_P_k%d.csv", s + 1);
1130 sprintf(str,
"ntt_G_k%d.csv", s + 1);
1131 fname_G.assign(str);
1132 sprintf(str,
"ntt_D_k%d.csv", s + 1);
1133 fname_D.assign(str);
1134 sprintf(str,
"ntt_Dv_k%d.csv", s + 1);
1135 fname_Dv.assign(str);
1136 sprintf(str,
"ntt_T_k%d.csv", s + 1);
1137 fname_T.assign(str);
1138 sprintf(str,
"ntt_Tv_k%d.csv", s + 1);
1139 fname_Tv.assign(str);
1140 sprintf(str,
"ntt_P_k%d.csv", s + 1);
1141 fname_P.assign(str);
1151 cout <<
"Written file " << fname_F <<
" of size " << Fio.
file_size(fname_F) << endl;
1152 cout <<
"Written file " << fname_G <<
" of size " << Fio.
file_size(fname_G) << endl;
1153 cout <<
"Written file " << fname_D <<
" of size " << Fio.
file_size(fname_D) << endl;
1154 cout <<
"Written file " << fname_Dv <<
" of size " << Fio.
file_size(fname_Dv) << endl;
1155 cout <<
"Written file " << fname_T <<
" of size " << Fio.
file_size(fname_T) << endl;
1156 cout <<
"Written file " << fname_Tv <<
" of size " << Fio.
file_size(fname_Tv) << endl;
1157 cout <<
"Written file " << fname_P <<
" of size " << Fio.
file_size(fname_P) << endl;
1166 int f_v = (verbose_level = 1);
1167 int i, j, i0, t, h, a;
1171 cout <<
"number_theoretic_transform::paste k=" <<
k << endl;
1175 cout <<
"algebra_global::paste t=" << t << endl;
1176 cout <<
"algebra_global::paste N[s + 1]=" <<
N[s + 1] << endl;
1177 cout <<
"algebra_global::paste N[k]=" <<
N[
k] << endl;
1182 for (h = 0; h < t; h++) {
1184 cout <<
"h=" << h <<
" i0=" << i0 << endl;
1186 for (i = 0; i <
N[s + 1]; i++) {
1187 for (j = 0; j <
N[s + 1]; j++) {
1188 a = Xr[s][i *
N[s + 1] + j];
1189 X[s][(i0 + i) *
N[
k] + i0 + j] = a;
1195 cout <<
"number_theoretic_transform::paste created matrix" << endl;
1199 cout <<
"number_theoretic_transform::paste done" << endl;
1205 int f_v = (verbose_level = 1);
1209 cout <<
"number_theoretic_transform::make_G_matrix s=" << s << endl;
1214 for (i = 0; i <
N[s]; i++) {
1215 Gr[s][i *
N[s + 1] + i] = 1;
1216 Gr[s][i *
N[s + 1] +
N[s] + i] = 1;
1217 Gr[s][(
N[s] + i) *
N[s + 1] + i] = 1;
1218 Gr[s][(
N[s] + i) *
N[s + 1] +
N[s] + i] =
F->
negate(1);
1222 cout <<
"number_theoretic_transform::make_G_matrix done" << endl;
1229 int f_v = (verbose_level = 1);
1233 cout <<
"number_theoretic_transform::make_D_matrix s=" << s << endl;
1240 for (i = 0; i <
N[s]; i++) {
1242 Dr[s][i *
N[s + 1] + i] = 1;
1243 Dr[s][(
N[s] + i) *
N[s + 1] +
N[s] + i] =
gamma;
1258 for (i = 0; i <
N[s]; i++) {
1260 Dvr[s][i *
N[s + 1] + i] = 1;
1272 cout <<
"number_theoretic_transform::make_D_matrix done" << endl;
1278 int f_v = (verbose_level = 1);
1281 cout <<
"number_theoretic_transform::make_T_matrix s=" << s << endl;
1285 int Id2[] = {1,0,0,1};
1290 N[s], 2,
Tr[s], sz, 0 );
1291 if (sz !=
N[s + 1]) {
1292 cout <<
"sz != N[s + 1]" << endl;
1299 N[s], 2,
Tvr[s], sz, 0 );
1300 if (sz !=
N[s + 1]) {
1301 cout <<
"sz != N[s + 1]" << endl;
1306 cout <<
"number_theoretic_transform::make_T_matrix done" << endl;
1314 int f_v = (verbose_level = 1);
1318 cout <<
"number_theoretic_transform::make_P_matrix s=" << s << endl;
1322 for (i = 0; i <
N[s]; i++) {
1323 Pr[s][i *
N[s + 1] + 2 * i] = 1;
1324 Pr[s][(
N[s] + i) *
N[s + 1] + 2 * i + 1] = 1;
1327 cout <<
"number_theoretic_transform::make_P_matrix done" << endl;
1333 int nb,
int sz,
int *Result,
int verbose_level)
1335 int f_v = (verbose_level = 1);
1339 cout <<
"number_theoretic_transform::multiply_matrix_stack nb=" << nb << endl;
1346 for (i = 2; i < nb; i++) {
1353 cout <<
"number_theoretic_transform::multiply_matrix_stack done" << endl;
1367 t0[0] = F->
add(input[0], input[8]);
1368 t0[1] = F->
add(input[0], F->
negate(input[8]));
1369 t0[2] = F->
add(input[4], input[12]);
1370 t0[3] = F->
add(input[4], F->
negate(input[12]));
1371 t0[4] = F->
add(input[2], input[10]);
1372 t0[5] = F->
add(input[2], F->
negate(input[10]));
1373 t0[6] = F->
add(input[6], input[14]);
1374 t0[7] = F->
add(input[6], F->
negate(input[14]));
1375 t0[8] = F->
add(input[1], input[9]);
1376 t0[9] = F->
add(input[1], F->
negate(input[9]));
1377 t0[10] = F->
add(input[5], input[13]);
1378 t0[11] = F->
add(input[5], F->
negate(input[13]));
1379 t0[12] = F->
add(input[3], input[11]);
1380 t0[13] = F->
add(input[3], F->
negate(input[11]));
1381 t0[14] = F->
add(input[7], input[15]);
1382 t0[15] = F->
add(input[7], F->
negate(input[15]));
1386 t1[3] = F->
mult(13, t0[3]);
1390 t1[7] = F->
mult(13, t0[7]);
1394 t1[11] = F->
mult(13, t0[11]);
1398 t1[15] = F->
mult(13, t0[15]);
1399 t2[0] = F->
add(t1[0], t1[2]);
1400 t2[1] = F->
add(t1[1], t1[3]);
1401 t2[2] = F->
add(t1[0], F->
negate(t1[2]));
1402 t2[3] = F->
add(t1[1], F->
negate(t1[3]));
1403 t2[4] = F->
add(t1[4], t1[6]);
1404 t2[5] = F->
add(t1[5], t1[7]);
1405 t2[6] = F->
add(t1[4], F->
negate(t1[6]));
1406 t2[7] = F->
add(t1[5], F->
negate(t1[7]));
1407 t2[8] = F->
add(t1[8], t1[10]);
1408 t2[9] = F->
add(t1[9], t1[11]);
1409 t2[10] = F->
add(t1[8], F->
negate(t1[10]));
1410 t2[11] = F->
add(t1[9], F->
negate(t1[11]));
1411 t2[12] = F->
add(t1[12], t1[14]);
1412 t2[13] = F->
add(t1[13], t1[15]);
1413 t2[14] = F->
add(t1[12], F->
negate(t1[14]));
1414 t2[15] = F->
add(t1[13], F->
negate(t1[15]));
1420 t3[5] = F->
mult(9, t2[5]);
1421 t3[6] = F->
mult(13, t2[6]);
1422 t3[7] = F->
mult(15, t2[7]);
1428 t3[13] = F->
mult(9, t2[13]);
1429 t3[14] = F->
mult(13, t2[14]);
1430 t3[15] = F->
mult(15, t2[15]);
1431 t4[0] = F->
add(t3[0], t3[4]);
1432 t4[1] = F->
add(t3[1], t3[5]);
1433 t4[2] = F->
add(t3[2], t3[6]);
1434 t4[3] = F->
add(t3[3], t3[7]);
1435 t4[4] = F->
add(t3[0], F->
negate(t3[4]));
1436 t4[5] = F->
add(t3[1], F->
negate(t3[5]));
1437 t4[6] = F->
add(t3[2], F->
negate(t3[6]));
1438 t4[7] = F->
add(t3[3], F->
negate(t3[7]));
1439 t4[8] = F->
add(t3[8], t3[12]);
1440 t4[9] = F->
add(t3[9], t3[13]);
1441 t4[10] = F->
add(t3[10], t3[14]);
1442 t4[11] = F->
add(t3[11], t3[15]);
1443 t4[12] = F->
add(t3[8], F->
negate(t3[12]));
1444 t4[13] = F->
add(t3[9], F->
negate(t3[13]));
1445 t4[14] = F->
add(t3[10], F->
negate(t3[14]));
1446 t4[15] = F->
add(t3[11], F->
negate(t3[15]));
1456 t5[9] = F->
mult(3, t4[9]);
1457 t5[10] = F->
mult(9, t4[10]);
1458 t5[11] = F->
mult(10, t4[11]);
1459 t5[12] = F->
mult(13, t4[12]);
1460 t5[13] = F->
mult(5, t4[13]);
1461 t5[14] = F->
mult(15, t4[14]);
1462 t5[15] = F->
mult(11, t4[15]);
1463 output[0] = F->
add(t5[0], t5[8]);
1464 output[1] = F->
add(t5[1], t5[9]);
1465 output[2] = F->
add(t5[2], t5[10]);
1466 output[3] = F->
add(t5[3], t5[11]);
1467 output[4] = F->
add(t5[4], t5[12]);
1468 output[5] = F->
add(t5[5], t5[13]);
1469 output[6] = F->
add(t5[6], t5[14]);
1470 output[7] = F->
add(t5[7], t5[15]);
1471 output[8] = F->
add(t5[0], F->
negate(t5[8]));
1472 output[9] = F->
add(t5[1], F->
negate(t5[9]));
1473 output[10] = F->
add(t5[2], F->
negate(t5[10]));
1474 output[11] = F->
add(t5[3], F->
negate(t5[11]));
1475 output[12] = F->
add(t5[4], F->
negate(t5[12]));
1476 output[13] = F->
add(t5[5], F->
negate(t5[13]));
1477 output[14] = F->
add(t5[6], F->
negate(t5[14]));
1478 output[15] = F->
add(t5[7], F->
negate(t5[15]));
1493 t0[0] = F->
add(input[0], input[8]);
1494 t0[1] = F->
add(input[0], F->
negate(input[8]));
1495 t0[2] = F->
add(input[4], input[12]);
1496 t0[3] = F->
add(input[4], F->
negate(input[12]));
1497 t0[4] = F->
add(input[2], input[10]);
1498 t0[5] = F->
add(input[2], F->
negate(input[10]));
1499 t0[6] = F->
add(input[6], input[14]);
1500 t0[7] = F->
add(input[6], F->
negate(input[14]));
1501 t0[8] = F->
add(input[1], input[9]);
1502 t0[9] = F->
add(input[1], F->
negate(input[9]));
1503 t0[10] = F->
add(input[5], input[13]);
1504 t0[11] = F->
add(input[5], F->
negate(input[13]));
1505 t0[12] = F->
add(input[3], input[11]);
1506 t0[13] = F->
add(input[3], F->
negate(input[11]));
1507 t0[14] = F->
add(input[7], input[15]);
1508 t0[15] = F->
add(input[7], F->
negate(input[15]));
1512 t1[3] = F->
mult(4, t0[3]);
1516 t1[7] = F->
mult(4, t0[7]);
1520 t1[11] = F->
mult(4, t0[11]);
1524 t1[15] = F->
mult(4, t0[15]);
1525 t2[0] = F->
add(t1[0], t1[2]);
1526 t2[1] = F->
add(t1[1], t1[3]);
1527 t2[2] = F->
add(t1[0], F->
negate(t1[2]));
1528 t2[3] = F->
add(t1[1], F->
negate(t1[3]));
1529 t2[4] = F->
add(t1[4], t1[6]);
1530 t2[5] = F->
add(t1[5], t1[7]);
1531 t2[6] = F->
add(t1[4], F->
negate(t1[6]));
1532 t2[7] = F->
add(t1[5], F->
negate(t1[7]));
1533 t2[8] = F->
add(t1[8], t1[10]);
1534 t2[9] = F->
add(t1[9], t1[11]);
1535 t2[10] = F->
add(t1[8], F->
negate(t1[10]));
1536 t2[11] = F->
add(t1[9], F->
negate(t1[11]));
1537 t2[12] = F->
add(t1[12], t1[14]);
1538 t2[13] = F->
add(t1[13], t1[15]);
1539 t2[14] = F->
add(t1[12], F->
negate(t1[14]));
1540 t2[15] = F->
add(t1[13], F->
negate(t1[15]));
1546 t3[5] = F->
mult(2, t2[5]);
1547 t3[6] = F->
mult(4, t2[6]);
1548 t3[7] = F->
mult(8, t2[7]);
1554 t3[13] = F->
mult(2, t2[13]);
1555 t3[14] = F->
mult(4, t2[14]);
1556 t3[15] = F->
mult(8, t2[15]);
1557 t4[0] = F->
add(t3[0], t3[4]);
1558 t4[1] = F->
add(t3[1], t3[5]);
1559 t4[2] = F->
add(t3[2], t3[6]);
1560 t4[3] = F->
add(t3[3], t3[7]);
1561 t4[4] = F->
add(t3[0], F->
negate(t3[4]));
1562 t4[5] = F->
add(t3[1], F->
negate(t3[5]));
1563 t4[6] = F->
add(t3[2], F->
negate(t3[6]));
1564 t4[7] = F->
add(t3[3], F->
negate(t3[7]));
1565 t4[8] = F->
add(t3[8], t3[12]);
1566 t4[9] = F->
add(t3[9], t3[13]);
1567 t4[10] = F->
add(t3[10], t3[14]);
1568 t4[11] = F->
add(t3[11], t3[15]);
1569 t4[12] = F->
add(t3[8], F->
negate(t3[12]));
1570 t4[13] = F->
add(t3[9], F->
negate(t3[13]));
1571 t4[14] = F->
add(t3[10], F->
negate(t3[14]));
1572 t4[15] = F->
add(t3[11], F->
negate(t3[15]));
1582 t5[9] = F->
mult(6, t4[9]);
1583 t5[10] = F->
mult(2, t4[10]);
1584 t5[11] = F->
mult(12, t4[11]);
1585 t5[12] = F->
mult(4, t4[12]);
1586 t5[13] = F->
mult(7, t4[13]);
1587 t5[14] = F->
mult(8, t4[14]);
1588 t5[15] = F->
mult(14, t4[15]);
1589 output[0] = F->
negate(F->
add(t5[0], t5[8]));
1590 output[1] = F->
negate(F->
add(t5[1], t5[9]));
1591 output[2] = F->
negate(F->
add(t5[2], t5[10]));
1592 output[3] = F->
negate(F->
add(t5[3], t5[11]));
1593 output[4] = F->
negate(F->
add(t5[4], t5[12]));
1594 output[5] = F->
negate(F->
add(t5[5], t5[13]));
1595 output[6] = F->
negate(F->
add(t5[6], t5[14]));
1596 output[7] = F->
negate(F->
add(t5[7], t5[15]));
int nb_times_add_called()
int nb_times_mult_called()
int multiplicative_order(int a)
void finite_field_init(int q, int f_without_tables, int verbose_level)
linear_algebra::linear_algebra * Linear_algebra
void make_Fourier_matrices(int omega, int k, int *N, int **A, int **Av, int *Omega, int verbose_level)
void mult_matrix_matrix(int *A, int *B, int *C, int m, int n, int o, int verbose_level)
void mult_vector_from_the_right(int *A, int *v, int *Av, int m, int n)
void Kronecker_product_square_but_arbitrary(int *A, int *B, int na, int nb, int *AB, int &N, int verbose_level)
basic number theoretic functions
int i_power_j(int i, int j)
a collection of functions related to file io
void int_matrix_write_csv(std::string &fname, int *M, int m, int n)
long int file_size(std::string &fname)
interface to system functions
int random_integer(int p)
void get_date(std::string &str)
homogeneous polynomials of a given degree in a given number of variables over a finite field GF(q)
void multiply_mod_negatively_wrapped(int *coeff1, int *coeff2, int *coeff3, int verbose_level)
void init(field_theory::finite_field *F, int nb_vars, int degree, int f_init_incidence_structure, monomial_ordering_type Monomial_ordering_type, int verbose_level)
void print_monomial_ordering(std::ostream &ost)
void multiply_mod(int *coeff1, int *coeff2, int *coeff3, int verbose_level)
#define Int_vec_zero(A, B)
#define Int_matrix_print(A, B, C)
#define Int_vec_copy(A, B, C)
the orbiter library for the classification of combinatorial objects