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