source: git/kernel/ncSAMult.cc @ 342c80

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