source: git/kernel/gring.cc @ 367c32

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