source: git/kernel/gring.cc @ 32c4523

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