Annotation of OpenXM_contrib2/asir2000/builtin/pdiv.c, Revision 1.5
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
1.4 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.3 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.5 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/builtin/pdiv.c,v 1.4 2000/08/22 05:03:59 noro Exp $
1.3 noro 49: */
1.1 noro 50: #include "ca.h"
51: #include "parse.h"
52:
53: void Psdiv(), Psrem(), Ptdiv(), Psqr(), Pinva_mod();
54: void Psdiv_gf2n(), Psrem_gf2n();
55: void Psdivm(), Psremm(), Psqrm();
56: void Psrem_mod();
57: void Pugcd();
58: void Purem();
59: void Pudiv();
60:
61: struct ftab pdiv_tab[] = {
62: {"sdiv",Psdiv,-3},
63: {"srem",Psrem,-3},
64: {"sdiv_gf2n",Psdiv_gf2n,2},
65: {"srem_gf2n",Psrem_gf2n,2},
66: {"sqr",Psqr,-3},
1.5 ! noro 67: {"tdiv",Ptdiv,-3},
1.1 noro 68: {"udiv",Pudiv,2},
69: {"sdivm",Psdivm,-4},
70: {"sremm",Psremm,-4},
71: {"sqrm",Psqrm,-4},
72: {"inva_mod",Pinva_mod,3},
73: {"srem_mod",Psrem_mod,3},
74: {"ugcd",Pugcd,2},
75: {"urem",Purem,2},
76: {0,0,0},
77: };
78:
79: void Psdiv(arg,rp)
80: NODE arg;
81: Obj *rp;
82: {
83: P q,r,dnd,dnd1,dvr,dvr1;
84: V v;
85: VL vl;
86:
87: asir_assert(ARG0(arg),O_P,"sdiv");
88: asir_assert(ARG1(arg),O_P,"sdiv");
89: dnd = (P)ARG0(arg); dvr = (P)ARG1(arg);
90: if ( argc(arg) == 3 ) {
91: v = VR((P)ARG2(arg));
92: change_mvar(CO,dnd,v,&dnd1); change_mvar(CO,dvr,v,&dvr1);
93: reordvar(CO,v,&vl);
94: divsrp(vl,dnd1,dvr1,&q,&r);
95: restore_mvar(CO,q,v,(P *)rp);
96: } else
97: divsrp(CO,dnd,dvr,(P *)rp,&r);
98: }
99:
100: void Psrem(arg,rp)
101: NODE arg;
102: Obj *rp;
103: {
104: P q,r,dnd,dnd1,dvr,dvr1;
105: V v;
106: VL vl;
107:
108: asir_assert(ARG0(arg),O_P,"srem");
109: asir_assert(ARG1(arg),O_P,"srem");
110: dnd = (P)ARG0(arg); dvr = (P)ARG1(arg);
111: if ( argc(arg) == 3 ) {
112: v = VR((P)ARG2(arg));
113: change_mvar(CO,dnd,v,&dnd1); change_mvar(CO,dvr,v,&dvr1);
114: reordvar(CO,v,&vl);
115: divsrp(vl,dnd1,dvr1,&q,&r);
116: restore_mvar(CO,r,v,(P *)rp);
117: } else
118: divsrp(CO,dnd,dvr,&q,(P *)rp);
119: }
120:
121: void Psqr(arg,rp)
122: NODE arg;
123: LIST *rp;
124: {
125: P q,q1,r,r1,dnd,dnd1,dvr,dvr1;
126: NODE n,tn;
127: V v;
128: VL vl;
129:
130: asir_assert(ARG0(arg),O_P,"sqr");
131: asir_assert(ARG1(arg),O_P,"sqr");
132: dnd = (P)ARG0(arg); dvr = (P)ARG1(arg);
133: if ( argc(arg) == 3 ) {
134: v = VR((P)ARG2(arg));
135: change_mvar(CO,dnd,v,&dnd1); change_mvar(CO,dvr,v,&dvr1);
136: reordvar(CO,v,&vl);
137: divsrp(vl,dnd1,dvr1,&q1,&r1);
138: restore_mvar(CO,q1,v,&q); restore_mvar(CO,r1,v,&r);
139: } else
140: divsrp(CO,dnd,dvr,&q,&r);
141: MKNODE(tn,r,0); MKNODE(n,q,tn); MKLIST(*rp,n);
142: }
143:
144: void Psdiv_gf2n(arg,rp)
145: NODE arg;
146: GF2N *rp;
147: {
148: GF2N dnd,dvr;
149: UP2 q,r;
150:
151: dnd = (GF2N)ARG0(arg); dvr = (GF2N)ARG1(arg);
152: if ( !dvr )
153: error("sdiv_gf2n : division by 0");
154: else if ( !dnd )
155: *rp = 0;
156: else {
157: qrup2(dnd->body,dvr->body,&q,&r);
158: MKGF2N(q,*rp);
159: }
160: }
161:
162: void Psrem_gf2n(arg,rp)
163: NODE arg;
164: GF2N *rp;
165: {
166: GF2N dnd,dvr;
167: UP2 q,r;
168:
169: dnd = (GF2N)ARG0(arg); dvr = (GF2N)ARG1(arg);
170: if ( !dvr )
171: error("srem_gf2n : division by 0");
172: else if ( !dnd )
173: *rp = 0;
174: else {
175: qrup2(dnd->body,dvr->body,&q,&r);
176: MKGF2N(r,*rp);
177: }
178: }
179:
180: void Ptdiv(arg,rp)
181: NODE arg;
182: P *rp;
183: {
184: P p1,p2,q1,q2,q,c1,c2,c;
1.5 ! noro 185: int m;
1.1 noro 186:
187: p1 = (P)ARG0(arg); p2 = (P)ARG1(arg);
188: asir_assert(p1,O_P,"tdiv");
189: asir_assert(p2,O_P,"tdiv");
190: if ( !p1 || !p2 )
191: *rp = 0;
192: else if ( (OID(p1) > O_P) || (OID(p2) > O_P ) )
193: *rp = 0;
1.5 ! noro 194: else if ( argc(arg) == 3 ) {
! 195: m = QTOS((Q)ARG2(arg));
! 196: ptomp(m,p1,&q1); ptomp(m,p2,&q2);
! 197: if ( divtmp(CO,m,q1,q2,&q) )
! 198: mptop(q,rp);
! 199: else
! 200: *rp = 0;
! 201: } else {
1.1 noro 202: ptozp(p1,1,(Q *)&c1,&q1); ptozp(p2,1,(Q *)&c2,&q2);
203: if ( divtpz(CO,q1,q2,&q) ) {
204: divq((Q)c1,(Q)c2,(Q *)&c); mulp(CO,q,c,rp);
205: } else
206: *rp = 0;
207: }
208: }
209:
210: void Pudiv(arg,rp)
211: NODE arg;
212: LIST *rp;
213: {
214: P q,r,dnd,dvr;
215: NODE n,tn;
216:
217: asir_assert(ARG0(arg),O_P,"udiv");
218: asir_assert(ARG1(arg),O_P,"udiv");
219: dnd = (P)ARG0(arg); dvr = (P)ARG1(arg);
220: udivpz(dnd,dvr,&q,&r);
221: MKNODE(tn,r,0); MKNODE(n,q,tn); MKLIST(*rp,n);
222: }
223:
224: void Psdivm(arg,rp)
225: NODE arg;
226: Obj *rp;
227: {
228: P q,r,dnd,dnd1,dndm,dvr,dvr1,dvrm,t;
229: V v;
230: VL vl;
231: int m;
232:
233: asir_assert(ARG0(arg),O_P,"sdivm");
234: asir_assert(ARG1(arg),O_P,"sdivm");
235: asir_assert(ARG2(arg),O_N,"sdivm");
236: dnd = (P)ARG0(arg); dvr = (P)ARG1(arg); m = QTOS((Q)ARG2(arg));
237: if ( argc(arg) == 4 ) {
238: v = VR((P)ARG3(arg));
239: change_mvar(CO,dnd,v,&dnd1); change_mvar(CO,dvr,v,&dvr1);
240: reordvar(CO,v,&vl);
241: ptomp(m,dnd1,&dndm); ptomp(m,dvr1,&dvrm);
242: divsrmp(vl,m,dndm,dvrm,&t,&r); mptop(t,&q);
243: restore_mvar(CO,q,v,(P *)rp);
244: } else {
245: ptomp(m,dnd,&dndm); ptomp(m,dvr,&dvrm);
246: divsrmp(CO,m,dndm,dvrm,&t,&r); mptop(t,(P *)rp);
247: }
248: }
249:
250: void Psremm(arg,rp)
251: NODE arg;
252: Obj *rp;
253: {
254: P q,r,dnd,dnd1,dndm,dvr,dvr1,dvrm,t;
255: V v;
256: VL vl;
257: int m;
258:
259: asir_assert(ARG0(arg),O_P,"sremm");
260: asir_assert(ARG1(arg),O_P,"sremm");
261: asir_assert(ARG2(arg),O_N,"sremm");
262: dnd = (P)ARG0(arg); dvr = (P)ARG1(arg); m = QTOS((Q)ARG2(arg));
263: if ( argc(arg) == 4 ) {
264: v = VR((P)ARG3(arg));
265: change_mvar(CO,dnd,v,&dnd1); change_mvar(CO,dvr,v,&dvr1);
266: reordvar(CO,v,&vl);
267: ptomp(m,dnd1,&dndm); ptomp(m,dvr1,&dvrm);
268: divsrmp(vl,m,dndm,dvrm,&q,&t); mptop(t,&r);
269: restore_mvar(CO,r,v,(P *)rp);
270: } else {
271: ptomp(m,dnd,&dndm); ptomp(m,dvr,&dvrm);
272: divsrmp(CO,m,dndm,dvrm,&q,&t); mptop(t,(P *)rp);
273: }
274: }
275:
276: void Psqrm(arg,rp)
277: NODE arg;
278: LIST *rp;
279: {
280: P q,q1,r,r1,dnd,dnd1,dndm,dvr,dvr1,dvrm;
281: NODE n,tn;
282: V v;
283: VL vl;
284: int m;
285:
286: asir_assert(ARG0(arg),O_P,"sqrm");
287: asir_assert(ARG1(arg),O_P,"sqrm");
288: asir_assert(ARG2(arg),O_N,"sqrm");
289: dnd = (P)ARG0(arg); dvr = (P)ARG1(arg); m = QTOS((Q)ARG2(arg));
290: if ( argc(arg) == 4 ) {
291: v = VR((P)ARG3(arg));
292: change_mvar(CO,dnd,v,&dnd1); change_mvar(CO,dvr,v,&dvr1);
293: reordvar(CO,v,&vl);
294: ptomp(m,dnd1,&dndm); ptomp(m,dvr1,&dvrm);
1.2 noro 295: divsrmp(vl,m,dndm,dvrm,&q,&r); mptop(q,&q1); mptop(r,&r1);
1.1 noro 296: restore_mvar(CO,q1,v,&q); restore_mvar(CO,r1,v,&r);
297: } else {
298: ptomp(m,dnd,&dndm); ptomp(m,dvr,&dvrm);
1.2 noro 299: divsrmp(CO,m,dndm,dvrm,&q1,&r1); mptop(q1,&q); mptop(r1,&r);
1.1 noro 300: }
301: MKNODE(tn,r,0); MKNODE(n,q,tn); MKLIST(*rp,n);
302: }
303:
304: void Pinva_mod(arg,rp)
305: NODE arg;
306: P *rp;
307: {
308: P dp,f;
309: Q q;
310: int n,i;
311: int mod;
312: V v;
313: UM wf,wdp,winv;
314:
315: asir_assert(ARG0(arg),O_P,"gcda_mod");
316: asir_assert(ARG1(arg),O_N,"gcda_mod");
317: asir_assert(ARG2(arg),O_P,"gcda_mod");
318: dp = (P)ARG0(arg);
319: mod = QTOS((Q)ARG1(arg));
320: f = (P)ARG2(arg);
321: if ( NUM(f) ) {
322: i = invm(rem(NM((Q)f),mod),mod);
323: STOQ(i,q); *rp = (P)q;
324: } else {
325: v = VR(dp);
326: n = MAX(UDEG(dp),UDEG(f));
327: wf = W_UMALLOC(n); wdp = W_UMALLOC(n);
328: winv = W_UMALLOC(n);
329: ptoum(mod,f,wf); ptoum(mod,dp,wdp);
330: invum(mod,wdp,wf,winv);
331: if ( DEG(winv) < 0 )
332: *rp = 0;
333: else {
334: umtop(v,winv,rp);
335: }
336: }
337: }
338:
339: void Psrem_mod(arg,rp)
340: NODE arg;
341: P *rp;
342: {
343: P p1,p2;
344: int n,dr;
345: int mod;
346: V v;
347: UM wp1,wp2,q;
348:
349: asir_assert(ARG0(arg),O_P,"srem_mod");
350: asir_assert(ARG1(arg),O_P,"srem_mod");
351: asir_assert(ARG2(arg),O_N,"srem_mod");
352: p1 = (P)ARG0(arg); p2 = (P)ARG1(arg); mod = QTOS((Q)ARG2(arg));
353: if ( !p1 || NUM(p1) )
354: *rp = p1;
355: else {
356: v = VR(p1);
357: n = MAX(UDEG(p1),UDEG(p2));
358: wp1 = W_UMALLOC(n); wp2 = W_UMALLOC(n); q = W_UMALLOC(n);
359: ptoum(mod,p1,wp1); ptoum(mod,p2,wp2);
360: dr = divum(mod,wp1,wp2,q);
361: if ( ( DEG(wp1) = dr ) == -1 )
362: *rp = 0;
363: else
364: umtop(v,wp1,rp);
365: }
366: }
367:
368: void Purem(arg,rp)
369: NODE arg;
370: P *rp;
371: {
372: asir_assert(ARG0(arg),O_P,"urem");
373: asir_assert(ARG1(arg),O_P,"urem");
374: uremp((P)ARG0(arg),(P)ARG1(arg),rp);
375: }
376:
377: void Pugcd(arg,rp)
378: NODE arg;
379: P *rp;
380: {
381: asir_assert(ARG0(arg),O_P,"ugcd");
382: asir_assert(ARG1(arg),O_P,"ugcd");
383: ugcdp((P)ARG0(arg),(P)ARG1(arg),rp);
384: }
385:
386: void invum(mod,dp,f,inv)
387: int mod;
388: UM dp,f,inv;
389: {
390: UM g1,g2,a1,a2,a3,wm,q,tum;
391: int d,dr;
392:
393: d = DEG(dp)+DEG(f)+10;
394: g1 = W_UMALLOC(d); g2 = W_UMALLOC(d); a1 = W_UMALLOC(d);
395: a2 = W_UMALLOC(d); a3 = W_UMALLOC(d); wm = W_UMALLOC(d);
396: q = W_UMALLOC(d);
397: DEG(a1) = 0; COEF(a1)[0] = 1; DEG(a2) = -1;
398: cpyum(f,g1); cpyum(dp,g2);
399: while ( 1 ) {
400: dr = divum(mod,g1,g2,q); tum = g1; g1 = g2; g2 = tum;
401: if ( ( DEG(g2) = dr ) == -1 )
402: break;
403: mulum(mod,a2,q,wm); subum(mod,a1,wm,a3); dr = divum(mod,a3,dp,q);
404: tum = a1; a1 = a2; a2 = a3; a3 = tum; DEG(a3) = dr;
405: }
406: if ( DEG(g1) != 0 )
407: DEG(inv) = -1;
408: else if ( COEF(g1)[0] != 1 )
409: mulsum(mod,a2,invm(COEF(g1)[0],mod),inv);
410: else
411: cpyum(a2,inv);
412: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>