source: git/libpolys/polys/nc/ncSAMult.h @ 1377c9

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