Annotation of OpenXM_contrib2/asir2000/engine/up_lm.c, Revision 1.4
1.2 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.3 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.2 noro 27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
47: *
1.4 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/engine/up_lm.c,v 1.3 2000/08/22 05:04:07 noro Exp $
1.2 noro 49: */
1.1 noro 50: #include "ca.h"
51: #include <math.h>
52:
53: extern GC_dont_gc;
54: extern struct oEGT eg_chrem,eg_fore,eg_back;
55: extern int debug_up;
56: extern int up_lazy;
1.4 ! noro 57: extern int current_ff;
1.1 noro 58:
59: void crup_lm(ModNum **,int,int *,int,N,N,UP *);
60:
61: void fft_mulup_lm(n1,n2,nr)
62: UP n1,n2;
63: UP *nr;
64: {
65: ModNum *f1,*f2,*w,*fr;
66: ModNum *frarray[1024];
67: int modarray[1024];
68: int frarray_index = 0;
69: N m,m1,m2,lm_mod;
70: int d1,d2,dmin,i,mod,root,d,cond,bound;
71: UP r;
72:
73: if ( !n1 || !n2 ) {
74: *nr = 0; return;
75: }
76: d1 = n1->d; d2 = n2->d; dmin = MIN(d1,d2);
77: if ( !d1 || !d2 ) {
78: mulup(n1,n2,nr); return;
79: }
80: getmod_lm(&lm_mod);
81: if ( !lm_mod )
82: error("fft_mulup_lm : current_mod_lm is not set");
83: m = ONEN;
84: bound = maxblenup(n1)+maxblenup(n2)+int_bits(dmin)+2;
85: f1 = (ModNum *)ALLOCA((d1+d2+1)*sizeof(ModNum));
86: f2 = (ModNum *)ALLOCA((d1+d2+1)*sizeof(ModNum));
87: w = (ModNum *)ALLOCA(6*(1<<int_bits(d1+d2+1))*sizeof(ModNum));
88: for ( i = 0; i < NPrimes; i++ ) {
89: FFT_primes(i,&mod,&root,&d);
90: if ( (1<<d) < d1+d2+1 )
91: continue;
92: modarray[frarray_index] = mod;
93: frarray[frarray_index++] = fr
94: = (ModNum *)ALLOCA((d1+d2+1)*sizeof(ModNum));
95: uptofmarray(mod,n1,f1);
96: uptofmarray(mod,n2,f2);
97: cond = FFT_pol_product(d1,f1,d2,f2,fr,i,w);
98: if ( cond )
99: error("fft_mulup : error in FFT_pol_product");
100: STON(mod,m1); muln(m,m1,&m2); m = m2;
101: if ( n_bits(m) > bound ) {
102: /* GC_dont_gc = 1; */
103: crup_lm(frarray,d1+d2,modarray,frarray_index,m,lm_mod,&r);
104: uptolmup(r,nr);
105: GC_dont_gc = 0;
106: return;
107: }
108: }
109: error("fft_mulup : FFT_primes exhausted");
110: }
111:
112: void fft_squareup_lm(n1,nr)
113: UP n1;
114: UP *nr;
115: {
116: ModNum *f1,*w,*fr;
117: ModNum *frarray[1024];
118: int modarray[1024];
119: int frarray_index = 0;
120: N m,m1,m2,lm_mod;
121: int d1,dmin,i,mod,root,d,cond,bound;
122: UP r;
123:
124: if ( !n1 ) {
125: *nr = 0; return;
126: }
127: d1 = n1->d; dmin = d1;
128: if ( !d1 ) {
129: mulup(n1,n1,nr); return;
130: }
131: getmod_lm(&lm_mod);
132: if ( !lm_mod )
133: error("fft_squareup_lm : current_mod_lm is not set");
134: m = ONEN;
135: bound = 2*maxblenup(n1)+int_bits(d1)+2;
136: f1 = (ModNum *)ALLOCA((2*d1+1)*sizeof(ModNum));
137: w = (ModNum *)ALLOCA(6*(1<<int_bits(2*d1+1))*sizeof(ModNum));
138: for ( i = 0; i < NPrimes; i++ ) {
139: FFT_primes(i,&mod,&root,&d);
140: if ( (1<<d) < 2*d1+1 )
141: continue;
142: modarray[frarray_index] = mod;
143: frarray[frarray_index++] = fr
144: = (ModNum *)ALLOCA((2*d1+1)*sizeof(ModNum));
145: uptofmarray(mod,n1,f1);
146: cond = FFT_pol_square(d1,f1,fr,i,w);
147: if ( cond )
148: error("fft_mulup : error in FFT_pol_product");
149: STON(mod,m1); muln(m,m1,&m2); m = m2;
150: if ( n_bits(m) > bound ) {
151: /* GC_dont_gc = 1; */
152: crup_lm(frarray,2*d1,modarray,frarray_index,m,lm_mod,&r);
153: uptolmup(r,nr);
154: GC_dont_gc = 0;
155: return;
156: }
157: }
158: error("fft_squareup : FFT_primes exhausted");
159: }
160:
161: void trunc_fft_mulup_lm(n1,n2,dbd,nr)
162: UP n1,n2;
163: int dbd;
164: UP *nr;
165: {
166: ModNum *f1,*f2,*fr,*w;
167: ModNum *frarray[1024];
168: int modarray[1024];
169: int frarray_index = 0;
170: N m,m1,m2,lm_mod;
171: int d1,d2,dmin,i,mod,root,d,cond,bound;
172: UP r;
173:
174: if ( !n1 || !n2 ) {
175: *nr = 0; return;
176: }
177: d1 = n1->d; d2 = n2->d; dmin = MIN(d1,d2);
178: if ( !d1 || !d2 ) {
179: tmulup(n1,n2,dbd,nr); return;
180: }
181: getmod_lm(&lm_mod);
182: if ( !lm_mod )
183: error("trunc_fft_mulup_lm : current_mod_lm is not set");
184: m = ONEN;
185: bound = maxblenup(n1)+maxblenup(n2)+int_bits(dmin)+2;
186: f1 = (ModNum *)ALLOCA((d1+d2+1)*sizeof(ModNum));
187: f2 = (ModNum *)ALLOCA((d1+d2+1)*sizeof(ModNum));
188: w = (ModNum *)ALLOCA(6*(1<<int_bits(d1+d2+1))*sizeof(ModNum));
189: for ( i = 0; i < NPrimes; i++ ) {
190: FFT_primes(i,&mod,&root,&d);
191: if ( (1<<d) < d1+d2+1 )
192: continue;
193:
194: modarray[frarray_index] = mod;
195: frarray[frarray_index++] = fr
196: = (ModNum *)ALLOCA((d1+d2+1)*sizeof(ModNum));
197: uptofmarray(mod,n1,f1);
198: uptofmarray(mod,n2,f2);
199: cond = FFT_pol_product(d1,f1,d2,f2,fr,i,w);
200: if ( cond )
201: error("fft_mulup : error in FFT_pol_product");
202: STON(mod,m1); muln(m,m1,&m2); m = m2;
203: if ( n_bits(m) > bound ) {
204: /* GC_dont_gc = 1; */
205: crup_lm(frarray,MIN(dbd-1,d1+d2),modarray,frarray_index,m,lm_mod,&r);
206: uptolmup(r,nr);
207: GC_dont_gc = 0;
208: return;
209: }
210: }
211: error("trunc_fft_mulup : FFT_primes exhausted");
212: }
213:
214: void crup_lm(f,d,mod,index,m,lm_mod,r)
215: ModNum **f;
216: int d;
217: int *mod;
218: int index;
219: N m;
220: N lm_mod;
221: UP *r;
222: {
223: double *k;
224: double c2;
225: unsigned int *w;
226: unsigned int zi,au,al;
227: UL a;
228: int i,j,l,len;
229: UP s,s1,u;
230: struct oUP c;
231: N t,ci,mi,qn;
232: unsigned int **sum;
233: unsigned int *sum_b;
234: Q q;
235: struct oEGT eg0,eg1;
236:
237: if ( !lm_mod )
238: error("crup_lm : current_mod_lm is not set");
239: k = (double *)ALLOCA((d+1)*sizeof(double));
240: for ( j = 0; j <= d; j++ )
241: k[j] = 0.5;
242: up_lazy = 1;
243: sum = (unsigned int **)ALLOCA((d+1)*sizeof(unsigned int *));
244: len = (int_bits(index)+n_bits(lm_mod)+31)/32+1;
245: w = (unsigned int *)ALLOCA((len+1)*sizeof(unsigned int));
246: sum_b = (unsigned int *)MALLOC_ATOMIC((d+1)*len*sizeof(unsigned int));
247: for ( j = 0; j <= d; j++ ) {
248: sum[j] = sum_b+len*j;
249: bzero((char *)sum[j],len*sizeof(unsigned int));
250: }
251: for ( i = 0, s = 0; i < index; i++ ) {
252: divin(m,mod[i],&ci);
253: zi = (unsigned int)invm((unsigned int)rem(ci,mod[i]),mod[i]);
254:
255: STON(zi,t); muln(ci,t,&mi);
256: divn(mi,lm_mod,&qn,&t);
257: if ( t )
258: for ( j = 0; j <= d; j++ ) {
259: bzero((char *)w,(len+1)*sizeof(unsigned int));
260: muln_1(BD(t),PL(t),(unsigned int)f[i][j],w);
261: for ( l = PL(t); l >= 0 && !w[l]; l--);
262: l++;
263: if ( l )
264: addarray_to(w,l,sum[j],len);
265: }
266: c2 = (double)zi/(double)mod[i];
267: for ( j = 0; j <= d; j++ )
268: k[j] += c2*f[i][j];
269: }
270: uiarraytoup(sum,len,d,&s);
271: GC_free(sum_b);
272:
273: u = UPALLOC(d);
274: for ( j = 0; j <= d; j++ ) {
275: #if 1
276: a = (UL)floor(k[j]);
277: #if defined(i386) || defined(__alpha) || defined(VISUAL)
278: au = ((unsigned int *)&a)[1];
279: al = ((unsigned int *)&a)[0];
280: #else
281: al = ((unsigned int *)&a)[1];
282: au = ((unsigned int *)&a)[0];
283: #endif
284: if ( au ) {
285: NEWQ(q); SGN(q) = 1; NM(q)=NALLOC(2); DN(q)=0;
286: PL(NM(q))=2; BD(NM(q))[0]=al; BD(NM(q))[1] = au;
287: } else
288: UTOQ(al,q);
289: #else
290: al = (int)floor(k[j]); STOQ(al,q);
291: #endif
292: u->c[j] = (Num)q;
293: }
294: for ( j = d; j >= 0 && !u->c[j]; j-- );
295: if ( j < 0 )
296: u = 0;
297: else
298: u->d = j;
299: divn(m,lm_mod,&qn,&t); NTOQ(t,-1,q);
300: c.d = 0; c.c[0] = (Num)q;
301: mulup(u,&c,&s1);
302: up_lazy = 0;
303:
304: addup(s,s1,r);
305: }
306:
307: void fft_rembymulup_special_lm(n1,n2,inv2,nr)
308: UP n1,n2,inv2;
309: UP *nr;
310: {
311: int d1,d2,d;
312: UP r1,t,s,q,u;
313:
314: if ( !n2 )
315: error("rembymulup : division by 0");
316: else if ( !n1 || !n2->d )
317: *nr = 0;
318: else if ( (d1 = n1->d) < (d2 = n2->d) )
319: *nr = n1;
320: else {
321: d = d1-d2;
322: reverseup(n1,d1,&t); truncup(t,d+1,&r1);
323: trunc_fft_mulup_lm(r1,inv2,d+1,&t);
324: truncup(t,d+1,&s);
325: reverseup(s,d,&q);
326: trunc_fft_mulup_lm(q,n2,d2,&t); truncup(t,d2,&u);
327: truncup(n1,d2,&s);
328: subup(s,u,nr);
329: }
330: }
331:
332: void uptolmup(n,nr)
333: UP n;
334: UP *nr;
335: {
336: int i,d;
337: Q *c;
338: LM *cr;
339: UP r;
340:
341: if ( !n )
342: *nr = 0;
343: else {
344: d = n->d; c = (Q *)n->c;
345: *nr = r = UPALLOC(d); cr = (LM *)r->c;
346: for ( i = 0; i <= d; i++ )
347: qtolm(c[i],&cr[i]);
348: for ( i = d; i >= 0 && !cr[i]; i-- );
349: if ( i < 0 )
350: *nr = 0;
351: else
352: r->d = i;
353: }
354: }
355:
356: save_up(obj,name)
357: UP obj;
358: char *name;
359: {
360: P p;
361: Obj ret;
362: NODE n0,n1;
363: STRING s;
364:
365: uptop(obj,&p);
366: MKSTR(s,name);
367: MKNODE(n1,s,0); MKNODE(n0,p,n1);
368: Pbsave(n0,&ret);
369: }
370:
371: void hybrid_powermodup(f,xp)
372: UP f;
373: UP *xp;
374: {
375: N n;
376: UP x,y,t,invf,s;
377: int k;
378: LM lm;
379: struct oEGT eg_sq,eg_rem,eg_mul,eg_inv,eg0,eg1,eg2,eg3;
380: char name[BUFSIZ];
381:
382: getmod_lm(&n);
383: if ( !n )
384: error("hybrid_powermodup : current_mod_lm is not set");
385: MKLM(ONEN,lm);
386: x = UPALLOC(1); x->d = 1; x->c[1] = (Num)lm;
387: y = UPALLOC(0); y->d = 0; y->c[0] = (Num)lm;
388:
389: reverseup(f,f->d,&t);
390: invmodup(t,f->d,&s); uptolmup(s,&invf);
391: for ( k = n_bits(n)-1; k >= 0; k-- ) {
392: hybrid_squareup(FF_GFP,y,&t);
393: hybrid_rembymulup_special(FF_GFP,t,f,invf,&s);
394: y = s;
395: if ( n->b[k/32] & (1<<(k%32)) ) {
396: mulup(y,x,&t);
397: remup(t,f,&s);
398: y = s;
399: }
400: }
401: *xp = y;
402: }
403:
404: void powermodup(f,xp)
405: UP f;
406: UP *xp;
407: {
408: N n;
409: UP x,y,t,invf,s;
410: int k;
411: LM lm;
1.4 ! noro 412: GFS fs;
! 413: Num c;
1.1 noro 414: struct oEGT eg_sq,eg_rem,eg_mul,eg_inv,eg0,eg1,eg2,eg3;
415:
1.4 ! noro 416: if ( !current_ff )
! 417: error("powermodup : current_ff is not set");
1.1 noro 418: field_order_ff(&n);
1.4 ! noro 419: switch ( current_ff ) {
! 420: case FF_GFP:
! 421: case FF_GFPN:
! 422: MKLM(ONEN,lm);
! 423: c = (Num)lm;
! 424: break;
! 425: case FF_GFS:
! 426: mqtogfs(ONEM,&fs);
! 427: c = (Num)fs;
! 428: break;
! 429: default:
! 430: error("powermodup : not implemented yet");
! 431: }
! 432: x = UPALLOC(1); x->d = 1; x->c[1] = c;
! 433: y = UPALLOC(0); y->d = 0; y->c[0] = c;
1.1 noro 434:
435: reverseup(f,f->d,&t);
1.4 ! noro 436: invmodup(t,f->d,&s);
! 437: switch ( current_ff ) {
! 438: case FF_GFP:
! 439: case FF_GFPN:
! 440: uptolmup(s,&invf);
! 441: break;
! 442: case FF_GFS:
! 443: invf = s; /* XXX */
! 444: break;
! 445: default:
! 446: error("powermodup : not implemented yet");
! 447: }
1.1 noro 448: for ( k = n_bits(n)-1; k >= 0; k-- ) {
449: ksquareup(y,&t);
450: rembymulup_special(t,f,invf,&s);
451: y = s;
452: if ( n->b[k/32] & (1<<(k%32)) ) {
453: mulup(y,x,&t);
454: remup(t,f,&s);
455: y = s;
456: }
457: }
458: *xp = y;
459: }
460:
461: /* g^d mod f */
462:
463: void hybrid_generic_powermodup(g,f,d,xp)
464: UP g,f;
465: Q d;
466: UP *xp;
467: {
468: N e;
469: UP x,y,t,invf,s;
470: int k;
471: LM lm;
472: struct oEGT eg_sq,eg_rem,eg_mul,eg_inv,eg0,eg1,eg2,eg3;
473:
474: e = NM(d);
475: MKLM(ONEN,lm);
476: y = UPALLOC(0); y->d = 0; y->c[0] = (Num)lm;
477: remup(g,f,&x);
478: if ( !x ) {
479: *xp = !d ? y : 0;
480: return;
481: } else if ( !x->d ) {
482: pwrup(x,d,xp);
483: return;
484: }
485: reverseup(f,f->d,&t);
486: invmodup(t,f->d,&invf);
487: for ( k = n_bits(e)-1; k >= 0; k-- ) {
488: hybrid_squareup(FF_GFP,y,&t);
489: hybrid_rembymulup_special(FF_GFP,t,f,invf,&s);
490: y = s;
491: if ( e->b[k/32] & (1<<(k%32)) ) {
492: mulup(y,x,&t);
493: remup(t,f,&s);
494: y = s;
495: }
496: }
497: *xp = y;
498: }
499:
500: void generic_powermodup(g,f,d,xp)
501: UP g,f;
502: Q d;
503: UP *xp;
504: {
505: N e;
506: UP x,y,t,invf,s;
507: int k;
508: LM lm;
1.4 ! noro 509: GFS fs;
! 510: Num c;
1.1 noro 511: struct oEGT eg_sq,eg_rem,eg_mul,eg_inv,eg0,eg1,eg2,eg3;
512:
513: e = NM(d);
1.4 ! noro 514: switch ( current_ff ) {
! 515: case FF_GFP:
! 516: case FF_GFPN:
! 517: MKLM(ONEN,lm);
! 518: c = (Num)lm;
! 519: break;
! 520: case FF_GFS:
! 521: mqtogfs(ONEM,&fs);
! 522: c = (Num)fs;
! 523: break;
! 524: default:
! 525: error("generic_powermodup : not implemented yet");
! 526: }
! 527: y = UPALLOC(0); y->d = 0; y->c[0] = c;
1.1 noro 528: remup(g,f,&x);
529: if ( !x ) {
530: *xp = !d ? y : 0;
531: return;
532: } else if ( !x->d ) {
533: pwrup(x,d,xp);
534: return;
535: }
536: reverseup(f,f->d,&t);
537: invmodup(t,f->d,&invf);
538: for ( k = n_bits(e)-1; k >= 0; k-- ) {
539: ksquareup(y,&t);
540: rembymulup_special(t,f,invf,&s);
541: y = s;
542: if ( e->b[k/32] & (1<<(k%32)) ) {
543: mulup(y,x,&t);
544: remup(t,f,&s);
545: y = s;
546: }
547: }
548: *xp = y;
549: }
550:
551: void hybrid_powertabup(f,xp,tab)
552: UP f;
553: UP xp;
554: UP *tab;
555: {
556: UP y,t,invf;
557: int i,d;
558: LM lm;
559: struct oEGT eg_rem,eg_mul,eg0,eg1,eg2;
560:
561: d = f->d;
562: MKLM(ONEN,lm);
563: y = UPALLOC(0); y->d = 0; y->c[0] = (Num)lm;
564: tab[0] = y;
565: tab[1] = xp;
566:
567: reverseup(f,f->d,&t);
568: invmodup(t,f->d,&invf);
569:
570: for ( i = 2; i < d; i++ ) {
571: if ( debug_up )
572: fprintf(stderr,".");
573: hybrid_mulup(FF_GFP,tab[i-1],xp,&t);
574: hybrid_rembymulup_special(FF_GFP,t,f,invf,&tab[i]);
575: }
576: }
577:
578: void powertabup(f,xp,tab)
579: UP f;
580: UP xp;
581: UP *tab;
582: {
583: UP y,t,invf;
584: int i,d;
585: LM lm;
1.4 ! noro 586: GFS fs;
! 587: Num c;
1.1 noro 588: struct oEGT eg_rem,eg_mul,eg0,eg1,eg2;
589:
590: d = f->d;
1.4 ! noro 591: switch ( current_ff ) {
! 592: case FF_GFP:
! 593: case FF_GFPN:
! 594: MKLM(ONEN,lm);
! 595: c = (Num)lm;
! 596: break;
! 597: case FF_GFS:
! 598: mqtogfs(ONEM,&fs);
! 599: c = (Num)fs;
! 600: break;
! 601: default:
! 602: error("powertabup : not implemented yet");
! 603: }
! 604: y = UPALLOC(0); y->d = 0; y->c[0] = c;
1.1 noro 605: tab[0] = y;
606: tab[1] = xp;
607:
608: reverseup(f,f->d,&t);
609: invmodup(t,f->d,&invf);
610:
611: for ( i = 2; i < d; i++ ) {
612: if ( debug_up )
613: fprintf(stderr,".");
614: kmulup(tab[i-1],xp,&t);
615: rembymulup_special(t,f,invf,&tab[i]);
616: }
617: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>