source: git/libpolys/polys/nc/ncSAMult.h @ 5b1536

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