source: git/libpolys/polys/nc/old.gring.cc @ 210e07

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