[BACK]Return to ddM.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / asm

Annotation of OpenXM_contrib2/asir2000/asm/ddM.c, Revision 1.1.1.1

1.1       noro        1: /* $OpenXM: OpenXM/src/asir99/asm/ddM.c,v 1.1.1.1 1999/11/10 08:12:25 noro Exp $ */
                      2: #include "ca.h"
                      3: #include "base.h"
                      4: #include "inline.h"
                      5:
                      6: void ksquareummain(int,UM,UM);
                      7: void kmulummain(int,UM,UM,UM);
                      8: void c_copyum(UM,int,int *);
                      9: void copyum(UM,UM);
                     10: void extractum(UM,int,int,UM);
                     11: void ksquareum(int,UM,UM);
                     12: void kmulum(int,UM,UM,UM);
                     13:
                     14: /*
                     15:  * mod is declared as 'int', because several xxxum functions contains signed
                     16:  * integer addition/subtraction. So mod should be less than 2^31.
                     17:  */
                     18:
                     19: void mulum(mod,p1,p2,pr)
                     20: int mod;
                     21: UM p1,p2,pr;
                     22: {
                     23:        int *pc1,*pcr;
                     24:        int *c1,*c2,*cr;
                     25:        unsigned int mul;
                     26:        int i,j,d1,d2;
                     27:
                     28:        if ( ( (d1 = DEG(p1)) < 0) || ( (d2 = DEG(p2)) < 0 ) ) {
                     29:                DEG(pr) = -1;
                     30:                return;
                     31:        }
                     32:        c1 = COEF(p1); c2 = COEF(p2); cr = COEF(pr);
                     33:        bzero((char *)cr,(int)((d1+d2+1)*sizeof(int)));
                     34:        for ( i = 0; i <= d2; i++, cr++ )
                     35:                if ( mul = *c2++ )
                     36:                        for ( j = 0, pc1 = c1, pcr = cr; j <= d1; j++, pc1++, pcr++ ) {
                     37:                                DMAR(*pc1,mul,*pcr,mod,*pcr)
                     38:                        }
                     39:        DEG(pr) = d1 + d2;
                     40: }
                     41:
                     42: void mulsum(mod,p,n,pr)
                     43: int mod,n;
                     44: UM p,pr;
                     45: {
                     46:        int *sp,*dp;
                     47:        int i;
                     48:
                     49:        for ( i = DEG(pr) = DEG(p), sp = COEF(p)+i, dp = COEF(pr)+i;
                     50:                  i >= 0; i--, dp--, sp-- ) {
                     51:                DMAR(*sp,n,0,mod,*dp)
                     52:        }
                     53: }
                     54:
                     55: int divum(mod,p1,p2,pq)
                     56: int mod;
                     57: UM p1,p2,pq;
                     58: {
                     59:        int *pc1,*pct;
                     60:        int *c1,*c2,*ct;
                     61:        unsigned int inv,hd,tmp;
                     62:        int i,j, d1,d2,dd;
                     63:
                     64:        if ( (d1 = DEG(p1)) < (d2 = DEG(p2)) ) {
                     65:                DEG(pq) = -1;
                     66:                return d1;
                     67:        }
                     68:        c1 = COEF(p1); c2 = COEF(p2); dd = d1-d2;
                     69:        if ( ( hd = c2[d2] ) != 1 ) {
                     70:                inv = invm(hd,mod);
                     71:                for ( pc1 = c2 + d2; pc1 >= c2; pc1-- ) {
                     72:                        DMAR(*pc1,inv,0,mod,*pc1)
                     73:                }
                     74:        } else
                     75:                inv = 1;
                     76:        for ( i = dd, ct = c1+d1; i >= 0; i-- )
                     77:                if ( tmp = *ct-- ) {
                     78:                        tmp = mod - tmp;
                     79:                        for ( j = d2-1, pct = ct, pc1 = c2+j; j >= 0; j--, pct--, pc1-- ) {
                     80:                                DMAR(*pc1,tmp,*pct,mod,*pct)
                     81:                        }
                     82:                }
                     83:        if ( inv != 1 ) {
                     84:                for ( pc1 = c1+d2, pct = c1+d1; pc1 <= pct; pc1++ ) {
                     85:                        DMAR(*pc1,inv,0,mod,*pc1)
                     86:                }
                     87:                for ( pc1 = c2, pct = c2+d2, inv = hd; pc1 <= pct; pc1++ ) {
                     88:                        DMAR(*pc1,inv,0,mod,*pc1)
                     89:                }
                     90:        }
                     91:        for ( i = d2-1, pc1 = c1+i; i >= 0 && !(*pc1); pc1--, i-- );
                     92:        for ( DEG(pq) = j = dd, pc1 = c1+d1, pct = COEF(pq)+j; j >= 0; j-- )
                     93:                *pct-- = *pc1--;
                     94:        return i;
                     95: }
                     96:
                     97: void diffum(mod,f,fd)
                     98: int mod;
                     99: UM f,fd;
                    100: {
                    101:        int *dp,*sp;
                    102:        int i;
                    103:        UL ltmp;
                    104:
                    105:        for ( i = DEG(f), dp = COEF(fd)+i-1, sp = COEF(f)+i;
                    106:                i >= 1; i--, dp--, sp-- ) {
                    107:                DMAR(*sp,i,0,mod,*dp)
                    108:        }
                    109:        degum(fd,DEG(f) - 1);
                    110: }
                    111:
                    112: unsigned int pwrm(mod,a,n)
                    113: int mod,a;
                    114: int n;
                    115: {
                    116:        unsigned int s,t;
                    117:
                    118:        if ( !n )
                    119:                return 1;
                    120:        else if ( n == 1 )
                    121:                return a;
                    122:        else {
                    123:                t = pwrm(mod,a,n/2);
                    124:                DMAR(t,t,0,mod,s)
                    125:                if ( n % 2 ) {
                    126:                        DMAR(s,a,0,mod,t)
                    127:                        return t;
                    128:                } else
                    129:                        return s;
                    130:        }
                    131: }
                    132:
                    133: unsigned int invm(s,mod)
                    134: unsigned int s;
                    135: int mod;
                    136: {
                    137:        unsigned int r,a2,q;
                    138:        unsigned int f1,f2,a1;
                    139:
                    140:        for ( f1 = s, f2 = mod, a1 = 1, a2 = 0; ; ) {
                    141:                q = f1/f2; r = f1 - f2*q; f1 = f2;
                    142:                if ( !(f2 = r) )
                    143:                        break;
                    144:                DMAR(a2,q,0,mod,r)
                    145: /*             r = ( a1 - r + mod ) % mod; */
                    146:                if ( a1 >= r )
                    147:                        r = a1 - r;
                    148:                else {
                    149:                        r = (mod - r) + a1;
                    150:                }
                    151:                a1 = a2; a2 = r;
                    152:        }
                    153: /*     return( ( a2 >= 0 ? a2 : a2 + mod ) ); */
                    154:        return a2;
                    155: }
                    156:
                    157: unsigned int rem(n,m)
                    158: N n;
                    159: unsigned int m;
                    160: {
                    161:        unsigned int *x;
                    162:        unsigned int t,r;
                    163:        int i;
                    164:
                    165:        if ( !n )
                    166:                return 0;
                    167:        for ( i = PL(n)-1, x = BD(n)+i, r = 0; i >= 0; i--, x-- ) {
                    168: #if defined(sparc)
                    169:                r = dsar(m,r,*x);
                    170: #else
                    171:                DSAB(m,r,*x,t,r)
                    172: #endif
                    173:        }
                    174:        return r;
                    175: }
                    176:
                    177: #ifndef sparc
                    178: void addpadic(mod,n,n1,n2)
                    179: int mod;
                    180: int n;
                    181: unsigned int *n1,*n2;
                    182: {
                    183:        unsigned int carry,tmp;
                    184:        int i;
                    185:
                    186:        for ( i = 0, carry = 0; i < n; i++ ) {
                    187:                tmp = *n1++ + *n2 + carry;
                    188:                DQR(tmp,mod,carry,*n2++)
                    189: /*
                    190:                carry = tmp / mod;
                    191:                *n2++ = tmp - ( carry * mod );
                    192: */
                    193:        }
                    194: }
                    195: #endif
                    196:
                    197: void mulpadic(mod,n,n1,n2,nr)
                    198: int mod;
                    199: int n;
                    200: unsigned int *n1;
                    201: unsigned int *n2,*nr;
                    202: {
                    203:        unsigned int *pn1,*pnr;
                    204:        unsigned int carry,mul;
                    205:        int i,j;
                    206:
                    207:        bzero((char *)nr,(int)(n*sizeof(int)));
                    208:        for ( j = 0; j < n; j++, n2++, nr++ )
                    209:                if ( mul = *n2 )
                    210:                        for ( i = j, carry = 0, pn1 = n1, pnr = nr;
                    211:                                i < n; i++, pn1++, pnr++ ) {
                    212:                                carry += *pnr;
                    213:                                DMAB(mod,*pn1,mul,carry,carry,*pnr)
                    214:                        }
                    215: }
                    216:
                    217: extern up_kara_mag;
                    218:
                    219: void kmulum(mod,n1,n2,nr)
                    220: UM n1,n2,nr;
                    221: {
                    222:        UM n,t,s,m,carry;
                    223:        int d,d1,d2,len,i,l;
                    224:        unsigned int *r,*r0;
                    225:
                    226:        if ( !n1 || !n2 ) {
                    227:                nr->d = -1; return;
                    228:        }
                    229:        d1 = DEG(n1)+1; d2 = DEG(n2)+1;
                    230:        if ( (d1 < up_kara_mag) || (d2 < up_kara_mag) ) {
                    231:                mulum(mod,n1,n2,nr); return;
                    232:        }
                    233:        if ( d1 < d2 ) {
                    234:                n = n1; n1 = n2; n2 = n;
                    235:                d = d1; d1 = d2; d2 = d;
                    236:        }
                    237:        if ( d2 > (d1+1)/2 ) {
                    238:                kmulummain(mod,n1,n2,nr); return;
                    239:        }
                    240:        d = (d1/d2)+((d1%d2)!=0);
                    241:        len = (d+1)*d2;
                    242:        r0 = (unsigned int *)ALLOCA(len*sizeof(int));
                    243:        bzero((char *)r0,len*sizeof(int));
                    244:        m = W_UMALLOC(d2+1);
                    245:        carry = W_UMALLOC(d2+1);
                    246:        t = W_UMALLOC(d1+d2+1);
                    247:        s = W_UMALLOC(d1+d2+1);
                    248:        for ( carry = 0, i = 0, r = r0; i < d; i++, r += d2 ) {
                    249:                extractum(n1,i*d2,d2,m);
                    250:                if ( m ) {
                    251:                        kmulum(mod,m,n2,t);
                    252:                        addum(mod,t,carry,s);
                    253:                        c_copyum(s,d2,r);
                    254:                        extractum(s,d2,d2,carry);
                    255:                } else {
                    256:                        c_copyum(carry,d2,r);
                    257:                        carry = 0;
                    258:                }
                    259:        }
                    260:        c_copyum(carry,d2,r);
                    261:        for ( l = len - 1; !r0[l]; l-- );
                    262:        l++;
                    263:        DEG(nr) = l-1;
                    264:        bcopy((char *)r0,(char *)COEF(nr),l*sizeof(int));
                    265: }
                    266:
                    267: void ksquareum(mod,n1,nr)
                    268: int mod;
                    269: UM n1,nr;
                    270: {
                    271:        int d1;
                    272:
                    273:        if ( !n1 ) {
                    274:                nr->d = -1; return;
                    275:        }
                    276:        d1 = DEG(n1)+1;
                    277:        if ( (d1 < up_kara_mag) ) {
                    278:                pwrum(mod,n1,2,nr); return;
                    279:        }
                    280:        ksquareummain(mod,n1,nr);
                    281: }
                    282:
                    283: void extractum(n,index,len,nr)
                    284: UM n;
                    285: int index,len;
                    286: UM nr;
                    287: {
                    288:        int *m;
                    289:        int l;
                    290:
                    291:        if ( !n ) {
                    292:                nr->d = -1; return;
                    293:        }
                    294:        m = COEF(n)+index;
                    295:        if ( (l = (DEG(n)+1)-index) >= len ) {
                    296:                for ( l = len - 1; (l >= 0) && !m[l]; l-- );
                    297:                l++;
                    298:        }
                    299:        if ( l <= 0 ) {
                    300:                nr->d = -1; return;
                    301:        } else {
                    302:                DEG(nr) = l-1;
                    303:                bcopy((char *)m,(char *)COEF(nr),l*sizeof(Q));
                    304:        }
                    305: }
                    306:
                    307: void copyum(n1,n2)
                    308: UM n1,n2;
                    309: {
                    310:        n2->d = n1->d;
                    311:        bcopy((char *)n1->c,(char *)n2->c,(n1->d+1)*sizeof(int));
                    312: }
                    313:
                    314: void c_copyum(n,len,p)
                    315: UM n;
                    316: int len;
                    317: int *p;
                    318: {
                    319:        if ( n )
                    320:                bcopy((char *)COEF(n),(char *)p,MIN((DEG(n)+1),len)*sizeof(int));
                    321: }
                    322:
                    323: void kmulummain(mod,n1,n2,nr)
                    324: int mod;
                    325: UM n1,n2,nr;
                    326: {
                    327:        int d1,d2,h,len;
                    328:        UM n1lo,n1hi,n2lo,n2hi,hi,lo,mid1,mid2,mid,s1,s2,t1,t2;
                    329:
                    330:        d1 = DEG(n1)+1; d2 = DEG(n2)+1; h = (d1+1)/2;
                    331:        n1lo = W_UMALLOC(d1+1); n1hi = W_UMALLOC(d1+1);
                    332:        n2lo = W_UMALLOC(d2+1); n2hi = W_UMALLOC(d2+1);
                    333:        lo = W_UMALLOC(d1+d2+1); hi = W_UMALLOC(d1+d2+1);
                    334:        mid1 = W_UMALLOC(d1+d2+1); mid2 = W_UMALLOC(d1+d2+1);
                    335:        mid = W_UMALLOC(d1+d2+1);
                    336:        s1 = W_UMALLOC(d1+d2+1); s2 = W_UMALLOC(d1+d2+1);
                    337:        extractum(n1,0,h,n1lo); extractum(n1,h,d1-h,n1hi);
                    338:        extractum(n2,0,h,n2lo); extractum(n2,h,d2-h,n2hi);
                    339:        kmulum(mod,n1hi,n2hi,hi); kmulum(mod,n1lo,n2lo,lo);
                    340:        len = DEG(hi)+1+2*h; t1 = W_UMALLOC(len-1); DEG(t1) = len-1;
                    341:        bzero((char *)COEF(t1),len*sizeof(int));
                    342:        if ( lo )
                    343:                bcopy((char *)COEF(lo),(char *)COEF(t1),(DEG(lo)+1)*sizeof(int));
                    344:        if ( hi )
                    345:                bcopy((char *)COEF(hi),(char *)(COEF(t1)+2*h),(DEG(hi)+1)*sizeof(int));
                    346:
                    347:        addum(mod,hi,lo,mid1);
                    348:        subum(mod,n1hi,n1lo,s1); subum(mod,n2lo,n2hi,s2); kmulum(mod,s1,s2,mid2);
                    349:        addum(mod,mid1,mid2,mid);
                    350:        if ( mid ) {
                    351:                len = DEG(mid)+1+h; t2 = W_UMALLOC(len-1); DEG(t2) = len-1;
                    352:                bzero((char *)COEF(t2),len*sizeof(int));
                    353:                bcopy((char *)COEF(mid),(char *)(COEF(t2)+h),(DEG(mid)+1)*sizeof(int));
                    354:                addum(mod,t1,t2,nr);
                    355:        } else
                    356:                copyum(t1,nr);
                    357: }
                    358:
                    359: void ksquareummain(mod,n1,nr)
                    360: int mod;
                    361: UM n1,nr;
                    362: {
                    363:        int d1,h,len;
                    364:        UM n1lo,n1hi,hi,lo,mid1,mid2,mid,s1,t1,t2;
                    365:
                    366:        d1 = DEG(n1)+1; h = (d1+1)/2;
                    367:        n1lo = W_UMALLOC(d1+1); n1hi = W_UMALLOC(d1+1);
                    368:        lo = W_UMALLOC(2*d1+1); hi = W_UMALLOC(2*d1+1);
                    369:        mid1 = W_UMALLOC(2*d1+1); mid2 = W_UMALLOC(2*d1+1);
                    370:        mid = W_UMALLOC(2*d1+1);
                    371:        s1 = W_UMALLOC(2*d1+1);
                    372:        extractum(n1,0,h,n1lo); extractum(n1,h,d1-h,n1hi);
                    373:        ksquareum(mod,n1hi,hi); ksquareum(mod,n1lo,lo);
                    374:        len = DEG(hi)+1+2*h; t1 = W_UMALLOC(len-1); DEG(t1) = len-1;
                    375:        bzero((char *)COEF(t1),len*sizeof(int));
                    376:        if ( lo )
                    377:                bcopy((char *)COEF(lo),(char *)COEF(t1),(DEG(lo)+1)*sizeof(int));
                    378:        if ( hi )
                    379:                bcopy((char *)COEF(hi),(char *)(COEF(t1)+2*h),(DEG(hi)+1)*sizeof(int));
                    380:
                    381:        addum(mod,hi,lo,mid1);
                    382:        subum(mod,n1hi,n1lo,s1); ksquareum(mod,s1,mid2);
                    383:        subum(mod,mid1,mid2,mid);
                    384:        if ( mid ) {
                    385:                len = DEG(mid)+1+h; t2 = W_UMALLOC(len-1); DEG(t2) = len-1;
                    386:                bzero((char *)COEF(t2),len*sizeof(int));
                    387:                bcopy((char *)COEF(mid),(char *)(COEF(t2)+h),(DEG(mid)+1)*sizeof(int));
                    388:                addum(mod,t1,t2,nr);
                    389:        } else
                    390:                copyum(t1,nr);
                    391: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>