source: git/libpolys/polys/nc/ncSAMult.cc @ 1f5565d

spielwiese
Last change on this file since 1f5565d was 1f5565d, checked in by Oleksandr Motsak <motsak@…>, 12 years ago
added HWeyl add: experimental handling of homogenized Weyl algebras (formulas/detection and related)
  • Property mode set to 100644
File size: 25.8 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 *  Version: $Id$
10 *******************************************************************/
11
12#define MYTEST 0
13
14#if MYTEST
15#define OM_CHECK 4
16#define OM_TRACK 5
17// these settings must be before "mod2.h" in order to work!!!
18#endif
19
20
21#include "config.h"
22#include <misc/auxiliary.h>
23
24#ifdef HAVE_PLURAL
25
26
27#ifndef NDEBUG
28#define OUTPUT MYTEST
29#else
30#define OUTPUT 0
31#endif
32
33# define PLURAL_INTERNAL_DECLARATIONS
34#include "nc/nc.h"
35#include "nc/sca.h"
36
37#include <misc/options.h>
38#include <coeffs/numbers.h>
39#include "coeffrings.h"
40
41
42// #include <kernel/p_Procs.h>
43#include "monomials/ring.h"
44#include "monomials/p_polys.h"
45
46#include "nc/ncSAMult.h" // for CMultiplier etc classes
47// #include "nc/sca.h" // for SCA
48
49
50namespace
51{
52
53// poly functions defined in p_Procs: ;
54static poly ggnc_pp_Mult_mm(const poly p, const poly m, const ring r, poly& last)
55{
56  if( (p == NULL) || (m == NULL) )
57    return NULL;
58
59  assume( (p != NULL) && (m != NULL) && (r != NULL) );
60
61#if OUTPUT 
62  PrintS("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ggnc_pp_Mult_mm(p, m) VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ");
63  PrintLn();
64  PrintS("p: "); p_Write(p, r);   
65  PrintS("m: "); p_Write(m, r);     
66#endif
67  poly pResult;
68 
69  if (p_IsConstant(m, r))
70    pResult = pp_Mult_nn(p, p_GetCoeff(m,r),r);
71  else
72  { 
73    CGlobalMultiplier* const pMultiplier = r->GetNC()->GetGlobalMultiplier();
74    assume( pMultiplier != NULL );
75
76    poly pMonom = pMultiplier->LM(m, r);
77    pResult = pMultiplier->MultiplyPE(p, pMonom);
78    p_Delete(&pMonom, r);
79    p_Test(pResult, r);
80    pResult = p_Mult_nn(pResult, p_GetCoeff(m, r), r);
81  }
82
83#if OUTPUT 
84  p_Test(pResult, r);
85
86  PrintS("ggnc_pp_Mult_mm(p, m) => "); p_Write(pResult, r);
87  PrintS("p: "); p_Write(p, r);   
88  PrintS("m: "); p_Write(m, r);     
89  PrintS("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ");
90  PrintLn();
91#endif
92
93  return pResult;
94
95}
96
97static poly ggnc_p_Mult_mm(poly p, const poly m, const ring r)
98{
99  if( (p == NULL) || (m == NULL) )
100  {
101    p_Delete(&p, r);
102    return NULL;
103  }
104
105  assume( (p != NULL) && (m != NULL) && (r != NULL) );
106
107#if OUTPUT 
108  PrintS("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ggnc_p_Mult_mm(p, m) VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ");
109  PrintLn();
110  PrintS("p: ");
111  p_Write(p, r);   
112  PrintS("m: ");
113  p_Write(m, r); 
114#endif
115
116  poly pResult;
117
118  if (p_IsConstant(m, r))
119    pResult = p_Mult_nn(p, p_GetCoeff(m,r),r);
120  else
121  { 
122    CGlobalMultiplier* const pMultiplier = r->GetNC()->GetGlobalMultiplier();
123    assume( pMultiplier != NULL );
124
125    poly pMonom = pMultiplier->LM(m, r);
126    pResult = pMultiplier->MultiplyPEDestroy(p, pMonom);
127    p_Delete(&pMonom, r);
128    p_Test(pResult, r);
129    pResult = p_Mult_nn(pResult, p_GetCoeff(m, r), r);
130  }
131
132#if OUTPUT 
133  p_Test(pResult, r);
134
135  PrintS("ggnc_p_Mult_mm(p, m) => "); p_Write(pResult, r);     
136//  PrintS("p: "); p_Write(p, r);   
137  PrintS("m: "); p_Write(m, r);     
138  PrintS("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ");
139  PrintLn();
140#endif
141 
142  return pResult;
143
144}
145
146static poly ggnc_mm_Mult_p(const poly m, poly p, 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_mm_Mult_p(m, p) 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_mm_Mult_p(m, p) => "); 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->GetNC()->p_Procs.mm_Mult_p   = ggnc_mm_Mult_p;
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#endif
Note: See TracBrowser for help on using the repository browser.