Annotation of OpenXM_contrib2/asir2000/engine/up_lm.c, Revision 1.2
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
! 26: * e-mail at risa-admin@flab.fujitsu.co.jp of the detailed specification
! 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: *
! 48: * $OpenXM: OpenXM_contrib2/asir2000/engine/up_lm.c,v 1.1.1.1 1999/12/03 07:39:08 noro Exp $
! 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;
57:
58: void crup_lm(ModNum **,int,int *,int,N,N,UP *);
59:
60: void fft_mulup_lm(n1,n2,nr)
61: UP n1,n2;
62: UP *nr;
63: {
64: ModNum *f1,*f2,*w,*fr;
65: ModNum *frarray[1024];
66: int modarray[1024];
67: int frarray_index = 0;
68: N m,m1,m2,lm_mod;
69: int d1,d2,dmin,i,mod,root,d,cond,bound;
70: UP r;
71:
72: if ( !n1 || !n2 ) {
73: *nr = 0; return;
74: }
75: d1 = n1->d; d2 = n2->d; dmin = MIN(d1,d2);
76: if ( !d1 || !d2 ) {
77: mulup(n1,n2,nr); return;
78: }
79: getmod_lm(&lm_mod);
80: if ( !lm_mod )
81: error("fft_mulup_lm : current_mod_lm is not set");
82: m = ONEN;
83: bound = maxblenup(n1)+maxblenup(n2)+int_bits(dmin)+2;
84: f1 = (ModNum *)ALLOCA((d1+d2+1)*sizeof(ModNum));
85: f2 = (ModNum *)ALLOCA((d1+d2+1)*sizeof(ModNum));
86: w = (ModNum *)ALLOCA(6*(1<<int_bits(d1+d2+1))*sizeof(ModNum));
87: for ( i = 0; i < NPrimes; i++ ) {
88: FFT_primes(i,&mod,&root,&d);
89: if ( (1<<d) < d1+d2+1 )
90: continue;
91: modarray[frarray_index] = mod;
92: frarray[frarray_index++] = fr
93: = (ModNum *)ALLOCA((d1+d2+1)*sizeof(ModNum));
94: uptofmarray(mod,n1,f1);
95: uptofmarray(mod,n2,f2);
96: cond = FFT_pol_product(d1,f1,d2,f2,fr,i,w);
97: if ( cond )
98: error("fft_mulup : error in FFT_pol_product");
99: STON(mod,m1); muln(m,m1,&m2); m = m2;
100: if ( n_bits(m) > bound ) {
101: /* GC_dont_gc = 1; */
102: crup_lm(frarray,d1+d2,modarray,frarray_index,m,lm_mod,&r);
103: uptolmup(r,nr);
104: GC_dont_gc = 0;
105: return;
106: }
107: }
108: error("fft_mulup : FFT_primes exhausted");
109: }
110:
111: void fft_squareup_lm(n1,nr)
112: UP n1;
113: UP *nr;
114: {
115: ModNum *f1,*w,*fr;
116: ModNum *frarray[1024];
117: int modarray[1024];
118: int frarray_index = 0;
119: N m,m1,m2,lm_mod;
120: int d1,dmin,i,mod,root,d,cond,bound;
121: UP r;
122:
123: if ( !n1 ) {
124: *nr = 0; return;
125: }
126: d1 = n1->d; dmin = d1;
127: if ( !d1 ) {
128: mulup(n1,n1,nr); return;
129: }
130: getmod_lm(&lm_mod);
131: if ( !lm_mod )
132: error("fft_squareup_lm : current_mod_lm is not set");
133: m = ONEN;
134: bound = 2*maxblenup(n1)+int_bits(d1)+2;
135: f1 = (ModNum *)ALLOCA((2*d1+1)*sizeof(ModNum));
136: w = (ModNum *)ALLOCA(6*(1<<int_bits(2*d1+1))*sizeof(ModNum));
137: for ( i = 0; i < NPrimes; i++ ) {
138: FFT_primes(i,&mod,&root,&d);
139: if ( (1<<d) < 2*d1+1 )
140: continue;
141: modarray[frarray_index] = mod;
142: frarray[frarray_index++] = fr
143: = (ModNum *)ALLOCA((2*d1+1)*sizeof(ModNum));
144: uptofmarray(mod,n1,f1);
145: cond = FFT_pol_square(d1,f1,fr,i,w);
146: if ( cond )
147: error("fft_mulup : error in FFT_pol_product");
148: STON(mod,m1); muln(m,m1,&m2); m = m2;
149: if ( n_bits(m) > bound ) {
150: /* GC_dont_gc = 1; */
151: crup_lm(frarray,2*d1,modarray,frarray_index,m,lm_mod,&r);
152: uptolmup(r,nr);
153: GC_dont_gc = 0;
154: return;
155: }
156: }
157: error("fft_squareup : FFT_primes exhausted");
158: }
159:
160: void trunc_fft_mulup_lm(n1,n2,dbd,nr)
161: UP n1,n2;
162: int dbd;
163: UP *nr;
164: {
165: ModNum *f1,*f2,*fr,*w;
166: ModNum *frarray[1024];
167: int modarray[1024];
168: int frarray_index = 0;
169: N m,m1,m2,lm_mod;
170: int d1,d2,dmin,i,mod,root,d,cond,bound;
171: UP r;
172:
173: if ( !n1 || !n2 ) {
174: *nr = 0; return;
175: }
176: d1 = n1->d; d2 = n2->d; dmin = MIN(d1,d2);
177: if ( !d1 || !d2 ) {
178: tmulup(n1,n2,dbd,nr); return;
179: }
180: getmod_lm(&lm_mod);
181: if ( !lm_mod )
182: error("trunc_fft_mulup_lm : current_mod_lm is not set");
183: m = ONEN;
184: bound = maxblenup(n1)+maxblenup(n2)+int_bits(dmin)+2;
185: f1 = (ModNum *)ALLOCA((d1+d2+1)*sizeof(ModNum));
186: f2 = (ModNum *)ALLOCA((d1+d2+1)*sizeof(ModNum));
187: w = (ModNum *)ALLOCA(6*(1<<int_bits(d1+d2+1))*sizeof(ModNum));
188: for ( i = 0; i < NPrimes; i++ ) {
189: FFT_primes(i,&mod,&root,&d);
190: if ( (1<<d) < d1+d2+1 )
191: continue;
192:
193: modarray[frarray_index] = mod;
194: frarray[frarray_index++] = fr
195: = (ModNum *)ALLOCA((d1+d2+1)*sizeof(ModNum));
196: uptofmarray(mod,n1,f1);
197: uptofmarray(mod,n2,f2);
198: cond = FFT_pol_product(d1,f1,d2,f2,fr,i,w);
199: if ( cond )
200: error("fft_mulup : error in FFT_pol_product");
201: STON(mod,m1); muln(m,m1,&m2); m = m2;
202: if ( n_bits(m) > bound ) {
203: /* GC_dont_gc = 1; */
204: crup_lm(frarray,MIN(dbd-1,d1+d2),modarray,frarray_index,m,lm_mod,&r);
205: uptolmup(r,nr);
206: GC_dont_gc = 0;
207: return;
208: }
209: }
210: error("trunc_fft_mulup : FFT_primes exhausted");
211: }
212:
213: void crup_lm(f,d,mod,index,m,lm_mod,r)
214: ModNum **f;
215: int d;
216: int *mod;
217: int index;
218: N m;
219: N lm_mod;
220: UP *r;
221: {
222: double *k;
223: double c2;
224: unsigned int *w;
225: unsigned int zi,au,al;
226: UL a;
227: int i,j,l,len;
228: UP s,s1,u;
229: struct oUP c;
230: N t,ci,mi,qn;
231: unsigned int **sum;
232: unsigned int *sum_b;
233: Q q;
234: struct oEGT eg0,eg1;
235:
236: if ( !lm_mod )
237: error("crup_lm : current_mod_lm is not set");
238: k = (double *)ALLOCA((d+1)*sizeof(double));
239: for ( j = 0; j <= d; j++ )
240: k[j] = 0.5;
241: up_lazy = 1;
242: sum = (unsigned int **)ALLOCA((d+1)*sizeof(unsigned int *));
243: len = (int_bits(index)+n_bits(lm_mod)+31)/32+1;
244: w = (unsigned int *)ALLOCA((len+1)*sizeof(unsigned int));
245: sum_b = (unsigned int *)MALLOC_ATOMIC((d+1)*len*sizeof(unsigned int));
246: for ( j = 0; j <= d; j++ ) {
247: sum[j] = sum_b+len*j;
248: bzero((char *)sum[j],len*sizeof(unsigned int));
249: }
250: for ( i = 0, s = 0; i < index; i++ ) {
251: divin(m,mod[i],&ci);
252: zi = (unsigned int)invm((unsigned int)rem(ci,mod[i]),mod[i]);
253:
254: STON(zi,t); muln(ci,t,&mi);
255: divn(mi,lm_mod,&qn,&t);
256: if ( t )
257: for ( j = 0; j <= d; j++ ) {
258: bzero((char *)w,(len+1)*sizeof(unsigned int));
259: muln_1(BD(t),PL(t),(unsigned int)f[i][j],w);
260: for ( l = PL(t); l >= 0 && !w[l]; l--);
261: l++;
262: if ( l )
263: addarray_to(w,l,sum[j],len);
264: }
265: c2 = (double)zi/(double)mod[i];
266: for ( j = 0; j <= d; j++ )
267: k[j] += c2*f[i][j];
268: }
269: uiarraytoup(sum,len,d,&s);
270: GC_free(sum_b);
271:
272: u = UPALLOC(d);
273: for ( j = 0; j <= d; j++ ) {
274: #if 1
275: a = (UL)floor(k[j]);
276: #if defined(i386) || defined(__alpha) || defined(VISUAL)
277: au = ((unsigned int *)&a)[1];
278: al = ((unsigned int *)&a)[0];
279: #else
280: al = ((unsigned int *)&a)[1];
281: au = ((unsigned int *)&a)[0];
282: #endif
283: if ( au ) {
284: NEWQ(q); SGN(q) = 1; NM(q)=NALLOC(2); DN(q)=0;
285: PL(NM(q))=2; BD(NM(q))[0]=al; BD(NM(q))[1] = au;
286: } else
287: UTOQ(al,q);
288: #else
289: al = (int)floor(k[j]); STOQ(al,q);
290: #endif
291: u->c[j] = (Num)q;
292: }
293: for ( j = d; j >= 0 && !u->c[j]; j-- );
294: if ( j < 0 )
295: u = 0;
296: else
297: u->d = j;
298: divn(m,lm_mod,&qn,&t); NTOQ(t,-1,q);
299: c.d = 0; c.c[0] = (Num)q;
300: mulup(u,&c,&s1);
301: up_lazy = 0;
302:
303: addup(s,s1,r);
304: }
305:
306: void fft_rembymulup_special_lm(n1,n2,inv2,nr)
307: UP n1,n2,inv2;
308: UP *nr;
309: {
310: int d1,d2,d;
311: UP r1,t,s,q,u;
312:
313: if ( !n2 )
314: error("rembymulup : division by 0");
315: else if ( !n1 || !n2->d )
316: *nr = 0;
317: else if ( (d1 = n1->d) < (d2 = n2->d) )
318: *nr = n1;
319: else {
320: d = d1-d2;
321: reverseup(n1,d1,&t); truncup(t,d+1,&r1);
322: trunc_fft_mulup_lm(r1,inv2,d+1,&t);
323: truncup(t,d+1,&s);
324: reverseup(s,d,&q);
325: trunc_fft_mulup_lm(q,n2,d2,&t); truncup(t,d2,&u);
326: truncup(n1,d2,&s);
327: subup(s,u,nr);
328: }
329: }
330:
331: void uptolmup(n,nr)
332: UP n;
333: UP *nr;
334: {
335: int i,d;
336: Q *c;
337: LM *cr;
338: UP r;
339:
340: if ( !n )
341: *nr = 0;
342: else {
343: d = n->d; c = (Q *)n->c;
344: *nr = r = UPALLOC(d); cr = (LM *)r->c;
345: for ( i = 0; i <= d; i++ )
346: qtolm(c[i],&cr[i]);
347: for ( i = d; i >= 0 && !cr[i]; i-- );
348: if ( i < 0 )
349: *nr = 0;
350: else
351: r->d = i;
352: }
353: }
354:
355: save_up(obj,name)
356: UP obj;
357: char *name;
358: {
359: P p;
360: Obj ret;
361: NODE n0,n1;
362: STRING s;
363:
364: uptop(obj,&p);
365: MKSTR(s,name);
366: MKNODE(n1,s,0); MKNODE(n0,p,n1);
367: Pbsave(n0,&ret);
368: }
369:
370: void hybrid_powermodup(f,xp)
371: UP f;
372: UP *xp;
373: {
374: N n;
375: UP x,y,t,invf,s;
376: int k;
377: LM lm;
378: struct oEGT eg_sq,eg_rem,eg_mul,eg_inv,eg0,eg1,eg2,eg3;
379: char name[BUFSIZ];
380:
381: getmod_lm(&n);
382: if ( !n )
383: error("hybrid_powermodup : current_mod_lm is not set");
384: MKLM(ONEN,lm);
385: x = UPALLOC(1); x->d = 1; x->c[1] = (Num)lm;
386: y = UPALLOC(0); y->d = 0; y->c[0] = (Num)lm;
387:
388: reverseup(f,f->d,&t);
389: invmodup(t,f->d,&s); uptolmup(s,&invf);
390: for ( k = n_bits(n)-1; k >= 0; k-- ) {
391: hybrid_squareup(FF_GFP,y,&t);
392: hybrid_rembymulup_special(FF_GFP,t,f,invf,&s);
393: y = s;
394: if ( n->b[k/32] & (1<<(k%32)) ) {
395: mulup(y,x,&t);
396: remup(t,f,&s);
397: y = s;
398: }
399: }
400: *xp = y;
401: }
402:
403: void powermodup(f,xp)
404: UP f;
405: UP *xp;
406: {
407: N n;
408: UP x,y,t,invf,s;
409: int k;
410: LM lm;
411: struct oEGT eg_sq,eg_rem,eg_mul,eg_inv,eg0,eg1,eg2,eg3;
412:
413: field_order_ff(&n);
414: if ( !n )
415: error("powermodup : current_mod_lm is not set");
416: MKLM(ONEN,lm);
417: x = UPALLOC(1); x->d = 1; x->c[1] = (Num)lm;
418: y = UPALLOC(0); y->d = 0; y->c[0] = (Num)lm;
419:
420: reverseup(f,f->d,&t);
421: invmodup(t,f->d,&s); uptolmup(s,&invf);
422: for ( k = n_bits(n)-1; k >= 0; k-- ) {
423: ksquareup(y,&t);
424: rembymulup_special(t,f,invf,&s);
425: y = s;
426: if ( n->b[k/32] & (1<<(k%32)) ) {
427: mulup(y,x,&t);
428: remup(t,f,&s);
429: y = s;
430: }
431: }
432: *xp = y;
433: }
434:
435: /* g^d mod f */
436:
437: void hybrid_generic_powermodup(g,f,d,xp)
438: UP g,f;
439: Q d;
440: UP *xp;
441: {
442: N e;
443: UP x,y,t,invf,s;
444: int k;
445: LM lm;
446: struct oEGT eg_sq,eg_rem,eg_mul,eg_inv,eg0,eg1,eg2,eg3;
447:
448: e = NM(d);
449: MKLM(ONEN,lm);
450: y = UPALLOC(0); y->d = 0; y->c[0] = (Num)lm;
451: remup(g,f,&x);
452: if ( !x ) {
453: *xp = !d ? y : 0;
454: return;
455: } else if ( !x->d ) {
456: pwrup(x,d,xp);
457: return;
458: }
459: reverseup(f,f->d,&t);
460: invmodup(t,f->d,&invf);
461: for ( k = n_bits(e)-1; k >= 0; k-- ) {
462: hybrid_squareup(FF_GFP,y,&t);
463: hybrid_rembymulup_special(FF_GFP,t,f,invf,&s);
464: y = s;
465: if ( e->b[k/32] & (1<<(k%32)) ) {
466: mulup(y,x,&t);
467: remup(t,f,&s);
468: y = s;
469: }
470: }
471: *xp = y;
472: }
473:
474: void generic_powermodup(g,f,d,xp)
475: UP g,f;
476: Q d;
477: UP *xp;
478: {
479: N e;
480: UP x,y,t,invf,s;
481: int k;
482: LM lm;
483: struct oEGT eg_sq,eg_rem,eg_mul,eg_inv,eg0,eg1,eg2,eg3;
484:
485: e = NM(d);
486: MKLM(ONEN,lm);
487: y = UPALLOC(0); y->d = 0; y->c[0] = (Num)lm;
488: remup(g,f,&x);
489: if ( !x ) {
490: *xp = !d ? y : 0;
491: return;
492: } else if ( !x->d ) {
493: pwrup(x,d,xp);
494: return;
495: }
496: reverseup(f,f->d,&t);
497: invmodup(t,f->d,&invf);
498: for ( k = n_bits(e)-1; k >= 0; k-- ) {
499: ksquareup(y,&t);
500: rembymulup_special(t,f,invf,&s);
501: y = s;
502: if ( e->b[k/32] & (1<<(k%32)) ) {
503: mulup(y,x,&t);
504: remup(t,f,&s);
505: y = s;
506: }
507: }
508: *xp = y;
509: }
510:
511: void hybrid_powertabup(f,xp,tab)
512: UP f;
513: UP xp;
514: UP *tab;
515: {
516: UP y,t,invf;
517: int i,d;
518: LM lm;
519: struct oEGT eg_rem,eg_mul,eg0,eg1,eg2;
520:
521: d = f->d;
522: MKLM(ONEN,lm);
523: y = UPALLOC(0); y->d = 0; y->c[0] = (Num)lm;
524: tab[0] = y;
525: tab[1] = xp;
526:
527: reverseup(f,f->d,&t);
528: invmodup(t,f->d,&invf);
529:
530: for ( i = 2; i < d; i++ ) {
531: if ( debug_up )
532: fprintf(stderr,".");
533: hybrid_mulup(FF_GFP,tab[i-1],xp,&t);
534: hybrid_rembymulup_special(FF_GFP,t,f,invf,&tab[i]);
535: }
536: }
537:
538: void powertabup(f,xp,tab)
539: UP f;
540: UP xp;
541: UP *tab;
542: {
543: UP y,t,invf;
544: int i,d;
545: LM lm;
546: struct oEGT eg_rem,eg_mul,eg0,eg1,eg2;
547:
548: d = f->d;
549: MKLM(ONEN,lm);
550: y = UPALLOC(0); y->d = 0; y->c[0] = (Num)lm;
551: tab[0] = y;
552: tab[1] = xp;
553:
554: reverseup(f,f->d,&t);
555: invmodup(t,f->d,&invf);
556:
557: for ( i = 2; i < d; i++ ) {
558: if ( debug_up )
559: fprintf(stderr,".");
560: kmulup(tab[i-1],xp,&t);
561: rembymulup_special(t,f,invf,&tab[i]);
562: }
563: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>