source: git/libpolys/polys/nc/ncSAMult.cc @ a9277b

spielwiese
Last change on this file since a9277b was a9277b, checked in by Hans Schoenemann <hannes@…>, 6 years ago
chg: move p_mm_Mult to pProcs out of plural stuff
  • Property mode set to 100644
File size: 25.6 KB
Line 
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
49namespace
50{
51
52// poly functions defined in p_Procs: ;
53static 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
96static 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 */
146static 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
195static poly ggnc_mm_Mult_pp(const poly m, const poly p, 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_mm_Mult_pp(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_mm_Mult_pp(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
243static 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->GetNC()->p_Procs.mm_Mult_pp  = ggnc_mm_Mult_pp;
261
262}
263
264}
265
266BOOLEAN 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
293CGlobalMultiplier::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
306CGlobalMultiplier::~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!!!
323poly 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
492poly 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
505poly 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///////////////////////////////////////////////////////////////////////////////////////////
522CCommutativeSpecialPairMultiplier::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
532CCommutativeSpecialPairMultiplier::~CCommutativeSpecialPairMultiplier()
533{
534#if OUTPUT
535  PrintS("CCommutativeSpecialPairMultiplier::~CCommutativeSpecialPairMultiplier()");
536  PrintLn();
537#endif
538}
539
540// Exponent * Exponent
541poly 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///////////////////////////////////////////////////////////////////////////////////////////
554CAntiCommutativeSpecialPairMultiplier::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
564CAntiCommutativeSpecialPairMultiplier::~CAntiCommutativeSpecialPairMultiplier()
565{
566#if OUTPUT
567        PrintS("CAntiCommutativeSpecialPairMultiplier::~CAntiCommutativeSpecialPairMultiplier()");
568        PrintLn();
569#endif
570}
571
572// Exponent * Exponent
573poly 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///////////////////////////////////////////////////////////////////////////////////////////
586CQuasiCommutativeSpecialPairMultiplier::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
598CQuasiCommutativeSpecialPairMultiplier::~CQuasiCommutativeSpecialPairMultiplier()
599{
600#if OUTPUT
601        PrintS("CQuasiCommutativeSpecialPairMultiplier::~CQuasiCommutativeSpecialPairMultiplier()");
602        PrintLn();
603#endif
604}
605
606// Exponent * Exponent
607poly 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///////////////////////////////////////////////////////////////////////////////////////////
621CWeylSpecialPairMultiplier::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
633CWeylSpecialPairMultiplier::~CWeylSpecialPairMultiplier()
634{
635#if OUTPUT
636  PrintS("CWeylSpecialPairMultiplier::~CWeylSpecialPairMultiplier()");
637  PrintLn();
638#endif
639}
640
641// Exponent * Exponent
642poly 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///////////////////////////////////////////////////////////////////////////////////////////
659CHWeylSpecialPairMultiplier::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
669CHWeylSpecialPairMultiplier::~CHWeylSpecialPairMultiplier()
670{
671#if OUTPUT
672  PrintS("CHWeylSpecialPairMultiplier::~CHWeylSpecialPairMultiplier()");
673  PrintLn();
674#endif
675}
676
677// Exponent * Exponent
678poly 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///////////////////////////////////////////////////////////////////////////////////////////
696CShiftSpecialPairMultiplier::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
707CShiftSpecialPairMultiplier::~CShiftSpecialPairMultiplier()
708{
709#if OUTPUT
710  PrintS("CShiftSpecialPairMultiplier::~CShiftSpecialPairMultiplier()");
711  PrintLn();
712#endif
713}
714
715// Exponent * Exponent
716poly 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///////////////////////////////////////////////////////////////////////////////////////////
738CExternalSpecialPairMultiplier::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
748CExternalSpecialPairMultiplier::~CExternalSpecialPairMultiplier()
749{
750#if OUTPUT
751  PrintS("CExternalSpecialPairMultiplier::~CExternalSpecialPairMultiplier()");
752  PrintLn();
753#endif
754}
755
756// Exponent * Exponent
757poly 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!
778CSpecialPairMultiplier* 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
832CPowerMultiplier::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
847CPowerMultiplier::~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}!
860poly 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}!
924poly 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}
991poly 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
1060CSpecialPairMultiplier::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
1074CSpecialPairMultiplier::~CSpecialPairMultiplier()
1075{
1076#if OUTPUT
1077  PrintS("CSpecialPairMultiplier::~CSpecialPairMultiplier()!");
1078  PrintLn();
1079#endif
1080}
1081
1082
1083
1084// Monom * Exponent
1085poly 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
1097poly 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
1108template class CMultiplier<CPower>;
1109template class CMultiplier<int>;
1110template class CMultiplier<spolyrec*>;
1111
1112
1113#endif
Note: See TracBrowser for help on using the repository browser.