source: git/libpolys/polys/nc/ncSAMult.h @ 32d07a5

spielwiese
Last change on this file since 32d07a5 was 32d07a5, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
Adding/Fixing currRing for non-commutative stuff
  • Property mode set to 100644
File size: 16.5 KB
Line 
1#ifndef GRING_SA_MULT_H
2#define GRING_SA_MULT_H
3/*****************************************
4 *  Computer Algebra System SINGULAR     *
5 *****************************************/
6/* $Id$ */
7
8#ifdef HAVE_PLURAL
9
10// #include <ncSAMult.h> // for CMultiplier etc classes
11
12#include <misc/options.h>
13#include <polys/monomials/ring.h>
14#include <polys/nc/summator.h>// for CPolynomialSummator class
15#include <reporter/reporter.h> // for Print!
16#include <polys/monomials/p_polys.h>
17#include <polys/operations/p_Mult_q.h>
18
19//#include <polys/nc/ncSACache.h> // for CCacheHash etc classes
20#include <polys/nc/ncSAFormula.h> // for CFormulaPowerMultiplier and enum Enum_ncSAType
21
22// //////////////////////////////////////////////////////////////////////// //
23//
24
25bool ncInitSpecialPairMultiplication(ring r);
26
27
28template <typename CExponent>
29class CMultiplier
30{
31  protected:
32    ring m_basering;
33    int  m_NVars; // N = number of variables
34
35  public:
36    CMultiplier(ring rBaseRing): m_basering(rBaseRing), m_NVars(rBaseRing->N) {};
37    virtual ~CMultiplier() {};
38
39    const ring GetBasering() const { return m_basering; };
40    inline int NVars() const { return m_NVars; }
41
42
43    inline poly LM(const poly pTerm, const ring r, int i = 1) const
44    {
45      poly pMonom = p_LmInit(pTerm, r);
46      pSetCoeff0(pMonom, n_Init(i, r));
47      return pMonom;
48    }
49
50    // Term * Exponent -> Monom * Exponent
51    inline poly MultiplyTE(const poly pTerm, const CExponent expRight)
52    {
53      const ring r = GetBasering();
54      poly pMonom = LM(pTerm, r);
55     
56      poly result = p_Mult_nn(MultiplyME(pMonom, expRight), p_GetCoeff(pTerm, r), r);
57
58      p_Delete(&pMonom, r);
59
60      return result;
61    }
62   
63
64    // Exponent * Term -> Exponent * Monom
65    inline poly MultiplyET(const CExponent expLeft, const poly pTerm)
66    {
67      const ring r = GetBasering();
68      poly pMonom = LM(pTerm, r);
69
70      poly result = p_Mult_nn(MultiplyEM(expLeft, pMonom), p_GetCoeff(pTerm, r), r);
71
72      p_Delete(&pMonom, r);
73      return result;
74     
75
76    }
77
78//  protected:
79
80    // Exponent * Exponent
81    virtual poly MultiplyEE(const CExponent expLeft, const CExponent expRight) = 0;   
82
83    // Monom * Exponent
84    virtual poly MultiplyME(const poly pMonom, const CExponent expRight) = 0;
85   
86    // Exponent * Monom
87    virtual poly MultiplyEM(const CExponent expLeft, const poly pMonom) = 0;
88     
89  private: // no copy constuctors!
90    CMultiplier();
91    CMultiplier(const CMultiplier&);
92    CMultiplier& operator=(const CMultiplier&);
93   
94};
95
96
97class CSpecialPairMultiplier: public CMultiplier<int> 
98{
99  private:
100    int m_i;
101    int m_j;
102
103//    poly m_c_ij;
104//    poly m_d_ij;
105   
106   
107  public:
108    // 1 <= i < j <= NVars()
109    CSpecialPairMultiplier(ring r, int i, int j);
110    virtual ~CSpecialPairMultiplier();
111
112    inline int GetI() const { return m_i; } // X
113    inline int GetJ() const { return m_j; } // Y > X!
114
115//  protected:
116    typedef int CExponent;
117
118    // Exponent * Exponent
119    // Computes: var(j)^{expLeft} * var(i)^{expRight}
120    virtual poly MultiplyEE(const CExponent expLeft, const CExponent expRight) = 0;
121
122    // Monom * Exponent
123    // pMonom must be of the form: var(j)^{n}
124    virtual poly MultiplyME(const poly pMonom, const CExponent expRight);
125
126    // Exponent * Monom
127    // pMonom must be of the form: var(i)^{m}
128    virtual poly MultiplyEM(const CExponent expLeft, const poly pMonom);
129
130};
131
132
133
134
135
136struct CPower // represents var(iVar)^{iPower}
137{
138  int Var;
139  int Power;
140
141  CPower(int i, int n): Var(i), Power(n) {};
142
143/*
144  inline poly GetPoly(const ring r) const // TODO: search for GetPoly(r, 1) and remove "1"!
145  {
146    poly p = p_One(r);
147    p_SetExp(p, Var, Power, r);
148    p_Setm(p, r);
149    return p;
150  };
151  inline poly GetPoly(const ring r, int c) const
152  {
153    poly p = p_ISet(c, r);
154    p_SetExp(p, Var, Power, r);
155    p_Setm(p, r);
156    return p;
157  };
158*/
159 
160};
161
162
163
164
165
166
167class CPowerMultiplier: public CMultiplier<CPower>
168{
169  private:
170    CSpecialPairMultiplier** m_specialpairs; // upper triangular submatrix of pairs 1 <= i < j <= N of a N x N matrix.
171
172
173  public:
174    CPowerMultiplier(ring r);
175    virtual ~CPowerMultiplier();
176
177    inline CSpecialPairMultiplier* GetPair(int i, int j) const
178    {
179      assume( m_specialpairs != NULL );
180      assume( i > 0 );
181      assume( i < j );
182      assume( j <= NVars() );
183
184      return m_specialpairs[( (NVars() * ((i)-1) - ((i) * ((i)-1))/2 + (j)-1) - (i) )];
185    }
186
187    inline CSpecialPairMultiplier*& GetPair(int i, int j)
188    {
189      assume( m_specialpairs != NULL );
190      assume( i > 0 );
191      assume( i < j );
192      assume( j <= NVars() );
193
194      return m_specialpairs[( (NVars() * ((i)-1) - ((i) * ((i)-1))/2 + (j)-1) - (i) )];
195    }
196   
197//  protected:
198    typedef CPower CExponent;
199
200    // Exponent * Exponent
201    // Computes: var(j)^{expLeft} * var(i)^{expRight}
202    virtual poly MultiplyEE(const CExponent expLeft, const CExponent expRight);
203
204    // Monom * Exponent
205    // pMonom may NOT be of the form: var(j)^{n}!
206    virtual poly MultiplyME(const poly pMonom, const CExponent expRight);
207
208    // Exponent * Monom
209    // pMonom may NOT be of the form: var(i)^{m}!
210    virtual poly MultiplyEM(const CExponent expLeft, const poly pMonom);
211
212    // Main templates:
213
214    // Poly * Exponent
215    inline poly MultiplyPE(const poly pPoly, const CExponent expRight)
216    {
217      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
218      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
219
220      for( poly q = pPoly; q !=NULL; q = pNext(q) )
221        sum += MultiplyTE(q, expRight); 
222
223      return sum;
224    }
225
226    // Exponent * Poly
227    inline poly MultiplyEP(const CExponent expLeft, const poly pPoly)
228    {
229      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
230      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
231
232      for( poly q = pPoly; q !=NULL; q = pNext(q) )
233        sum += MultiplyET(expLeft, q); 
234
235      return sum;
236    }
237
238    // Poly * Exponent
239    inline poly MultiplyPEDestroy(poly pPoly, const CExponent expRight)
240    {
241      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
242      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
243
244      for( ; pPoly!=NULL; pPoly  = p_LmDeleteAndNext(pPoly, GetBasering()) )
245        sum += MultiplyTE(pPoly, expRight); 
246
247      return sum;
248    }
249
250    // Exponent * Poly
251    inline poly MultiplyEPDestroy(const CExponent expLeft, poly pPoly)
252    {
253      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
254      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
255
256      for( ; pPoly!=NULL; pPoly  = p_LmDeleteAndNext(pPoly, GetBasering()) )
257        sum += MultiplyET(expLeft, pPoly); 
258
259      return sum;
260    }
261
262   
263};
264
265
266
267class CGlobalMultiplier: public CMultiplier<poly>
268{
269  private:
270//    CGlobalCacheHash* m_cache;
271    CPowerMultiplier* m_powers;
272    const CFormulaPowerMultiplier* m_RingFormulaMultiplier;
273
274  public:
275    typedef CMultiplier<poly> CBaseType;
276   
277    CGlobalMultiplier(ring r);
278    virtual ~CGlobalMultiplier();
279
280
281//  protected:   
282    typedef poly CExponent;
283
284    // the following methods are literally equal!
285   
286    // Exponent * Exponent
287    // TODO: handle components!!!
288    virtual poly MultiplyEE(const CExponent expLeft, const CExponent expRight);   
289
290    // Monom * Exponent
291    virtual poly MultiplyME(const poly pMonom, const CExponent expRight);
292
293    // Exponent * Monom
294    virtual poly MultiplyEM(const CExponent expLeft, const poly pMonom);
295
296
297    // Main templates:
298
299    // Poly * Exponent
300    inline poly MultiplyPE(const poly pPoly, const CExponent expRight)
301    {
302      assume( pPoly != NULL );      assume( expRight != NULL );
303      const int iComponentMonom = p_GetComp(expRight, GetBasering());
304
305      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
306      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
307
308
309      if( iComponentMonom!=0 )
310      {
311        for( poly q = pPoly; q !=NULL; q = pNext(q) )
312        {
313#ifdef PDEBUG
314          {
315            const int iComponent = p_GetComp(q, GetBasering());
316            assume(iComponent == 0);         
317            if( iComponent!=0 )
318            {
319              Werror("MultiplyPE: both sides have non-zero components: %d and %d!\n", iComponent, iComponentMonom);
320              // what should we do further?!?
321              return NULL;
322            }
323
324          }
325#endif                   
326          sum += MultiplyTE(q, expRight); // NO Component!!!
327        }
328        poly t = sum; p_SetCompP(t, iComponentMonom, GetBasering());
329        return t;
330      } // iComponentMonom != 0!
331      else
332      { // iComponentMonom == 0!
333        for( poly q = pPoly; q !=NULL; q = pNext(q) )
334        {
335          const int iComponent = p_GetComp(q, GetBasering());
336
337#ifdef PDEBUG         
338          if( iComponent!=0 )
339          {
340            Warn("MultiplyPE: Multiplication in the left module from the right by component %d!\n", iComponent);
341            // what should we do further?!?
342          }
343#endif
344          poly t = MultiplyTE(q, expRight); // NO Component!!!
345          p_SetCompP(t, iComponent, GetBasering());         
346          sum += t;         
347        }       
348        return sum;
349      } // iComponentMonom == 0!
350    }
351
352    // Exponent * Poly
353    inline poly MultiplyEP(const CExponent expLeft, const poly pPoly)
354    {
355      assume( pPoly != NULL );      assume( expLeft != NULL );
356      const int iComponentMonom = p_GetComp(expLeft, GetBasering());
357
358      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
359      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
360
361      if( iComponentMonom!=0 )
362      {
363        for( poly q = pPoly; q !=NULL; q = pNext(q) )
364        {
365#ifdef PDEBUG
366          {
367            const int iComponent = p_GetComp(q, GetBasering());
368            assume(iComponent == 0);         
369            if( iComponent!=0 )
370            {
371              Werror("MultiplyEP: both sides have non-zero components: %d and %d!\n", iComponent, iComponentMonom);
372                // what should we do further?!?
373              return NULL;
374            }
375          }
376#endif                   
377          sum += MultiplyET(expLeft, q);
378        }
379        poly t = sum; p_SetCompP(t, iComponentMonom, GetBasering());
380        return t;
381      } // iComponentMonom != 0!
382      else
383      { // iComponentMonom == 0!
384        for( poly q = pPoly; q !=NULL; q = pNext(q) )
385        {
386          const int iComponent = p_GetComp(q, GetBasering());
387
388          poly t = MultiplyET(expLeft, q); // NO Component!!!
389          p_SetCompP(t, iComponent, GetBasering());         
390          sum += t;         
391        }       
392        return sum;
393      } // iComponentMonom == 0!
394    }
395
396    // Poly * Exponent
397    inline poly MultiplyPEDestroy(poly pPoly, const CExponent expRight)
398    {
399      assume( pPoly != NULL );      assume( expRight != NULL );
400      const int iComponentMonom = p_GetComp(expRight, GetBasering());
401
402      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
403      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
404
405
406      if( iComponentMonom!=0 )
407      {
408        for(poly q = pPoly ; q!=NULL; q = p_LmDeleteAndNext(q, GetBasering()) )
409        {
410#ifdef PDEBUG
411          {
412            const int iComponent = p_GetComp(q, GetBasering());
413            assume(iComponent == 0);         
414            if( iComponent!=0 )
415            {
416              Werror("MultiplyPEDestroy: both sides have non-zero components: %d and %d!\n", iComponent, iComponentMonom);
417              // what should we do further?!?
418              return NULL;
419            }
420
421          }
422#endif                   
423          sum += MultiplyTE(q, expRight); // NO Component!!!
424        }
425        poly t = sum; p_SetCompP(t, iComponentMonom, GetBasering());
426        return t;
427      } // iComponentMonom != 0!
428      else
429      { // iComponentMonom == 0!
430        for(poly q = pPoly ; q!=NULL; q = p_LmDeleteAndNext(q, GetBasering()) )
431        {
432          const int iComponent = p_GetComp(q, GetBasering());
433
434#ifdef PDEBUG         
435          if( iComponent!=0 )
436          {
437            Warn("MultiplyPEDestroy: Multiplication in the left module from the right by component %d!\n", iComponent);
438            // what should we do further?!?
439          }
440#endif
441          poly t = MultiplyTE(q, expRight); // NO Component!!!
442          p_SetCompP(t, iComponent, GetBasering());         
443          sum += t;         
444        }       
445        return sum;
446      } // iComponentMonom == 0!
447
448    }
449
450    // Exponent * Poly
451    inline poly MultiplyEPDestroy(const CExponent expLeft, poly pPoly)
452    {
453
454      assume( pPoly != NULL );      assume( expLeft != NULL );
455      const int iComponentMonom = p_GetComp(expLeft, GetBasering());
456
457      bool bUsePolynomial = TEST_OPT_NOT_BUCKETS || (pLength(pPoly) < MIN_LENGTH_BUCKET);
458      CPolynomialSummator sum(GetBasering(), bUsePolynomial);
459
460      if( iComponentMonom!=0 )
461      {
462        for(poly q = pPoly ; q!=NULL; q = p_LmDeleteAndNext(q, GetBasering()) )
463        {
464#ifdef PDEBUG
465          {
466            const int iComponent = p_GetComp(q, GetBasering());
467            assume(iComponent == 0);         
468            if( iComponent!=0 )
469            {
470              Werror("MultiplyEPDestroy: both sides have non-zero components: %d and %d!\n", iComponent, iComponentMonom);
471                // what should we do further?!?
472              return NULL;
473            }
474          }
475#endif                   
476          sum += MultiplyET(expLeft, q);
477        }
478        poly t = sum; p_SetCompP(t, iComponentMonom, GetBasering());
479        return t;
480      } // iComponentMonom != 0!
481      else
482      { // iComponentMonom == 0!
483        for(poly q = pPoly ; q!=NULL; q = p_LmDeleteAndNext(q, GetBasering()) )
484        {
485          const int iComponent = p_GetComp(q, GetBasering());
486
487          poly t = MultiplyET(expLeft, q); // NO Component!!!
488          p_SetCompP(t, iComponent, GetBasering());         
489          sum += t;         
490        }       
491        return sum;
492      } // iComponentMonom == 0!
493
494    }
495
496
497   
498
499};
500
501
502
503//////////////////////////////////////////////////////////////////////////
504class CCommutativeSpecialPairMultiplier: public CSpecialPairMultiplier
505{
506        public:
507                CCommutativeSpecialPairMultiplier(ring r, int i, int j);
508                virtual ~CCommutativeSpecialPairMultiplier();
509
510                // Exponent * Exponent
511                virtual poly MultiplyEE(const int expLeft, const int expRight);   
512};
513
514//////////////////////////////////////////////////////////////////////////
515class CAntiCommutativeSpecialPairMultiplier: public CSpecialPairMultiplier
516{
517        public:
518                CAntiCommutativeSpecialPairMultiplier(ring r, int i, int j);
519                virtual ~CAntiCommutativeSpecialPairMultiplier();
520
521                // Exponent * Exponent
522                virtual poly MultiplyEE(const int expLeft, const int expRight);   
523};
524
525
526//////////////////////////////////////////////////////////////////////////
527class CQuasiCommutativeSpecialPairMultiplier: public CSpecialPairMultiplier
528{
529        private:
530                const number m_q;
531                // TODO: make cache for some 'good' powers!?
532
533  public:
534                CQuasiCommutativeSpecialPairMultiplier(ring r, int i, int j, number q);
535                virtual ~CQuasiCommutativeSpecialPairMultiplier();
536
537                // Exponent * Exponent
538                virtual poly MultiplyEE(const int expLeft, const int expRight);   
539};
540
541
542//////////////////////////////////////////////////////////////////////////
543class CWeylSpecialPairMultiplier: public CSpecialPairMultiplier
544{
545  private:
546    const number m_g;
547    // TODO: make cache for some 'good' powers!?
548
549  public:
550    CWeylSpecialPairMultiplier(ring r, int i, int j, number g);
551    virtual ~CWeylSpecialPairMultiplier();
552
553    // Exponent * Exponent
554    virtual poly MultiplyEE(const int expLeft, const int expRight);   
555};
556
557
558//////////////////////////////////////////////////////////////////////////
559class CShiftSpecialPairMultiplier: public CSpecialPairMultiplier
560{
561  private:   
562    const number m_shiftCoef;
563    const int m_shiftVar;
564    // TODO: make cache for some 'good' powers!?
565
566  public:
567    CShiftSpecialPairMultiplier(ring r, int i, int j, int s, number c);
568    virtual ~CShiftSpecialPairMultiplier();
569
570    // Exponent * Exponent
571    virtual poly MultiplyEE(const int expLeft, const int expRight);   
572};
573
574
575
576// need: enum Enum_ncSAType;
577
578//////////////////////////////////////////////////////////////////////////
579// Using external 'formula' routins
580class CExternalSpecialPairMultiplier: public CSpecialPairMultiplier
581{
582  private:
583    Enum_ncSAType m_ncSAtype;
584  public:
585    CExternalSpecialPairMultiplier(ring r, int i, int j, Enum_ncSAType type);
586    virtual ~CExternalSpecialPairMultiplier();
587
588    // Exponent * Exponent
589    virtual poly MultiplyEE(const int expLeft, const int expRight);   
590};
591
592
593#endif // HAVE_PLURAL :(
594#endif //
Note: See TracBrowser for help on using the repository browser.