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