|
|
1.1 root 1: /* foop[i] >>= 1; */
2: #include "qs.h"
3: extern char *malloc();
4: #define ison(n, v) (v[(n) >> 5] & (1 << ((n) & 31)))
5: #define on(n, v) v[(n) >> 5] |= (1 << ((n) & 31))
6: #define off(n, v) v[(n) >> 5] &= ~(1 << ((n) & 31))
7:
8: mint *one;
9:
10: vec *vecs; /* a few extra ones to make sure */
11: int nvecs, vsize;
12: unsigned int *matrix;
13: int *foop;
14:
15: int *pivot;
16:
17: svvec(n, a, b, q, orig)
18: int *a, *b;
19: mint *q, *orig;
20: { int i, p;
21: for(i = 0; i < n; i++) {
22: if((b[i] & 1) == 0)
23: continue;
24: p = a[i];
25: on(p, vecs[nvecs].rval);
26: }
27: vecs[nvecs].iam = -1;
28: vecs[nvecs].aval = itom(0);
29: move(q, vecs[nvecs].aval);
30: vecs[nvecs].qval = itom(0);
31: move(orig, vecs[nvecs].qval);
32: vecs[nvecs].ps = (int *)malloc((n + 2) * sizeof(int));
33: vecs[nvecs].exps = (short *)malloc((n + 2) * sizeof(short));
34: vecs[nvecs].vlen = n;
35: for(i = 0; i < n; i++) {
36: vecs[nvecs].ps[i] = a[i];
37: vecs[nvecs].exps[i] = b[i];
38: }
39: #ifdef DEBUG
40: checkvec(nvecs);
41: #endif
42: lu();
43: nvecs++;
44: if(nvecs >= np + 100) {
45: printf("hey, tried 100 extra times?\n");
46: exit(0);
47: }
48: }
49:
50: /* lu decomposition, maybe */
51: lu()
52: { int i;
53: /* too much work */
54: for(i = 0; i < nvecs; i++) {
55: if(vecs[i].iam < 0)
56: continue;
57: if(!ison(vecs[i].iam, vecs[nvecs].rval))
58: continue;
59: elim(vecs[i].iam, i, nvecs);
60: }
61: for(i = np - 1; i >= 0; i--)
62: if(pivot[i] == -1 && ison(i, vecs[nvecs].rval)) {
63: pivot[i] = nvecs;
64: vecs[nvecs].iam = i;
65: break;
66: }
67: #ifdef DEBUG
68: checkrow(nvecs);
69: #endif
70: if(vecs[nvecs].iam != -1)
71: return;
72: for(i = 0; i < np; i++)
73: if(ison(i, vecs[nvecs].rval) && pivot[i] == -1)
74: return;
75: doit(nvecs);
76: }
77:
78: elim(piv, a, b) /* add row a to row b */
79: { int i;
80: for(i = 0; i < vsize; i++)
81: vecs[b].rval[i] ^= vecs[a].rval[i];
82: if(ison(piv, vecs[b].rval))
83: abort("elim");
84: on(piv, vecs[b].rval);
85: }
86:
87:
88: mint *xa, *xb, *xc, *xd, *xe, *xbb;
89: doit(n) /* row n is now a winner, we hope */
90: { static flg = 0;
91: int i, j;
92: #ifdef DEBUG
93: checkrow(n);
94: #endif
95: if(flg++ == 0) {
96: xa = itom(1), xb = itom(0), xc = itom(0), xd = itom(0);
97: xe = itom(0), xbb = itom(0);
98: }
99: for(i = 0; i < np; i++)
100: foop[i] = 0;
101: move(xa, xb);
102: move(xa, xe);
103: move(xa, xbb);
104: for(i = 0; i < np; i++)
105: if(ison(i, vecs[n].rval)) {
106: refactor(pivot[i]);
107: mult(xe, vecs[pivot[i]].aval, xe);
108: mdiv(xe, num, xc, xe);
109: }
110: refactor(n);
111: mult(xe, vecs[n].aval, xe);
112: mdiv(xe, num, xc, xe);
113: move(one, xd);
114: for(i = 0; i < np; i++) {
115: if(foop[i] & 1) {
116: printf("hey, not a square foop[%d] = %d\n", i, foop[i]);
117: fflush(stdout);
118: abort();
119: }
120: foop[i] >>= 1;
121: }
122: for(i = 1; i < np; i++) /* skip -1 */
123: if(foop[i] > 0) {
124: for(j = 0; j < foop[i]; j++)
125: mult(xd, mintp[i], xd);
126: mdiv(xd, num, xc, xd);
127: }
128: msub(xe, xd, xb);
129: gcd(xb, num, xc);
130: printf("gcd(%d) ", nvecs), mout(xc);
131: if(mcmp(xc, num) != 0 && (xc->len != 1 || xc->val[0] != 1)) {
132: newfactor(xc);
133: mdiv(num, xc, xb, xe);
134: newfactor(xb);
135: return;
136: }
137: if(mcmp(xc, num) == 0)
138: return;
139: madd(xe, xd, xb);
140: mult(xe, xe, xe);
141: mult(xd, xd, xd);
142: msub(xe, xd, xbb);
143: mdiv(xbb, num, xc, xbb);
144: mdiv(xb, num, xc, xb);
145: if(xb->len != 0) {
146: for(i = 0; i < (np<100?np:100); i++)
147: if(foop[i] != 0)
148: printf("p %d e %d\n", goodp[i], foop[i]);
149: printf("...\n");
150: for(i = 0; i <= n; i++)
151: checkrow(i);
152: abort();
153: }
154: }
155:
156: refactor(n)
157: { int i;
158: if(n < 0)
159: printf("refactor(%d)?\n", n);
160: for(i = 0; i < vecs[n].vlen; i++) {
161: if(vecs[n].ps[i] >= np || vecs[n].ps[i] < 0)
162: printf("oops n %d vlen %d ps[%d] %d\n", n, vecs[n].vlen, i, vecs[n].ps[i]);
163: foop[vecs[n].ps[i]] += vecs[n].exps[i];
164: }
165: }
166:
167: #ifdef DEBUG
168: checkrow(n)
169: { vec *v = vecs + n;
170: int i, j;
171: static mint *lhs, *scratch, *rhs, *arhs;
172: static flg = 0;
173: if(flg++ == 0)
174: arhs = itom(0), rhs = itom(0), scratch = itom(0), lhs = itom(0);
175: for(i = 0; i < np; i++)
176: foop[i] = 0;
177: move(v->aval, lhs);
178: for(i = 0; i < np; i++)
179: if(ison(i, v->rval) && pivot[i] >= 0 && pivot[i] != n) {
180: mult(lhs, vecs[pivot[i]].aval, lhs);
181: mdiv(lhs, num, scratch, lhs);
182: }
183: mult(lhs, lhs, lhs);
184: mdiv(lhs, num, scratch, lhs);
185: move(v->qval, rhs);
186: refactor(n);
187: for(i = 0; i < np; i++)
188: if(ison(i, v->rval) && pivot[i] >= 0 && pivot[i] != n) {
189: mult(rhs, vecs[pivot[i]].qval, rhs);
190: mdiv(rhs, num, scratch, rhs);
191: refactor(pivot[i]);
192: }
193: if(rhs->len < 0)
194: madd(rhs, num, rhs);
195: move(one, arhs);
196: for(i = 1; i < np; i++)
197: if(foop[i] > 0) {
198: for(j = 0; j < foop[i]; j++)
199: mult(arhs, mintp[i], arhs);
200: mdiv(arhs, num, scratch, arhs);
201: }
202: if(foop[0] & 1)
203: msub(num, arhs, arhs);
204: if(mcmp(lhs, rhs) == 0 && mcmp(rhs, arhs) == 0)
205: return;
206: printf("row %d failed!\n", n);
207: printf("lhs "), mout(lhs);
208: printf("rhs "), mout(rhs);
209: printf("arhs "), mout(arhs);
210: exit(1);
211: }
212:
213: checkvec(n)
214: { static mint *xa, *xb, *xc;
215: static flg = 0;
216: int i, j;
217: vec *v = vecs + n;
218: if(!flg++) {
219: xa = itom(0), xb = itom(0), xc = itom(0);
220: }
221: mult(v->aval, v->aval, xa);
222: mdiv(xa, num, xa, xb);
223: mdiv(v->qval, num, xa, xc);
224: if(mcmp(xb, xc) != 0) {
225: printf("a * a != q mod num\n");
226: exit(1);
227: }
228: move(one, xa);
229: for(i = 0; i < v->vlen; i++) {
230: for(j = 0; j < v->exps[i]; j++) {
231: mult(xa, mintp[v->ps[i]], xa);
232: mdiv(xa, num, xb, xa);
233: }
234: }
235: move(v->qval, xb);
236: if(xb->len < 0)
237: madd(xb, num, xb);
238: if(mcmp(xa, xb) != 0) {
239: printf("vec not q! "), mout(xa), mout(v->qval);
240: exit(1);
241: }
242: }
243: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.