1 | /**************************************** |
---|
2 | * Computer Algebra System SINGULAR * |
---|
3 | ****************************************/ |
---|
4 | /*************************************************************** |
---|
5 | * File: gring.cc |
---|
6 | * Purpose: pMult family of procedures |
---|
7 | * Author: levandov (Viktor Levandovsky) |
---|
8 | * Created: 8/00 - 11/00 |
---|
9 | * Version: $Id: gring.cc,v 1.2 2000-11-20 16:02:03 levandov Exp $ |
---|
10 | *******************************************************************/ |
---|
11 | #include "mod2.h" |
---|
12 | #include "gring.h" |
---|
13 | #include "polys.h" |
---|
14 | #ifdef HAVE_PLURAL |
---|
15 | |
---|
16 | //global nc_macros : |
---|
17 | #define freeT(A) omFree((ADDRESS)A,(pVariables+1)*sizeof(Exponent_t)) |
---|
18 | #define freeN(A,k) omFree((ADDRESS)A,k*sizeof(number)) |
---|
19 | |
---|
20 | poly nc_pp_Mult_mm(poly p, const poly m, const poly spNoether, const ring ri) |
---|
21 | { |
---|
22 | p_Test(p, ri); |
---|
23 | p_LmTest(m, ri); |
---|
24 | if (p == NULL) return NULL; |
---|
25 | spolyrec rp; |
---|
26 | poly q = &rp, r; |
---|
27 | number ln = pGetCoeff(m); |
---|
28 | omBin bin = ri->PolyBin; |
---|
29 | DECLARE_LENGTH(const unsigned long length = ri->ExpL_Size); |
---|
30 | const unsigned long* m_e = m->exp; |
---|
31 | pAssume(!n_IsZero(ln,ri)); |
---|
32 | pAssume1(p_GetComp(m, ri) == 0 || p_MaxComp(p, ri) == 0); |
---|
33 | |
---|
34 | do |
---|
35 | { |
---|
36 | p_AllocBin( pNext(q), bin, ri); |
---|
37 | q = pNext(q); |
---|
38 | pSetCoeff0(q, n_Mult(ln, pGetCoeff(p), ri)); |
---|
39 | // old: p_MemSum(q->exp, p->exp, m_e, length); |
---|
40 | q = mm_Mult_mm(p->exp,m_e); // give exponents only? |
---|
41 | p_MemAddAdjust(q, ri); |
---|
42 | p = pNext(p); |
---|
43 | } |
---|
44 | while (p != NULL); |
---|
45 | |
---|
46 | pNext(q) = NULL; |
---|
47 | p_Test(pNext(&rp), ri); |
---|
48 | return pNext(&rp); |
---|
49 | } |
---|
50 | |
---|
51 | poly nc_mm_Mult_nn(Exponent_t *F, Exponent_t *G, const ring ri) |
---|
52 | |
---|
53 | /* destroys both f and g , f,g are monomials with the coefficient */ |
---|
54 | //poly pMultTT(poly f, poly g) |
---|
55 | { |
---|
56 | poly out=NULL; |
---|
57 | int nv=pVariables; |
---|
58 | int i; |
---|
59 | number cF,cG,cOut; |
---|
60 | // What can we do with coeffs? |
---|
61 | // cF=pGetCoeff(f); |
---|
62 | // cG=pGetCoeff(g); |
---|
63 | cOut=nMult(cF,cG); |
---|
64 | int iF,jG,iG; |
---|
65 | |
---|
66 | Exponent_t exp=F[0]; |
---|
67 | |
---|
68 | iF=nv; |
---|
69 | while ((F[iF]==0)&&(iF>=1)) iF--; /* last exp_num of F */ |
---|
70 | jG=1; |
---|
71 | while ((G[jG]==0)&&(jG<=nv)) jG++; /* first exp_num of G */ |
---|
72 | iG=nv; |
---|
73 | while ((G[iG]==0)&&(iG>=1)) iG--; /* last exp_num of G */ |
---|
74 | |
---|
75 | |
---|
76 | if (iF<=jG) /* i.e. no mixed exp_num */ |
---|
77 | { |
---|
78 | out=pOne(); |
---|
79 | for (i=1;i<=nv;i++) { F[i]=F[i]+G[i];} |
---|
80 | // F[0]=exp; |
---|
81 | pSetExpV(out,F); |
---|
82 | pSetCoeff(out,cOut); |
---|
83 | pSetm(out); |
---|
84 | freeT(F);freeT(G); |
---|
85 | return(out); |
---|
86 | } |
---|
87 | |
---|
88 | if (iG==jG) /* g is uni */ |
---|
89 | { |
---|
90 | // if (ri->nc->type==nc_skew) -- postpone to TU |
---|
91 | out=pMultTU(F,jG,G[jG]); |
---|
92 | out=pSetCoeffP(out,cOut); |
---|
93 | pSetCompP(out,exp); |
---|
94 | freeT(F);freeT(G); |
---|
95 | nDelete(&cOut); |
---|
96 | return(out); |
---|
97 | } |
---|
98 | number n1=nInit(1); |
---|
99 | Exponent_t *Prv=(Exponent_t *)Alloc0((pVariables+1)*sizeof(Exponent_t)); |
---|
100 | Exponent_t *Nxt=(Exponent_t *)Alloc0((pVariables+1)*sizeof(Exponent_t)); |
---|
101 | |
---|
102 | int nnv=nv+1; |
---|
103 | int *log=(int *)Alloc0((nnv)*sizeof(int)); |
---|
104 | int cnt=0; int cnf=0; |
---|
105 | |
---|
106 | /* splitting F wrt jG */ |
---|
107 | for (i=1;i<=jG;i++) |
---|
108 | { |
---|
109 | Prv[i]=F[i]; Nxt[i]=0; /* mult at the very end */ |
---|
110 | if (F[i]!=0) cnf++; |
---|
111 | } |
---|
112 | |
---|
113 | if (cnf==0) freeT(Prv); |
---|
114 | |
---|
115 | for (i=jG+1;i<=nv;i++) |
---|
116 | { |
---|
117 | Nxt[i]=F[i]; |
---|
118 | if (cnf!=0) Prv[i]=0; |
---|
119 | if (F[i]!=0) |
---|
120 | { |
---|
121 | cnt++; |
---|
122 | } /* effective part for F */ |
---|
123 | } |
---|
124 | freeT(F); |
---|
125 | cnt=0; |
---|
126 | |
---|
127 | for (i=1;i<=nv;i++) |
---|
128 | { |
---|
129 | if (G[i]!=0) |
---|
130 | { |
---|
131 | cnt++; |
---|
132 | log[cnt]=i; |
---|
133 | } /* lG for G */ |
---|
134 | } |
---|
135 | |
---|
136 | /* ---------------------- A C T I O N ------------------------ */ |
---|
137 | poly D=NULL; |
---|
138 | poly Rout=NULL; |
---|
139 | number *c=(number *)Alloc0((nv+1)*sizeof(number)); |
---|
140 | c[0]=nInit(1); |
---|
141 | |
---|
142 | Exponent_t *Op=Nxt; |
---|
143 | Exponent_t *On=G; |
---|
144 | Exponent_t *U=(Exponent_t *)Alloc0((pVariables+1)*sizeof(Exponent_t)); |
---|
145 | |
---|
146 | for (i=jG;i<=nv;i++) U[i]=Nxt[i]+G[i]; /* make leadterm */ |
---|
147 | for (i=1;i<jG;i++) U[i]=0; |
---|
148 | Nxt=NULL; G=NULL; |
---|
149 | |
---|
150 | Op[0]=exp; |
---|
151 | cnt=1; |
---|
152 | int t=0; |
---|
153 | poly w=NULL; |
---|
154 | poly Pn=pOne(); |
---|
155 | pSetExpV(Pn,On); |
---|
156 | pSetm(Pn); |
---|
157 | |
---|
158 | while (On[iG]!=0) |
---|
159 | { |
---|
160 | t=log[cnt]; |
---|
161 | |
---|
162 | w=pMultTU(Op,t,On[t]); |
---|
163 | c[cnt]=nMult(c[cnt-1],pGetCoeff(w)); |
---|
164 | D = pNext(w); /* getting coef and rest D */ |
---|
165 | pDelete1(&w); w=NULL; |
---|
166 | |
---|
167 | Op[t] += On[t]; /* update exp_vectors */ |
---|
168 | On[t] = 0; |
---|
169 | |
---|
170 | if (t!=iG) /* not the last step */ |
---|
171 | { |
---|
172 | On[0]=exp; |
---|
173 | pSetExpV(Pn,On); |
---|
174 | pSetm(Pn); |
---|
175 | Rout=pMultT(D,Pn); |
---|
176 | } |
---|
177 | else |
---|
178 | { Rout=D; D=NULL; } |
---|
179 | |
---|
180 | |
---|
181 | if (Rout!=NULL) |
---|
182 | { |
---|
183 | Rout=pSetCoeffP(Rout,c[cnt-1]); /* Rest is ready */ |
---|
184 | out=pAdd(out,Rout); |
---|
185 | Rout=NULL; |
---|
186 | } |
---|
187 | cnt++; |
---|
188 | } |
---|
189 | freeT(On);freeT(Op); |
---|
190 | pDelete(&Pn); |
---|
191 | Free((ADDRESS)log,nnv*sizeof(int)); |
---|
192 | |
---|
193 | /* leadterm and Prv-part with cOut */ |
---|
194 | |
---|
195 | Rout=pOne(); |
---|
196 | /* U is lead.monomial */ |
---|
197 | U[0]=exp; |
---|
198 | pSetExpV(Rout,U);pSetm(Rout); /* use again this name Rout */ |
---|
199 | pSetCoeff(Rout,c[cnt-1]); |
---|
200 | out=pAdd(out,Rout); |
---|
201 | Rout=NULL; |
---|
202 | freeT(U); freeN(c,nnv); |
---|
203 | if (cnf!=0) /* Prv is non-zero vector */ |
---|
204 | { |
---|
205 | Rout=pOne(); |
---|
206 | Prv[0]=exp; |
---|
207 | pSetExpV(Rout,Prv); |
---|
208 | pSetm(Rout); |
---|
209 | pSetCoeff(Rout,cOut); //here cOut from begin |
---|
210 | out=pMultT2(Rout,out); //getting finite result |
---|
211 | freeT(Prv); |
---|
212 | pDelete(&Rout); |
---|
213 | } |
---|
214 | else |
---|
215 | { |
---|
216 | out=pSetCoeffP(out,cOut); |
---|
217 | nDelete(&cOut); |
---|
218 | } |
---|
219 | |
---|
220 | pSetCompP(out, exp); |
---|
221 | return (out); |
---|
222 | } |
---|
223 | |
---|
224 | //----------pMultUU--------- |
---|
225 | poly nc_uu_Mult_ww (int i, int a, int j, int b,const ring r) |
---|
226 | { |
---|
227 | int nv=pVariables; |
---|
228 | poly out=NULL; |
---|
229 | |
---|
230 | if (i<=j) /* usual expression fg */ |
---|
231 | { |
---|
232 | out=pOne(); |
---|
233 | p_SetExp(out,j,b,r); |
---|
234 | p_SetExp(out,i,a,r); |
---|
235 | if (i==j) p_SetExp(out,j,a+b,r); |
---|
236 | p_Setm(out,r); |
---|
237 | return(out); |
---|
238 | } |
---|
239 | else /* when i>j */ |
---|
240 | { |
---|
241 | if (a==0) |
---|
242 | { |
---|
243 | if (b==0) |
---|
244 | { |
---|
245 | out=pOne(); |
---|
246 | return(out); |
---|
247 | } |
---|
248 | else |
---|
249 | { |
---|
250 | out=pOne(); |
---|
251 | p_SetExp(out,j,b,r);p_Setm(out,r); |
---|
252 | return(out); |
---|
253 | } |
---|
254 | } |
---|
255 | else |
---|
256 | { |
---|
257 | if (b==0) |
---|
258 | { |
---|
259 | out=pOne(); |
---|
260 | p_SetExp(out,i,a,r);p_Setm(out,r); |
---|
261 | return(out); |
---|
262 | } |
---|
263 | } |
---|
264 | |
---|
265 | } |
---|
266 | // is it already computed ? |
---|
267 | |
---|
268 | int vik = UPMATELEM(j,i); |
---|
269 | // FOR future nc_skew case |
---|
270 | // if ((ri->nc->type==nc_skew)||(ri->nc->MF[vik]==0)) |
---|
271 | // { |
---|
272 | // out=pOne(); |
---|
273 | // pSetExp(out,j,b); pSetExp(out,i,a); |
---|
274 | // pSetm(out); |
---|
275 | // number tmp_number=NULL; |
---|
276 | // nPower(c,a*b,&tmp_number); |
---|
277 | // pSetCoeff(out,tmp_number); |
---|
278 | // return (out); |
---|
279 | // } |
---|
280 | matrix cMT=r->MT[vik]; |
---|
281 | int cMTsize=r->MTsize[vik]; |
---|
282 | |
---|
283 | if (((a<cMTsize)&&(b<cMTsize))&&(MATELEM(cMT,a,b)!=NULL)) |
---|
284 | { |
---|
285 | out=p_Copy(MATELEM(cMT,a,b),r); |
---|
286 | return (out); |
---|
287 | } |
---|
288 | |
---|
289 | //End(Zero_Exceptions = (0,0),(0,b),(a,0),(a==b) ) |
---|
290 | //in fact, now a>=1 and b>=1; and j<i |
---|
291 | |
---|
292 | poly C=MATELEM(r->C,j,i); |
---|
293 | number c=p_GetCoeff(C,r); //coeff |
---|
294 | poly D=MATELEM(r->D,j,i); //rest |
---|
295 | |
---|
296 | int newcMTsize=0; |
---|
297 | |
---|
298 | if (D==NULL) /* (skew)-commutativity check */ |
---|
299 | { |
---|
300 | out=pOne(); |
---|
301 | p_SetExp(out,j,b,r); p_SetExp(out,i,a,r); |
---|
302 | p_Setm(out,r); |
---|
303 | number tmp_number=NULL; |
---|
304 | nPower(c,a*b,&tmp_number); |
---|
305 | p_SetCoeff(out,tmp_number,r); |
---|
306 | return(out); |
---|
307 | } |
---|
308 | |
---|
309 | if ((a==1)&&(b==1)) |
---|
310 | { |
---|
311 | out= p_Copy(MATELEM(cMT,1,1),r); /* already computed */ |
---|
312 | return(out); |
---|
313 | } |
---|
314 | D=NULL; |
---|
315 | |
---|
316 | if (a>=b) {newcMTsize=a;} else {newcMTsize=b;} |
---|
317 | if (newcMTsize>cMTsize) |
---|
318 | { |
---|
319 | newcMTsize = newcMTsize+cMTsize; |
---|
320 | matrix tmp = mpNew(newcMTsize,newcMTsize); |
---|
321 | for (int p=1;p<nv;p++) |
---|
322 | { |
---|
323 | for (int q=p;q<=nv;q++) |
---|
324 | { |
---|
325 | MATELEM(tmp,p,q) = MATELEM(r->MT[UPMATELEM(j,i)],p,q); |
---|
326 | MATELEM(r->MT[UPMATELEM(j,i)],p,q)=NULL; |
---|
327 | } |
---|
328 | } |
---|
329 | id_Delete((ideal *)&(r->MT[UPMATELEM(j,i)]),r); |
---|
330 | r->MT[UPMATELEM(j,i)] = tmp; |
---|
331 | r->MTsize[UPMATELEM(j,i)] = newcMTsize; |
---|
332 | } /* The update of multiplication matrix is finished */ |
---|
333 | |
---|
334 | cMT=r->MT[UPMATELEM(j,i)]; //cMT=current MT |
---|
335 | |
---|
336 | poly x=pOne();p_SetExp(x,j,1,r);p_Setm(x,r);//var(j); |
---|
337 | poly y=pOne();p_SetExp(y,i,1,r);pSetm(y,r);//var(i); for convenience |
---|
338 | |
---|
339 | int k,m; |
---|
340 | poly t=NULL; |
---|
341 | /* ------------ Main Cycles ----------------------------*/ |
---|
342 | |
---|
343 | for (k=2;k<=a;k++) |
---|
344 | { |
---|
345 | t=MATELEM(cMT,k,1); |
---|
346 | |
---|
347 | if (t==NULL) /* not computed yet */ |
---|
348 | { |
---|
349 | t=p_Copy(MATELEM(cMT,k-1,1),r); |
---|
350 | // t = pMultT2(y,t); |
---|
351 | t = nc_m_Mult_pp(y,t,,r); |
---|
352 | MATELEM(cMT,k,1) = t; |
---|
353 | } |
---|
354 | t=NULL; |
---|
355 | } |
---|
356 | |
---|
357 | |
---|
358 | for (m=2;m<=b;m++) |
---|
359 | { |
---|
360 | t=MATELEM(cMT,a,m); |
---|
361 | |
---|
362 | if (t==NULL) //not computed yet |
---|
363 | { |
---|
364 | t=p_Copy(MATELEM(cMT,a,m-1),r); |
---|
365 | // t = pMultT(t,x); |
---|
366 | t = nc_p_Mult_q(t,x,,r); |
---|
367 | MATELEM(cMT,a,m) = t; |
---|
368 | } |
---|
369 | t=NULL; |
---|
370 | } |
---|
371 | p_Delete(&x,r); p_Delete(&y,r); |
---|
372 | t=MATELEM(cMT,a,b); |
---|
373 | return(p_Copy(t,r)); /* as last computed element was cMT[a,b] */ |
---|
374 | } |
---|
375 | #endif |
---|