[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     ! 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>