source: git/libpolys/polys/nc/old.gring.cc @ 80ca3c

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