1 /****************************************
2 * Computer Algebra System SINGULAR *
3 ****************************************/
4 /***************************************************************
5 * File: ncSAMult.cc
6 * Purpose: implementation of multiplication in simple NC subalgebras
7 * Author: motsak
8 * Created:
9 *******************************************************************/
10
11 #define MYTEST 0
12
13 #if MYTEST
14 #define OM_CHECK 4
15 #define OM_TRACK 5
16 // these settings must be before "mod2.h" in order to work!!!
17 #endif
18
19
20
21
22
23 #include "misc/auxiliary.h"
24
25 #ifdef HAVE_PLURAL
26
27
28 #ifndef SING_NDEBUG
29 #define OUTPUT MYTEST
30 #else
31 #define OUTPUT 0
32 #endif
33
34 # define PLURAL_INTERNAL_DECLARATIONS
35 #include "nc/nc.h"
36 #include "nc/sca.h"
37
38 #include "misc/options.h"
39 #include "coeffs/numbers.h"
40
41
42 #include "monomials/ring.h"
43 #include "monomials/p_polys.h"
44
45 #include "nc/ncSAMult.h" // for CMultiplier etc classes
46 // #include "nc/sca.h" // for SCA
47
48
49 namespace
50 {
51
52 // poly functions defined in p_Procs: ;
ggnc_pp_Mult_mm(const poly p,const poly m,const ring r)53 static poly ggnc_pp_Mult_mm(const poly p, const poly m, const ring r)
54 {
55 if( (p == NULL) || (m == NULL) )
56 return NULL;
57
58 assume( (p != NULL) && (m != NULL) && (r != NULL) );
59
60 #if OUTPUT
61 PrintS("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ggnc_pp_Mult_mm(p, m) VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ");
62 PrintLn();
63 PrintS("p: "); p_Write(p, r);
64 PrintS("m: "); p_Write(m, r);
65 #endif
66 poly pResult;
67
68 if (p_IsConstant(m, r))
69 pResult = __pp_Mult_nn(p, p_GetCoeff(m,r),r);
70 else
71 {
72 CGlobalMultiplier* const pMultiplier = r->GetNC()->GetGlobalMultiplier();
73 assume( pMultiplier != NULL );
74
75 poly pMonom = pMultiplier->LM(m, r);
76 pResult = pMultiplier->MultiplyPE(p, pMonom);
77 p_Delete(&pMonom, r);
78 p_Test(pResult, r);
79 pResult = __p_Mult_nn(pResult, p_GetCoeff(m, r), r);
80 }
81
82 #if OUTPUT
83 p_Test(pResult, r);
84
85 PrintS("ggnc_pp_Mult_mm(p, m) => "); p_Write(pResult, r);
86 PrintS("p: "); p_Write(p, r);
87 PrintS("m: "); p_Write(m, r);
88 PrintS("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ");
89 PrintLn();
90 #endif
91
92 return pResult;
93
94 }
95
ggnc_p_Mult_mm(poly p,const poly m,const ring r)96 static poly ggnc_p_Mult_mm(poly p, const poly m, const ring r)
97 {
98 if( (p == NULL) || (m == NULL) )
99 {
100 p_Delete(&p, r);
101 return NULL;
102 }
103
104 assume( (p != NULL) && (m != NULL) && (r != NULL) );
105
106 #if OUTPUT
107 PrintS("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ggnc_p_Mult_mm(p, m) VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ");
108 PrintLn();
109 PrintS("p: ");
110 p_Write(p, r);
111 PrintS("m: ");
112 p_Write(m, r);
113 #endif
114
115 poly pResult;
116
117 if (p_IsConstant(m, r))
118 pResult = __p_Mult_nn(p, p_GetCoeff(m,r),r);
119 else
120 {
121 CGlobalMultiplier* const pMultiplier = r->GetNC()->GetGlobalMultiplier();
122 assume( pMultiplier != NULL );
123
124 poly pMonom = pMultiplier->LM(m, r);
125 pResult = pMultiplier->MultiplyPEDestroy(p, pMonom);
126 p_Delete(&pMonom, r);
127 p_Test(pResult, r);
128 pResult = __p_Mult_nn(pResult, p_GetCoeff(m, r), r);
129 }
130
131 #if OUTPUT
132 p_Test(pResult, r);
133
134 PrintS("ggnc_p_Mult_mm(p, m) => "); p_Write(pResult, r);
135 // PrintS("p: "); p_Write(p, r);
136 PrintS("m: "); p_Write(m, r);
137 PrintS("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ");
138 PrintLn();
139 #endif
140
141 return pResult;
142
143 }
144
145 /* m*p */
ggnc_p_mm_Mult(poly p,const poly m,const ring r)146 static poly ggnc_p_mm_Mult(poly p, const poly m, const ring r)
147 {
148 if( (p == NULL) || (m == NULL) )
149 {
150 p_Delete(&p, r);
151 return NULL;
152 }
153
154 assume( (p != NULL) && (m != NULL) && (r != NULL) );
155
156 p_Test(m, r);
157 p_Test(p, r);
158
159 #if OUTPUT
160 PrintS("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ggnc_p_mm_Mult(p,m) VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ");
161 PrintLn();
162 PrintS("m: "); p_Write(m, r);
163 PrintS("p: "); p_Write(p, r);
164 #endif
165
166 poly pResult;
167
168 if (p_IsConstant(m, r))
169 pResult = __p_Mult_nn(p, p_GetCoeff(m,r),r);
170 else
171 {
172 CGlobalMultiplier* const pMultiplier = r->GetNC()->GetGlobalMultiplier();
173 assume( pMultiplier != NULL );
174
175 poly pMonom = pMultiplier->LM(m, r);
176 pResult = pMultiplier->MultiplyEPDestroy(pMonom, p);
177 p_Delete(&pMonom, r);
178 p_Test(pResult, r);
179 pResult = __p_Mult_nn(pResult, p_GetCoeff(m, r), r);
180 }
181
182 #if OUTPUT
183 p_Test(pResult, r);
184
185 PrintS("ggnc_p_mm_Mult(p,m) => "); p_Write(pResult, r);
186 // PrintS("p: "); p_Write(p, r);
187 PrintS("m: "); p_Write(m, r);
188 PrintS("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ");
189 PrintLn();
190 #endif
191
192 return pResult;
193 }
194
ggnc_pp_mm_Mult(const poly p,const poly m,const ring r)195 static poly ggnc_pp_mm_Mult(const poly p, const poly m, const ring r)
196 {
197 if( (p == NULL) || (m == NULL) )
198 {
199 return NULL;
200 }
201
202 assume( (p != NULL) && (m != NULL) && (r != NULL) );
203
204 p_Test(m, r);
205 p_Test(p, r);
206
207 #if OUTPUT
208 PrintS("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ggnc_pp_mm_Mult(m, p) VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ");
209 PrintLn();
210 PrintS("m: "); p_Write(m, r);
211 PrintS("p: "); p_Write(p, r);
212 #endif
213
214 poly pResult;
215
216 if (p_IsConstant(m, r))
217 pResult = __pp_Mult_nn(p, p_GetCoeff(m,r),r);
218 else
219 {
220 CGlobalMultiplier* const pMultiplier = r->GetNC()->GetGlobalMultiplier();
221 assume( pMultiplier != NULL );
222
223 poly pMonom = pMultiplier->LM(m, r);
224 pResult = pMultiplier->MultiplyEP(pMonom, p);
225 p_Delete(&pMonom, r);
226 p_Test(pResult, r);
227 pResult = __p_Mult_nn(pResult, p_GetCoeff(m, r), r);
228 }
229
230 #if OUTPUT
231 p_Test(pResult, r);
232
233 PrintS("ggnc_pp_mm_Mult(m, p) => "); p_Write(pResult, r);
234 PrintS("p: "); p_Write(p, r);
235 PrintS("m: "); p_Write(m, r);
236 PrintS("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ");
237 PrintLn();
238 #endif
239
240 return pResult;
241 }
242
ggnc_p_ProcsSet(ring rGR,p_Procs_s * p_Procs)243 static void ggnc_p_ProcsSet(ring rGR, p_Procs_s* p_Procs)
244 {
245 #if OUTPUT
246 PrintS("|ggnc_p_ProcsSet()");
247 PrintLn();
248 #endif
249
250 assume( p_Procs != NULL );
251
252 // "commutative"
253 p_Procs->p_Mult_mm = rGR->p_Procs->p_Mult_mm = ggnc_p_Mult_mm;
254 p_Procs->pp_Mult_mm = rGR->p_Procs->pp_Mult_mm = ggnc_pp_Mult_mm;
255
256 p_Procs->p_Minus_mm_Mult_qq = rGR->p_Procs->p_Minus_mm_Mult_qq = NULL;
257
258 // non-commutaitve multiplication by monomial from the left
259 rGR->p_Procs->p_mm_Mult = ggnc_p_mm_Mult;
260 rGR->p_Procs->pp_mm_Mult = ggnc_pp_mm_Mult;
261
262 }
263
264 }
265
ncInitSpecialPairMultiplication(ring r)266 BOOLEAN ncInitSpecialPairMultiplication(ring r)
267 {
268 #if OUTPUT
269 PrintS("ncInitSpecialPairMultiplication(ring), ring: \n");
270 rWrite(r, TRUE);
271 PrintLn();
272 #endif
273
274 if(!rIsPluralRing(r))// ; // :(((
275 return TRUE;
276
277 if(rIsSCA(r))
278 return TRUE;
279
280 if( r->GetNC()->GetGlobalMultiplier() != NULL )
281 {
282 WarnS("Already defined!");
283 return TRUE;
284 }
285
286 r->GetNC()->GetGlobalMultiplier() = new CGlobalMultiplier(r);
287
288 ggnc_p_ProcsSet(r, r->p_Procs);
289 return FALSE; // ok!
290 }
291
292
CGlobalMultiplier(ring r)293 CGlobalMultiplier::CGlobalMultiplier(ring r):
294 CMultiplier<poly>(r), m_RingFormulaMultiplier(GetFormulaPowerMultiplier(r))
295 {
296 #if OUTPUT
297 PrintS("CGlobalMultiplier::CGlobalMultiplier(ring)!");
298 PrintLn();
299 #endif
300
301 // m_cache = new CGlobalCacheHash(r);
302 m_powers = new CPowerMultiplier(r);
303 }
304
305
~CGlobalMultiplier()306 CGlobalMultiplier::~CGlobalMultiplier()
307 {
308 #if OUTPUT
309 PrintS("CGlobalMultiplier::~CGlobalMultiplier()!");
310 PrintLn();
311 #endif
312
313 // delete m_cache;
314 delete m_powers;
315
316 // we cannot delete m_RingFormulaMultiplier as it belongs to the ring!
317 }
318
319
320
321 // Exponent * Exponent
322 // TODO: handle components!!!
MultiplyEE(const CGlobalMultiplier::CExponent expLeft,const CGlobalMultiplier::CExponent expRight)323 poly CGlobalMultiplier::MultiplyEE(const CGlobalMultiplier::CExponent expLeft, const CGlobalMultiplier::CExponent expRight)
324 {
325
326 const ring r = GetBasering();
327
328 #if OUTPUT
329 PrintS("CGlobalMultiplier::MultiplyEE(expLeft, expRight)!");
330 PrintLn();
331 PrintS("expL: "); p_Write(expLeft, GetBasering());
332 PrintS("expR: "); p_Write(expRight, GetBasering());
333 #endif
334
335 // CCacheHash<poly>::CCacheItem* pLookup;
336 //
337 // int b = m_cache->LookupEE(expLeft, expRight, pLookup);
338 // // TODO!!!
339 //
340 // // up to now:
341 // assume( b == -1 );
342
343 // TODO: use PowerMultiplier!!!!
344
345 poly product = NULL;
346
347 const int N = NVars();
348 int j = N;
349 int i = 1;
350
351 int ej = p_GetExp(expLeft, j, r);
352 int ei = p_GetExp(expRight, i, r);
353
354 while( (i < j) && !((ej != 0) && (ei != 0)) )
355 {
356 if( ei == 0 )
357 ei = p_GetExp(expRight, ++i, r);
358
359 if( ej == 0 )
360 ej = p_GetExp(expLeft, --j, r);
361 }
362
363
364 #if OUTPUT
365 PrintS("<CGlobalMultiplier::MultiplyEE>");
366 PrintLn();
367 Print("i: %d, j: %d", i, j);
368 PrintLn();
369 Print("ei: %d, ej: %d", ei, ej);
370 PrintLn();
371 #endif
372
373
374 // | expLeft | * | expRight |
375 // |<<<< ej 0..0| , |0..0 ei >>>>|
376 // |<<<< j <<<N| , |1>>> i >>>>|
377
378 if( i >= j ) // BUG here!!!???
379 {
380 // either i == j or i = j + 1 => commutative multiple!
381 // TODO: it can be done more efficiently! ()
382 product = p_Head(expRight, r);
383
384 // | expLeft | * | expRight |
385 // |<<<< ej 0....0| , |0..00 ei >>>>|
386 // |<<<< j i <<<N| , |1>>>j i >>>>|
387
388 if(i > j)
389 {
390 --i;
391 ei = 0;
392 }
393
394 if( i == j )
395 {
396 if( ej != 0 )
397 p_SetExp(product, i, ei + ej, r);
398 }
399
400 --i;
401
402 for(; i > 0; --i)
403 {
404 const int e = p_GetExp(expLeft, i, r);
405
406 if( e > 0 )
407 p_SetExp(product, i, e, r);
408 }
409
410 p_Setm(product, r);
411
412 } else
413 { // i < j, ei != 0, ej != 0
414
415 Enum_ncSAType PairType = _ncSA_notImplemented;
416
417 if( m_RingFormulaMultiplier != NULL )
418 PairType = m_RingFormulaMultiplier->GetPair(i, j);
419
420
421 if( PairType == _ncSA_notImplemented )
422 product = m_powers->MultiplyEE( CPower(j, ej), CPower(i, ei) );
423 // return ggnc_uu_Mult_ww_vert(i, a, j, b, r);
424 else
425 // return m_RingFormulaMultiplier->Multiply(j, i, b, a);
426 product = CFormulaPowerMultiplier::Multiply( PairType, i, j, ei, ej, GetBasering());
427
428
429 #if OUTPUT
430 PrintS("<CGlobalMultiplier::MultiplyEE> ==> ");
431 PrintLn();
432 Print("i: %d, j: %d", i, j);
433 PrintLn();
434 Print("ei: %d, ej: %d", ei, ej);
435 PrintLn();
436 PrintS("<product>: "); p_Write(product, GetBasering());
437 #endif
438
439
440 // TODO: Choose some multiplication strategy!!!
441
442 while( (product != NULL) && !((i == NVars()) && (j == 1)) )
443 {
444
445 // make some choice here!:
446
447 if( i < NVars() )
448 {
449 ei = p_GetExp(expRight, ++i, r);
450
451 while( (ei == 0) && (i < NVars()) )
452 ei = p_GetExp(expRight, ++i, r);
453
454 if( ei != 0 )
455 product = m_powers->MultiplyPEDestroy(product, CPower(i, ei));
456 }
457
458 if( j > 1 )
459 {
460 ej = p_GetExp(expLeft, --j, r);
461
462 while( (ej == 0) && (1 < j) )
463 ej = p_GetExp(expLeft, --j, r);
464
465 if( ej != 0 )
466 product = m_powers->MultiplyEPDestroy(CPower(j, ej), product);
467 }
468
469
470 #if OUTPUT
471 PrintS("<CGlobalMultiplier::MultiplyEE> ==> ");
472 PrintLn();
473 Print("i: %d, j: %d", i, j);
474 PrintLn();
475 Print("ei: %d, ej: %d", ei, ej);
476 PrintLn();
477 PrintS("<product>: "); p_Write(product, GetBasering());
478 #endif
479
480 }
481
482 }
483
484 // // TODO!
485 //
486 // m_cache->StoreEE( expLeft, expRight, product);
487 // // up to now:
488 return product;
489 }
490
491 // Monom * Exponent
MultiplyME(const poly pMonom,const CGlobalMultiplier::CExponent expRight)492 poly CGlobalMultiplier::MultiplyME(const poly pMonom, const CGlobalMultiplier::CExponent expRight)
493 {
494 #if OUTPUT
495 PrintS("CGlobalMultiplier::MultiplyME(monom, expR)!");
496 PrintLn();
497 PrintS("Monom: "); p_Write(pMonom, GetBasering());
498 PrintS("expR: "); p_Write(expRight, GetBasering());
499 #endif
500
501 return MultiplyEE(pMonom, expRight);
502 }
503
504 // Exponent * Monom
MultiplyEM(const CGlobalMultiplier::CExponent expLeft,const poly pMonom)505 poly CGlobalMultiplier::MultiplyEM(const CGlobalMultiplier::CExponent expLeft, const poly pMonom)
506 {
507 #if OUTPUT
508 PrintS("CGlobalMultiplier::MultiplyEM(expL, monom)!");
509 PrintLn();
510 PrintS("expL: "); p_Write(expLeft, GetBasering());
511 PrintS("Monom: "); p_Write(pMonom, GetBasering());
512 #endif
513
514 return MultiplyEE(expLeft, pMonom);
515 }
516
517
518
519
520
521 ///////////////////////////////////////////////////////////////////////////////////////////
CCommutativeSpecialPairMultiplier(ring r,int i,int j)522 CCommutativeSpecialPairMultiplier::CCommutativeSpecialPairMultiplier(ring r, int i, int j):
523 CSpecialPairMultiplier(r, i, j)
524 {
525 #if OUTPUT
526 Print("CCommutativeSpecialPairMultiplier::CCommutativeSpecialPairMultiplier(ring, i: %d, j: %d)!", i, j);
527 PrintLn();
528 #endif
529 }
530
531
~CCommutativeSpecialPairMultiplier()532 CCommutativeSpecialPairMultiplier::~CCommutativeSpecialPairMultiplier()
533 {
534 #if OUTPUT
535 PrintS("CCommutativeSpecialPairMultiplier::~CCommutativeSpecialPairMultiplier()");
536 PrintLn();
537 #endif
538 }
539
540 // Exponent * Exponent
MultiplyEE(const int expLeft,const int expRight)541 poly CCommutativeSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
542 {
543 #if OUTPUT
544 Print("CCommutativeSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
545 PrintLn();
546 #endif
547
548 const ring r = GetBasering();
549
550 return CFormulaPowerMultiplier::ncSA_1xy0x0y0(GetI(), GetJ(), expRight, expLeft, r);
551 }
552
553 ///////////////////////////////////////////////////////////////////////////////////////////
CAntiCommutativeSpecialPairMultiplier(ring r,int i,int j)554 CAntiCommutativeSpecialPairMultiplier::CAntiCommutativeSpecialPairMultiplier(ring r, int i, int j):
555 CSpecialPairMultiplier(r, i, j)
556 {
557 #if OUTPUT
558 Print("CAntiCommutativeSpecialPairMultiplier::CAntiCommutativeSpecialPairMultiplier(ring, i: %d, j: %d)!", i, j);
559 PrintLn();
560 #endif
561 }
562
563
~CAntiCommutativeSpecialPairMultiplier()564 CAntiCommutativeSpecialPairMultiplier::~CAntiCommutativeSpecialPairMultiplier()
565 {
566 #if OUTPUT
567 PrintS("CAntiCommutativeSpecialPairMultiplier::~CAntiCommutativeSpecialPairMultiplier()");
568 PrintLn();
569 #endif
570 }
571
572 // Exponent * Exponent
MultiplyEE(const int expLeft,const int expRight)573 poly CAntiCommutativeSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
574 {
575 #if OUTPUT
576 Print("CAntiCommutativeSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
577 PrintLn();
578 #endif
579
580 const ring r = GetBasering();
581
582 return CFormulaPowerMultiplier::ncSA_Mxy0x0y0(GetI(), GetJ(), expRight, expLeft, r);
583 }
584
585 ///////////////////////////////////////////////////////////////////////////////////////////
CQuasiCommutativeSpecialPairMultiplier(ring r,int i,int j,number q)586 CQuasiCommutativeSpecialPairMultiplier::CQuasiCommutativeSpecialPairMultiplier(ring r, int i, int j, number q):
587 CSpecialPairMultiplier(r, i, j), m_q(q)
588 {
589 #if OUTPUT
590 Print("CQuasiCommutativeSpecialPairMultiplier::CQuasiCommutativeSpecialPairMultiplier(ring, i: %d, j: %d, q)!", i, j);
591 PrintLn();
592 PrintS("Parameter q: ");
593 n_Write(q, r);
594 #endif
595 }
596
597
~CQuasiCommutativeSpecialPairMultiplier()598 CQuasiCommutativeSpecialPairMultiplier::~CQuasiCommutativeSpecialPairMultiplier()
599 {
600 #if OUTPUT
601 PrintS("CQuasiCommutativeSpecialPairMultiplier::~CQuasiCommutativeSpecialPairMultiplier()");
602 PrintLn();
603 #endif
604 }
605
606 // Exponent * Exponent
MultiplyEE(const int expLeft,const int expRight)607 poly CQuasiCommutativeSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
608 {
609 #if OUTPUT
610 Print("CQuasiCommutativeSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
611 PrintLn();
612 #endif
613
614 const ring r = GetBasering();
615
616 return CFormulaPowerMultiplier::ncSA_Qxy0x0y0(GetI(), GetJ(), expRight, expLeft, m_q, r);
617 }
618
619
620 ///////////////////////////////////////////////////////////////////////////////////////////
CWeylSpecialPairMultiplier(ring r,int i,int j,number g)621 CWeylSpecialPairMultiplier::CWeylSpecialPairMultiplier(ring r, int i, int j, number g):
622 CSpecialPairMultiplier(r, i, j), m_g(g)
623 {
624 #if OUTPUT
625 Print("CWeylSpecialPairMultiplier::CWeylSpecialPairMultiplier(ring, i: %d, j: %d, g)!", i, j);
626 PrintLn();
627 PrintS("Parameter g: ");
628 n_Write(g, r);
629 #endif
630 }
631
632
~CWeylSpecialPairMultiplier()633 CWeylSpecialPairMultiplier::~CWeylSpecialPairMultiplier()
634 {
635 #if OUTPUT
636 PrintS("CWeylSpecialPairMultiplier::~CWeylSpecialPairMultiplier()");
637 PrintLn();
638 #endif
639 }
640
641 // Exponent * Exponent
MultiplyEE(const int expLeft,const int expRight)642 poly CWeylSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
643 {
644 #if OUTPUT
645 Print("CWeylSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
646 PrintLn();
647 #endif
648 // Char == 0, otherwise - problem!
649
650
651 const ring r = GetBasering();
652
653 assume( expLeft*expRight > 0 );
654
655 return CFormulaPowerMultiplier::ncSA_1xy0x0yG(GetI(), GetJ(), expRight, expLeft, m_g, r);
656 }
657
658 ///////////////////////////////////////////////////////////////////////////////////////////
CHWeylSpecialPairMultiplier(ring r,int i,int j,int k)659 CHWeylSpecialPairMultiplier::CHWeylSpecialPairMultiplier(ring r, int i, int j, int k):
660 CSpecialPairMultiplier(r, i, j), m_k(k)
661 {
662 #if OUTPUT
663 Print("CHWeylSpecialPairMultiplier::CHWeylSpecialPairMultiplier(ring, i: %d, j: %d, k: %d)!", i, j, k);
664 PrintLn();
665 #endif
666 }
667
668
~CHWeylSpecialPairMultiplier()669 CHWeylSpecialPairMultiplier::~CHWeylSpecialPairMultiplier()
670 {
671 #if OUTPUT
672 PrintS("CHWeylSpecialPairMultiplier::~CHWeylSpecialPairMultiplier()");
673 PrintLn();
674 #endif
675 }
676
677 // Exponent * Exponent
MultiplyEE(const int expLeft,const int expRight)678 poly CHWeylSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
679 {
680 #if OUTPUT
681 Print("CHWeylSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
682 PrintLn();
683 #endif
684 // Char == 0, otherwise - problem!
685
686
687 const ring r = GetBasering();
688
689 assume( expLeft*expRight > 0 );
690
691 return CFormulaPowerMultiplier::ncSA_1xy0x0yT2(GetI(), GetJ(), expRight, expLeft, m_k, r);
692 }
693
694
695 ///////////////////////////////////////////////////////////////////////////////////////////
CShiftSpecialPairMultiplier(ring r,int i,int j,int s,number c)696 CShiftSpecialPairMultiplier::CShiftSpecialPairMultiplier(ring r, int i, int j, int s, number c):
697 CSpecialPairMultiplier(r, i, j), m_shiftCoef(c), m_shiftVar(s)
698 {
699 #if OUTPUT
700 Print("CShiftSpecialPairMultiplier::CShiftSpecialPairMultiplier(ring, i: %d, j: %d, s: %d, c)!", i, j, s);
701 PrintLn();
702 PrintS("Parameter c: "); n_Write(c, r);
703 #endif
704 }
705
706
~CShiftSpecialPairMultiplier()707 CShiftSpecialPairMultiplier::~CShiftSpecialPairMultiplier()
708 {
709 #if OUTPUT
710 PrintS("CShiftSpecialPairMultiplier::~CShiftSpecialPairMultiplier()");
711 PrintLn();
712 #endif
713 }
714
715 // Exponent * Exponent
MultiplyEE(const int expLeft,const int expRight)716 poly CShiftSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
717 {
718 #if OUTPUT
719 Print("CShiftSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
720 PrintLn();
721 #endif
722 // Char == 0, otherwise - problem!
723
724 assume( expLeft*expRight > 0 );
725
726 const ring r = GetBasering();
727
728 if( m_shiftVar != GetI() ) // YX = XY + b*Y?
729 return CFormulaPowerMultiplier::ncSA_1xy0xBy0(GetI(), GetJ(), expRight, expLeft, m_shiftCoef, r); // case: (1, 0, beta, 0, 0)
730 else
731 return CFormulaPowerMultiplier::ncSA_1xyAx0y0(GetI(), GetJ(), expRight, expLeft, m_shiftCoef, r); // case: (1, alpha, 0, 0)
732
733 }
734
735
736
737 ///////////////////////////////////////////////////////////////////////////////////////////
CExternalSpecialPairMultiplier(ring r,int i,int j,Enum_ncSAType type)738 CExternalSpecialPairMultiplier::CExternalSpecialPairMultiplier(ring r, int i, int j, Enum_ncSAType type):
739 CSpecialPairMultiplier(r, i, j), m_ncSAtype(type)
740 {
741 #if OUTPUT
742 Print("CExternalSpecialPairMultiplier::CExternalSpecialPairMultiplier(ring, i: %d, j: %d, type: %d, c)!", i, j, (int)type);
743 PrintLn();
744 #endif
745 }
746
747
~CExternalSpecialPairMultiplier()748 CExternalSpecialPairMultiplier::~CExternalSpecialPairMultiplier()
749 {
750 #if OUTPUT
751 PrintS("CExternalSpecialPairMultiplier::~CExternalSpecialPairMultiplier()");
752 PrintLn();
753 #endif
754 }
755
756 // Exponent * Exponent
MultiplyEE(const int expLeft,const int expRight)757 poly CExternalSpecialPairMultiplier::MultiplyEE(const int expLeft, const int expRight)
758 {
759 #if OUTPUT
760 Print("CExternalSpecialPairMultiplier::MultiplyEE(var(%d)^{%d}, var(%d)^{%d})!", GetJ(), expLeft, GetI(), expRight);
761 PrintLn();
762 #endif
763 // Char == 0, otherwise - problem!
764
765 assume( expLeft*expRight > 0 );
766
767 const ring r = GetBasering();
768
769 return CFormulaPowerMultiplier::Multiply(m_ncSAtype, GetI(), GetJ(), expRight, expLeft, r);
770
771 }
772
773
774
775 ///////////////////////////////////////////////////////////////////////////////////////////
776
777 // factory method!
AnalyzePair(const ring r,int i,int j)778 CSpecialPairMultiplier* AnalyzePair(const ring r, int i, int j)
779 {
780 #if OUTPUT
781 Print("AnalyzePair(ring, i: %d, j: %d)!", i, j);
782 PrintLn();
783 #endif
784
785 Enum_ncSAType type = CFormulaPowerMultiplier::AnalyzePair(r, i, j);
786
787 if( type == _ncSA_notImplemented ) return NULL;
788
789
790 // last possibility:
791 return new CExternalSpecialPairMultiplier(r, i, j, type); // For tests!
792
793
794 if( type == _ncSA_1xy0x0y0 )
795 return new CCommutativeSpecialPairMultiplier(r, i, j);
796
797 if( type == _ncSA_Mxy0x0y0 )
798 return new CAntiCommutativeSpecialPairMultiplier(r, i, j);
799
800 if( type == _ncSA_Qxy0x0y0 )
801 {
802 const number q = p_GetCoeff(GetC(r, i, j), r);
803 return new CQuasiCommutativeSpecialPairMultiplier(r, i, j, q);
804 }
805
806 const poly d = GetD(r, i, j);
807
808 assume( d != NULL );
809 assume( pNext(d) == NULL );
810
811 const number g = p_GetCoeff(d, r);
812
813 if( type == _ncSA_1xy0x0yG ) // Weyl
814 return new CWeylSpecialPairMultiplier(r, i, j, g);
815
816 if( type == _ncSA_1xyAx0y0 ) // Shift 1
817 return new CShiftSpecialPairMultiplier(r, i, j, i, g);
818
819 if( type == _ncSA_1xy0xBy0 ) // Shift 2
820 return new CShiftSpecialPairMultiplier(r, i, j, j, g);
821
822 if( type == _ncSA_1xy0x0yT2 ) // simple homogenized Weyl algebra
823 return new CHWeylSpecialPairMultiplier(r, i, j, p_IsPurePower(d, r));
824
825 }
826
827
828
829
830
831
CPowerMultiplier(ring r)832 CPowerMultiplier::CPowerMultiplier(ring r): CMultiplier<CPower>(r)
833 {
834 #if OUTPUT
835 PrintS("CPowerMultiplier::CPowerMultiplier(ring)!");
836 PrintLn();
837 #endif
838
839 m_specialpairs = (CSpecialPairMultiplier**)omAlloc0( ((NVars() * (NVars()-1)) / 2) * sizeof(CSpecialPairMultiplier*) );
840
841 for( int i = 1; i < NVars(); i++ )
842 for( int j = i + 1; j <= NVars(); j++ )
843 GetPair(i, j) = AnalyzePair(GetBasering(), i, j); // factory method!
844 }
845
846
~CPowerMultiplier()847 CPowerMultiplier::~CPowerMultiplier()
848 {
849 #if OUTPUT
850 PrintS("CPowerMultiplier::~CPowerMultiplier()!");
851 PrintLn();
852 #endif
853
854 omFreeSize((ADDRESS)m_specialpairs, ((NVars() * (NVars()-1)) / 2) * sizeof(CSpecialPairMultiplier*) );
855 }
856
857
858 // Monom * Exponent
859 // pMonom may NOT be of the form: var(j)^{n}!
MultiplyME(const poly pMonom,const CExponent expRight)860 poly CPowerMultiplier::MultiplyME(const poly pMonom, const CExponent expRight)
861 {
862 const int j = expRight.Var;
863 const int n = expRight.Power;
864
865 const ring r = GetBasering();
866
867 #if OUTPUT
868 Print("CPowerMultiplier::MultiplyME(monom * var(%d)^{%d})!", j, n);
869 PrintLn();
870 PrintS("Monom: "); p_Write(pMonom, r);
871 #endif
872
873 assume( (j > 0) && (j <= NVars()));
874
875 if( n == 0 )
876 return p_Head(pMonom, r); // Copy?!?
877
878
879 int v = NVars();
880 int e = p_GetExp(pMonom, v, r);
881
882 while((v > j) && (e == 0))
883 e = p_GetExp(pMonom, --v, r);
884
885 // TODO: review this!
886 if( v == j )
887 {
888 poly p = p_Head(pMonom, r);
889 p_SetExp(p, v, e + n, r);
890 p_Setm(p, r);
891
892 return p;
893 }
894
895 assume( v > j );
896 assume( e > 0 );
897
898 // And now the General Case: v > j!
899
900 poly p = MultiplyEE( CPower(v, e), expRight ); // Easy way!
901
902 --v;
903
904 while(v > 0)
905 {
906 e = p_GetExp(pMonom, v, GetBasering());
907
908 if( e > 0 )
909 p = MultiplyEPDestroy(CPower(v, e), p);
910
911 --v;
912 }
913
914 #if OUTPUT
915 PrintS("CPowerMultiplier::MultiplyME() ===> ");
916 p_Write(p, GetBasering());
917 #endif
918
919 return p;
920 }
921
922 // Exponent * Monom
923 // pMonom may NOT be of the form: var(i)^{m}!
MultiplyEM(const CExponent expLeft,const poly pMonom)924 poly CPowerMultiplier::MultiplyEM(const CExponent expLeft, const poly pMonom)
925 {
926 const ring r = GetBasering();
927
928 // TODO: as above! (difference due to Left/Right semmantics!)
929 const int j = expLeft.Var;
930 const int n = expLeft.Power;
931
932 #if OUTPUT
933 Print("CPowerMultiplier::MultiplyEM(var(%d)^{%d} * monom)!", j, n);
934 PrintLn();
935 PrintS("Monom: "); p_Write(pMonom, r);
936 #endif
937
938 assume( (j > 0) && (j <= NVars()));
939
940 if( n == 0 )
941 return p_Head(pMonom, r); // Copy?!?
942
943
944 int v = 1; // NVars();
945 int e = p_GetExp(pMonom, v, r);
946
947 while((v < j) && (e == 0))
948 e = p_GetExp(pMonom, ++v, r);
949
950 if( v == j )
951 {
952 poly p = p_Head(pMonom, r);
953 p_SetExp(p, j, e + n, r);
954 p_Setm(p, r);
955
956 return p;
957 }
958
959 assume( v < j );
960 assume( e > 0 );
961
962
963 // And now the General Case: v > j!
964
965 poly p = MultiplyEE( expLeft, CPower(v, e) ); // Easy way!
966
967 ++v;
968
969 while(v <= NVars())
970 {
971 e = p_GetExp(pMonom, v, r);
972
973 if( e > 0 )
974 p = MultiplyPEDestroy(p, CPower(v, e));
975
976 ++v;
977 }
978
979 #if OUTPUT
980 PrintS("CPowerMultiplier::MultiplyEM() ===> ");
981 p_Write(p, r);
982 #endif
983
984 return p;
985
986 }
987
988
989 // Exponent * Exponent
990 // Computes: var(j)^{expLeft} * var(i)^{expRight}
MultiplyEE(const CExponent expLeft,const CExponent expRight)991 poly CPowerMultiplier::MultiplyEE(const CExponent expLeft, const CExponent expRight)
992 {
993 #if OUTPUT
994 PrintS("CPowerMultiplier::MultiplyEE)!");
995 PrintLn();
996 #endif
997
998 const int i = expRight.Var, j = expLeft.Var;
999 const int ei = expRight.Power, ej = expLeft.Power;
1000
1001 #if OUTPUT
1002 Print("Input: var(%d)^{%d} * var(%d)^{%d}", j, ej, i, ei);
1003 PrintLn();
1004 #endif
1005
1006 assume(1 <= i);
1007 assume(j <= NVars());
1008 assume(1 <= j);
1009 assume(i <= NVars());
1010 assume(ei > 0);
1011 assume(ej > 0);
1012
1013 if( i >= j )
1014 {
1015 const ring r = GetBasering();
1016
1017 poly product = p_One(r);
1018 p_SetExp(product, j, ej, r);
1019 p_SetExp(product, i, ei, r);
1020 p_Setm(product, r);
1021
1022 return product;
1023
1024 } else
1025 {
1026 assume(i < j);
1027
1028 // No Cache Lookup!? :(
1029
1030 CSpecialPairMultiplier* pSpecialMultiplier = GetPair(i, j);
1031
1032 // Special case?
1033 if( pSpecialMultiplier != NULL )
1034 {
1035 assume( pSpecialMultiplier->GetI() == i );
1036 assume( pSpecialMultiplier->GetJ() == j );
1037 assume( pSpecialMultiplier->GetBasering() == GetBasering() );
1038
1039 return pSpecialMultiplier->MultiplyEE(ej, ei);
1040 } else
1041 {
1042 // Perform general NC Multiplication:
1043 // TODO
1044
1045 WerrorS("Sorry the general case is not implemented this way yet!!!");
1046 assume(0);
1047
1048 // poly product = NULL;
1049 }
1050 }
1051
1052 return NULL;
1053 }
1054
1055
1056
1057
1058
1059
CSpecialPairMultiplier(ring r,int i,int j)1060 CSpecialPairMultiplier::CSpecialPairMultiplier(ring r, int i, int j):
1061 CMultiplier<int>(r), m_i(i), m_j(j)
1062 {
1063 #if OUTPUT
1064 Print("CSpecialPairMultiplier::CSpecialPairMultiplier(ring, i: %d, j: %d)!", i, j);
1065 PrintLn();
1066 #endif
1067
1068 assume(i < j);
1069 assume(i > 0);
1070 assume(j <= NVars());
1071 }
1072
1073
~CSpecialPairMultiplier()1074 CSpecialPairMultiplier::~CSpecialPairMultiplier()
1075 {
1076 #if OUTPUT
1077 PrintS("CSpecialPairMultiplier::~CSpecialPairMultiplier()!");
1078 PrintLn();
1079 #endif
1080 }
1081
1082
1083
1084 // Monom * Exponent
MultiplyME(const poly pMonom,const CExponent expRight)1085 poly CSpecialPairMultiplier::MultiplyME(const poly pMonom, const CExponent expRight)
1086 {
1087 #if OUTPUT
1088 Print("CSpecialPairMultiplier::MultiplyME(monom, var(%d)^{%d})!", GetI(), expRight);
1089 PrintLn();
1090 PrintS("Monom: "); p_Write(pMonom, GetBasering());
1091 #endif
1092
1093 return MultiplyEE(p_GetExp(pMonom, GetJ(), GetBasering()), expRight);
1094 }
1095
1096 // Exponent * Monom
MultiplyEM(const CExponent expLeft,const poly pMonom)1097 poly CSpecialPairMultiplier::MultiplyEM(const CExponent expLeft, const poly pMonom)
1098 {
1099 #if OUTPUT
1100 Print("CSpecialPairMultiplier::MultiplyEM(var(%d)^{%d}, monom)!", GetJ(), expLeft);
1101 PrintLn();
1102 PrintS("Monom: "); p_Write(pMonom, GetBasering());
1103 #endif
1104
1105 return MultiplyEE(expLeft, p_GetExp(pMonom, GetI(), GetBasering()));
1106 }
1107
1108 template class CMultiplier<CPower>;
1109 template class CMultiplier<int>;
1110 template class CMultiplier<spolyrec*>;
1111
1112
1113 #endif
1114