source: git/Singular/gring.cc @ bf27e44

fieker-DuValspielwiese
Last change on this file since bf27e44 was 2aadaa, checked in by Viktor Levandovskyy <levandov@…>, 23 years ago
Plural adoptions git-svn-id: file:///usr/local/Singular/svn/trunk@5268 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 15.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    gring.cc
6 *  Purpose: p_Mult family of procedures
7 *  Author:  levandov (Viktor Levandovsky)
8 *  Created: 8/00 - 11/00
9 *  Version: $Id: gring.cc,v 1.5 2001-02-23 15:41:10 levandov Exp $
10 *******************************************************************/
11#include "mod2.h"
12#include "gring.h"
13#ifdef HAVE_PLURAL
14
15//global nc_macros :
16#define freeT(A,v) omFreeSize((ADDRESS)A,(v+1)*sizeof(Exponent_t))
17#define freeN(A,k) omFreeSize((ADDRESS)A,k*sizeof(number))
18
19// poly functions defined in p_Procs :
20poly nc_pp_Mult_mm(poly p, const poly m, const ring r, poly &last)
21{
22  return(nc_p_Mult_mm(p_Copy(p,r),m,r));
23}
24
25// poly nc_p_Mult_mm(poly p, poly m, const ring r); defined below
26poly nc_p_Minus_mm_Mult_qq(poly p, const poly m, poly q, const ring r)
27{
28  number minus1=n_Init(-1,r);
29  poly mc=p_Mult_nn(p_Copy(m,r),minus1,r);
30  poly mmc=nc_mm_Mult_p(mc,p_Copy(q,r),r);
31  p_Delete(&mc,r);
32  p=p_Add_q(p,mmc,r);
33  n_Delete(&minus1,r);
34  return(p);
35}
36
37//----------- auxiliary routines--------------------------
38poly _nc_p_Mult_q(poly p, poly q, const int copy, const ring r)
39  /* destroy p,q */
40{
41  poly res=0;
42  while (q!=NULL)
43    {
44      res=res+nc_pp_Mult_mm(p,p_Head(q,r),r);
45      p_LmDeleteAndNext(q,r);
46    }
47  p_Delete(&p,r);
48  return(res);
49}
50
51poly  nc_p_Mult_mm(poly p, const poly m, const ring r)
52/* p is poly, m is mono with coeff, p killed after */
53// former pMultT
54{
55  if ((p==NULL) || (m==NULL)) return(NULL);
56//  if (pNext(p)==NULL) return(nc_mm_Mult_nn(p,pCopy(m),r));
57// excluded  - the cycle will do it anyway - OK.
58
59#ifdef PDEBUG
60  p_Test(p,r);
61  p_Test(m,r);
62#endif
63  poly v=NULL;
64  poly out=NULL;
65  Exponent_t *P=(Exponent_t *)omAlloc0((r->N+1)*sizeof(Exponent_t));
66  Exponent_t *M=(Exponent_t *)omAlloc0((r->N+1)*sizeof(Exponent_t));
67// coefficients:
68  number cP,cM,cOut;
69  p_GetExpV(m,M,r);
70  cM=p_GetCoeff(m,r);
71// components:
72  const Exponent_t expM=p_GetComp(m,r);
73  Exponent_t expP=0;
74  Exponent_t expOut=0;
75 
76  while (p!=NULL)
77  {
78    v=p_Head(p,r);
79    p_Test(v,r);
80    p_Test(p,r);
81   
82    expP=p_GetComp(v,r);
83    if (expP==0)
84    {
85      if (expM==0)
86      {
87        expOut=0;
88      }
89      else
90      {
91        expOut=expM;
92      }     
93    }
94    else
95    {
96      if (expM==0)
97      {
98        expOut=expP;
99      }
100      else
101      {
102        // REPORT_ERROR AND BREAK
103        Print("exponent mismatch");
104        expOut=NULL;
105      }
106    }
107   
108    p_GetExpV(v,P,r);
109    cP=p_GetCoeff(v,r);
110    v= nc_mm_Mult_nn(P,M,r);
111//  P=NULL;
112// or     freeT(P,r->N); ?
113    cOut=n_Mult(cP,n_Copy(cM,r),r);
114    v=p_Mult_nn(v,cOut,r);
115    p_SetCompP(v,expOut,r);
116    out = p_Add_q(out,v,r);
117    //    p_DeleteLm(&p,r);
118    p_LmDeleteAndNext(p,r);
119  }
120  freeT(P,r->N);
121//  freeT(M,r->N);
122  return(out);
123}
124
125poly nc_mm_Mult_p(const poly m, poly p, const ring r)
126/* p is poly, m is mono with coeff, p killed after */
127/* former pMultT2 */
128{
129  if ((p==NULL) || (m==NULL)) return(NULL);
130//  if (pNext(p)==NULL) return(nc_mm_Mult_nn(p,pCopy(m),r));
131// excluded  - the cycle will do it anyway - OK.
132
133#ifdef PDEBUG
134  p_Test(p,r);
135  p_Test(m,r);
136#endif
137  poly v=NULL;
138  poly out=NULL;
139  Exponent_t *P=(Exponent_t *)omAlloc0((r->N+1)*sizeof(Exponent_t));
140  Exponent_t *M=(Exponent_t *)omAlloc0((r->N+1)*sizeof(Exponent_t));
141// coefficients:
142  number cP,cM,cOut;
143  p_GetExpV(m,M,r);
144  cM=p_GetCoeff(m,r);
145// components:
146  const Exponent_t expM=p_GetComp(m,r);
147  Exponent_t expP=0;
148  Exponent_t expOut=0;
149 
150  while (p!=NULL)
151  {
152    v=p_Head(p,r);
153    p_Test(v,r);
154    p_Test(p,r);
155   
156    expP=p_GetComp(v,r);
157    if (expP==0)
158    {
159      if (expM==0)
160      {
161        expOut=0;
162      }
163      else
164      {
165        expOut=expM;
166      }     
167    }
168    else
169    {
170      if (expM==0)
171      {
172        expOut=expP;
173      }
174      else
175      {
176        // REPORT_ERROR AND BREAK
177        expOut=NULL;
178      }
179    }
180   
181    p_GetExpV(v,P,r);
182    cP=p_GetCoeff(v,r);
183    v= nc_mm_Mult_nn(M,P,r);
184//    P=NULL;
185//  freeT(P,r->N);
186    cOut=n_Mult(cP,n_Copy(cM,r),r);
187    v=p_Mult_nn(v,cOut,r);
188    p_SetCompP(v,expOut,r);
189    out = p_Add_q(out,v,r);
190    p_DeleteLm(&p,r);
191  }
192  freeT(P,r->N);
193//  freeT(M,r->N);
194  return(out);
195}
196
197poly nc_mm_Mult_nn(Exponent_t *F0, Exponent_t *G0, const ring r)
198/* destroys nothing, no coeffs and exps */
199/* very modified former  poly pMultTT(poly f, poly g) */
200{
201  poly out=NULL;
202  int i;
203  int iF,jG,iG;
204  int ExpSize=(r->N+1)*sizeof(Exponent_t);
205
206  Exponent_t *F=(Exponent_t *)omAlloc0(ExpSize);
207  Exponent_t *G=(Exponent_t *)omAlloc0(ExpSize);
208
209  for(i=1;i<=r->N;i++)
210  {
211    F[i]=F0[i];
212    G[i]=G0[i];
213  }
214  F[0]=0;
215  G[0]=0;
216 
217  iF=r->N;
218  while ((F[iF]==0)&&(iF>=1)) iF--; /* last exp_num of F */
219  jG=1;
220  while ((G[jG]==0)&&(jG<=r->N)) jG++;  /* first exp_num of G */
221  iG=r->N;
222  while ((G[iG]==0)&&(iG>=1)) iG--;  /* last exp_num of G */
223
224  if (iF<=jG)
225// i.e. no mixed exp_num , MERGE case
226  {
227    out=pOne();
228    for (i=1;i<=r->N;i++)
229    {
230      F[i]=F[i]+G[i];
231    } 
232    p_SetExpV(out,F,r);
233    p_Setm(out,r);
234    freeT(F,r->N);
235    freeT(G,r->N);
236    return(out);
237  }
238
239  if (iG==jG)
240// g is univariate monomial
241  {
242//    if (ri->nc->type==nc_skew) -- postpone to TU   
243    out=nc_mm_Mult_uu(F,jG,G[jG],r);
244    freeT(F,r->N);
245    freeT(G,r->N);
246    return(out);
247  }
248 
249  number n1=n_Init(1,r);
250  Exponent_t *Prv=(Exponent_t *)omAlloc0(ExpSize);
251  Exponent_t *Nxt=(Exponent_t *)omAlloc0(ExpSize);
252
253  int *log=(int *)omAlloc0((r->N+1)*sizeof(int));
254  int cnt=0; int cnf=0;
255
256  /* splitting F wrt jG */
257  for (i=1;i<=jG;i++)
258  {
259    Prv[i]=F[i]; Nxt[i]=0; /* mult at the very end */
260    if (F[i]!=0) cnf++;
261  }
262
263  if (cnf==0) freeT(Prv,r->N);
264
265  for (i=jG+1;i<=r->N;i++)
266  {
267    Nxt[i]=F[i];
268//    if (cnf!=0)  Prv[i]=0;
269    if (F[i]!=0)
270    {
271      cnt++;
272    }              /* effective part for F */
273  }
274  freeT(F,r->N);
275  cnt=0;
276
277  for (i=1;i<=r->N;i++)
278  {
279    if (G[i]!=0)
280    {
281     cnt++;
282     log[cnt]=i;
283     }               /* lG for G */
284   }
285
286/* ---------------------- A C T I O N ------------------------ */
287  poly D=NULL;
288  poly Rout=NULL;
289  number *c=(number *)omAlloc0((r->N+1)*sizeof(number));
290  c[0]=n_Init(1,r);
291
292  Exponent_t *Op=Nxt;
293  Exponent_t *On=G;
294  Exponent_t *U=(Exponent_t *)omAlloc0(ExpSize);
295
296  for (i=jG;i<=r->N;i++) U[i]=Nxt[i]+G[i];  /* make leadterm */
297//  for (i=1;i<jG;i++) U[i]=0;
298  Nxt=NULL;
299  G=NULL;
300  cnt=1;
301  int t=0;
302  poly w=NULL;
303  poly Pn=pOne();
304  p_SetExpV(Pn,On,r);
305  p_Setm(Pn,r);
306
307  while (On[iG]!=0)
308  {
309     t=log[cnt];
310
311     w=nc_mm_Mult_uu(Op,t,On[t],r);
312     c[cnt]=n_Mult(c[cnt-1],p_GetCoeff(w,r),r);
313     D = pNext(w);  /* getting coef and rest D */
314     p_DeleteLm(&w,r);
315     w=NULL;
316
317     Op[t] += On[t];   /* update exp_vectors */
318     On[t] = 0;
319
320     if (t!=iG)    /* not the last step */
321     {
322       p_SetExpV(Pn,On,r);
323       p_Setm(Pn,r);
324       p_Test(Pn,r);
325       
326//       if (pNext(D)==0)
327// is D a monomial? could be postponed higher
328//       {
329//       Rout=nc_mm_Mult_nn(D,Pn,r);
330//       }
331//       else
332//       {
333       Rout=nc_p_Mult_mm(D,Pn,r); 
334//       }
335     }
336     else
337     {
338       Rout=D;
339       D=NULL;
340     }
341     
342     if (Rout!=NULL)
343     {
344       Rout=p_Mult_nn(Rout,c[cnt-1],r); /* Rest is ready */
345       out=p_Add_q(out,Rout,r);
346       Rout=NULL;
347     }
348     cnt++;
349  }
350  freeT(On,r->N);
351  freeT(Op,r->N);
352  p_Delete(&Pn,r);
353  omFreeSize((ADDRESS)log,(r->N+1)*sizeof(int));
354
355/* leadterm and Prv-part */
356
357  Rout=pOne();
358  /* U is lead.monomial */
359  U[0]=0;
360  p_SetExpV(Rout,U,r);
361  p_Setm(Rout,r);  /* use again this name Rout */
362  p_Test(Rout,r);
363  p_SetCoeff(Rout,c[cnt-1],r);
364  out=p_Add_q(out,Rout,r);
365//  Rout=NULL;
366  freeT(U,r->N);
367  freeN(c,r->N+1);
368  if (cnf!=0)  /* Prv is non-zero vector */
369  {
370    Rout=pOne();
371    Prv[0]=0;
372    p_SetExpV(Rout,Prv,r);
373    p_Setm(Rout,r);
374    p_Test(Rout,r);
375    out=nc_mm_Mult_p(Rout,out,r); //getting finite result
376    freeT(Prv,r->N);
377    p_Delete(&Rout,r);
378  }
379  return (out);
380}
381
382
383poly nc_mm_Mult_uu(Exponent_t *F,int jG,int bG, const ring r)
384/* f=mono(F),g=(x_iG)^bG */
385{
386  poly out=NULL;
387  int i;
388  number num=NULL;
389 
390  int iF=r->N;
391  while ((F[iF]==0)&&(iF>0)) iF-- ;   /* last exponent_num of F */
392
393  if (iF==0)  /* F==zero vector in other words */
394  {
395   out=pOne();
396   p_SetExp(out,jG,bG,r);
397   p_Setm(out,r);
398   return(out);
399  }
400
401  int jF=1;
402  while ((F[jF]==0)&&(jF<=r->N)) jF++;  /* first exp of F */
403
404  if (iF<=jG)                       /* i.e. no mixed exp_num */
405  {
406    out=pOne();
407    F[jG]=F[jG]+bG;
408    p_SetExpV(out,F,r);
409    p_Setm(out,r);
410//  num=NULL;
411    return(out);
412  }
413
414  if (iF==jF)              /* uni times uni */
415  {
416   out=nc_uu_Mult_ww(iF,F[iF],jG,bG,r);
417//   num=NULL;
418   return(out);
419  }
420 
421  Exponent_t *Prv=(Exponent_t*)omAlloc0((r->N+1)*sizeof(Exponent_t));
422  Exponent_t *Nxt=(Exponent_t*)omAlloc0((r->N+1)*sizeof(Exponent_t));
423  int *lF=(int *)omAlloc0((r->N+1)*sizeof(int));
424  int cnt=0; int cnf=0;
425  /* splitting F wrt jG */
426  for (i=1;i<=jG;i++) /* mult at the very end */
427  {
428    Prv[i]=F[i]; Nxt[i]=0;
429    if (F[i]!=0) cnf++;
430  }
431  if (cnf==0)  freeT(Prv,r->N);
432  for (i=jG+1;i<=r->N;i++)
433  {
434    Nxt[i]=F[i];
435    if (cnf!=0) { Prv[i]=0;}
436    if (F[i]!=0)
437    {
438     cnt++;
439     lF[cnt]=i;
440     }                 /* eff_part,lF_for_F */
441  }
442
443  if (cnt==1) /* Nxt consists of 1 nonzero el-t only */
444  {
445    int q=lF[1];
446    poly Rout=pOne();
447    out=nc_uu_Mult_ww(q,Nxt[q],jG,bG,r);
448    freeT(Nxt,r->N);
449
450    if (cnf!=0)
451    {
452       Prv[0]=0;
453       p_SetExpV(Rout,Prv,r);
454       p_Setm(Rout,r);
455       p_Test(Rout,r);
456       freeT(Prv,r->N);
457       out=nc_mm_Mult_p(Rout,out,r); /* getting finite result */
458//pMultT2
459    }
460
461    omFreeSize((ADDRESS)lF,(r->N+1)*sizeof(int));
462    p_Delete(&Rout,r);
463    return (out);
464  }
465/* -------------------- MAIN ACTION --------------------- */
466
467  poly D=NULL;
468  poly Rout=NULL;
469  number *c=(number *)omAlloc0((cnt+2)*sizeof(number));
470  c[cnt+1]=n_Init(1,r);
471  i=cnt+2;      /* later in freeN */
472  Exponent_t *Op=Nxt;
473  Exponent_t *On=(Exponent_t *)omAlloc0((r->N+1)*sizeof(Exponent_t));
474  Exponent_t *U=(Exponent_t *)omAlloc0((r->N+1)*sizeof(Exponent_t));
475
476  for (int ii=1;ii<=r->N;ii++)
477  {
478    U[ii]=Nxt[ii];
479  }
480  U[jG] = U[jG] + bG;
481
482  /* Op=Nxt and initial On=(0); */
483  Nxt=NULL;
484
485  poly Pp;
486  poly Pn;
487  int t=0;
488  int first=lF[1];
489  int nlast=lF[cnt];
490  int kk=0;
491//  cnt--;   /* now lF[cnt] should be <=iF-1 */
492
493  while (Op[first]!=0)
494  {
495     t=lF[cnt];   /* cnt as it was computed */
496
497     poly w=nc_uu_Mult_ww(t,Op[t],jG,bG,r);
498     c[cnt]=n_Copy(p_GetCoeff(w,r),r);
499     D = pNext(w);  /* getting coef and rest D */
500     p_DeleteLm(&w,r);
501     w=NULL;
502
503     Op[t]= 0;
504     Pp=pOne();
505     p_SetExpV(Pp,Op,r);
506     p_Setm(Pp,r);
507
508     if (t<nlast)
509     {
510       kk=lF[cnt+1];
511       On[kk]=F[kk];
512       
513       Pn=pOne();
514       p_SetExpV(Pn,On,r);
515       p_Setm(Pn,r);
516
517       if (t!=first)   /* typical expr */
518       {
519         w=nc_p_Mult_mm(D,Pn,r);
520         Rout=nc_mm_Mult_p(Pp,w,r);
521         w=NULL;
522       }
523       else                   /* last step */
524       {
525         On[t]=0;
526         p_SetExpV(Pn,On,r);
527         p_Setm(Pn,r);
528         Rout=nc_p_Mult_mm(D,Pn,r);
529       }
530       p_Test(Pp,r);
531       p_Delete(&Pn,r);
532     }
533     else                     /* first step */
534     {
535       Rout=nc_mm_Mult_p(Pp,D,r);
536     }
537
538     p_Test(Pp,r);
539     p_Delete(&Pp,r);
540     num=n_Mult(c[cnt+1],c[cnt],r);
541     n_Delete(&c[cnt],r);
542     c[cnt]=num;
543     Rout=p_Mult_nn(Rout,c[cnt+1],r); /* Rest is ready */
544     out=p_Add_q(out,Rout,r);
545//     Rout=NULL;
546     Pp=NULL;
547     cnt--;
548  }
549// only to be safe:
550  Pn=Pp=NULL;
551  freeT(On,r->N);
552  freeT(Op,r->N);
553
554/* leadterm and Prv-part with coef 1 */
555//  U[0]=exp;
556 
557//  U[jG]=U[jG]+bG;  /* make leadterm */
558// ??????????? we have done it already :-0
559  Rout=pOne();
560  p_SetExpV(Rout,U,r);
561  p_Setm(Rout,r);  /* use again this name */
562  p_SetCoeff(Rout,c[cnt+1],r);  /* last computed coef */
563  out=p_Add_q(out,Rout,r);
564  Rout=NULL;
565  freeT(U,r->N);
566  freeN(c,i);
567  omFreeSize((ADDRESS)lF,(r->N+1)*sizeof(int));
568
569  if (cnf!=0)
570  {
571    Rout=pOne();
572    p_SetExpV(Rout,Prv,r);
573    p_Setm(Rout,r);
574    freeT(Prv,r->N);
575    out=nc_mm_Mult_p(Rout,out,r); /* getting finite result */
576    p_Delete(&Rout,r);
577  }
578  return (out);
579}
580
581//----------pMultUU---------
582poly nc_uu_Mult_ww (int i, int a, int j, int b, const ring r)
583{
584  poly out=NULL;
585  number tmp_number=NULL;
586 
587// first check wether the polynom is alredy computed
588  int vik = UPMATELEM(j,i,r->N);
589  matrix cMT=r->nc->MT[vik];
590  int cMTsize=r->nc->MTsize[vik];
591
592  if (((a<cMTsize)&&(b<cMTsize))&&(MATELEM(cMT,a,b)!=NULL))
593  {
594     out=p_Copy(MATELEM(cMT,a,b),r);
595     return (out);
596  }
597
598//Now check zero exeptions, commutativity and should we do something at all? 
599      out=pOne();
600      p_SetExp(out,j,b,r);
601      p_SetExp(out,i,a,r);
602      if (i==j) p_SetExp(out,j,a+b,r);
603      p_Setm(out,r);
604      if ((a==0)||(b==0)||(i<=j)) return(out);//zero exeptions and usual case
605     
606      if (r->nc->COM[UPMATELEM(i,j,r->N)]!=NULL) //commutative or quasicommutative case
607      {
608        if (r->nc->COM[UPMATELEM(i,j,r->N)]!=n_Init(1,r)) //commutative case
609        {
610          return(out);
611        }     
612        else
613        {
614          tmp_number=p_GetCoeff(r->nc->COM[UPMATELEM(i,j,r->N)],r); //quasicommutative case
615          nPower(tmp_number,a*b,&tmp_number);
616          p_SetCoeff(out,tmp_number,r);
617          return(out);
618        }
619      }// end commutative or quasicommutative case
620
621//we are here if  i>j and variables do not commute or quasicommute
622//in fact, now a>=1 and b>=1; and j<i
623
624//  poly C=MATELEM(r->nc->C,j,i);               
625//  number c=p_GetCoeff(C,r); //coeff           
626//  p_Delete(&C,r);
627     
628  int newcMTsize=0;
629 
630  p_Delete(&out,r);//Shura thinks it is nesessary
631 
632  if (a>=b) {newcMTsize=a;} else {newcMTsize=b;}
633  if (newcMTsize>cMTsize)
634  {
635     newcMTsize = newcMTsize+cMTsize;
636     matrix tmp = mpNew(newcMTsize,newcMTsize);
637     int k,m;
638     
639     for (k=1;k<r->N;k++)
640     {
641        for (m=1;m<=r->N;m++)
642        {
643           MATELEM(tmp,k,m) = MATELEM(r->nc->MT[UPMATELEM(j,i,r->N)],k,m);
644           MATELEM(r->nc->MT[UPMATELEM(j,i,r->N)],k,m)=NULL;
645        }
646     }
647     id_Delete((ideal *)&(r->nc->MT[UPMATELEM(j,i,r->N)]),r);
648     r->nc->MT[UPMATELEM(j,i,r->N)] = tmp;
649     r->nc->MTsize[UPMATELEM(j,i,r->N)] = newcMTsize;
650  }  /* The update of multiplication matrix is finished */
651
652  cMT=r->nc->MT[UPMATELEM(j,i,r->N)];         //cMT=current MT
653
654  poly x=pOne();p_SetExp(x,j,1,r);p_Setm(x,r);//var(j);
655  poly y=pOne();p_SetExp(y,i,1,r);p_Setm(y,r);//var(i);  for convenience
656 
657  poly t=NULL;
658/* ------------ Main Cycles ----------------------------*/
659
660  for (k=2;k<=a;k++)
661  {
662     t=MATELEM(cMT,k,1);
663
664     if (t==NULL)   /* not computed yet */
665     {
666        t=p_Copy(MATELEM(cMT,k-1,1),r);
667//        t = pMultT2(y,t);
668        t = nc_mm_Mult_p(y,t,r);
669        MATELEM(cMT,k,1) = t;
670     }
671     t=NULL;
672  }
673 
674  for (m=2;m<=b;m++)
675  {
676     t=MATELEM(cMT,a,m);
677     if (t==NULL)   //not computed yet
678     {
679        t=p_Copy(MATELEM(cMT,a,m-1),r);
680//        t = pMultT(t,x);
681        t = nc_p_Mult_mm(t,x,r);
682        MATELEM(cMT,a,m) = t;
683     }
684     t=NULL;
685  }
686  p_Delete(&x,r);
687  p_Delete(&y,r);
688  t=MATELEM(cMT,a,b);
689  return(p_Copy(t,r));  /* as last computed element was cMT[a,b] */
690}
691#endif
Note: See TracBrowser for help on using the repository browser.