source: git/kernel/gring.cc @ 8049ad

fieker-DuValspielwiese
Last change on this file since 8049ad was 151000, checked in by Motsak Oleksandr <motsak@…>, 16 years ago
*motsak: some more NC ShortSpoly! in kutil... git-svn-id: file:///usr/local/Singular/svn/trunk@10747 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 81.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    gring.cc
6 *  Purpose: noncommutative kernel procedures
7 *  Author:  levandov (Viktor Levandovsky)
8 *  Created: 8/00 - 11/00
9 *  Version: $Id: gring.cc,v 1.55 2008-06-10 14:35:40 motsak Exp $
10 *******************************************************************/
11
12#define OM_CHECK 4
13#define OM_TRACK 5
14
15#include "mod2.h"
16
17#ifdef HAVE_PLURAL
18#define PLURAL_INTERNAL_DECLARATIONS
19
20#include "febase.h"
21#include "ring.h"
22#include "polys.h"
23#include "numbers.h"
24#include "ideals.h"
25#include "matpol.h"
26#include "kbuckets.h"
27#include "kstd1.h"
28#include "sbuckets.h"
29#include "prCopy.h"
30#include "p_Mult_q.h"
31
32#include "pInline1.h"
33   
34#include "gring.h"
35#include "sca.h"
36
37
38#define MYTEST 0
39#define OUTPUT 0
40
41
42// dirty tricks:
43#include "p_MemAdd.h"
44
45bool bUseExtensions = true;
46
47/* global nc_macros : */
48
49#define freeT(A,v) omFreeSize((ADDRESS)A,(v+1)*sizeof(int))
50#define freeN(A,k) omFreeSize((ADDRESS)A,k*sizeof(number))
51
52
53// some forward declarations:
54
55
56// polynomial multiplication functions for p_Procs :
57poly gnc_pp_Mult_mm(const poly p, const poly m, const ring r, poly &last);
58poly gnc_p_Mult_mm(poly p, const poly m, const ring r);
59poly gnc_mm_Mult_p(const poly m, poly p, const ring r);
60poly gnc_mm_Mult_pp(const poly m, const poly p, const ring r);
61
62
63// set pProcs for r and global variable p_Procs as for general non-commutative algebras.
64void gnc_p_ProcsSet(ring rGR, p_Procs_s* p_Procs);
65
66/* syzygies : */
67poly gnc_CreateSpolyOld(const poly p1, const poly p2/*, poly spNoether*/, const ring r);
68poly gnc_ReduceSpolyOld(const poly p1, poly p2/*, poly spNoether*/, const ring r);
69
70poly gnc_CreateSpolyNew(const poly p1, const poly p2/*, poly spNoether*/, const ring r);
71poly gnc_ReduceSpolyNew(const poly p1, poly p2/*, poly spNoether*/, const ring r);
72
73
74
75void gnc_kBucketPolyRedNew(kBucket_pt b, poly p, number *c);
76void gnc_kBucketPolyRed_ZNew(kBucket_pt b, poly p, number *c);
77
78void gnc_kBucketPolyRedOld(kBucket_pt b, poly p, number *c);
79void gnc_kBucketPolyRed_ZOld(kBucket_pt b, poly p, number *c);
80
81
82// poly gnc_ReduceSpolyNew(poly p1, poly p2, poly spNoether, const ring r);
83// void gnc_ReduceSpolyTail(poly p1, poly q, poly q2, poly spNoether, const ring r);
84
85// void nc_kBucketPolyRed(kBucket_pt b, poly p);
86
87ideal gnc_gr_mora(const ideal, const ideal, const intvec *, const intvec *, kStrategy); // Not yet!
88ideal gnc_gr_bba (const ideal F, const ideal Q, const intvec *, const intvec *, kStrategy strat);
89
90
91#if 0
92// deprecated functions:
93//  poly gnc_p_Minus_mm_Mult_qq_ign(poly p, const poly m, poly q, int & d1, poly d2, const ring ri, poly &d3);
94//  poly gnc_p_Minus_mm_Mult_qq(poly p, const poly m, poly q, const ring r);
95//  poly nc_p_Minus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp, int lq, const ring r);
96//  poly nc_p_Plus_mm_Mult_qq (poly p, const poly m, const poly q, int &lp, int lq, const ring r);
97#endif
98
99
100
101/*2
102* returns the LCM of the head terms of a and b
103* without coefficient!!!
104*/
105poly p_Lcm(const poly a, const poly b, const long lCompM, const ring r)
106{
107  poly m = // p_ISet(1, r);
108          p_Init(r); 
109
110  const int pVariables = r->N;
111
112  for (int i = pVariables; i; i--)
113  {
114    const int lExpA = p_GetExp (a, i, r);
115    const int lExpB = p_GetExp (b, i, r);
116
117    p_SetExp (m, i, si_max(lExpA, lExpB), r);
118  }
119
120  p_SetComp (m, lCompM, r);
121
122  p_Setm(m,r);
123
124#ifdef PDEBUG
125//  p_Test(m,r);
126#endif
127
128  n_New(&(p_GetCoeff(m, r)), r); 
129
130  return(m);
131};
132
133poly p_Lcm(const poly a, const poly b, const ring r)
134{
135#ifdef PDEBUG
136  p_Test(a, r);
137  p_Test(b, r);
138#endif
139
140  const long lCompP1 = p_GetComp(a, r);
141  const long lCompP2 = p_GetComp(b, r);
142
143  const poly m = p_Lcm(a, b, si_max(lCompP1, lCompP2), r);
144 
145#ifdef PDEBUG
146//  p_Test(m,r);
147#endif
148  return(m);
149};
150
151
152
153///////////////////////////////////////////////////////////////////////////////
154poly nc_p_Minus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp,
155                                    const int, const poly, const ring r)
156{
157  poly mc  = p_Neg( p_Copy(m, r), r );
158  poly mmc = nc_mm_Mult_pp( mc, q, r );
159  p_Delete(&mc, r);
160
161  p = p_Add_q(p, mmc, r);
162
163  lp = pLength(p); // ring independent!
164
165  return(p);
166}
167
168// returns p + m*q destroys p, const: q, m
169poly nc_p_Plus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp,
170                              const int, const ring r)
171{
172  p = p_Add_q(p, nc_mm_Mult_pp( m, q, r ), r);
173
174  lp = pLength(p);
175
176  return(p);
177}
178
179#if 0
180poly gnc_p_Minus_mm_Mult_qq_ign(poly p, const poly m, poly q, int & d1, poly d2, const ring r, poly &d3)
181{
182  poly t;
183  int  i;
184
185  return gnc_p_Minus_mm_Mult_qq(p, m, q, d1, i, t, r);
186}
187#endif
188
189
190//----------- auxiliary routines--------------------------
191poly _gnc_p_Mult_q(poly p, poly q, const int copy, const ring r)
192  /* destroy p,q unless copy=1 */
193{
194  poly res=NULL;
195  poly ghost=NULL;
196  poly qq,pp;
197  if (copy)
198  {
199    qq=p_Copy(q,r);
200    pp=p_Copy(p,r);
201  }
202  else
203  {
204    qq=q;
205    pp=p;
206  }
207  while (qq!=NULL)
208  {
209    res=p_Add_q(res, pp_Mult_mm(pp, qq, r), r); // p_Head(qq, r)?
210    qq=p_LmDeleteAndNext(qq,r);
211  }
212  p_Delete(&pp,r);
213  return(res);
214}
215
216// return pPolyP * pPolyQ; destroy or reuse pPolyP and pPolyQ
217poly _nc_p_Mult_q(poly pPolyP, poly pPolyQ, const ring rRing)
218{
219  assume( rIsPluralRing(rRing) );
220
221  poly pResult = NULL;
222
223  // always length(q) times "p * q[j]"
224  for( ; pPolyQ!=NULL; pPolyQ  = p_LmDeleteAndNext( pPolyQ, rRing ) )
225    pResult = p_Add_q( pResult, pp_Mult_mm( pPolyP, pPolyQ, rRing), rRing );
226    // rRing->p_Procs->pp_Mult_mm() <--> sca_nc_pp_Mult_mm
227
228  p_Delete( &pPolyP, rRing );
229
230#ifdef PDEBUG
231  p_Test(pResult,rRing);
232#endif
233
234  return(pResult);
235}
236
237
238// return pPolyP * pPolyQ; preserve pPolyP and pPolyQ
239poly _nc_pp_Mult_qq(const poly pPolyP, const poly pPolyQ, const ring rRing)
240{
241  assume( rIsPluralRing(rRing) );
242
243  poly pResult = NULL;
244
245  // always length(q) times "p * q[j]"
246  for( poly q = pPolyQ; q !=NULL; q = pNext(q) )
247    pResult = p_Add_q( pResult, pp_Mult_mm(pPolyP, q, rRing), rRing );
248
249#ifdef PDEBUG
250  p_Test(pResult,rRing);
251#endif
252
253  return(pResult);
254}
255
256
257
258poly gnc_mm_Mult_nn (int *F, int *G, const ring r);
259poly gnc_mm_Mult_uu (int *F,int jG,int bG, const ring r);
260
261/* #define nc_uu_Mult_ww nc_uu_Mult_ww_vert */
262poly gnc_uu_Mult_ww (int i, int a, int j, int b, const ring r);
263/* poly nc_uu_Mult_ww_vert (int i, int a, int j, int b, const ring r); */
264/* poly nc_uu_Mult_ww_horvert (int i, int a, int j, int b, const ring r); */
265/* poly nc_uu_Mult_ww_hvdiag (int i, int a, int j, int b, const ring r); */
266/* not written yet */
267
268
269poly gnc_p_Mult_mm_Common(poly p, const poly m, int side, const ring r)
270/* p is poly, m is mono with coeff, destroys p */
271/* if side==1, computes p_Mult_mm; otherwise, mm_Mult_p */
272{
273  if ((p==NULL) || (m==NULL)) return NULL;
274  /*  if (pNext(p)==NULL) return(nc_mm_Mult_nn(p,pCopy(m),r)); */
275  /* excluded  - the cycle will do it anyway - OK. */
276  if (p_IsConstant(m,r)) return(p_Mult_nn(p,p_GetCoeff(m,r),r));
277
278#ifdef PDEBUG
279  p_Test(p,r);
280  p_Test(m,r);
281#endif
282  poly v=NULL;
283  int rN=r->N;
284  int *P=(int *)omAlloc0((rN+1)*sizeof(int));
285  int *M=(int *)omAlloc0((rN+1)*sizeof(int));
286  /* coefficients: */
287  number cP,cM,cOut;
288  p_GetExpV(m, M, r);
289  cM=p_GetCoeff(m,r);
290  /* components:*/
291  const int expM=p_GetComp(m,r);
292  int expP=0;
293  int expOut=0;
294  /* bucket constraints: */
295  int UseBuckets=1;
296  if (pLength(p)< MIN_LENGTH_BUCKET || TEST_OPT_NOT_BUCKETS) UseBuckets=0;
297  sBucket_pt bu_out;
298  poly out=NULL;
299  if (UseBuckets) bu_out=sBucketCreate(r);
300
301  while (p!=NULL)
302  {
303#ifdef PDEBUG
304    p_Test(p,r);
305#endif
306    expP=p_GetComp(p,r);
307    if (expP==0)
308    {
309      expOut=expM;
310    }
311    else
312    {
313      if (expM==0)
314      {
315        expOut=expP;
316#ifdef PDEBUG
317    if (side)
318        {
319      Print("gnc_p_Mult_mm: Multiplication in the left module from the right");
320    }
321#endif
322      }
323      else
324      {
325        /* REPORT_ERROR */
326#ifdef PDEBUG
327    const char* s;
328    if (side==1) s="gnc_p_Mult_mm";
329    else s="gnc_mm_Mult_p";
330    Print("%s: exponent mismatch %d and %d\n",s,expP,expM);
331#endif
332        expOut=0;
333      }
334    }
335    p_GetExpV(p,P,r);
336    cP=p_GetCoeff(p,r);
337    cOut=n_Mult(cP,cM,r);
338    if (side==1)
339    {
340      v = gnc_mm_Mult_nn(P, M, r);
341    }
342    else
343    {
344      v = gnc_mm_Mult_nn(M, P, r);
345    }
346    v = p_Mult_nn(v,cOut,r);
347    p_SetCompP(v,expOut,r);
348    if (UseBuckets) sBucket_Add_p(bu_out,v,pLength(v));
349    else out = p_Add_q(out,v,r);
350    p_DeleteLm(&p,r);
351  }
352  freeT(P,rN);
353  freeT(M,rN);
354  if (UseBuckets)
355  {
356    out = NULL;
357    int len = pLength(out);
358    sBucketDestroyAdd(bu_out, &out, &len);
359  }
360#ifdef PDEBUG
361  p_Test(out,r);
362#endif
363  return(out);
364}
365
366/* poly functions defined in p_Procs : */
367poly gnc_pp_Mult_mm(const poly p, const poly m, const ring r, poly &last)
368{
369  return( gnc_p_Mult_mm_Common(p_Copy(p,r), m, 1, r) );
370}
371
372poly gnc_p_Mult_mm(poly p, const poly m, const ring r)
373{
374  return( gnc_p_Mult_mm_Common(p, m, 1, r) );
375}
376
377poly gnc_mm_Mult_p(const poly m, poly p, const ring r)
378{
379  return( gnc_p_Mult_mm_Common(p, m, 0, r) );
380}
381
382poly gnc_mm_Mult_pp(const poly m, const poly p, const ring r)
383{
384  return( gnc_p_Mult_mm_Common(p_Copy(p,r), m, 0, r) );
385}
386
387
388
389poly gnc_mm_Mult_nn(int *F0, int *G0, const ring r)
390/* destroys nothing, no coeffs and exps */
391{
392  poly out=NULL;
393  int i,j;
394  int iF,jG,iG;
395  int rN=r->N;
396  int ExpSize=(((rN+1)*sizeof(int)+sizeof(long)-1)/sizeof(long))*sizeof(long);
397
398  int *F=(int *)omAlloc0((rN+1)*sizeof(int));
399  int *G=(int *)omAlloc0((rN+1)*sizeof(int));
400
401  memcpy(F, F0,(rN+1)*sizeof(int));
402  // pExpVectorCopy(F,F0);
403  memcpy(G, G0,(rN+1)*sizeof(int));
404  //  pExpVectorCopy(G,G0);
405  F[0]=0; /* important for p_MemAdd */
406  G[0]=0;
407
408  iF=rN;
409  while ((F[iF]==0)&&(iF>=1)) iF--; /* last exp_num of F */
410  if (iF==0) /* F0 is zero vector */
411  {
412    out=pOne();
413    p_SetExpV(out,G0,r);
414    p_Setm(out,r);
415    freeT(F,rN);
416    freeT(G,rN);
417    return(out);
418  }
419  jG=1;
420  while ((G[jG]==0)&&(jG<rN)) jG++;  /* first exp_num of G */
421  iG=rN;
422  while ((G[iG]==0)&&(iG>1)) iG--;  /* last exp_num of G */
423
424  out=pOne();
425
426  if (iF<=jG)
427    /* i.e. no mixed exp_num , MERGE case */
428  {
429    p_MemAdd_LengthGeneral(F, G, ExpSize/sizeof(long));
430    p_SetExpV(out,F,r);
431    p_Setm(out,r);
432    //    omFreeSize((ADDRESS)F,ExpSize);
433    freeT(F,rN);
434    freeT(G,rN);
435    return(out);
436  }
437
438  number cff=n_Init(1,r);
439  number tmp_num=NULL;
440  int cpower=0;
441
442  if (ncRingType(r)==nc_skew)
443  {
444    if (r->GetNC()->IsSkewConstant==1)
445    {
446      int tpower=0;
447      for(j=jG; j<=iG; j++)
448      {
449        if (G[j]!=0)
450        {
451          cpower = 0;
452          for(i=j+1; i<=iF; i++)
453          {
454            cpower = cpower + F[i];
455          }
456          cpower = cpower*G[j];
457          tpower = tpower + cpower;
458        }
459      }
460      cff = n_Copy(p_GetCoeff(MATELEM(r->GetNC()->COM,1,2),r),r);
461      nPower(cff,tpower,&tmp_num);
462      n_Delete(&cff,r);
463      cff = tmp_num;
464    }
465    else /* skew commutative with nonequal coeffs */
466    {
467      number totcff=n_Init(1,r);
468      for(j=jG; j<=iG; j++)
469      {
470        if (G[j]!=0)
471        {
472          cpower = 0;
473          for(i=j+1; i<=iF; i++)
474          {
475            if (F[i]!=0)
476            {
477              cpower = F[i]*G[j];
478              cff = n_Copy(p_GetCoeff(MATELEM(r->GetNC()->COM,j,i),r),r);
479              nPower(cff,cpower,&tmp_num);
480              cff = nMult(totcff,tmp_num);
481          nDelete(&totcff);
482              nDelete(&tmp_num);
483              totcff = n_Copy(cff,r);
484              n_Delete(&cff,r);
485            }
486          } /* end 2nd for */
487        }
488      }
489      cff=totcff;
490    }
491    p_MemAdd_LengthGeneral(F, G, ExpSize/sizeof(long));
492    p_SetExpV(out,F,r);
493    p_Setm(out,r);
494    p_SetCoeff(out,cff,r);
495    //    p_MemAdd_NegWeightAdjust(p, r); ??? do we need this?
496    freeT(F,rN);
497    freeT(G,rN);
498    return(out);
499  } /* end nc_skew */
500
501  /* now we have to destroy out! */
502  p_Delete(&out,r);
503  out = NULL;
504
505  if (iG==jG)
506    /* g is univariate monomial */
507  {
508    /*    if (ri->GetNC()->type==nc_skew) -- postpone to TU */
509    out = gnc_mm_Mult_uu(F,jG,G[jG],r);
510    freeT(F,rN);
511    freeT(G,rN);
512    return(out);
513  }
514
515  number n1=n_Init(1,r);
516  int *Prv=(int *)omAlloc0((rN+1)*sizeof(int));
517  int *Nxt=(int *)omAlloc0((rN+1)*sizeof(int));
518
519  int *log=(int *)omAlloc0((rN+1)*sizeof(int));
520  int cnt=0; int cnf=0;
521
522  /* splitting F wrt jG */
523  for (i=1;i<=jG;i++)
524  {
525    Prv[i]=F[i]; Nxt[i]=0; /* mult at the very end */
526    if (F[i]!=0) cnf++;
527  }
528
529  if (cnf==0) freeT(Prv,rN);
530
531  for (i=jG+1;i<=rN;i++)
532  {
533    Nxt[i]=F[i];
534    /*    if (cnf!=0)  Prv[i]=0; */
535    if (F[i]!=0)
536    {
537      cnt++;
538    }              /* effective part for F */
539  }
540  freeT(F,rN);
541  cnt=0;
542
543  for (i=1;i<=rN;i++)
544  {
545    if (G[i]!=0)
546    {
547     cnt++;
548     log[cnt]=i;
549     }               /* lG for G */
550   }
551
552/* ---------------------- A C T I O N ------------------------ */
553  poly D=NULL;
554  poly Rout=NULL;
555  number *c=(number *)omAlloc0((rN+1)*sizeof(number));
556  c[0]=n_Init(1,r);
557
558  int *Op=Nxt;
559  int *On=G;
560  int *U=(int *)omAlloc0((rN+1)*sizeof(int));
561
562  for (i=jG;i<=rN;i++) U[i]=Nxt[i]+G[i];  /* make leadterm */
563  Nxt=NULL;
564  G=NULL;
565  cnt=1;
566  int t=0;
567  poly w=NULL;
568  poly Pn=pOne();
569  p_SetExpV(Pn,On,r);
570  p_Setm(Pn,r);
571
572  while (On[iG]!=0)
573  {
574     t=log[cnt];
575
576     w=gnc_mm_Mult_uu(Op,t,On[t],r);
577     c[cnt]=n_Mult(c[cnt-1],p_GetCoeff(w,r),r);
578     D = pNext(w);  /* getting coef and rest D */
579     p_DeleteLm(&w,r);
580     w=NULL;
581
582     Op[t] += On[t];   /* update exp_vectors */
583     On[t] = 0;
584
585     if (t!=iG)    /* not the last step */
586     {
587       p_SetExpV(Pn,On,r);
588       p_Setm(Pn,r);
589#ifdef PDEBUG
590       p_Test(Pn,r);
591#endif
592
593//       if (pNext(D)==0)
594// is D a monomial? could be postponed higher
595//       {
596//       Rout=nc_mm_Mult_nn(D,Pn,r);
597//       }
598//       else
599//       {
600       Rout=gnc_p_Mult_mm(D,Pn,r);
601//       }
602     }
603     else
604     {
605       Rout=D;
606       D=NULL;
607     }
608
609     if (Rout!=NULL)
610     {
611       Rout=p_Mult_nn(Rout,c[cnt-1],r); /* Rest is ready */
612       out=p_Add_q(out,Rout,r);
613       Rout=NULL;
614     }
615     cnt++;
616  }
617  freeT(On,rN);
618  freeT(Op,rN);
619  p_Delete(&Pn,r);
620  omFreeSize((ADDRESS)log,(rN+1)*sizeof(int));
621
622  /* leadterm and Prv-part */
623
624  Rout=pOne();
625  /* U is lead.monomial */
626  U[0]=0;
627  p_SetExpV(Rout,U,r);
628  p_Setm(Rout,r);  /* use again this name Rout */
629#ifdef PDEBUG
630  p_Test(Rout,r);
631#endif
632  p_SetCoeff(Rout,c[cnt-1],r);
633  out=p_Add_q(out,Rout,r);
634  freeT(U,rN);
635  freeN(c,rN+1);
636  if (cnf!=0)  /* Prv is non-zero vector */
637  {
638    Rout=pOne();
639    Prv[0]=0;
640    p_SetExpV(Rout,Prv,r);
641    p_Setm(Rout,r);
642#ifdef PDEBUG
643    p_Test(Rout,r);
644#endif
645    out=gnc_mm_Mult_p(Rout,out,r); /* getting the final result */
646    freeT(Prv,rN);
647    p_Delete(&Rout,r);
648  }
649  return (out);
650}
651
652
653poly gnc_mm_Mult_uu(int *F,int jG,int bG, const ring r)
654/* f=mono(F),g=(x_iG)^bG */
655{
656  poly out=NULL;
657  int i;
658  number num=NULL;
659
660  int rN=r->N;
661  int iF=r->N;
662  while ((F[iF]==0)&&(iF>0)) iF-- ;   /* last exponent_num of F */
663
664  if (iF==0)  /* F==zero vector in other words */
665  {
666   out=pOne();
667   p_SetExp(out,jG,bG,r);
668   p_Setm(out,r);
669   return(out);
670  }
671
672  int jF=1;
673  while ((F[jF]==0)&&(jF<=rN)) jF++;  /* first exp of F */
674
675  if (iF<=jG)                       /* i.e. no mixed exp_num */
676  {
677    out=pOne();
678    F[jG]=F[jG]+bG;
679    p_SetExpV(out,F,r);
680    p_Setm(out,r);
681    return(out);
682  }
683
684  if (iF==jF)              /* uni times uni */
685  {
686   out=gnc_uu_Mult_ww(iF,F[iF],jG,bG,r);
687   return(out);
688  }
689
690  /* Now: F is mono with >=2 exponents, jG<iF */
691  /* check the quasi-commutative case */
692//   matrix LCOM=r->GetNC()->COM;
693//   number rescoef=n_Init(1,r);
694//   number tmpcoef=n_Init(1,r);
695//   int tmpint;
696//   i=iF;
697//   while (i>=jG+1)
698//     /* all the non-zero exponents */
699//   {
700//     if (MATELEM(LCOM,jG,i)!=NULL)
701//     {
702//       tmpcoef=pGetCoeff(MATELEM(LCOM,jG,i));
703//       tmpint=(int)F[i];
704//       nPower(tmpcoef,F[i],&tmpcoef);
705//       rescoef=nMult(rescoef,tmpcoef);
706//       i--;
707//     }
708//     else
709//     {
710//       if (F[i]!=0) break;
711//     }
712//   }
713//   if (iF==i)
714//   /* no action took place*/
715//   {
716
717//   }
718//   else /* power the result up to bG */
719//   {
720//     nPower(rescoef,bG,&rescoef);
721//     /* + cleanup, post-processing */
722//   }
723
724  int *Prv=(int*)omAlloc0((rN+1)*sizeof(int));
725  int *Nxt=(int*)omAlloc0((rN+1)*sizeof(int));
726  int *lF=(int *)omAlloc0((rN+1)*sizeof(int));
727  int cnt=0; int cnf=0;
728  /* splitting F wrt jG */
729  for (i=1;i<=jG;i++) /* mult at the very end */
730  {
731    Prv[i]=F[i]; Nxt[i]=0;
732    if (F[i]!=0) cnf++;
733  }
734  if (cnf==0)  freeT(Prv,rN);
735  for (i=jG+1;i<=rN;i++)
736  {
737    Nxt[i]=F[i];
738    if (cnf!=0) { Prv[i]=0;}
739    if (F[i]!=0)
740    {
741      cnt++;
742      lF[cnt]=i;
743    }                 /* eff_part,lF_for_F */
744  }
745
746  if (cnt==1) /* Nxt consists of 1 nonzero el-t only */
747  {
748    int q=lF[1];
749    poly Rout=pOne();
750    out=gnc_uu_Mult_ww(q,Nxt[q],jG,bG,r);
751    freeT(Nxt,rN);
752
753    if (cnf!=0)
754    {
755       Prv[0]=0;
756       p_SetExpV(Rout,Prv,r);
757       p_Setm(Rout,r);
758#ifdef PDEBUG
759       p_Test(Rout,r);
760#endif
761       freeT(Prv,rN);
762       out=gnc_mm_Mult_p(Rout,out,r); /* getting the final result */
763    }
764
765    omFreeSize((ADDRESS)lF,(rN+1)*sizeof(int));
766    p_Delete(&Rout,r);
767    return (out);
768  }
769/* -------------------- MAIN ACTION --------------------- */
770
771  poly D=NULL;
772  poly Rout=NULL;
773  number *c=(number *)omAlloc0((cnt+2)*sizeof(number));
774  c[cnt+1]=n_Init(1,r);
775  i=cnt+2;         /* later in freeN */
776  int *Op=Nxt;
777  int *On=(int *)omAlloc0((rN+1)*sizeof(int));
778  int *U=(int *)omAlloc0((rN+1)*sizeof(int));
779
780
781  //  pExpVectorCopy(U,Nxt);
782  memcpy(U, Nxt,(rN+1)*sizeof(int));
783  U[jG] = U[jG] + bG;
784
785  /* Op=Nxt and initial On=(0); */
786  Nxt=NULL;
787
788  poly Pp;
789  poly Pn;
790  int t=0;
791  int first=lF[1];
792  int nlast=lF[cnt];
793  int kk=0;
794  /*  cnt--;   */
795  /* now lF[cnt] should be <=iF-1 */
796
797  while (Op[first]!=0)
798  {
799     t=lF[cnt];   /* cnt as it was computed */
800
801     poly w=gnc_uu_Mult_ww(t,Op[t],jG,bG,r);
802     c[cnt]=n_Copy(p_GetCoeff(w,r),r);
803     D = pNext(w);  /* getting coef and rest D */
804     p_DeleteLm(&w,r);
805     w=NULL;
806
807     Op[t]= 0;
808     Pp=pOne();
809     p_SetExpV(Pp,Op,r);
810     p_Setm(Pp,r);
811
812     if (t<nlast)
813     {
814       kk=lF[cnt+1];
815       On[kk]=F[kk];
816
817       Pn=pOne();
818       p_SetExpV(Pn,On,r);
819       p_Setm(Pn,r);
820
821       if (t!=first)   /* typical expr */
822       {
823         w=gnc_p_Mult_mm(D,Pn,r);
824         Rout=gnc_mm_Mult_p(Pp,w,r);
825         w=NULL;
826       }
827       else                   /* last step */
828       {
829         On[t]=0;
830         p_SetExpV(Pn,On,r);
831         p_Setm(Pn,r);
832         Rout=gnc_p_Mult_mm(D,Pn,r);
833       }
834#ifdef PDEBUG
835       p_Test(Pp,r);
836#endif
837       p_Delete(&Pn,r);
838     }
839     else                     /* first step */
840     {
841       Rout=gnc_mm_Mult_p(Pp,D,r);
842     }
843#ifdef PDEBUG
844     p_Test(Pp,r);
845#endif
846     p_Delete(&Pp,r);
847     num=n_Mult(c[cnt+1],c[cnt],r);
848     n_Delete(&c[cnt],r);
849     c[cnt]=num;
850     Rout=p_Mult_nn(Rout,c[cnt+1],r); /* Rest is ready */
851     out=p_Add_q(out,Rout,r);
852     Pp=NULL;
853     cnt--;
854  }
855  /* only to feel safe:*/
856  Pn=Pp=NULL;
857  freeT(On,rN);
858  freeT(Op,rN);
859
860/* leadterm and Prv-part with coef 1 */
861/*  U[0]=exp; */
862/*  U[jG]=U[jG]+bG;  */
863/* make leadterm */
864/* ??????????? we have done it already :-0 */
865  Rout=pOne();
866  p_SetExpV(Rout,U,r);
867  p_Setm(Rout,r);  /* use again this name */
868  p_SetCoeff(Rout,c[cnt+1],r);  /* last computed coef */
869  out=p_Add_q(out,Rout,r);
870  Rout=NULL;
871  freeT(U,rN);
872  freeN(c,i);
873  omFreeSize((ADDRESS)lF,(rN+1)*sizeof(int));
874
875  if (cnf!=0)
876  {
877    Rout=pOne();
878    p_SetExpV(Rout,Prv,r);
879    p_Setm(Rout,r);
880    freeT(Prv,rN);
881    out=gnc_mm_Mult_p(Rout,out,r); /* getting the final result */
882    p_Delete(&Rout,r);
883  }
884  return (out);
885}
886
887poly gnc_uu_Mult_ww_vert (int i, int a, int j, int b, const ring r)
888{
889  int k,m;
890  int rN=r->N;
891  matrix cMT=r->GetNC()->MT[UPMATELEM(j,i,rN)];         /* cMT=current MT */
892
893  poly x=pOne();p_SetExp(x,j,1,r);p_Setm(x,r);
894/* var(j); */
895  poly y=pOne();p_SetExp(y,i,1,r);p_Setm(y,r);
896/*var(i);  for convenience */
897#ifdef PDEBUG
898  p_Test(x,r);
899  p_Test(y,r);
900#endif
901  poly t=NULL;
902/* ------------ Main Cycles ----------------------------*/
903
904  for (k=2;k<=a;k++)
905  {
906     t = nc_p_CopyGet(MATELEM(cMT,k,1),r);
907
908     if (t==NULL)   /* not computed yet */
909     {
910       t = nc_p_CopyGet(MATELEM(cMT,k-1,1),r);
911       //        t=p_Copy(MATELEM(cMT,k-1,1),r);
912       t = gnc_mm_Mult_p(y,t,r);
913       MATELEM(cMT,k,1) = nc_p_CopyPut(t,r);
914       //        omCheckAddr(cMT->m);
915       p_Delete(&t,r);
916     }
917     t=NULL;
918  }
919
920  for (m=2;m<=b;m++)
921  {
922    t = nc_p_CopyGet(MATELEM(cMT,a,m),r);
923    //     t=MATELEM(cMT,a,m);
924    if (t==NULL)   //not computed yet
925    {
926      t = nc_p_CopyGet(MATELEM(cMT,a,m-1),r);
927      //      t=p_Copy(MATELEM(cMT,a,m-1),r);
928      t = gnc_p_Mult_mm(t,x,r);
929      MATELEM(cMT,a,m) = nc_p_CopyPut(t,r);
930      //      MATELEM(cMT,a,m) = t;
931      //        omCheckAddr(cMT->m);
932      p_Delete(&t,r);
933    }
934    t=NULL;
935  }
936  p_Delete(&x,r);
937  p_Delete(&y,r);
938  //  t=MATELEM(cMT,a,b);
939  t= nc_p_CopyGet(MATELEM(cMT,a,b),r);
940  //  return(p_Copy(t,r));
941  /* since the last computed element was cMT[a,b] */
942  return(t);
943}
944
945poly gnc_uu_Mult_ww (int i, int a, int j, int b, const ring r)
946  /* (x_i)^a times (x_j)^b */
947  /* x_i = y,  x_j = x ! */
948{
949  /* Check zero exceptions, (q-)commutativity and is there something to do? */
950  assume(a!=0);
951  assume(b!=0);
952  poly out=pOne();
953  if (i<=j)
954  {
955    p_SetExp(out,i,a,r);
956    p_AddExp(out,j,b,r);
957    p_Setm(out,r);
958    return(out);
959  }/* zero exeptions and usual case */
960  /*  if ((a==0)||(b==0)||(i<=j)) return(out); */
961
962  if (MATELEM(r->GetNC()->COM,j,i)!=NULL)
963    /* commutative or quasicommutative case */
964  {
965    p_SetExp(out,i,a,r);
966    p_AddExp(out,j,b,r);
967    p_Setm(out,r);
968    if (r->cf->nIsOne(p_GetCoeff(MATELEM(r->GetNC()->COM,j,i),r))) /* commutative case */
969    {
970      return(out);
971    }
972    else
973    {
974      number tmp_number=p_GetCoeff(MATELEM(r->GetNC()->COM,j,i),r); /* quasicommutative case */
975      nPower(tmp_number,a*b,&tmp_number);
976      p_SetCoeff(out,tmp_number,r);
977      return(out);
978    }
979  }/* end_of commutative or quasicommutative case */
980  p_Delete(&out,r);
981
982  /* we are here if  i>j and variables do not commute or quasicommute */
983  /* in fact, now a>=1 and b>=1; and j<i */
984  /* now check whether the polynomial is already computed */
985  int rN=r->N;
986  int vik = UPMATELEM(j,i,rN);
987  int cMTsize=r->GetNC()->MTsize[vik];
988  int newcMTsize=0;
989  newcMTsize=si_max(a,b);
990
991  if (newcMTsize<=cMTsize)
992  {
993    out =  nc_p_CopyGet(MATELEM(r->GetNC()->MT[vik],a,b),r);
994    if (out !=NULL) return (out);
995  }
996  int k,m;
997  if (newcMTsize > cMTsize)
998  {
999    int inM=(((newcMTsize+6)/7)*7);
1000    assume (inM>=newcMTsize);
1001    newcMTsize = inM;
1002    //    matrix tmp = (matrix)omAlloc0(inM*inM*sizeof(poly));
1003    matrix tmp = mpNew(newcMTsize,newcMTsize);
1004
1005    for (k=1;k<=cMTsize;k++)
1006    {
1007      for (m=1;m<=cMTsize;m++)
1008      {
1009    out = MATELEM(r->GetNC()->MT[UPMATELEM(j,i,rN)],k,m);
1010        if ( out != NULL )
1011        {
1012          MATELEM(tmp,k,m) = out;/*MATELEM(r->GetNC()->MT[UPMATELEM(j,i,rN)],k,m)*/
1013          //           omCheckAddr(tmp->m);
1014          MATELEM(r->GetNC()->MT[UPMATELEM(j,i,rN)],k,m)=NULL;
1015          //           omCheckAddr(r->GetNC()->MT[UPMATELEM(j,i,rN)]->m);
1016        }
1017      }
1018    }
1019    id_Delete((ideal *)&(r->GetNC()->MT[UPMATELEM(j,i,rN)]),r);
1020    r->GetNC()->MT[UPMATELEM(j,i,rN)] = tmp;
1021    tmp=NULL;
1022    r->GetNC()->MTsize[UPMATELEM(j,i,rN)] = newcMTsize;
1023  }
1024  /* The update of multiplication matrix is finished */
1025    pDelete(&out);
1026    out = gnc_uu_Mult_ww_vert(i, a, j, b, r);
1027    //    out = nc_uu_Mult_ww_horvert(i, a, j, b, r);
1028    return(out);
1029}
1030
1031poly gnc_uu_Mult_ww_horvert (int i, int a, int j, int b, const ring r)
1032
1033{
1034  int k,m;
1035  int rN=r->N;
1036  matrix cMT=r->GetNC()->MT[UPMATELEM(j,i,rN)];         /* cMT=current MT */
1037
1038  poly x=pOne();p_SetExp(x,j,1,r);p_Setm(x,r);/* var(j); */
1039  poly y=pOne();p_SetExp(y,i,1,r);p_Setm(y,r); /*var(i);  for convenience */
1040#ifdef PDEBUG
1041  p_Test(x,r);
1042  p_Test(y,r);
1043#endif
1044
1045  poly t=NULL;
1046
1047  int toXY;
1048  int toYX;
1049
1050  if (a==1) /* y*x^b, b>=2 */
1051  {
1052    toXY=b-1;
1053    while ( (MATELEM(cMT,1,toXY)==NULL) && (toXY>=2)) toXY--;
1054    for (m=toXY+1;m<=b;m++)
1055    {
1056      t=MATELEM(cMT,1,m);
1057      if (t==NULL)   /* remove after debug */
1058      {
1059        t = p_Copy(MATELEM(cMT,1,m-1),r);
1060        t = gnc_p_Mult_mm(t,x,r);
1061        MATELEM(cMT,1,m) = t;
1062        /*        omCheckAddr(cMT->m); */
1063      }
1064      else
1065      {
1066        /* Error, should never get there */
1067        WarnS("Error: a=1; MATELEM!=0");
1068      }
1069      t=NULL;
1070    }
1071    return(p_Copy(MATELEM(cMT,1,b),r));
1072  }
1073
1074  if (b==1) /* y^a*x, a>=2 */
1075  {
1076    toYX=a-1;
1077    while ( (MATELEM(cMT,toYX,1)==NULL) && (toYX>=2)) toYX--;
1078    for (m=toYX+1;m<=a;m++)
1079    {
1080      t=MATELEM(cMT,m,1);
1081      if (t==NULL)   /* remove after debug */
1082      {
1083        t = p_Copy(MATELEM(cMT,m-1,1),r);
1084        t = gnc_mm_Mult_p(y,t,r);
1085        MATELEM(cMT,m,1) = t;
1086        /*        omCheckAddr(cMT->m); */
1087      }
1088      else
1089      {
1090        /* Error, should never get there */
1091        WarnS("Error: b=1, MATELEM!=0");
1092      }
1093      t=NULL;
1094    }
1095    return(p_Copy(MATELEM(cMT,a,1),r));
1096  }
1097
1098/* ------------ Main Cycles ----------------------------*/
1099  /*            a>1, b>1              */
1100
1101  int dXY=0; int dYX=0;
1102  /* dXY = distance for computing x-mult, then y-mult */
1103  /* dYX = distance for computing y-mult, then x-mult */
1104  int toX=a-1; int toY=b-1; /* toX = to axe X, toY = to axe Y */
1105  toXY=b-1; toYX=a-1;
1106  /* if toX==0, toXY = dist. to computed y * x^toXY */
1107  /* if toY==0, toYX = dist. to computed y^toYX * x */
1108  while ( (MATELEM(cMT,toX,b)==NULL) && (toX>=1)) toX--;
1109  if (toX==0) /* the whole column is not computed yet */
1110  {
1111    while ( (MATELEM(cMT,1,toXY)==NULL) && (toXY>=1)) toXY--;
1112    /* toXY >=1 */
1113    dXY=b-1-toXY;
1114  }
1115  dXY=dXY+a-toX; /* the distance to nearest computed y^toX x^b */
1116
1117  while ( (MATELEM(cMT,a,toY)==NULL) && (toY>=1)) toY--;
1118  if (toY==0) /* the whole row is not computed yet */
1119  {
1120    while ( (MATELEM(cMT,toYX,1)==NULL) && (toYX>=1)) toYX--;
1121    /* toYX >=1 */
1122    dYX=a-1-toYX;
1123  }
1124  dYX=dYX+b-toY; /* the distance to nearest computed y^a x^toY */
1125
1126  if (dYX>=dXY)
1127  {
1128    /* first x, then y */
1129    if (toX==0) /* start with the row*/
1130    {
1131      for (m=toXY+1;m<=b;m++)
1132      {
1133        t=MATELEM(cMT,1,m);
1134        if (t==NULL)   /* remove after debug */
1135        {
1136          t = p_Copy(MATELEM(cMT,1,m-1),r);
1137          t = gnc_p_Mult_mm(t,x,r);
1138          MATELEM(cMT,1,m) = t;
1139          /*        omCheckAddr(cMT->m); */
1140        }
1141        else
1142        {
1143          /* Error, should never get there */
1144          WarnS("dYX>=dXY,toXY; MATELEM==0");
1145        }
1146        t=NULL;
1147      }
1148      toX=1; /* y*x^b is computed */
1149    }
1150    /* Now toX>=1 */
1151    for (k=toX+1;k<=a;k++)
1152    {
1153      t=MATELEM(cMT,k,b);
1154      if (t==NULL)   /* remove after debug */
1155      {
1156        t = p_Copy(MATELEM(cMT,k-1,b),r);
1157        t = gnc_mm_Mult_p(y,t,r);
1158        MATELEM(cMT,k,b) = t;
1159        /*        omCheckAddr(cMT->m); */
1160      }
1161      else
1162      {
1163        /* Error, should never get there */
1164        WarnS("dYX>=dXY,toX; MATELEM==0");
1165      }
1166      t=NULL;
1167    }
1168  } /* endif (dYX>=dXY) */
1169
1170
1171  if (dYX<dXY)
1172  {
1173    /* first y, then x */
1174    if (toY==0) /* start with the column*/
1175    {
1176      for (m=toYX+1;m<=a;m++)
1177      {
1178        t=MATELEM(cMT,m,1);
1179        if (t==NULL)   /* remove after debug */
1180        {
1181          t = p_Copy(MATELEM(cMT,m-1,1),r);
1182          t = gnc_mm_Mult_p(y,t,r);
1183          MATELEM(cMT,m,1) = t;
1184          /*        omCheckAddr(cMT->m); */
1185        }
1186        else
1187        {
1188          /* Error, should never get there */
1189          WarnS("dYX<dXY,toYX; MATELEM==0");
1190        }
1191        t=NULL;
1192      }
1193      toY=1; /* y^a*x is computed */
1194    }
1195    /* Now toY>=1 */
1196    for (k=toY+1;k<=b;k++)
1197    {
1198      t=MATELEM(cMT,a,k);
1199      if (t==NULL)   /* remove after debug */
1200      {
1201        t = p_Copy(MATELEM(cMT,a,k-1),r);
1202        t = gnc_p_Mult_mm(t,x,r);
1203        MATELEM(cMT,a,k) = t;
1204        /*        omCheckAddr(cMT->m); */
1205      }
1206      else
1207      {
1208        /* Error, should never get there */
1209        WarnS("dYX<dXY,toY; MATELEM==0");
1210      }
1211      t=NULL;
1212    }
1213  } /* endif (dYX<dXY) */
1214
1215  p_Delete(&x,r);
1216  p_Delete(&y,r);
1217  t=p_Copy(MATELEM(cMT,a,b),r);
1218  return(t);  /* since the last computed element was cMT[a,b] */
1219}
1220
1221
1222/* ----------------------------- Syzygies ---------------------- */
1223
1224/*2
1225* reduction of p2 with p1
1226* do not destroy p1, but p2
1227* p1 divides p2 -> for use in NF algorithm
1228*/
1229poly gnc_ReduceSpolyOld(const poly p1, poly p2/*,poly spNoether*/, const ring r)
1230{
1231  assume(p_LmDivisibleBy(p1, p2, r));
1232
1233  if (p_GetComp(p1,r)!=p_GetComp(p2,r)
1234  && (p_GetComp(p1,r)!=0)
1235  && (p_GetComp(p2,r)!=0))
1236  {
1237#ifdef PDEBUG
1238    Print("nc_ReduceSpolyOld: different components");
1239#endif
1240    return(NULL);
1241  }
1242  poly m = pOne();
1243  p_ExpVectorDiff(m,p2,p1,r);
1244  //p_Setm(m,r);
1245#ifdef PDEBUG
1246  p_Test(m,r);
1247#endif
1248  /* pSetComp(m,r)=0? */
1249  poly   N  = nc_mm_Mult_p(m, p_Head(p1,r), r);
1250  number C  = n_Copy( p_GetCoeff(N,  r), r);
1251  number cF = n_Copy( p_GetCoeff(p2, r),r);
1252  /* GCD stuff */
1253  number cG = nGcd(C, cF, r);
1254  if ( !nEqual(cG, n_Init(1,r) ) )
1255  {
1256    cF = nDiv(cF, cG);
1257    C  = nDiv(C,  cG);
1258  }
1259  p2 = p_Mult_nn(p2, C, r);
1260  poly out = nc_mm_Mult_pp(m, pNext(p1), r);
1261  N = p_Add_q(N, out, r);
1262  p_Test(p2,r);
1263  p_Test(N,r);
1264  number MinusOne = n_Init(-1,r);
1265  if (!n_Equal(cF,MinusOne,r))
1266  {
1267    cF = n_Neg(cF,r);
1268    N  = p_Mult_nn(N, cF, r);
1269    p_Test(N,r);
1270  }
1271  out = p_Add_q(p2,N,r);
1272  p_Test(out,r);
1273  if ( out!=NULL ) pContent(out);
1274  p_Delete(&m,r);
1275  n_Delete(&cF,r);
1276  n_Delete(&C,r);
1277  n_Delete(&MinusOne,r);
1278  return(out);
1279
1280}
1281
1282poly gnc_ReduceSpolyNew(const poly p1, poly p2, const ring r)
1283{
1284  assume(p_LmDivisibleBy(p1, p2, r));
1285
1286  const long lCompP1 = p_GetComp(p1,r);
1287  const long lCompP2 = p_GetComp(p2,r);
1288
1289  if ((lCompP1!=lCompP2) && (lCompP1!=0) && (lCompP2!=0))
1290  {
1291#ifdef PDEBUG
1292    Werror("gnc_ReduceSpolyNew: different non-zero components!");
1293#endif
1294    return(NULL);
1295  }
1296
1297  poly m = pOne();
1298  p_ExpVectorDiff(m, p2, p1, r);
1299  //p_Setm(m,r);
1300#ifdef PDEBUG
1301  p_Test(m,r);
1302#endif
1303
1304  /* pSetComp(m,r)=0? */
1305  poly   N  = nc_mm_Mult_p(m, p_Head(p1,r), r);
1306
1307  number C  = n_Copy( p_GetCoeff(N,  r), r);
1308  number cF = n_Copy( p_GetCoeff(p2, r), r);
1309
1310  /* GCD stuff */
1311  number cG = nGcd(C, cF, r);
1312
1313  if (!n_IsOne(cG, r))
1314  {
1315    cF = n_Div(cF, cG, r);
1316    C  = n_Div(C,  cG, r);
1317  }
1318
1319  p2 = p_Mult_nn(p2, C, r); // p2 !!!
1320  p_Test(p2,r);
1321  n_Delete(&C,r);
1322
1323  poly out = nc_mm_Mult_pp(m, pNext(p1), r);
1324  p_Delete(&m,r);
1325
1326  N = p_Add_q(N, out, r);
1327  p_Test(N,r);
1328
1329  if (!n_IsMOne(cF,r)) // ???
1330  {
1331    cF = n_Neg(cF,r);
1332    N  = p_Mult_nn(N, cF, r);
1333    p_Test(N,r);
1334  }
1335
1336  out = p_Add_q(p2,N,r); // delete N, p2
1337  p_Test(out,r);
1338  if ( out!=NULL ) pContent(out);
1339  n_Delete(&cF,r);
1340  return(out);
1341}
1342
1343
1344/*4
1345* creates the S-polynomial of p1 and p2
1346* do not destroy p1 and p2
1347*/
1348poly gnc_CreateSpolyOld(poly p1, poly p2/*,poly spNoether*/, const ring r)
1349{
1350  if ((p_GetComp(p1,r)!=p_GetComp(p2,r))
1351  && (p_GetComp(p1,r)!=0)
1352  && (p_GetComp(p2,r)!=0))
1353  {
1354#ifdef PDEBUG
1355    Print("gnc_CreateSpolyOld : different components!");
1356#endif
1357    return(NULL);
1358  }
1359  if ((ncRingType(r)==nc_lie) && pHasNotCF(p1,p2)) /* prod crit */
1360  {
1361    return(nc_p_Bracket_qq(pCopy(p2),p1));
1362  }
1363  poly pL=pOne();
1364  poly m1=pOne();
1365  poly m2=pOne();
1366  pLcm(p1,p2,pL);
1367  p_Setm(pL,r);
1368#ifdef PDEBUG
1369  p_Test(pL,r);
1370#endif
1371  p_ExpVectorDiff(m1,pL,p1,r);
1372  //p_SetComp(m1,0,r);
1373  //p_Setm(m1,r);
1374#ifdef PDEBUG
1375  p_Test(m1,r);
1376#endif
1377  p_ExpVectorDiff(m2,pL,p2,r);
1378  //p_SetComp(m2,0,r);
1379  //p_Setm(m2,r);
1380#ifdef PDEBUG
1381  p_Test(m2,r);
1382#endif
1383  p_Delete(&pL,r);
1384  /* zero exponents ! */
1385  poly M1    = nc_mm_Mult_p(m1,p_Head(p1,r),r);
1386  number C1  = n_Copy(p_GetCoeff(M1,r),r);
1387  poly M2    = nc_mm_Mult_p(m2,p_Head(p2,r),r);
1388  number C2  = n_Copy(p_GetCoeff(M2,r),r);
1389  /* GCD stuff */
1390  number C = nGcd(C1,C2,r);
1391  if (!nEqual(C,n_Init(1,r)))
1392  {
1393    C1=nDiv(C1,C);
1394    C2=nDiv(C2,C);
1395  }
1396  M1=p_Mult_nn(M1,C2,r);
1397  p_SetCoeff(m1,C2,r);
1398  number MinusOne=n_Init(-1,r);
1399  if (n_Equal(C1,MinusOne,r))
1400  {
1401    M2=p_Add_q(M1,M2,r);
1402  }
1403  else
1404  {
1405    C1=n_Neg(C1,r);
1406    M2=p_Mult_nn(M2,C1,r);
1407    M2=p_Add_q(M1,M2,r);
1408    p_SetCoeff(m2,C1,r);
1409  }
1410  /* M1 is killed, M2=res = C2 M1 - C1 M2 */
1411  poly tmp=p_Copy(p1,r);
1412  tmp=p_LmDeleteAndNext(tmp,r);
1413  M1=nc_mm_Mult_p(m1,tmp,r);
1414  tmp=p_Copy(p2,r);
1415  tmp=p_LmDeleteAndNext(tmp,r);
1416  M2=p_Add_q(M2,M1,r);
1417  M1=nc_mm_Mult_p(m2,tmp,r);
1418  M2=p_Add_q(M2,M1,r);
1419  p_Delete(&m1,r);
1420  p_Delete(&m2,r);
1421  //  n_Delete(&C1,r);
1422  //  n_Delete(&C2,r);
1423  n_Delete(&MinusOne,r);
1424#ifdef PDEBUG
1425  p_Test(M2,r);
1426#endif
1427  if (M2!=NULL) pCleardenom(M2);
1428  if (M2!=NULL) pContent(M2);
1429  return(M2);
1430}
1431
1432poly gnc_CreateSpolyNew(poly p1, poly p2/*,poly spNoether*/, const ring r)
1433{
1434  assume(r == currRing);
1435
1436#ifdef PDEBUG
1437  pTest(p1);
1438  pTest(p2);
1439#if MYTEST
1440  Print("p1: "); pWrite(p1);
1441  Print("p2: "); pWrite(p2);
1442#endif
1443#endif
1444 
1445  const long lCompP1 = p_GetComp(p1,r);
1446  const long lCompP2 = p_GetComp(p2,r);
1447
1448  if ((lCompP1!=lCompP2) && (lCompP1!=0) && (lCompP2!=0))
1449  {
1450#ifdef PDEBUG
1451    Werror("gnc_CreateSpolyNew: different non-zero components!");
1452#endif
1453    return(NULL);
1454  }
1455
1456#ifdef PDEBUG
1457  if (lCompP1!=lCompP2)
1458  {
1459    WarnS("gnc_CreateSpolyNew: vector & poly in SPoly!");
1460  }
1461#endif
1462 
1463 
1464//   if ((r->GetNC()->type==nc_lie) && pHasNotCF(p1,p2)) /* prod crit */
1465//   {
1466//     return(nc_p_Bracket_qq(pCopy(p2),p1));
1467//   }
1468
1469//  poly pL=p_ISet(1, r);
1470
1471  poly m1=p_ISet(1, r);
1472  poly m2=p_ISet(1, r);
1473
1474  poly pL = p_Lcm(p1,p2,r);                               // pL = lcm( lm(p1), lm(p2) )
1475
1476
1477#ifdef PDEBUG
1478//  p_Test(pL,r);
1479#endif
1480
1481  p_ExpVectorDiff(m1, pL, p1, r);                  // m1 = pL / lm(p1)
1482  //p_SetComp(m1,0,r);
1483  //p_Setm(m1,r);
1484
1485#ifdef PDEBUG
1486  p_Test(m1,r);
1487#endif
1488//  assume(p_GetComp(m1,r) == 0);
1489
1490  p_ExpVectorDiff(m2, pL, p2, r);                  // m2 = pL / lm(p2)
1491
1492  //p_SetComp(m2,0,r);
1493  //p_Setm(m2,r);
1494#ifdef PDEBUG
1495  p_Test(m2,r);
1496#endif
1497
1498#ifdef PDEBUG
1499#if MYTEST
1500  Print("m1: "); pWrite(m1);
1501  Print("m2: "); pWrite(m2);
1502#endif
1503#endif
1504
1505 
1506//  assume(p_GetComp(m2,r) == 0);
1507
1508#ifdef PDEBUG
1509#if 0 
1510  if(  (p_GetComp(m2,r) != 0) || (p_GetComp(m1,r) != 0) )
1511  {
1512    WarnS("gnc_CreateSpolyNew: wrong monomials!");
1513   
1514   
1515#ifdef RDEBUG
1516    PrintS("m1 = "); p_Write(m1, r);
1517    pDebugPrintR(m1, r);
1518   
1519    PrintS("m2 = "); p_Write(m2, r);
1520    pDebugPrintR(m2, r);
1521
1522    PrintS("p1 = "); p_Write(p1, r);
1523    pDebugPrintR(p1, r);
1524
1525    PrintS("p2 = "); p_Write(p2, r);
1526    pDebugPrintR(p2, r);
1527
1528    PrintS("pL = "); p_Write(pL, r);
1529    pDebugPrintR(pL, r);
1530#endif
1531   
1532  }
1533 
1534#endif
1535#endif
1536 
1537  p_Delete(&pL,r);
1538
1539  /* zero exponents !? */
1540  poly M1    = nc_mm_Mult_p(m1,p_Head(p1,r),r); // M1 = m1 * lt(p1)
1541  poly M2    = nc_mm_Mult_p(m2,p_Head(p2,r),r); // M2 = m2 * lt(p2)
1542
1543#ifdef PDEBUG
1544  p_Test(M1,r);
1545  p_Test(M2,r);
1546
1547#if MYTEST
1548  Print("M1: "); pWrite(M1);
1549  Print("M2: "); pWrite(M2);
1550#endif
1551#endif
1552 
1553  if(M1 == NULL || M2 == NULL)
1554  {
1555#ifdef PDEBUG
1556       Print("\np1 = ");
1557       p_Write(p1, r);
1558
1559       Print("m1 = ");
1560       p_Write(m1, r);
1561
1562       Print("p2 = ");
1563       p_Write(p2, r);
1564
1565       Print("m2 = ");
1566       p_Write(m2, r);
1567
1568       Werror("ERROR in nc_CreateSpoly: result of multiplication is Zero!\n");
1569#endif
1570       return(NULL);
1571  }
1572
1573  number C1  = n_Copy(p_GetCoeff(M1,r),r);      // C1 = lc(M1)
1574  number C2  = n_Copy(p_GetCoeff(M2,r),r);      // C2 = lc(M2)
1575
1576  /* GCD stuff */
1577  number C = nGcd(C1, C2, r);                     // C = gcd(C1, C2)
1578
1579  if (!n_IsOne(C, r))                              // if C != 1
1580  {
1581    C1=n_Div(C1, C, r);                              // C1 = C1 / C
1582    C2=n_Div(C2, C, r);                              // C2 = C2 / C
1583  }
1584
1585  n_Delete(&C,r); // destroy the number C
1586
1587  C1=n_Neg(C1,r);
1588
1589//   number MinusOne=n_Init(-1,r);
1590//   if (n_Equal(C1,MinusOne,r))                   // lc(M1) / gcd( lc(M1), lc(M2)) == -1 ????
1591//   {
1592//     M2=p_Add_q(M1,M2,r);                        // ?????
1593//   }
1594//   else
1595//   {
1596  M1=p_Mult_nn(M1,C2,r);                           // M1 = (C2*lc(p1)) * (lcm(lm(p1),lm(p2)) / lm(p1)) * lm(p1)
1597
1598#ifdef PDEBUG
1599  p_Test(M1,r);
1600#endif
1601
1602  M2=p_Mult_nn(M2,C1,r);                           // M2 =(-C1*lc(p2)) * (lcm(lm(p1),lm(p2)) / lm(p2)) * lm(p2)
1603
1604
1605 
1606#ifdef PDEBUG
1607  p_Test(M2,r);
1608
1609#if MYTEST
1610  Print("M1: "); pWrite(M1);
1611  Print("M2: "); pWrite(M2);
1612#endif
1613#endif
1614
1615#endif
1616
1617  M2=p_Add_q(M1,M2,r);                             // M1 is killed, M2 = spoly(lt(p1), lt(p2)) = C2*M1 - C1*M2
1618
1619#ifdef PDEBUG
1620  p_Test(M2,r);
1621
1622#if MYTEST
1623  Print("M2: "); pWrite(M2);
1624#endif
1625
1626#endif
1627
1628// M2 == 0 for supercommutative algebras!
1629//   }
1630//   n_Delete(&MinusOne,r);
1631
1632  p_SetCoeff(m1,C2,r);                           // lc(m1) = C2!!!
1633  p_SetCoeff(m2,C1,r);                           // lc(m2) = C1!!!
1634
1635#ifdef PDEBUG
1636  p_Test(m1,r);
1637  p_Test(m2,r);
1638#endif
1639
1640//  poly tmp = p_Copy(p1,r);                         // tmp = p1
1641//  tmp=p_LmDeleteAndNext(tmp,r);                  // tmp = tail(p1)
1642//#ifdef PDEBUG
1643//  p_Test(tmp,r);
1644//#endif
1645 
1646  M1 = nc_mm_Mult_pp(m1, pNext(p1), r);                      // M1 = m1 * tail(p1), delete tmp // ???
1647
1648#ifdef PDEBUG
1649  p_Test(M1,r);
1650
1651#if MYTEST
1652  Print("M1: "); pWrite(M1);
1653#endif
1654
1655#endif
1656 
1657  M2=p_Add_q(M2,M1,r);                           // M2 = spoly(lt(p1), lt(p2)) + m1 * tail(p1), delete M1
1658#ifdef PDEBUG
1659  p_Test(M2,r);
1660
1661#if MYTEST
1662  Print("M2: "); pWrite(M2);
1663#endif
1664
1665#endif
1666
1667//  tmp=p_Copy(p2,r);                              // tmp = p2
1668//  tmp=p_LmDeleteAndNext(tmp,r);                  // tmp = tail(p2)
1669
1670//#ifdef PDEBUG
1671//  p_Test(tmp,r);
1672//#endif
1673
1674  M1 = nc_mm_Mult_pp(m2, pNext(p2), r);                      // M1 = m2 * tail(p2), detele tmp
1675 
1676#ifdef PDEBUG
1677  p_Test(M1,r);
1678
1679#if MYTEST
1680  Print("M1: "); pWrite(M1);
1681#endif
1682
1683#endif
1684
1685  M2 = p_Add_q(M2,M1,r);                           // M2 = spoly(lt(p1), lt(p2)) + m1 * tail(p1) + m2*tail(p2)
1686
1687#ifdef PDEBUG
1688  p_Test(M2,r);
1689
1690#if MYTEST
1691  Print("M2: "); pWrite(M2);
1692#endif
1693 
1694#endif
1695                                                 // delete M1
1696
1697  p_Delete(&m1,r);  //  => n_Delete(&C1,r);
1698  p_Delete(&m2,r);  //  => n_Delete(&C2,r);
1699
1700#ifdef PDEBUG
1701  p_Test(M2,r);
1702#endif
1703
1704  if (M2!=NULL) pCleardenom(M2); //?
1705//  if (M2!=NULL) pContent(M2);
1706
1707  return(M2);
1708}
1709
1710
1711
1712
1713#if 0
1714/*5
1715* reduction of tail(q) with p1
1716* lead(p1) divides lead(pNext(q2)) and pNext(q2) is reduced
1717* do not destroy p1, but tail(q)
1718*/
1719void gnc_ReduceSpolyTail(poly p1, poly q, poly q2, poly spNoether, const ring r)
1720{
1721  poly a1=p_Head(p1,r);
1722  poly Q=pNext(q2);
1723  number cQ=p_GetCoeff(Q,r);
1724  poly m=pOne();
1725  p_ExpVectorDiff(m,Q,p1,r);
1726  //  p_SetComp(m,0,r);
1727  //p_Setm(m,r);
1728#ifdef PDEBUG
1729  p_Test(m,r);
1730#endif
1731  /* pSetComp(m,r)=0? */
1732  poly M = nc_mm_Mult_pp(m, p1,r);
1733  number C=p_GetCoeff(M,r);
1734  M=p_Add_q(M,nc_mm_Mult_p(m,p_LmDeleteAndNext(p_Copy(p1,r),r),r),r); // _pp?
1735  q=p_Mult_nn(q,C,r);
1736  number MinusOne=n_Init(-1,r);
1737  if (!n_Equal(cQ,MinusOne,r))
1738  {
1739    cQ=nNeg(cQ);
1740    M=p_Mult_nn(M,cQ,r);
1741  }
1742  Q=p_Add_q(Q,M,r);
1743  pNext(q2)=Q;
1744
1745  p_Delete(&m,r);
1746  n_Delete(&C,r);
1747  n_Delete(&cQ,r);
1748  n_Delete(&MinusOne,r);
1749  /*  return(q); */
1750}
1751#endif
1752
1753
1754/*6
1755* creates the commutative lcm(lm(p1),lm(p2))
1756* do not destroy p1 and p2
1757*/
1758poly nc_CreateShortSpoly(poly p1, poly p2, const ring r)
1759{
1760#ifdef PDEBUG
1761  p_Test(p1, r);
1762  p_Test(p2, r);
1763#endif
1764
1765  const long lCompP1 = p_GetComp(p1,r);
1766  const long lCompP2 = p_GetComp(p2,r);
1767
1768  if ((lCompP1!=lCompP2) && (lCompP1!=0) && (lCompP2!=0))
1769  {
1770#ifdef PDEBUG
1771    Werror("nc_CreateShortSpoly: wrong module components!"); // !!!!
1772#endif
1773    return(NULL);
1774  }
1775 
1776  poly m = p_Lcm(p1, p2, si_max(lCompP1, lCompP2), r);
1777
1778//  n_Delete(&p_GetCoeff(m, r), r);
1779//  pSetCoeff0(m, NULL);
1780
1781#ifdef PDEBUG
1782//  p_Test(m,r);
1783#endif
1784 
1785  return(m);
1786}
1787
1788void gnc_kBucketPolyRedOld(kBucket_pt b, poly p, number *c)
1789{
1790  // b will not be multiplied by any constant in this impl.
1791  // ==> *c=1
1792  *c=nInit(1);
1793  poly m=pOne();
1794  pExpVectorDiff(m,kBucketGetLm(b),p);
1795  //pSetm(m);
1796#ifdef PDEBUG
1797  pTest(m);
1798#endif
1799  poly pp= nc_mm_Mult_pp(m,p,currRing);
1800  assume(pp!=NULL);
1801  pDelete(&m);
1802  number n=nCopy(pGetCoeff(pp));
1803  number MinusOne=nInit(-1);
1804  number nn;
1805  if (!nEqual(n,MinusOne))
1806  {
1807    nn=nNeg(nInvers(n));
1808  }
1809  else nn=nInit(1);
1810  nDelete(&n);
1811  n=nMult(nn,pGetCoeff(kBucketGetLm(b)));
1812  nDelete(&nn);
1813  pp=p_Mult_nn(pp,n,currRing);
1814  nDelete(&n);
1815  nDelete(&MinusOne);
1816  int l=pLength(pp);
1817  kBucket_Add_q(b,pp,&l);
1818}
1819
1820void gnc_kBucketPolyRedNew(kBucket_pt b, poly p, number *c)
1821{
1822#ifdef PDEBUG
1823//   Print(">*");
1824#endif
1825
1826#ifdef KDEBUG
1827  if( !kbTest(b) )Werror("nc_kBucketPolyRed: broken bucket!");
1828#endif
1829
1830#ifdef PDEBUG
1831  pTest(p);
1832#if MYTEST
1833  Print("p: "); pWrite(p);
1834#endif
1835#endif
1836
1837  // b will not be multiplied by any constant in this impl.
1838  // ==> *c=1
1839  *c=nInit(1);
1840  poly m = pOne();
1841  const poly pLmB = kBucketGetLm(b); // no new copy!
1842
1843  assume( pLmB != NULL );
1844 
1845#ifdef PDEBUG
1846  pTest(pLmB);
1847
1848#if MYTEST
1849  Print("pLmB: "); pWrite(pLmB);
1850#endif
1851#endif
1852
1853  pExpVectorDiff(m, pLmB, p);
1854  //pSetm(m);
1855
1856#ifdef PDEBUG
1857  pTest(m);
1858#if MYTEST
1859  Print("m: "); pWrite(m);
1860#endif
1861#endif
1862
1863  poly pp = nc_mm_Mult_pp(m, p, currRing);
1864  pDelete(&m);
1865
1866  assume( pp != NULL );
1867  const number n = pGetCoeff(pp); // bug!
1868  number nn;
1869
1870  if (!n_IsMOne(n,currRing) ) // does this improve performance??!? also see below... // TODO: check later on.
1871  {
1872    nn=nNeg(nInvers(nCopy(n)));
1873  }
1874  else nn=nInit(1);           // if n == -1 => nn = 1 and -1/n otherwise
1875
1876  number t = nMult(nn,pGetCoeff(pLmB));
1877  nDelete(&nn);
1878
1879  pp = p_Mult_nn(pp,t,currRing);
1880  nDelete(&t);
1881
1882  int l = pLength(pp);
1883
1884#ifdef PDEBUG
1885  pTest(pp);
1886//   Print("PP: "); pWrite(pp);
1887#endif
1888
1889  kBucket_Add_q(b,pp,&l);
1890
1891
1892#ifdef PDEBUG
1893//   Print("*>");
1894#endif
1895}
1896
1897
1898void gnc_kBucketPolyRed_ZOld(kBucket_pt b, poly p, number *c)
1899{
1900  // b is multiplied by a constant in this impl.
1901  poly m=pOne();
1902  pExpVectorDiff(m,kBucketGetLm(b),p);
1903  //pSetm(m);
1904#ifdef PDEBUG
1905  pTest(m);
1906#endif
1907  if(p_IsConstant(m,currRing)){
1908    pDelete(&m);
1909    *c = kBucketPolyRed(b,p,pLength(p),NULL);
1910    return;
1911  }
1912  poly pp = nc_mm_Mult_pp(m,p,currRing);
1913  number c2,cc;
1914  pCleardenom_n(pp,c2);
1915  pDelete(&m);
1916  *c = kBucketPolyRed(b,pp,pLength(pp),NULL);
1917  //cc=*c;
1918  //*c=nMult(*c,c2);
1919  nDelete(&c2);
1920  //nDelete(&cc);
1921  pDelete(&pp);
1922
1923}
1924
1925void gnc_kBucketPolyRed_ZNew(kBucket_pt b, poly p, number *c)
1926{
1927  // b is multiplied by a constant in this impl.
1928  poly m=pOne();
1929  pExpVectorDiff(m,kBucketGetLm(b),p);
1930  //pSetm(m);
1931#ifdef PDEBUG
1932  pTest(m);
1933#endif
1934
1935  if(p_IsConstant(m,currRing))
1936  {
1937    pDelete(&m);
1938    *c = kBucketPolyRed(b,p,pLength(p),NULL);
1939    return;
1940  }
1941  poly pp = nc_mm_Mult_pp(m,p,currRing);
1942  number c2,cc;
1943  pCleardenom_n(pp,c2);
1944  pDelete(&m);
1945  *c = kBucketPolyRed(b,pp,pLength(pp),NULL);
1946  //cc=*c;
1947  //*c=nMult(*c,c2);
1948  nDelete(&c2);
1949  //nDelete(&cc);
1950  pDelete(&pp);
1951
1952}
1953
1954
1955inline void nc_PolyPolyRedOld(poly &b, poly p, number *c)
1956  // reduces b with p, do not delete both
1957{
1958  // b will not by multiplied by any constant in this impl.
1959  // ==> *c=1
1960  *c=nInit(1);
1961  poly m=pOne();
1962  pExpVectorDiff(m,pHead(b),p);
1963  //pSetm(m);
1964#ifdef PDEBUG
1965  pTest(m);
1966#endif
1967  poly pp=nc_mm_Mult_pp(m,p,currRing);
1968  assume(pp!=NULL);
1969
1970  pDelete(&m);
1971  number n=nCopy(pGetCoeff(pp));
1972  number MinusOne=nInit(-1);
1973  number nn;
1974  if (!nEqual(n,MinusOne))
1975  {
1976    nn=nNeg(nInvers(n));
1977  }
1978  else nn=nInit(1);
1979  nDelete(&n);
1980  n=nMult(nn,pGetCoeff(b));
1981  nDelete(&nn);
1982  pp=p_Mult_nn(pp,n,currRing);
1983  nDelete(&n);
1984  nDelete(&MinusOne);
1985  b=p_Add_q(b,pp,currRing);
1986}
1987
1988
1989inline void nc_PolyPolyRedNew(poly &b, poly p, number *c)
1990  // reduces b with p, do not delete both
1991{
1992#ifdef PDEBUG
1993  pTest(b);
1994  pTest(p);
1995#endif
1996
1997#if MYTEST
1998  PrintS("nc_PolyPolyRedNew(");
1999  pWrite0(b);
2000  PrintS(", ");
2001  pWrite0(p);
2002  PrintS(", *c): ");
2003#endif
2004
2005  // b will not by multiplied by any constant in this impl.
2006  // ==> *c=1
2007  *c=nInit(1);
2008
2009  poly pp = NULL;
2010
2011  // there is a problem when p is a square(=>0!)
2012
2013  while((b != NULL) && (pp == NULL))
2014  {
2015
2016//    poly pLmB = pHead(b);
2017    poly m = pOne();
2018    pExpVectorDiff(m, b, p);
2019//    pDelete(&pLmB);
2020  //pSetm(m);
2021
2022#ifdef PDEBUG
2023    pTest(m);
2024    pTest(b);
2025#endif
2026
2027    pp = nc_mm_Mult_pp(m, p, currRing);
2028
2029#if MYTEST
2030    PrintS("\n{b': ");
2031    pWrite0(b);
2032    PrintS(", m: ");
2033    pWrite0(m);
2034    PrintS(", pp: ");
2035    pWrite0(pp);
2036    PrintS(" }\n");
2037#endif
2038
2039    pDelete(&m); // one m for all tries!
2040
2041//    assume( pp != NULL );
2042
2043    if( pp == NULL )
2044    {
2045      b = p_LmDeleteAndNext(b, currRing);
2046
2047      if( !p_DivisibleBy(p, b, currRing) )
2048        return;
2049
2050    }
2051  }
2052
2053#if MYTEST
2054  PrintS("{b': ");
2055  pWrite0(b);
2056  PrintS(", pp: ");
2057  pWrite0(pp);
2058  PrintS(" }\n");
2059#endif
2060
2061
2062  if(b == NULL) return;
2063
2064
2065  assume(pp != NULL);
2066
2067  const number n = pGetCoeff(pp); // no new copy
2068
2069  number nn;
2070
2071  if (!n_IsMOne(n, currRing)) // TODO: as above.
2072  {
2073    nn=nNeg(nInvers(nCopy(n)));
2074  }
2075  else nn=nInit(1);
2076
2077  number t = nMult(nn, pGetCoeff(b));
2078  nDelete(&nn);
2079
2080  pp=p_Mult_nn(pp, t, currRing);
2081  nDelete(&t);
2082
2083  b=p_Add_q(b,pp,currRing);
2084
2085}
2086
2087void nc_PolyPolyRed(poly &b, poly p, number *c)
2088{
2089#if 0
2090  nc_PolyPolyRedOld(b, p, c);
2091#else
2092  nc_PolyPolyRedNew(b, p, c);
2093#endif
2094}
2095
2096
2097poly nc_mm_Bracket_nn(poly m1, poly m2);
2098
2099poly nc_p_Bracket_qq(poly p, poly q)
2100  /* returns [p,q], destroys p */
2101{
2102 
2103  if (!rIsPluralRing(currRing)) return(NULL);
2104  if (pComparePolys(p,q)) return(NULL);
2105  /* Components !? */
2106  poly Q=NULL;
2107  number coef=NULL;
2108  poly res=NULL;
2109  poly pres=NULL;
2110  int UseBuckets=1;
2111  if ((pLength(p)< MIN_LENGTH_BUCKET/2) && (pLength(q)< MIN_LENGTH_BUCKET/2) || TEST_OPT_NOT_BUCKETS) UseBuckets=0;
2112  sBucket_pt bu_out;
2113  if (UseBuckets) bu_out=sBucketCreate(currRing);
2114  while (p!=NULL)
2115  {
2116    Q=q;
2117    while(Q!=NULL)
2118    {
2119      pres=nc_mm_Bracket_nn(p,Q); /* since no coeffs are taken into account there */
2120      if (pres!=NULL)
2121      {
2122        coef = nMult(pGetCoeff(p),pGetCoeff(Q));
2123        pres = p_Mult_nn(pres,coef,currRing);
2124    if (UseBuckets) sBucket_Add_p(bu_out,pres,pLength(pres));
2125    else res=p_Add_q(res,pres,currRing);
2126        nDelete(&coef);
2127      }
2128      pIter(Q);
2129    }
2130    p=pLmDeleteAndNext(p);
2131  }
2132  if (UseBuckets)
2133  {
2134    res = NULL;
2135    int len = pLength(res);
2136    sBucketDestroyAdd(bu_out, &res, &len);
2137  }
2138  return(res);
2139}
2140
2141poly nc_mm_Bracket_nn(poly m1, poly m2)
2142  /*returns [m1,m2] for two monoms, destroys nothing */
2143  /* without coeffs */
2144{
2145  if (pLmIsConstant(m1) || pLmIsConstant(m1)) return(NULL);
2146  if (pLmCmp(m1,m2)==0) return(NULL);
2147  int rN=currRing->N;
2148  int *M1=(int *)omAlloc0((rN+1)*sizeof(int));
2149  int *M2=(int *)omAlloc0((rN+1)*sizeof(int));
2150  int *PREFIX=(int *)omAlloc0((rN+1)*sizeof(int));
2151  int *SUFFIX=(int *)omAlloc0((rN+1)*sizeof(int));
2152  pGetExpV(m1,M1);
2153  pGetExpV(m2,M2);
2154  poly res=NULL;
2155  poly ares=NULL;
2156  poly bres=NULL;
2157  poly prefix=NULL;
2158  poly suffix=NULL;
2159  int nMin,nMax;
2160  number nTmp=NULL;
2161  int i,j,k;
2162  for (i=1;i<=rN;i++)
2163  {
2164    if (M2[i]!=0)
2165    {
2166      ares=NULL;
2167      for (j=1;j<=rN;j++)
2168      {
2169        if (M1[j]!=0)
2170        {
2171          bres=NULL;
2172          /* compute [ x_j^M1[j],x_i^M2[i] ] */
2173          if (i<j) {nMax=j;  nMin=i;} else {nMax=i;  nMin=j;}
2174          if ( (i==j) || ((MATELEM(currRing->GetNC()->COM,nMin,nMax)!=NULL) && nIsOne(pGetCoeff(MATELEM(currRing->GetNC()->C,nMin,nMax))) )) /* not (the same exp. or commuting exps)*/
2175          { bres=NULL; }
2176          else
2177          {
2178            if (i<j) { bres=gnc_uu_Mult_ww(j,M1[j],i,M2[i],currRing); }
2179            else bres=gnc_uu_Mult_ww(i,M2[i],j,M1[j],currRing);
2180            if (nIsOne(pGetCoeff(bres)))
2181            {
2182              bres=pLmDeleteAndNext(bres);
2183            }
2184            else
2185            {
2186              nTmp=nSub(pGetCoeff(bres),nInit(1));
2187              pSetCoeff(bres,nTmp); /* only lc ! */
2188            }
2189#ifdef PDEBUG
2190            pTest(bres);
2191#endif
2192            if (i>j)  bres=p_Neg(bres, currRing);
2193          }
2194          if (bres!=NULL)
2195          {
2196            /* now mult (prefix, bres, suffix) */
2197            memcpy(SUFFIX, M1,(rN+1)*sizeof(int));
2198            memcpy(PREFIX, M1,(rN+1)*sizeof(int));
2199            for (k=1;k<=j;k++) SUFFIX[k]=0;
2200            for (k=j;k<=rN;k++) PREFIX[k]=0;
2201            SUFFIX[0]=0;
2202            PREFIX[0]=0;
2203            prefix=pOne();
2204            suffix=pOne();
2205            pSetExpV(prefix,PREFIX);
2206            pSetm(prefix);
2207            pSetExpV(suffix,SUFFIX);
2208            pSetm(suffix);
2209            if (!pLmIsConstant(prefix)) bres = gnc_mm_Mult_p(prefix, bres,currRing);
2210            if (!pLmIsConstant(suffix)) bres = gnc_p_Mult_mm(bres, suffix,currRing);
2211            ares=p_Add_q(ares, bres,currRing);
2212            /* What to give free? */
2213        /* Do we have to free PREFIX/SUFFIX? it seems so */
2214            pDelete(&prefix);
2215            pDelete(&suffix);
2216          }
2217        }
2218      }
2219      if (ares!=NULL)
2220      {
2221        /* now mult (prefix, bres, suffix) */
2222        memcpy(SUFFIX, M2,(rN+1)*sizeof(int));
2223        memcpy(PREFIX, M2,(rN+1)*sizeof(int));
2224        for (k=1;k<=i;k++) SUFFIX[k]=0;
2225        for (k=i;k<=rN;k++) PREFIX[k]=0;
2226        SUFFIX[0]=0;
2227        PREFIX[0]=0;
2228        prefix=pOne();
2229        suffix=pOne();
2230        pSetExpV(prefix,PREFIX);
2231        pSetm(prefix);
2232        pSetExpV(suffix,SUFFIX);
2233        pSetm(suffix);
2234        bres=ares;
2235        if (!pLmIsConstant(prefix)) bres = gnc_mm_Mult_p(prefix, bres,currRing);
2236        if (!pLmIsConstant(suffix)) bres = gnc_p_Mult_mm(bres, suffix,currRing);
2237        res=p_Add_q(res, bres,currRing);
2238        pDelete(&prefix);
2239        pDelete(&suffix);
2240      }
2241    }
2242  }
2243  freeT(M1, rN);
2244  freeT(M2, rN);
2245  freeT(PREFIX, rN);
2246  freeT(SUFFIX, rN);
2247  pTest(res);
2248  return(res);
2249}
2250
2251ideal twostd(ideal I) // works in currRing only!
2252{
2253  ideal J = kStd(I, currQuotient, testHomog, NULL, NULL, 0, 0, NULL); // in currRing!!!
2254  idSkipZeroes(J); // ring independent!
2255
2256  const int rN = currRing->N;
2257
2258  loop
2259  {
2260    ideal     K    = NULL;
2261    const int s    = idElem(J); // ring independent
2262
2263    for(int i = 0; i < s; i++)
2264    {
2265      const poly p = J->m[i];
2266
2267#ifdef PDEBUG
2268      p_Test(p, currRing);
2269#if 0
2270      Print("p: "); // !
2271      p_Write(p, currRing);
2272#endif
2273#endif
2274
2275      for (int j = 1; j <= rN; j++) // for all j = 1..N
2276      {
2277        poly varj = p_ISet(1, currRing);
2278        p_SetExp(varj, j, 1, currRing); 
2279        p_Setm(varj, currRing);
2280
2281        poly q = pp_Mult_mm(p, varj, currRing); // q = J[i] * var(j),
2282
2283#ifdef PDEBUG
2284        p_Test(varj, currRing);
2285        p_Test(p, currRing);
2286        p_Test(q, currRing);
2287#if 0
2288        Print("Reducing p: "); // !
2289        p_Write(p, currRing);
2290        Print("With q: "); // !
2291        p_Write(q, currRing);
2292#endif
2293#endif
2294
2295        p_Delete(&varj, currRing);
2296
2297        if (q != NULL)
2298        {
2299#ifdef PDEBUG         
2300#if 0
2301          Print("Reducing q[j = %d]: ", j); // !
2302          p_Write(q, currRing);
2303
2304          Print("With p:");
2305          p_Write(p, currRing);
2306
2307#endif
2308#endif
2309
2310          // bug: lm(p) may not divide lm(p * var(i)) in a SCA!
2311          if( p_LmDivisibleBy(p, q, currRing) )
2312            q = nc_ReduceSpoly(p, q, currRing);
2313
2314
2315#ifdef PDEBUG
2316          p_Test(q, currRing);
2317#if 0
2318          Print("reductum q/p: ");
2319          p_Write(q, currRing);
2320
2321          // Print("With J!\n");
2322#endif
2323#endif
2324         
2325//          if( q != NULL)
2326          q = kNF(J, currQuotient, q, 0, KSTD_NF_NONORM); // in currRing!!!
2327
2328#ifdef PDEBUG
2329          p_Test(q, currRing);
2330#if 0
2331          Print("NF(J/currQuotient)=> q: "); // !
2332          p_Write(q, currRing);
2333#endif
2334#endif
2335          if (q!=NULL)
2336          {
2337            if (p_IsConstant(q, currRing)) // => return (1)!
2338            {
2339              p_Delete(&q, currRing);
2340              id_Delete(&J, currRing);
2341
2342              if (K != NULL)
2343                id_Delete(&K, currRing);
2344
2345              ideal Q = idInit(1,1); // ring independent!
2346              Q->m[0] = p_ISet(1,currRing);
2347
2348              return(Q);
2349            }
2350
2351//            flag = false;
2352
2353            // K += q:
2354
2355            ideal Q = idInit(1,1); // ring independent
2356            Q->m[0]=q;
2357
2358            if( K == NULL )
2359              K = Q;
2360            else
2361            {
2362              ideal id_tmp = idSimpleAdd(K, Q); // in currRing
2363              id_Delete(&K, currRing);
2364              id_Delete(&Q, currRing);
2365              K = id_tmp; // K += Q
2366            }
2367          }
2368
2369
2370        } // if q != NULL
2371      } // for all variables
2372
2373    }
2374   
2375    if (K == NULL) // nothing new: i.e. all elements are two-sided
2376      return(J);
2377    /* now we update GrBasis J with K */
2378    //    iSize=IDELEMS(J);
2379#ifdef PDEBUG
2380    idTest(J); // in currRing!
2381#if 0
2382    Print("J:");
2383    idPrint(J);
2384    PrintLn();
2385#endif // debug
2386#endif
2387
2388
2389
2390#ifdef PDEBUG
2391    idTest(K); // in currRing!
2392#if 0
2393    Print("+K:");
2394    idPrint(K);
2395    PrintLn();
2396#endif // debug
2397#endif
2398
2399
2400    int iSize = idElem(J); // ring independent
2401
2402    // J += K:   
2403    ideal id_tmp = idSimpleAdd(J,K); // in currRing
2404    id_Delete(&K, currRing); id_Delete(&J, currRing);
2405
2406#if 1
2407    BITSET save_test=test;
2408    test|=Sy_bit(OPT_SB_1); // ring independent
2409    J = kStd(id_tmp, currQuotient, testHomog, NULL, NULL, 0, iSize); // J = J + K, J - std // in currRing!
2410    test = save_test;
2411#else
2412    J=kStd(id_tmp, currQuotient,testHomog,NULL,NULL,0,0,NULL);
2413#endif
2414
2415    id_Delete(&id_tmp, currRing);
2416    idSkipZeroes(J); // ring independent
2417
2418#ifdef PDEBUG
2419    idTest(J); // in currRing!
2420#if 0
2421    Print("J:");
2422    idPrint(J);
2423    PrintLn();
2424#endif // debug
2425#endif
2426  } // loop
2427}
2428
2429
2430matrix nc_PrintMat(int a, int b, ring r, int metric)
2431  /* returns matrix with the info on noncomm multiplication */
2432{
2433
2434  if ( (a==b) || !rIsPluralRing(r) ) return(NULL);
2435  int i;
2436  int j;
2437  if (a>b) {j=b; i=a;}
2438  else {j=a; i=b;}
2439  /* i<j */
2440  int rN=r->N;
2441  int size=r->GetNC()->MTsize[UPMATELEM(i,j,rN)];
2442  matrix M = r->GetNC()->MT[UPMATELEM(i,j,rN)];
2443  /*  return(M); */
2444  int sizeofres;
2445  if (metric==0)
2446  {
2447    sizeofres=sizeof(int);
2448  }
2449  if (metric==1)
2450  {
2451    sizeofres=sizeof(number);
2452  }
2453  matrix res=mpNew(size,size);
2454  int s;
2455  int t;
2456  int length;
2457  long totdeg;
2458  poly p;
2459  for(s=1;s<=size;s++)
2460  {
2461    for(t=1;t<=size;t++)
2462    {
2463      p=MATELEM(M,s,t);
2464      if (p==NULL)
2465      {
2466        MATELEM(res,s,t)=0;
2467      }
2468      else
2469      {
2470        length = pLength(p);
2471        if (metric==0) /* length */
2472        {
2473          MATELEM(res,s,t)= p_ISet(length,r);
2474        }
2475        else if (metric==1) /* sum of deg divided by the length */
2476        {
2477          totdeg=0;
2478          while (p!=NULL)
2479          {
2480            totdeg=totdeg+pDeg(p,r);
2481            pIter(p);
2482          }
2483          number ntd = nInit(totdeg);
2484          number nln = nInit(length);
2485          number nres=nDiv(ntd,nln);
2486          nDelete(&ntd);
2487          nDelete(&nln);
2488          MATELEM(res,s,t)=p_NSet(nres,r);
2489        }
2490      }
2491    }
2492  }
2493  return(res);
2494}
2495
2496void ncKill(ring r) 
2497// kills the nc extension of ring r
2498{
2499  if (r->GetNC()->ref >= 1) /* in use by somebody else */
2500  {
2501    r->GetNC()->ref--;
2502    r->GetNC() = NULL; // don't cleanup, just dereference
2503    return;
2504  }
2505  /* otherwise kill the previous nc data */
2506
2507  assume( r->GetNC()->ref == 0 );
2508
2509  int i,j;
2510  int rN=r->N;
2511  if ( rN > 1 )
2512  {
2513    for(i=1;i<rN;i++)
2514    {
2515      for(j=i+1;j<=rN;j++)
2516      {
2517        id_Delete((ideal *)&(r->GetNC()->MT[UPMATELEM(i,j,rN)]),r->GetNC()->basering);
2518      }
2519    }
2520    omFreeSize((ADDRESS)r->GetNC()->MT,rN*(rN-1)/2*sizeof(matrix));
2521    omFreeSize((ADDRESS)r->GetNC()->MTsize,rN*(rN-1)/2*sizeof(int));
2522    id_Delete((ideal *)&(r->GetNC()->COM),r->GetNC()->basering);
2523  }
2524  id_Delete((ideal *)&(r->GetNC()->C),r->GetNC()->basering);
2525  id_Delete((ideal *)&(r->GetNC()->D),r->GetNC()->basering);
2526
2527  if( rIsSCA(r) && (r->GetNC()->SCAQuotient() != NULL) )
2528  {
2529    id_Delete(&r->GetNC()->SCAQuotient(), r->GetNC()->basering);
2530  }
2531
2532  r->GetNC()->basering->ref--;
2533
2534  if ((r->GetNC()->basering->ref<=0)&&(r->GetNC()->basering->GetNC()==NULL))
2535  {
2536    rKill(r->GetNC()->basering);
2537  }
2538
2539  ncCleanUp(r);
2540}
2541
2542inline void ncCleanUp(nc_struct* p)
2543{
2544  assume(p != NULL);
2545  omFreeSize((ADDRESS)p,sizeof(nc_struct));
2546}
2547
2548inline void ncCleanUp(ring r)
2549{
2550  /* small CleanUp of r->GetNC() */
2551  assume(r != NULL);
2552  ncCleanUp(r->GetNC());
2553  r->GetNC() = NULL;
2554}
2555
2556// inline
2557void nc_rCopy0(ring res, const ring r)
2558{
2559  assume(rIsPluralRing(r));
2560  assume( res != r );
2561
2562  res->GetNC() = r->GetNC();
2563  res->GetNC()->ref++;
2564  nc_p_ProcsSet(res, res->p_Procs); 
2565}
2566
2567
2568
2569poly nc_p_CopyGet(poly a, const ring r)
2570/* for use in getting the mult. matrix elements*/
2571/* ring r must be a currRing! */
2572/* for consistency, copies a poly from the comm. r->GetNC()->basering */
2573/* to its image in NC ring */
2574{
2575  if (r != currRing)
2576  {
2577#ifdef PDEBUF
2578    Werror("nc_p_CopyGet call not in currRing");
2579#endif
2580    return(NULL);
2581  }
2582  if (!rIsPluralRing(r)) return(p_Copy(a,r));
2583  if (r==r->GetNC()->basering) return(p_Copy(a,r));
2584  else
2585  {
2586    return(prCopyR_NoSort(a,r->GetNC()->basering,r));
2587  }
2588}
2589
2590poly nc_p_CopyPut(poly a, const ring r)
2591/* for use in defining the mult. matrix elements*/
2592/* ring r must be a currRing! */
2593/* for consistency, puts a polynomial from the NC ring */
2594/* to its presentation in the comm. r->GetNC()->basering */
2595{
2596  if (r != currRing)
2597  {
2598#ifdef PDEBUF
2599    Werror("nc_p_CopyGet call not in currRing");
2600#endif
2601    return(NULL);
2602  }
2603
2604  if (!rIsPluralRing(r)) return(p_Copy(a,r));
2605  if (r==r->GetNC()->basering) return(p_Copy(a,r));
2606  else
2607  {
2608    return(prCopyR_NoSort(a,r,r->GetNC()->basering));
2609  }
2610}
2611
2612BOOLEAN nc_CheckSubalgebra(poly PolyVar, ring r)
2613  /* returns TRUE if there were errors */
2614  /* checks whether product of vars from PolyVar defines */
2615  /* an admissible subalgebra of r */
2616  /* r is indeed currRing and assumed to be noncomm. */
2617{
2618  ring save = currRing;
2619  int WeChangeRing = 0;
2620  if (currRing != r)
2621  {
2622    rChangeCurrRing(r);
2623    WeChangeRing = 1;
2624  }
2625  int rN=r->N;
2626  int *ExpVar=(int*)omAlloc0((rN+1)*sizeof(int));
2627  int *ExpTmp=(int*)omAlloc0((rN+1)*sizeof(int));
2628  p_GetExpV(PolyVar, ExpVar, r);
2629  int i; int j; int k;
2630  poly test=NULL;
2631  int OK=1;
2632  for (i=1; i<rN; i++)
2633  {
2634    if (ExpVar[i]==0) /* i.e. not in PolyVar */
2635    {
2636      for (j=i+1; j<=rN; j++)
2637      {
2638    if (ExpVar[j]==0)
2639    {
2640      test = nc_p_CopyGet(MATELEM(r->GetNC()->D,i,j),r);
2641      while (test!=NULL)
2642      {
2643            p_GetExpV(test, ExpTmp, r);
2644        OK=1;
2645        for (k=1;k<=rN;k++)
2646            {
2647          if (ExpTmp[k]!=0)
2648          {
2649        if (ExpVar[k]!=0) OK=0;
2650          }
2651            }
2652        if (!OK) return(TRUE);
2653        pIter(test);
2654          }
2655    }
2656      }
2657    }
2658  }
2659  p_Delete(&test,r);
2660  freeT(ExpVar,rN);
2661  freeT(ExpTmp,rN);
2662  if ( WeChangeRing )
2663    rChangeCurrRing(save);
2664  return(FALSE);
2665}
2666
2667
2668BOOLEAN gnc_CheckOrdCondition(matrix D, ring r)
2669/* returns TRUE if there were errors */
2670/* checks whether the current ordering */
2671/* is admissible for r and D == r->GetNC()->D */
2672/* to be executed in a currRing */
2673{
2674  /* analyze D: an upper triangular matrix of polys */
2675  /* check the ordering condition for D */
2676  ring save = currRing;
2677  int WeChangeRing = 0;
2678  if (r != currRing)
2679  {
2680    rChangeCurrRing(r);
2681    WeChangeRing = 1;
2682  }
2683  poly p,q;
2684  int i,j;
2685  int report = 0;
2686  for(i=1; i<r->N; i++)
2687  {
2688    for(j=i+1; j<=r->N; j++)
2689    {
2690      p = nc_p_CopyGet(MATELEM(D,i,j),r);
2691      if ( p != NULL)
2692      {
2693    q = p_ISet(1,r); // replaces pOne();
2694    p_SetExp(q,i,1,r);
2695    p_SetExp(q,j,1,r);
2696    p_Setm(q,r);
2697    if (p_LmCmp(q,p,r) != 1) /* i.e. lm(p)==xy < lm(q)==D_ij  */
2698    {
2699      Werror("Bad ordering at %d,%d\n",i,j);
2700#ifdef PDEBUG
2701      p_Write(p,r);
2702      p_Write(q,r);
2703#endif
2704      report = 1;
2705    }
2706    p_Delete(&q,r);
2707    p_Delete(&p,r);
2708    p = NULL;
2709      }
2710    }
2711  }
2712  if ( WeChangeRing )
2713    rChangeCurrRing(save);
2714  return(report);
2715}
2716
2717
2718
2719BOOLEAN nc_CallPlural(
2720                      matrix CCC, matrix DDD,
2721                      poly CCN, poly DDN,
2722                      ring r, 
2723                      bool bSetupQuotient, bool bCopyInput, bool bBeQuiet,
2724                      ring curr)
2725  /* returns TRUE if there were errors */
2726  /* analyze inputs, check them for consistency */
2727  /* detects nc_type, DO NOT initialize multiplication but call for it at the end*/
2728  /* checks the ordering condition and evtl. NDC */
2729// NOTE: all the data belong to the curr,
2730// we change r which may be the same ring, and must have the same representation!
2731{
2732//  assume( curr != r );
2733  assume( rSamePolyRep(r, curr) );
2734
2735
2736  if( r->N == 1 ) // clearly commutative!!!
2737  {
2738    assume(
2739           ( (CCC != NULL) && (MATCOLS(CCC) == 1) && (MATROWS(CCC) == 1) && (MATELEM(CCC,1,1) == NULL) ) ||
2740           ( (CCN == NULL) )
2741          );
2742   
2743    assume(
2744           ( (DDD != NULL) && (MATCOLS(DDD) == 1) && (MATROWS(DDD) == 1) && (MATELEM(DDD,1,1) == NULL) ) ||
2745           ( (DDN == NULL) )
2746          );
2747           
2748
2749  }
2750
2751 
2752  // there must be:
2753  assume( (CCC != NULL) != (CCN != NULL) ); // exactly one data about coeffs (C).
2754  assume( !((DDD != NULL) && (DDN != NULL)) ); // at most one data about tails (D).
2755 
2756  ring save = currRing;
2757
2758  if( save != curr )
2759    rChangeCurrRing(curr);
2760
2761#if OUTPUT
2762  if( CCC != NULL )
2763  {
2764    PrintS("nc_CallPlural(), Input data, CCC: \n");   
2765    iiWriteMatrix(CCC, "C", 2, 4);
2766  }
2767  if( DDD != NULL )
2768  {
2769    PrintS("nc_CallPlural(), Input data, DDD: \n"); 
2770    iiWriteMatrix(DDD, "D", 2, 4);
2771  }
2772#endif
2773
2774 
2775#ifndef NDEBUG
2776  idTest((ideal)CCC);
2777  idTest((ideal)DDD);
2778  pTest(CCN);
2779  pTest(DDN);
2780#endif
2781
2782  if( (!bBeQuiet) && (r->GetNC() != NULL) )
2783    WarnS("going to redefine the algebra structure");
2784 
2785  if( currRing != r )
2786    rChangeCurrRing(r);
2787
2788#ifndef NDEBUG
2789  idTest((ideal)CCC);
2790  idTest((ideal)DDD);
2791  pTest(CCN);
2792  pTest(DDN);
2793#endif
2794
2795  matrix CC = NULL;
2796  poly CN = NULL;
2797  matrix C; bool bCnew = false;
2798
2799  matrix DD = NULL;
2800  poly DN = NULL;
2801  matrix D; bool bDnew = false;
2802
2803  number nN, pN, qN;
2804
2805  bool IsSkewConstant = false, tmpIsSkewConstant;
2806  int i, j;
2807
2808  nc_type nctype = nc_undef;
2809 
2810  //////////////////////////////////////////////////////////////////
2811  // check the correctness of arguments, without any real chagnes!!!
2812
2813 
2814
2815  // check C
2816  if ((CCC != NULL) && ( (MATCOLS(CCC)==1) || MATROWS(CCC)==1 ) )
2817  {
2818    CN = MATELEM(CCC,1,1);
2819  }
2820  else
2821  {
2822    if ((CCC != NULL) && ( (MATCOLS(CCC)!=r->N) || (MATROWS(CCC)!=r->N) ))
2823    {
2824      Werror("Square %d x %d  matrix expected", r->N, r->N);
2825
2826      if( currRing != save )
2827        rChangeCurrRing(save);
2828      return TRUE;
2829    }
2830  }
2831  if (( CCC != NULL) && (CC == NULL)) CC = CCC; // mpCopy(CCC); // bug!?
2832  if (( CCN != NULL) && (CN == NULL)) CN = CCN;
2833
2834  // check D
2835  if ((DDD != NULL) && ( (MATCOLS(DDD)==1) || MATROWS(DDD)==1 ) )
2836  {
2837    DN = MATELEM(DDD,1,1);
2838  }
2839  else
2840  {
2841    if ((DDD != NULL) && ( (MATCOLS(DDD)!=r->N) || (MATROWS(DDD)!=r->N) ))
2842    {
2843      Werror("Square %d x %d  matrix expected",r->N,r->N);
2844
2845      if( currRing != save )
2846        rChangeCurrRing(save);
2847      return TRUE;
2848    }
2849  }
2850
2851  if (( DDD != NULL) && (DD == NULL)) DD = DDD; // mpCopy(DDD); // ???
2852  if (( DDN != NULL) && (DN == NULL)) DN = DDN;
2853
2854  // further checks and some analysis:
2855  // all data in 'curr'!
2856  if (CN != NULL)       /* create matrix C = CN * Id */
2857  {
2858    nN = p_GetCoeff(CN, curr);
2859    if (n_IsZero(nN, curr))
2860    {
2861      Werror("Incorrect input : zero coefficients are not allowed");
2862
2863      if( currRing != save )
2864        rChangeCurrRing(save);
2865      return TRUE;
2866    }
2867
2868    if (n_IsOne(nN, curr))
2869      nctype = nc_lie;
2870    else
2871      nctype = nc_general;
2872
2873    IsSkewConstant = true;
2874
2875    C = mpNew(r->N,r->N); // ring independent!
2876    bCnew = true;
2877
2878    for(i=1; i<r->N; i++)
2879      for(j=i+1; j<=r->N; j++)
2880        MATELEM(C,i,j) = prCopyR_NoSort(CN, curr, r); // nc_p_CopyPut(CN, r); // copy CN from curr into r
2881  } else
2882  if ( (CN == NULL) && (CC != NULL) ) /* copy matrix C */
2883  {
2884    /* analyze C */
2885
2886    pN = NULL; /* check the consistency later */
2887
2888    if( r->N > 1 )
2889      if ( MATELEM(CC,1,2) != NULL )
2890        pN = p_GetCoeff(MATELEM(CC,1,2), curr);
2891
2892    tmpIsSkewConstant = true;
2893
2894    for(i=1; i<r->N; i++)
2895      for(j=i+1; j<=r->N; j++)
2896      {
2897        if (MATELEM(CC,i,j) == NULL)
2898          qN = NULL;
2899        else
2900          qN = p_GetCoeff(MATELEM(CC,i,j),curr);
2901
2902        if ( qN == NULL )   /* check the consistency: Cij!=0 */
2903        // find also illegal pN
2904        {
2905          Werror("Incorrect input : matrix of coefficients contains zeros in the upper triangle");
2906
2907        if( currRing != save )
2908            rChangeCurrRing(save);
2909          return TRUE;
2910        }
2911
2912        if (!n_Equal(pN, qN, curr)) tmpIsSkewConstant = false;
2913      }
2914
2915    if( bCopyInput )
2916    {
2917      C = mpCopy(CC, curr, r); // Copy C into r!!!???
2918      bCnew = true;
2919    }
2920    else
2921      C = CC;
2922
2923    IsSkewConstant = tmpIsSkewConstant;
2924
2925    if ( tmpIsSkewConstant && n_IsOne(pN, curr) )
2926      nctype = nc_lie;
2927    else
2928      nctype = nc_general;
2929  }
2930
2931  /* initialition of the matrix D */
2932  if ( DD == NULL ) /* we treat DN only (it could also be NULL) */
2933  {
2934    D = mpNew(r->N,r->N); bDnew = true;
2935
2936    if (DN  == NULL)
2937    {
2938      if ( (nctype == nc_lie) || (nctype == nc_undef) )
2939        nctype = nc_comm; /* it was nc_skew earlier */
2940      else /* nc_general, nc_skew */
2941        nctype = nc_skew;
2942    }
2943    else /* DN  != NULL */
2944      for(i=1; i<r->N; i++)
2945        for(j=i+1; j<=r->N; j++)
2946          MATELEM(D,i,j) = prCopyR_NoSort(DN, curr, r); // project DN into r->GetNC()->basering!
2947  }
2948  else /* DD != NULL */
2949  {
2950    bool b = true; // DD == null ?
2951   
2952    for(int i = 1; (i < r->N) && b; i++)
2953    for(int j = i+1; (j <= r->N) && b; j++)
2954      if (MATELEM(DD, i, j) != NULL)
2955      {
2956        b = false;
2957        break;
2958      }
2959
2960    if (b) // D == NULL!!!
2961    {
2962      if ( (nctype == nc_lie) || (nctype == nc_undef) )
2963        nctype = nc_comm; /* it was nc_skew earlier */
2964      else /* nc_general, nc_skew */
2965        nctype = nc_skew;
2966    }
2967   
2968    if( bCopyInput )
2969    {
2970      D = mpCopy(DD, curr, r); // Copy DD into r!!!
2971      bDnew = true;
2972    }
2973    else
2974      D = DD;
2975
2976  }
2977
2978  assume( C != NULL );
2979  assume( D != NULL );
2980 
2981#if OUTPUT
2982  PrintS("nc_CallPlural(), Computed data, C: \n");
2983  iiWriteMatrix(C, "C", 2, 4);
2984
2985  PrintS("nc_CallPlural(), Computed data, D: \n");
2986  iiWriteMatrix(D, "D", 2, 4);
2987
2988  Print("\nTemporary: type = %d, IsSkewConstant = %d\n", nctype, IsSkewConstant);
2989#endif
2990
2991
2992
2993 
2994  // check the ordering condition for D (both matrix and poly cases):
2995  if ( gnc_CheckOrdCondition(D, r) )
2996  {
2997    if( bCnew ) mpDelete( &C, r );
2998    if( bDnew ) mpDelete( &D, r );
2999
3000    Werror("Matrix of polynomials violates the ordering condition");
3001
3002    if( currRing != save )
3003      rChangeCurrRing(save);
3004    return TRUE;
3005  }
3006
3007  // okay now we are ready for this!!!
3008
3009  // create new non-commutative structure
3010  nc_struct *nc_new = (nc_struct *)omAlloc0(sizeof(nc_struct));
3011
3012  ncRingType(nc_new) = nctype;
3013
3014  nc_new->C = C; // if C and D were given by matrices at the beginning they are in r
3015  nc_new->D = D; // otherwise they should be in r->GetNC()->basering(polynomial * Id_{N})
3016
3017  nc_new->IsSkewConstant = (IsSkewConstant?1:0);
3018
3019  nc_new->ref = 1;
3020  nc_new->basering = r; // !?
3021
3022  // Setup new NC structure!!!
3023  if (r->GetNC() != NULL)
3024    ncKill(r);
3025
3026  r->ref++; // ?
3027  r->GetNC() = nc_new;
3028
3029  if( currRing != save )
3030    rChangeCurrRing(save);
3031
3032  return gnc_InitMultiplication(r, bSetupQuotient);
3033}
3034
3035//////////////////////////////////////////////////////////////////////////////
3036BOOLEAN gnc_InitMultiplication(ring r, bool bSetupQuotient)
3037{
3038  /* returns TRUE if there were errors */
3039  /* initialize the multiplication: */
3040  /*  r->GetNC()->MTsize, r->GetNC()->MT, r->GetNC()->COM, */
3041  /* and r->GetNC()->IsSkewConstant for the skew case */
3042  if (rVar(r)==1)
3043  {
3044    ncRingType(r, nc_comm);
3045    r->GetNC()->IsSkewConstant=1;
3046    return FALSE;
3047  }
3048
3049  ring save = currRing;
3050
3051  int WeChangeRing = 0;
3052  if (currRing!=r)
3053  {
3054    rChangeCurrRing(r);
3055    WeChangeRing = 1;
3056  }
3057  assume( (currRing == r->GetNC()->basering)
3058       || ((currRing->GetNC()!=NULL) && (currRing->GetNC()->basering==r->GetNC()->basering)) );   // otherwise we cannot work with all these matrices!
3059
3060  int i,j;
3061  r->GetNC()->MT = (matrix *)omAlloc0((r->N*(r->N-1))/2*sizeof(matrix));
3062  r->GetNC()->MTsize = (int *)omAlloc0((r->N*(r->N-1))/2*sizeof(int));
3063  idTest(((ideal)r->GetNC()->C));
3064  matrix COM = mpCopy(r->GetNC()->C);
3065  poly p,q;
3066  short DefMTsize=7;
3067  int IsNonComm=0;
3068  int tmpIsSkewConstant;
3069
3070  for(i=1; i<r->N; i++)
3071  {
3072    for(j=i+1; j<=r->N; j++)
3073    {
3074      if ( MATELEM(r->GetNC()->D,i,j) == NULL ) /* quasicommutative case */
3075      {
3076        /* 1x1 mult.matrix */
3077        r->GetNC()->MTsize[UPMATELEM(i,j,r->N)] = 1;
3078        r->GetNC()->MT[UPMATELEM(i,j,r->N)] = mpNew(1,1);
3079      }
3080      else /* pure noncommutative case */
3081      {
3082        /* TODO check the special multiplication properties */
3083        IsNonComm = 1;
3084        p_Delete(&(MATELEM(COM,i,j)),r);
3085        //MATELEM(COM,i,j) = NULL; // done by p_Delete
3086        r->GetNC()->MTsize[UPMATELEM(i,j,r->N)] = DefMTsize; /* default sizes */
3087        r->GetNC()->MT[UPMATELEM(i,j,r->N)] = mpNew(DefMTsize, DefMTsize);
3088      }
3089      /* set MT[i,j,1,1] to c_i_j*x_i*x_j + D_i_j */
3090      p = p_ISet(1,r); /* instead of     p = pOne(); */
3091      if (MATELEM(r->GetNC()->C,i,j)!=NULL)
3092        p_SetCoeff(p,n_Copy(pGetCoeff(MATELEM(r->GetNC()->C,i,j)),r),r);
3093      p_SetExp(p,i,1,r);
3094      p_SetExp(p,j,1,r);
3095      p_Setm(p,r);
3096      p_Test(MATELEM(r->GetNC()->D,i,j),r->GetNC()->basering);
3097      q =  nc_p_CopyGet(MATELEM(r->GetNC()->D,i,j),r);
3098      p = p_Add_q(p,q,r);
3099      MATELEM(r->GetNC()->MT[UPMATELEM(i,j,r->N)],1,1) = nc_p_CopyPut(p,r);
3100      p_Delete(&p,r);
3101      // p = NULL;// done by p_Delete
3102    }
3103  }
3104  if (ncRingType(r)==nc_undef)
3105  {
3106    if (IsNonComm==1)
3107    {
3108      //      assume(pN!=NULL);
3109      //      if ((tmpIsSkewConstant==1) && (nIsOne(pGetCoeff(pN)))) r->GetNC()->type=nc_lie;
3110      //      else r->GetNC()->type=nc_general;
3111    }
3112    if (IsNonComm==0)
3113    {
3114      ncRingType(r, nc_skew); /* TODO: check whether it is commutative */
3115      r->GetNC()->IsSkewConstant=tmpIsSkewConstant;
3116    }
3117  }
3118  r->GetNC()->COM=COM;
3119
3120  nc_p_ProcsSet(r, r->p_Procs);
3121
3122  if(bSetupQuotient) // Test me!!!
3123  {
3124    nc_SetupQuotient(r); 
3125  }
3126
3127  if (save != currRing)
3128    rChangeCurrRing(save);
3129
3130  return FALSE;
3131}
3132
3133void gnc_p_ProcsSet(ring rGR, p_Procs_s* p_Procs)
3134{
3135  // "commutative"
3136  p_Procs->p_Mult_mm  = rGR->p_Procs->p_Mult_mm  = gnc_p_Mult_mm;
3137  p_Procs->pp_Mult_mm = rGR->p_Procs->pp_Mult_mm = gnc_pp_Mult_mm;
3138  p_Procs->p_Minus_mm_Mult_qq = rGR->p_Procs->p_Minus_mm_Mult_qq = NULL;
3139  // gnc_p_Minus_mm_Mult_qq_ign; // should not be used!!!???
3140
3141
3142
3143  // non-commutaitve multiplication by monomial from the left
3144  rGR->GetNC()->p_Procs.mm_Mult_p   = gnc_mm_Mult_p;
3145  rGR->GetNC()->p_Procs.mm_Mult_pp  = gnc_mm_Mult_pp;
3146
3147  rGR->GetNC()->p_Procs.GB          = gnc_gr_bba; // bba even for local case!
3148
3149//   rGR->GetNC()->p_Procs.GlobalGB    = gnc_gr_bba;
3150//   rGR->GetNC()->p_Procs.LocalGB     = gnc_gr_mora;
3151
3152
3153#if 0
3154  // Previous Plural's implementation...
3155  rGR->GetNC()->p_Procs.SPoly       = gnc_CreateSpolyOld;
3156  rGR->GetNC()->p_Procs.ReduceSPoly = gnc_ReduceSpolyOld;
3157
3158  rGR->GetNC()->p_Procs.BucketPolyRed  = gnc_kBucketPolyRedOld;
3159  rGR->GetNC()->p_Procs.BucketPolyRed_Z= gnc_kBucketPolyRed_ZOld;
3160#else
3161  // A bit cleaned up and somewhat rewritten functions...
3162  rGR->GetNC()->p_Procs.SPoly       = gnc_CreateSpolyNew;
3163  rGR->GetNC()->p_Procs.ReduceSPoly = gnc_ReduceSpolyNew; 
3164
3165  rGR->GetNC()->p_Procs.BucketPolyRed  = gnc_kBucketPolyRedNew;
3166  rGR->GetNC()->p_Procs.BucketPolyRed_Z= gnc_kBucketPolyRed_ZNew;
3167#endif
3168
3169
3170
3171
3172#if 0
3173    // Old Stuff
3174    p_Procs->p_Mult_mm   = gnc_p_Mult_mm;
3175    _p_procs->p_Mult_mm  = gnc_p_Mult_mm;
3176
3177    p_Procs->pp_Mult_mm  = gnc_pp_Mult_mm;
3178    _p_procs->pp_Mult_mm = gnc_pp_Mult_mm;
3179
3180    p_Procs->p_Minus_mm_Mult_qq = NULL; // gnc_p_Minus_mm_Mult_qq_ign;
3181    _p_procs->p_Minus_mm_Mult_qq= NULL; // gnc_p_Minus_mm_Mult_qq_ign;
3182
3183    r->GetNC()->mmMultP()       = gnc_mm_Mult_p;
3184    r->GetNC()->mmMultPP()      = gnc_mm_Mult_pp;
3185
3186    r->GetNC()->GB()            = gnc_gr_bba;
3187
3188    r->GetNC()->SPoly()         = gnc_CreateSpoly;
3189    r->GetNC()->ReduceSPoly()   = gnc_ReduceSpoly;
3190
3191#endif
3192}
3193
3194
3195// set pProcs table for rGR and global variable p_Procs
3196void nc_p_ProcsSet(ring rGR, p_Procs_s* p_Procs)
3197{
3198  assume(rIsPluralRing(rGR));
3199  assume(p_Procs!=NULL);
3200
3201  gnc_p_ProcsSet(rGR, p_Procs);
3202
3203  if(rIsSCA(rGR) && bUseExtensions)
3204  {
3205    sca_p_ProcsSet(rGR, p_Procs);
3206  }
3207}
3208
3209
3210
3211/* substitute the n-th variable by e in p
3212* destroy p
3213* e is not a constant
3214*/
3215poly nc_pSubst(poly p, int n, poly e)
3216{
3217  int rN=currRing->N;
3218  int *PRE = (int *)omAlloc0((rN+1)*sizeof(int));
3219  int *SUF = (int *)omAlloc0((rN+1)*sizeof(int));
3220  int i,j,pow;
3221  number C;
3222  poly suf,pre;
3223  poly res = NULL;
3224  poly out = NULL;
3225  while ( p!= NULL )
3226  {
3227    C =  pGetCoeff(p);
3228    pGetExpV(p, PRE); /* faster splitting? */
3229    pow = PRE[n]; PRE[n]=0;
3230    res = NULL;
3231    if (pow!=0)
3232    {
3233      for (i=n+1; i<=rN; i++)
3234      {
3235    SUF[i] = PRE[i];
3236    PRE[i] = 0;
3237      }
3238      res =  pPower(pCopy(e),pow);
3239      /* multiply with prefix */
3240      pre = pOne();
3241      pSetExpV(pre,PRE);
3242      pSetm(pre);
3243      res = nc_mm_Mult_p(pre,res,currRing);
3244      /* multiply with suffix */
3245      suf = pOne();
3246      pSetExpV(suf,SUF);
3247      pSetm(suf);
3248      res = p_Mult_mm(res,suf,currRing);
3249      res = p_Mult_nn(res,C,currRing);
3250      pSetComp(res,PRE[0]);
3251    }
3252    else /* pow==0 */
3253    {
3254      res = pHead(p);
3255    }
3256    p   = pLmDeleteAndNext(p);
3257    out = pAdd(out,res);
3258  }
3259  freeT(PRE,rN);
3260  freeT(SUF,rN);
3261  return(out);
3262}
3263
3264static ideal idPrepareStd(ideal T, ideal s,  int k)
3265{
3266  /* T is a left SB, without zeros, s is a list with zeros */
3267#ifdef PDEBUG
3268  if (IDELEMS(s)!=IDELEMS(T))
3269  {
3270    Print("ideals of diff. size!!!");
3271  }
3272#endif
3273  ideal t = idCopy(T);
3274  int j,rs=idRankFreeModule(s),rt=idRankFreeModule(t);
3275  poly p,q;
3276
3277  ideal res = idInit(2*idElem(t),1+idElem(t));
3278  if (rs == 0)
3279  {
3280    for (j=0; j<IDELEMS(t); j++)
3281    {
3282      if (s->m[j]!=NULL) pSetCompP(s->m[j],1);
3283      if (t->m[j]!=NULL) pSetCompP(t->m[j],1);
3284    }
3285    k = si_max(k,1);
3286  }
3287  for (j=0; j<IDELEMS(t); j++)
3288  {
3289    if (s->m[j]!=NULL)
3290    {
3291      p = s->m[j];
3292      q = pOne();
3293      pSetComp(q,k+1+j);
3294      pSetmComp(q);
3295#if 0
3296      while (pNext(p)) pIter(p);
3297      pNext(p) = q;
3298#else
3299      p = pAdd(p,q);
3300      s->m[j] = p;
3301#ifdef PDEBUG
3302    pTest(p);
3303#endif
3304#endif
3305    }
3306  }
3307  res = idSimpleAdd(t,s);
3308  idDelete(&t);
3309  res->rank = 1+idElem(T);
3310  return(res);
3311}
3312
3313ideal Approx_Step(ideal L)
3314{
3315  int N=currRing->N;
3316  int i,j; // k=syzcomp
3317  int flag, flagcnt=0, syzcnt=0;
3318  int syzcomp = 0;
3319  int k=1; /* for ideals not modules */
3320  ideal I = kStd(L, currQuotient,testHomog,NULL,NULL,0,0,NULL);
3321  idSkipZeroes(I);
3322  ideal s_I;
3323  int idI = idElem(I);
3324  ideal trickyQuotient,s_trickyQuotient;
3325  if (currQuotient !=NULL)
3326  {
3327    trickyQuotient = idSimpleAdd(currQuotient,I);
3328  }
3329  else
3330    trickyQuotient = I;
3331  idSkipZeroes(trickyQuotient);
3332  poly *var = (poly *)omAlloc0((N+1)*sizeof(poly));
3333  //  poly *W = (poly *)omAlloc0((2*N+1)*sizeof(poly));
3334  resolvente S = (resolvente)omAlloc0((N+1)*sizeof(ideal));
3335  ideal SI, res;
3336  matrix MI;
3337  poly x=pOne();
3338  var[0]=x;
3339  ideal   h2, h3, s_h2, s_h3;
3340  poly    p,q,qq;
3341  /* init vars */
3342  for (i=1; i<=N; i++ )
3343  {
3344    x = pOne();
3345    pSetExp(x,i,1);
3346    pSetm(x);
3347    var[i]=pCopy(x);
3348  }
3349  /* init NF's */
3350  for (i=1; i<=N; i++ )
3351  {
3352    h2 = idInit(idI,1);
3353    flag = 0;
3354    for (j=0; j< idI; j++ )
3355    {
3356      q = pp_Mult_mm(I->m[j],var[i],currRing);
3357      q = kNF(I,currQuotient,q,0,0);
3358      if (q!=0)
3359      {
3360    h2->m[j]=pCopy(q);
3361    //  pShift(&(h2->m[flag]),1);
3362    flag++;
3363    pDelete(&q);
3364      }
3365      else
3366    h2->m[j]=0;
3367    }
3368    /* W[1..idElems(I)] */
3369    if (flag >0)
3370    {
3371      /* compute syzygies with values in I*/
3372      //      idSkipZeroes(h2);
3373      //      h2 = idSimpleAdd(h2,I);
3374      //      h2->rank=flag+idI+1;
3375      idTest(h2);
3376      idShow(h2);
3377      ring orig_ring=currRing;
3378      ring syz_ring=rCurrRingAssure_SyzComp();
3379      syzcomp = 1;
3380      rSetSyzComp(syzcomp);
3381      if (orig_ring != syz_ring)
3382      {
3383    s_h2=idrCopyR_NoSort(h2,orig_ring);
3384    //  s_trickyQuotient=idrCopyR_NoSort(trickyQuotient,orig_ring);
3385    //  rDebugPrint(syz_ring);
3386    s_I=idrCopyR_NoSort(I,orig_ring);
3387      }
3388      else
3389      {
3390    s_h2 = h2;
3391    s_I  = I;
3392    //  s_trickyQuotient=trickyQuotient;
3393      }
3394      idTest(s_h2);
3395      //      idTest(s_trickyQuotient);
3396      Print(".proceeding with the variable %d\n",i);
3397      s_h3 = idPrepareStd(s_I, s_h2, 1);
3398      BITSET save_test=test;
3399      test|=Sy_bit(OPT_SB_1);
3400      idTest(s_h3);
3401      idDelete(&s_h2);
3402      s_h2=idCopy(s_h3);
3403      idDelete(&s_h3);
3404      Print("...computing Syz");
3405      s_h3 = kStd(s_h2, currQuotient,(tHomog)FALSE,NULL,NULL,syzcomp,idI);
3406      test=save_test;
3407      idShow(s_h3);
3408      if (orig_ring != syz_ring)
3409      {
3410    idDelete(&s_h2);
3411    for (j=0; j<IDELEMS(s_h3); j++)
3412    {
3413      if (s_h3->m[j] != NULL)
3414      {
3415        if (p_MinComp(s_h3->m[j],syz_ring) > syzcomp) /* i.e. it is a syzygy */
3416          pShift(&s_h3->m[j], -syzcomp);
3417        else
3418          pDelete(&s_h3->m[j]);
3419      }
3420    }
3421    idSkipZeroes(s_h3);
3422    s_h3->rank -= syzcomp;
3423    rChangeCurrRing(orig_ring);
3424    //  s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
3425    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
3426    rKill(syz_ring);
3427      }
3428      idTest(s_h3);
3429      S[syzcnt]=kStd(s_h3,currQuotient,(tHomog)FALSE,NULL,NULL);
3430      syzcnt++;
3431      idDelete(&s_h3);
3432    } /* end if flag >0 */
3433    else
3434    {
3435      flagcnt++;
3436    }
3437  }
3438  if (flagcnt == N)
3439  {
3440    Print("the input is a two--sided ideal");
3441    return(I);
3442  }
3443  if (syzcnt >0)
3444  {
3445    Print("..computing Intersect of %d modules\n",syzcnt);
3446    if (syzcnt == 1)
3447      SI = S[0];
3448    else
3449      SI = idMultSect(S, syzcnt);
3450    idShow(SI);
3451    MI = idModule2Matrix(SI);
3452    res= idInit(MATCOLS(MI),1);
3453    for (i=1; i<= MATCOLS(MI); i++)
3454    {
3455      p = NULL;
3456      for (j=0; j< idElem(I); j++)
3457      {
3458    q = pCopy(MATELEM(MI,j+1,i));
3459    if (q!=NULL)
3460    {
3461      q = pMult(q,pCopy(I->m[j]));
3462      p = pAdd(p,q);
3463    }
3464      }
3465      res->m[i-1]=p;
3466    }
3467    Print("final std");
3468    res = kStd(res, currQuotient,testHomog,NULL,NULL,0,0,NULL);
3469    idSkipZeroes(res);
3470    return(res);
3471  }
3472  else
3473  {
3474    Print("No syzygies");
3475    return(I);
3476  }
3477}
3478
3479
3480// creates a commutative nc extension; "converts" comm.ring to a Plural ring
3481ring nc_rCreateNCcomm(ring r)
3482{
3483  if (rIsPluralRing(r)) return r;
3484
3485  matrix C = mpNew(r->N,r->N); // ring-independent!?!
3486  matrix D = mpNew(r->N,r->N);
3487
3488  for(int i=1; i<r->N; i++)
3489    for(int j=i+1; j<=r->N; j++)
3490      MATELEM(C,i,j) = p_ISet(1, r);
3491
3492  if (nc_CallPlural(C, D, NULL, NULL, r)) // TODO: what about quotient ideal?
3493    WarnS("Error initializing multiplication!"); // No reaction!???
3494 
3495  return r;
3496}
3497
3498poly p_CopyEmbed(poly p, ring srcRing, int shift, int par_shift)
3499  /* NOT USED ANYMORE: replaced by maFindPerm in ring.cc */
3500  /* for use with embeddings: currRing is a sum of smaller rings */
3501  /* and srcRing is one of such smaller rings */
3502  /* shift defines the position of a subring in srcRing */
3503  /* par_shift defines the position of a subfield in basefield of CurrRing */
3504{
3505  if (currRing == srcRing)
3506  {
3507    return(p_Copy(p,currRing));
3508  }
3509  nMapFunc nMap=nSetMap(srcRing);
3510  poly q;
3511  //  if ( nMap == nCopy)
3512  //  {
3513  //    q = prCopyR(p,srcRing);
3514  //  }
3515  //  else
3516  {
3517    int *perm = (int *)omAlloc0((srcRing->N+1)*sizeof(int));
3518    int *par_perm = (int *)omAlloc0((srcRing->P+1)*sizeof(int));
3519    //    int *par_perm = (int *)omAlloc0((srcRing->P+1)*sizeof(int));
3520    int i;
3521    //    if (srcRing->P > 0)
3522    //    {
3523    //      for (i=0; i<srcRing->P; i++)
3524    //  par_perm[i]=-i;
3525    //    }
3526    if ((shift<0) || (shift > currRing->N))
3527    {
3528      Werror("bad shifts in p_CopyEmbed");
3529      return(0);
3530    }
3531    for (i=1; i<= srcRing->N; i++)
3532    {
3533      perm[i] = shift+i;
3534    }
3535    q = pPermPoly(p,perm,srcRing,nMap,par_perm,srcRing->P);
3536  }
3537  return(q);
3538}
3539
3540poly pOppose(ring Rop, poly p)
3541  /* opposes a vector p from Rop to currRing */
3542{
3543  /* the simplest case:*/
3544  if (  Rop == currRing )  return(pCopy(p));
3545  /* check Rop == rOpposite(currRing) */
3546  if ( !rIsLikeOpposite(currRing, Rop) )
3547  {
3548    WarnS("an opposite ring should be used");
3549    return NULL;
3550  }
3551  /* nMapFunc nMap = nSetMap(Rop);*/
3552  /* since we know that basefields coinside! */
3553  int *perm=(int *)omAlloc0((Rop->N+1)*sizeof(int));
3554  if (!p_IsConstantPoly(p, Rop))
3555  {
3556    /* we know perm exactly */
3557    int i;
3558    for(i=1; i<=Rop->N; i++)
3559    {
3560      perm[i] = Rop->N+1-i;
3561    }
3562  }
3563  poly res = pPermPoly(p, perm, Rop, nCopy);
3564  omFreeSize((ADDRESS)perm,(Rop->N+1)*sizeof(int));
3565  return res;
3566}
3567
3568ideal idOppose(ring Rop, ideal I)
3569  /* opposes a module I from Rop to currRing */
3570{
3571  /* the simplest case:*/
3572  if ( Rop == currRing ) return idCopy(I);
3573  /* check Rop == rOpposite(currRing) */
3574  if (!rIsLikeOpposite(currRing, Rop))
3575  {
3576    WarnS("an opposite ring should be used");
3577    return NULL;
3578  }
3579  int i;
3580  ideal idOp = idInit(I->ncols, I->rank);
3581  for (i=0; i< (I->ncols)*(I->nrows); i++)
3582  {
3583    idOp->m[i] = pOppose(Rop,I->m[i]);
3584  }
3585  idTest(idOp);
3586  return idOp;
3587}
3588
3589BOOLEAN rIsLikeOpposite(ring rBase, ring rCandidate)
3590  /* checks whether rings rBase and rCandidate */
3591  /* could be opposite to each other */
3592  /* returns TRUE if it is so */
3593{
3594  /* the same basefield */
3595  int diagnose = TRUE;
3596  ring save = currRing;
3597  rChangeCurrRing(rBase);
3598  nMapFunc nMap = nSetMap(rCandidate);
3599  if (nMap != nCopy) diagnose = FALSE;
3600  rChangeCurrRing(save);
3601  /* same number of variables */
3602  if (rBase->N != rCandidate->N) diagnose = FALSE;
3603  /* nc and comm ring */
3604  if ( rIsPluralRing(rBase) != rIsPluralRing(rCandidate) ) diagnose = FALSE;
3605  /* both are qrings */
3606  /* NO CHECK, since it is used in building opposite qring */
3607  /*  if ( ((rBase->qideal != NULL) && (rCandidate->qideal == NULL)) */
3608  /*       || ((rBase->qideal == NULL) && (rCandidate->qideal != NULL)) ) */
3609  /*  diagnose = FALSE; */
3610  /* TODO: varnames are e->E etc */
3611  return diagnose;
3612}
3613
3614
3615
3616bool nc_SetupQuotient(ring rGR, const ring rG)
3617{
3618  // currently only super-commutative extension deals with factors.
3619  if( bUseExtensions ) 
3620    return sca_SetupQuotient(rGR, rG);
3621 
3622  return false;   
3623}
3624
3625
3626
3627// int Commutative_Context(ring r, leftv expression)
3628//   /* returns 1 if expression consists */
3629//   /*  of commutative elements */
3630// {
3631//   /* crucial: poly -> ideal, module, matrix  */
3632// }
3633
3634// int Comm_Context_Poly(ring r, poly p)
3635// {
3636//   poly COMM=r->GetNC()->COMM;
3637//   poly pp=pOne();
3638//   memset(pp->exp,0,r->ExpL_Size*sizeof(long));
3639//   while (p!=NULL)
3640//   {
3641//     for (i=0;i<=r->ExpL_Size;i++)
3642//     {
3643//       if ((p->exp[i]) && (pp->exp[i]))  return(FALSE);
3644//       /* nonzero exponent of non-comm variable */
3645//     }
3646//     pIter(p);
3647//   }
3648//   return(TRUE);
3649// }
Note: See TracBrowser for help on using the repository browser.