source: git/libpolys/polys/nc/ncSAMult.cc @ 85bcd6

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