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

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