[BACK]Return to dmul CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / lib

Annotation of OpenXM_contrib2/asir2000/lib/dmul, Revision 1.3

1.3     ! 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/lib/dmul,v 1.2 2000/01/11 06:43:37 noro Exp $
        !            49: */
1.1       noro       50: #define MAX(a,b) ((a)>(b)?(a):(b))
                     51: #define MIN(a,b) ((a)>(b)?(b):(a))
                     52:
                     53: /* CAUTION: functions in this file are experimental. */
                     54:
                     55: /*
                     56:        return: F1*F2
                     57:        if option 'proc' is supplied as a list of server id's,
                     58:        F1*F2 is calculated by distributed computation.
                     59: */
                     60:
                     61: def d_mul(F1,F2)
                     62: {
                     63:        Procs = getopt(proc);
                     64:        if ( type(Procs) == -1 )
                     65:                Procs = [];
1.2       noro       66:        Mod = getopt(mod);
                     67:        if ( type(Mod) == -1 )
                     68:                Mod = 0;
1.1       noro       69:        NP = length(Procs)+1;
                     70:        V =var(F1);
1.2       noro       71:        if ( !V ) {
                     72:                T = F1*F2;
                     73:                if ( Mod )
                     74:                        return T % Mod;
                     75:                else
                     76:                        return T;
                     77:        }
1.1       noro       78:        D1 = deg(F1,V);
                     79:        D2 = deg(F2,V);
                     80:        Dmin = MIN(D1,D2);
                     81:        Dfft = p_mag(D1+D2+1)+1;
                     82:        Bound = maxblen(F1)+maxblen(F2)+p_mag(Dmin)+1;
1.2       noro       83:        if ( Bound < 32 )
                     84:                Bound = 32;
1.1       noro       85:        Marray = newvect(NP);
                     86:        MIarray = newvect(NP);
                     87:        for ( I = 0; I < NP; I++ ) {
                     88:                Marray[I] = 1;
                     89:                MIarray[I] = [];
                     90:        }
                     91:
                     92:        for ( M = 1, I = 0, J = 0; p_mag(M) <= Bound; J = (J+1)%NP ) {
                     93:                T = get_next_fft_prime(I,Dfft);
                     94:                if ( !T )
                     95:                        error("fft_mul_d : fft_prime exhausted.");
                     96:                Marray[J] *= T[1];
                     97:                MIarray[J] = cons(T[0],MIarray[J]);
                     98:                M *= T[1];
                     99:                I = T[0]+1;
                    100:        }
                    101:        /* Now,
                    102:                Marray[J] = FFTprime[Marray[J][0]]*...*FFTprime[Marray[J][...]]
                    103:                M = Marray[0]*...*Marray[NP-1]
                    104:        */
                    105:        C = newvect(NP);
                    106:        T0 = time();
                    107:        for ( J = 0; J < NP-1; J++ )
                    108:                ox_cmo_rpc(Procs[J],"call_umul",F1,F2,MIarray[J],Marray[J],M);
                    109:        T1 = time();
                    110:        R = call_umul(F1,F2,MIarray[NP-1],Marray[NP-1],M);
                    111:        T2 = time();
                    112:        for ( J = 0; J < NP-1; J++ )
                    113:                R += ox_pop_cmo(Procs[J]);
                    114:        T3 = time();
1.2       noro      115: /*     print(["send",T1[3]-T0[3],"self",T2[3]-T1[3],"recv",T3[3]-T2[3]]); */
                    116:        if ( Mod )
                    117:                return (R%M)%Mod;
                    118:        else
                    119:                return uadj_coef(R%M,M,ishift(M,1));
1.1       noro      120: }
                    121:
                    122: /*
                    123:        return: F1^2
                    124:        if option 'proc' is supplied as a list of server id's,
                    125:        F1^2 is calculated by distributed computation.
                    126: */
                    127:
                    128: def d_square(F1)
                    129: {
                    130:        Procs = getopt(proc);
                    131:        if ( type(Procs) == -1 )
                    132:                Procs = [];
1.2       noro      133:        Mod = getopt(mod);
                    134:        if ( type(Mod) == -1 )
                    135:                Mod = 0;
1.1       noro      136:        NP = length(Procs)+1;
                    137:        V =var(F1);
1.2       noro      138:        if ( !V ) {
                    139:                T = F1^2;
                    140:                if ( Mod )
                    141:                        return T % Mod;
                    142:                else
                    143:                        return T;
                    144:        }
1.1       noro      145:        D1 = deg(F1,V);
                    146:        Dfft = p_mag(2*D1+1)+1;
                    147:        Bound = 2*maxblen(F1)+p_mag(D1)+1;
1.2       noro      148:        if ( Bound < 32 )
                    149:                Bound = 32;
1.1       noro      150:        Marray = newvect(NP);
                    151:        MIarray = newvect(NP);
                    152:        for ( I = 0; I < NP; I++ ) {
                    153:                Marray[I] = 1;
                    154:                MIarray[I] = [];
                    155:        }
                    156:
                    157:        for ( M = 1, I = 0, J = 0; p_mag(M) <= Bound; J = (J+1)%NP ) {
                    158:                T = get_next_fft_prime(I,Dfft);
                    159:                if ( !T )
                    160:                        error("fft_mul_d : fft_prime exhausted.");
                    161:                Marray[J] *= T[1];
                    162:                MIarray[J] = cons(T[0],MIarray[J]);
                    163:                M *= T[1];
                    164:                I = T[0]+1;
                    165:        }
                    166:        /* Now,
                    167:                Marray[J] = FFTprime[Marray[J][0]]*...*FFTprime[Marray[J][...]]
                    168:                M = Marray[0]*...*Marray[NP-1]
                    169:        */
                    170:        C = newvect(NP);
                    171:        T0 = time();
                    172:        for ( J = 0; J < NP-1; J++ )
                    173:                ox_cmo_rpc(Procs[J],"call_usquare",F1,MIarray[J],Marray[J],M);
                    174:        T1 = time();
                    175:        R = call_usquare(F1,MIarray[NP-1],Marray[NP-1],M);
                    176:        T2 = time();
                    177:        for ( J = 0; J < NP-1; J++ )
                    178:                R += ox_pop_cmo(Procs[J]);
                    179:        T3 = time();
1.2       noro      180: /*     print(["send",T1[3]-T0[3],"self",T2[3]-T1[3],"recv",T3[3]-T2[3]]); */
                    181:        if ( Mod )
                    182:                return (R%M)%Mod;
                    183:        else
                    184:                return uadj_coef(R%M,M,ishift(M,1));
1.1       noro      185: }
                    186:
                    187: /*
                    188:        return: F1^2 mod V^(D+1)
                    189:        if option 'proc' is supplied as a list of server id's,
                    190:        F1*F2 mod V^(D+1) is calculated by distributed computation.
                    191: */
                    192:
                    193: def d_tmul(F1,F2,D)
                    194: {
                    195:        Procs = getopt(proc);
                    196:        if ( type(Procs) == -1 )
                    197:                Procs = [];
1.2       noro      198:        Mod = getopt(mod);
                    199:        if ( type(Mod) == -1 )
                    200:                Mod = 0;
1.1       noro      201:        NP = length(Procs)+1;
                    202:        V =var(F1);
1.2       noro      203:        if ( !V ) {
                    204:                T = utrunc(F1*F2,D);
                    205:                if ( Mod )
                    206:                        return T % Mod;
                    207:                else
                    208:                        return T;
                    209:        }
1.1       noro      210:        D1 = deg(F1,V);
                    211:        D2 = deg(F2,V);
                    212:        Dmin = MIN(D1,D2);
                    213:        Dfft = p_mag(D1+D2+1)+1;
                    214:        Bound = maxblen(F1)+maxblen(F2)+p_mag(Dmin)+1;
1.2       noro      215:        if ( Bound < 32 )
                    216:                Bound = 32;
1.1       noro      217:        Marray = newvect(NP);
                    218:        MIarray = newvect(NP);
                    219:        for ( I = 0; I < NP; I++ ) {
                    220:                Marray[I] = 1;
                    221:                MIarray[I] = [];
                    222:        }
                    223:
                    224:        for ( M = 1, I = 0, J = 0; p_mag(M) <= Bound; J = (J+1)%NP ) {
                    225:                T = get_next_fft_prime(I,Dfft);
                    226:                if ( !T )
                    227:                        error("fft_mul_d : fft_prime exhausted.");
                    228:                Marray[J] *= T[1];
                    229:                MIarray[J] = cons(T[0],MIarray[J]);
                    230:                M *= T[1];
                    231:                I = T[0]+1;
                    232:        }
                    233:        /* Now,
                    234:                Marray[J] = FFTprime[Marray[J][0]]*...*FFTprime[Marray[J][...]]
                    235:                M = Marray[0]*...*Marray[NP-1]
                    236:        */
                    237:        C = newvect(NP);
                    238:        T0 = time();
                    239:        for ( J = 0; J < NP-1; J++ )
                    240:                ox_cmo_rpc(Procs[J],"call_utmul",F1,F2,D,MIarray[J],Marray[J],M);
                    241:        T1 = time();
                    242:        R = call_utmul(F1,F2,D,MIarray[NP-1],Marray[NP-1],M);
                    243:        T2 = time();
                    244:        for ( J = 0; J < NP-1; J++ )
                    245:                R += ox_pop_cmo(Procs[J]);
                    246:        T3 = time();
1.2       noro      247: /*     print(["send",T1[3]-T0[3],"self",T2[3]-T1[3],"recv",T3[3]-T2[3]]); */
                    248:        if ( Mod )
                    249:                return (R%M)%Mod;
                    250:        else
                    251:                return uadj_coef(R%M,M,ishift(M,1));
                    252: }
                    253:
                    254: def d_rembymul(F1,F2,INVF2)
                    255: {
                    256:        Procs = getopt(proc);
                    257:        if ( type(Procs) == -1 )
                    258:                Procs = [];
                    259:        Mod = getopt(mod);
                    260:        if ( type(Mod) == -1 )
                    261:                Mod = 0;
                    262:        NP = length(Procs)+1;
                    263:        if ( !F2 )
                    264:                error("d_rembymul : division by 0");
                    265:        V =var(F1);
                    266:        if ( !V ) {
                    267:                T = srem(F1,F2);
                    268:                if ( Mod )
                    269:                        return T % Mod;
                    270:                else
                    271:                        return T;
                    272:        }
                    273:        D1 = deg(F1,V);
                    274:        D2 = deg(F2,V);
                    275:        if ( !F1 || !D2 )
                    276:                return 0;
                    277:        if ( D1 < D2 )
                    278:                return F1;
                    279:        D = D1-D2;
                    280:        R1 = utrunc(ureverse(F1),D);
                    281:        Q = ureverse(utrunc(d_tmul(R1,INVF2,D|proc=Procs,mod=Mod),D));
                    282:        if ( Mod )
                    283:                return (utrunc(F1,D2-1)-d_tmul(Q,F2,D2-1|proc=Procs,mod=Mod))%Mod;
                    284:        else
                    285:                return utrunc(F1,D2-1)-d_tmul(Q,F2,D2-1|proc=Procs);
1.1       noro      286: }
                    287:
                    288: def call_umul(F1,F2,Ind,M1,M)
                    289: {
                    290:        C = umul_specialmod(F1,F2,Ind);
                    291:        Mhat = idiv(M,M1);
                    292:        MhatInv = inv(Mhat,M1);
1.2       noro      293:        return Mhat*((MhatInv*C)%M1);
1.1       noro      294: }
                    295:
                    296: def call_usquare(F1,Ind,M1,M)
                    297: {
                    298:        C = usquare_specialmod(F1,Ind);
                    299:        Mhat = idiv(M,M1);
                    300:        MhatInv = inv(Mhat,M1);
1.2       noro      301:        return Mhat*((MhatInv*C)%M1);
1.1       noro      302: }
                    303:
                    304: def call_utmul(F1,F2,D,Ind,M1,M)
                    305: {
                    306:        C = utmul_specialmod(F1,F2,D,Ind);
                    307:        Mhat = idiv(M,M1);
                    308:        MhatInv = inv(Mhat,M1);
1.2       noro      309:        return Mhat*((MhatInv*C)%M1);
1.1       noro      310: }
                    311: end$

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