source: git/kernel/gring.cc @ 1495df4

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