10 #include "exponentialsum.h"
11 #include "innerproduct.h"
14 /****************************************************************************
15 * Note: Arguments are copied and not modified!
16 ****************************************************************************/
18 double complex innerproduct(int n1, int k1, int *h1, int **G1, int **GBar1, int Q1, int *D1, int **J1, int n2, int k2, int *h2, int **G2, int **GBar2, int Q2, int *D2, int **J2) {
19 // n1 should equal n2 (we assume this)
25 int *h = calloc(n, sizeof(int));
26 int **G = calloc(n, sizeof(int*));
27 int **GBar = calloc(n, sizeof(int*));
30 G[a] = calloc(n, sizeof(int));
31 GBar[a] = calloc(n, sizeof(int));
34 GBar[a][b] = GBar1[a][b];
39 int *D1copy = calloc(k1, sizeof(int));
40 int **J1copy = calloc(k1, sizeof(int*));
43 J1copy[a] = calloc(k1, sizeof(int));
45 J1copy[a][b] = J1[a][b];
50 int *D2copy = calloc(k2, sizeof(int));
51 int **J2copy = calloc(k2, sizeof(int*));
54 J2copy[a] = calloc(k2, sizeof(int));
56 J2copy[a][b] = J2[a][b];
61 int **R = calloc(k, sizeof(int*));
63 R[a] = calloc(k2, sizeof(int));
64 int **RT = calloc(k2, sizeof(int*));
66 RT[a] = calloc(k, sizeof(int));
69 for(a=k2; a<n2; a++) {
70 alpha = dotProductMod(h2, GBar2[a], n2, 2);
72 shrinkResult = shrink(n, &k, h, G, GBar, &Q1copy, &D1copy, &J1copy, GBar2[a], alpha);
73 if(shrinkResult == 'E') {// if EMPTY
75 deallocate_mem(&G, n); deallocate_mem(&GBar, n);
77 deallocate_mem(&J1copy, k);
79 deallocate_mem(&J2copy, k2);
80 deallocate_mem(&R, k);
81 deallocate_mem(&RT, k2);
86 // Now K = K1 intersect K2 = (n1, k1, h1, G1, GBar1)
87 int *y = calloc(k2, sizeof(int));
88 int *tmpVec = calloc(n2, sizeof(int));
89 addVectorMod(h,h2,tmpVec,n2,2);
91 y[a] = dotProductMod(tmpVec,GBar2[a],n2,2);
93 R[b][a] = dotProductMod(G[b],GBar2[a],n2,2);
97 // IF YOU UNCOMMENT THIS THEN YOU WILL BE CHANGING h2!!!
98 /* for(a=0; a<k2; a++) { */
99 /* for(b=0; b<n2; b++) { */
100 /* h2[b] = (h2[b] + y[a]*G2[a][b])%2; */
103 /* printf("h2 (should now match h):\n"); */
104 /* printVector(h2, n2); */
105 /* printf("h:\n"); */
106 /* printVector(h, n2); */
110 // update Q2 and D2 using Eqs. 52 and 53 with y
111 for(a=0; a<k2; a++) {
112 Q2copy = Q2copy + D2copy[a]*y[a];
113 for(b=a+1; b<k2; b++) {
114 Q2copy = Q2copy + J2copy[a][b]*y[a]*y[b];
119 for(a=0; a<k2; a++) {
121 D2copy[a] = D2copy[a] + J2copy[a][b]*y[b];
122 D2copy[a] = D2copy[a]%8;
127 // update D2copy and J2copy using Eqs. 49 and 50 with R
128 // (note that R is a kxk2 matrix so this may reduce the dimension of D2copy and J2copy)
129 y = calloc(k, sizeof(int));
133 y[c] = y[c] + R[c][a]*D2copy[a];
135 y[c] = y[c] + J2copy[a][b]*R[c][a]*R[c][b];
140 D2copy = calloc(k, sizeof(int));
141 memcpy(D2copy, y, sizeof(int)*k);
145 int **tmpMatrix = calloc(k2, sizeof(int*));
147 tmpMatrix[a] = calloc(k, sizeof(int));
148 multMatrixMod(J2copy,RT,tmpMatrix,k2,k2,k2,k,8);
149 deallocate_mem(&J2copy, k2);
150 J2copy = calloc(k, sizeof(int*));
152 J2copy[a] = calloc(k, sizeof(int));
153 multMatrixMod(R,tmpMatrix,J2copy,k,k2,k2,k,8);
155 deallocate_mem(&tmpMatrix, k2);
157 deallocate_mem(&R, k);
158 deallocate_mem(&RT, k2);
160 // Now (Q1, D1, J1) and (Q2, D2, J2) are defined in the same basis
162 int Q = (Q1copy - Q2copy)%8 < 0 ? (Q1copy - Q2copy)%8 + 8 : (Q1copy - Q2copy)%8;
163 int *D = calloc(k, sizeof(int));
164 int **J = calloc(k, sizeof(int*));
166 for(a=0; a<k; a++) { // again, if k=0 then no need to fill these
167 J[a] = calloc(k, sizeof(int));
168 D[a] = (D1copy[a] - D2copy[a])%8 < 0 ? (D1copy[a] - D2copy[a])%8 + 8 : (D1copy[a] - D2copy[a])%8;
170 J[a][b] = (J1copy[a][b] - J2copy[a][b])%8 < 0 ? (J1copy[a][b] - J2copy[a][b])%8 + 8 : (J1copy[a][b] - J2copy[a][b])%8;
175 deallocate_mem(&G, n); deallocate_mem(&GBar, n);
177 double complex amplitude = pow(2,-0.5*(k1+k2))*exponentialsum(&k, &Q, D, J);
180 deallocate_mem(&J, k);
183 deallocate_mem(&J1copy, k);
186 deallocate_mem(&J2copy, k);