source: git/kernel/gring.cc @ 022ef5

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