1 /****************************************
2 *  Computer Algebra System SINGULAR     *
3 ****************************************/
4 /***************************************************************
5  *  File:    ncSAFormula.cc
6  *  Purpose: implementation of multiplication by formulas 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 
21 
22 
23 #include "misc/auxiliary.h"
24 
25 #ifdef HAVE_PLURAL
26 
27 #define PLURAL_INTERNAL_DECLARATIONS
28 
29 #ifndef SING_NDEBUG
30 #define OUTPUT MYTEST
31 #else
32 #define OUTPUT 0
33 #endif
34 
35 #include "reporter/reporter.h"
36 
37 #include "coeffs/numbers.h"
38 
39 #include "nc/ncSAFormula.h"
40 // for CFormulaPowerMultiplier
41 
42 #include "monomials/ring.h"
43 #include "monomials/p_polys.h"
44 
45 #include "nc/sca.h"
46 
47 
48 
49 
ncInitSpecialPowersMultiplication(ring r)50 bool ncInitSpecialPowersMultiplication(ring r)
51 {
52 #if OUTPUT
53   PrintS("ncInitSpecialPowersMultiplication(ring), ring: \n");
54   rWrite(r, TRUE);
55   PrintLn();
56 #endif
57 
58   assume(rIsPluralRing(r));
59   assume(!rIsSCA(r));
60 
61 
62   if( r->GetNC()->GetFormulaPowerMultiplier() != NULL )
63   {
64     WarnS("Already defined!");
65     return false;
66   }
67 
68 
69   r->GetNC()->GetFormulaPowerMultiplier() = new CFormulaPowerMultiplier(r);
70 
71   return true;
72 
73 }
74 
75 
76 
77 
78 
79 
80 
81 // TODO: return q-coeff?
AreCommutingVariables(const ring r,int i,int j)82 static inline BOOLEAN AreCommutingVariables(const ring r, int i, int j/*, number *qq*/)
83 {
84 #if OUTPUT
85   Print("AreCommutingVariables(ring, k: %d, i: %d)!\n", j, i);
86 #endif
87 
88   assume(i != j);
89 
90   assume(i > 0);
91   assume(i <= r->N);
92 
93 
94   assume(j > 0);
95   assume(j <= r->N);
96 
97   const BOOLEAN reverse = (i > j);
98 
99   if (reverse) { int k = j; j = i; i = k; }
100 
101   assume(i < j);
102 
103   {
104     const poly d = GetD(r, i, j);
105 
106 #if OUTPUT
107     Print("D_{%d, %d} = ", i, j); p_Write(d, r);
108 #endif
109 
110     if( d != NULL)
111       return FALSE;
112   }
113 
114 
115   {
116     const number q = p_GetCoeff(GetC(r, i, j), r);
117 
118     if( !n_IsOne(q, r->cf) )
119       return FALSE;
120   }
121 
122   return TRUE; // [VAR(I), VAR(J)] = 0!!
123 
124 /*
125   if (reverse)
126     *qq = n_Invers(q, r);
127   else
128     *qq = n_Copy(q, r);
129   return TRUE;
130 */
131 }
132 
AnalyzePairType(const ring r,int i,int j)133 static inline Enum_ncSAType AnalyzePairType(const ring r, int i, int j)
134 {
135 #if OUTPUT
136   Print("AnalyzePair(ring, i: %d, j: %d):\n", i, j);
137 #endif
138 
139   const int N = r->N;
140 
141   assume(i < j);
142   assume(i > 0);
143   assume(j <= N);
144 
145 
146   const poly c = GetC(r, i, j);
147   const number q = pGetCoeff(c);
148   const poly d = GetD(r, i, j);
149 
150 #if 0 && OUTPUT
151   Print("C_{%d, %d} = ", i, j); p_Write(c, r); PrintLn();
152   Print("D_{%d, %d} = ", i, j); p_Write(d, r);
153 #endif
154 
155 //  const number q = p_GetCoeff(c, r);
156 
157   if( d == NULL)
158   {
159 
160     if( n_IsOne(q, r->cf) ) // commutative
161       return _ncSA_1xy0x0y0;
162 
163     if( n_IsMOne(q, r->cf) ) // anti-commutative
164       return _ncSA_Mxy0x0y0;
165 
166     return _ncSA_Qxy0x0y0; // quasi-commutative
167   } else
168   {
169     if( n_IsOne(q, r->cf) ) // "Lie" case
170     {
171       if( pNext(d) == NULL ) // Our Main Special Case: d is only a term!
172       {
173 //         const number g = p_GetCoeff(d, r); // not used for now
174         if( p_LmIsConstantComp(d, r) ) // Weyl
175           return _ncSA_1xy0x0yG;
176 
177         const int k = p_IsPurePower(d, r); // k if not pure power
178 
179         if( k > 0 ) // d = var(k)^??
180         {
181           const int exp = p_GetExp(d, k, r);
182 
183           if (exp == 1)
184           {
185             if(k == i) // 2 -ubalgebra in var(i) & var(j), with linear relation...?
186               return _ncSA_1xyAx0y0;
187 
188             if(k == j)
189               return _ncSA_1xy0xBy0;
190           } else if ( exp == 2 && k!= i && k != j)  // Homogenized Weyl algebra [x, Dx] = t^2?
191           {
192 //            number qi, qj;
193             if (AreCommutingVariables(r, k, i/*, &qi*/) && AreCommutingVariables(r, k, j/*, &qj*/) ) // [x, t] = [Dx, t] = 0?
194             {
195               const number g = pGetCoeff(d);
196 
197               if (n_IsOne(g, r->cf))
198                 return _ncSA_1xy0x0yT2; // save k!?, G = LC(d) == qi == qj == 1!!!
199             }
200           }
201         }
202       }
203     }
204     // Hmm, what about a more general case of q != 1???
205   }
206 #if OUTPUT
207   Print("C_{%d, %d} = ", i, j); p_Write(c, r);
208   Print("D_{%d, %d} = ", i, j); p_Write(d, r);
209   PrintS("====>>>>_ncSA_notImplemented\n");
210 #endif
211 
212   return _ncSA_notImplemented;
213 }
214 
215 
CFormulaPowerMultiplier(ring r)216 CFormulaPowerMultiplier::CFormulaPowerMultiplier(ring r): m_NVars(r->N), m_BaseRing(r)
217 {
218 #if OUTPUT
219   PrintS("CFormulaPowerMultiplier::CFormulaPowerMultiplier(ring)!");
220   PrintLn();
221 #endif
222 
223   m_SAPairTypes = (Enum_ncSAType*)omAlloc0( ((NVars() * (NVars()-1)) / 2) * sizeof(Enum_ncSAType) );
224 
225   for( int i = 1; i < NVars(); i++ )
226     for( int j = i + 1; j <= NVars(); j++ )
227       GetPair(i, j) = AnalyzePairType(GetBasering(), i, j);
228 }
229 
230 
231 
232 
~CFormulaPowerMultiplier()233 CFormulaPowerMultiplier::~CFormulaPowerMultiplier()
234 {
235 #if OUTPUT
236   PrintS("CFormulaPowerMultiplier::~CFormulaPowerMultiplier()!");
237   PrintLn();
238 #endif
239 
240   omFreeSize((ADDRESS)m_SAPairTypes, ((NVars() * (NVars()-1)) / 2) * sizeof(Enum_ncSAType) );
241 }
242 
243 
244 
245 
246 ///////////////////////////////////////////////////////////////////////////////////////////
CorrectPolyWRTOrdering(poly & pResult,const ring r)247 static inline void CorrectPolyWRTOrdering(poly &pResult, const ring r)
248 {
249   if( pNext(pResult) != NULL )
250   {
251     const int cmp = p_LmCmp(pResult, pNext(pResult), r);
252     assume( cmp != 0 ); // must not be equal!!!
253     if( cmp != 1 ) // Wrong order!!!
254       pResult = pReverse(pResult); // Reverse!!!
255   }
256   p_Test(pResult, r);
257 }
258 ///////////////////////////////////////////////////////////////////////////////////////////
ncSA_1xy0x0y0(const int i,const int j,const int n,const int m,const ring r)259 static inline poly ncSA_1xy0x0y0(const int i, const int j, const int n, const int m, const ring r)
260 {
261 #if OUTPUT
262   Print("ncSA_1xy0x0y0(var(%d)^{%d}, var(%d)^{%d}, r)!\n", j, m, i, n);
263 #endif
264 
265   poly p = p_One( r);
266   p_SetExp(p, j, m, r);
267   p_SetExp(p, i, n, r);
268   p_Setm(p, r);
269 
270   p_Test(p, r);
271 
272   return p;
273 
274 } //         return ncSA_1xy0x0y0(GetI(), GetJ(), expRight, expLeft, r);
275 ///////////////////////////////////////////////////////////////////////////////////////////
ncSA_Mxy0x0y0(const int i,const int j,const int n,const int m,const ring r)276 static inline poly ncSA_Mxy0x0y0(const int i, const int j, const int n, const int m, const ring r)
277 {
278 #if OUTPUT
279   Print("ncSA_{M = -1}xy0x0y0(var(%d)^{%d}, var(%d)^{%d}, r)!\n", j, m, i, n);
280 #endif
281 
282   const int  sign = 1 - ((n & (m & 1)) << 1);
283   poly p = p_ISet(sign, r);
284   p_SetExp(p, j, m, r);
285   p_SetExp(p, i, n, r);
286   p_Setm(p, r);
287 
288 
289   p_Test(p, r);
290 
291   return p;
292 
293 } //         return ncSA_Mxy0x0y0(GetI(), GetJ(), expRight, expLeft, r);
294 ///////////////////////////////////////////////////////////////////////////////////////////
ncSA_Qxy0x0y0(const int i,const int j,const int n,const int m,const number m_q,const ring r)295 static inline poly ncSA_Qxy0x0y0(const int i, const int j, const int n, const int m, const number m_q, const ring r)
296 {
297 #if OUTPUT
298   Print("ncSA_Qxy0x0y0(var(%d)^{%d}, var(%d)^{%d}, Q, r)!\n", j, m, i, n);
299 #endif
300 
301   int min, max;
302 
303   if( n < m )
304   {
305     min = n;
306     max = m;
307   }
308   else
309   {
310     min = m;
311     max = n;
312   }
313 
314   number qN;
315 
316   if( max == 1 )
317     qN = n_Copy(m_q, r->cf);
318   else
319   {
320     number t;
321     n_Power(m_q, max, &t, r->cf);
322 
323     if( min > 1 )
324     {
325       n_Power(t, min, &qN, r->cf);
326       n_Delete(&t, r->cf);
327     }
328     else
329       qN = t;
330   }
331 
332   poly p = p_NSet(qN, r);
333   p_SetExp(p, j, m, r);
334   p_SetExp(p, i, n, r);
335   p_Setm(p, r);
336 
337 
338   p_Test(p, r);
339 
340   return p;
341 
342 } //         return ncSA_Qxy0x0y0(GetI(), GetJ(), expRight, expLeft, m_q, r);
343 ///////////////////////////////////////////////////////////////////////////////////////////
ncSA_1xy0x0yG(const int i,const int j,const int n,const int m,const number m_g,const ring r)344 static inline poly ncSA_1xy0x0yG(const int i, const int j, const int n, const int m, const number m_g, const ring r)
345 {
346 #if OUTPUT
347   Print("ncSA_1xy0x0yG(var(%d)^{%d}, var(%d)^{%d}, G, r)!\n", j, m, i, n);
348   number t = n_Copy(m_g, r->cf);
349   PrintS("Parameter G: "); n_Write(t, r->cf);
350   n_Delete(&t, r->cf);
351 #endif
352 
353   int kn = n;
354   int km = m;
355 
356   number c = n_Init(1, r->cf);
357 
358   poly p = p_One( r);
359 
360   p_SetExp(p, j, km--, r); // y ^ (m-k)
361   p_SetExp(p, i, kn--, r); // x ^ (n-k)
362 
363   p_Setm(p, r); // pResult = x^n * y^m
364 
365 
366   poly pResult = p;
367   poly pLast = p;
368 
369   int min = si_min(m, n);
370 
371   int k = 1;
372 
373   for(; k < min; k++ )
374   {
375     number t = n_Init(km + 1, r->cf);
376     n_InpMult(t, m_g, r->cf); // t = ((m - k) + 1) * gamma
377     n_InpMult(c, t, r->cf);   // c = c'* ((m - k) + 1) * gamma
378     n_Delete(&t, r->cf);
379 
380     t = n_Init(kn + 1, r->cf);
381     n_InpMult(c, t, r->cf);   // c = (c'* ((m - k) + 1) * gamma) * ((n - k) + 1)
382     n_Delete(&t, r->cf);
383 
384     t = n_Init(k, r->cf);
385     c = n_Div(c, t, r->cf);
386     n_Delete(&t, r->cf);
387 
388 //    n_Normalize(c, r->cf);
389 
390     t = n_Copy(c, r->cf); // not the last!
391 
392     p = p_NSet(t, r);
393 
394     p_SetExp(p, j, km--, r); // y ^ (m-k)
395     p_SetExp(p, i, kn--, r); // x ^ (n-k)
396 
397     p_Setm(p, r); // pResult = x^n * y^m
398 
399     pNext(pLast) = p;
400     pLast = p;
401   }
402 
403   assume(k == min);
404   assume((km == 0) || (kn == 0) );
405 
406   {
407     n_InpMult(c, m_g, r->cf);   // c = c'* gamma
408 
409     if( km > 0 )
410     {
411       number t = n_Init(km + 1, r->cf);
412       n_InpMult(c, t, r->cf);   // c = (c'* gamma) * (m - k + 1)
413       n_Delete(&t, r->cf);
414     }
415 
416     if( kn > 0 )
417     {
418       number t = n_Init(kn + 1, r->cf);
419       n_InpMult(c, t, r->cf);   // c = (c'* gamma) * (n - k + 1)
420       n_Delete(&t, r->cf);
421     }
422 
423     number t = n_Init(k, r->cf); // c = ((c'* gamma) * ((n - k + 1) * (m - k + 1))) / k;
424     c = n_Div(c, t, r->cf);
425     n_Delete(&t, r->cf);
426   }
427 
428   p = p_NSet(c, r);
429 
430   p_SetExp(p, j, km, r); // y ^ (m-k)
431   p_SetExp(p, i, kn, r); // x ^ (n-k)
432 
433   p_Setm(p, r); //
434 
435   pNext(pLast) = p;
436 
437   CorrectPolyWRTOrdering(pResult, r);
438 
439   return pResult;
440 }
441 ///////////////////////////////////////////////////////////////////////////////////////////
442 ///////////////////////////////////////////////////////////////////////////////////////////
ncSA_1xy0x0yT2(const int i,const int j,const int n,const int m,const int m_k,const ring r)443 static inline poly ncSA_1xy0x0yT2(const int i, const int j, const int n, const int m, const int m_k, const ring r)
444 {
445 #if OUTPUT
446   Print("ncSA_1xy0x0yT2(var(%d)^{%d}, var(%d)^{%d}, t: var(%d), r)!\n", j, m, i, n, m_k);
447 #endif
448 
449   int kn = n;
450   int km = m;
451 
452   // k == 0!
453   number c = n_Init(1, r->cf);
454 
455   poly p = p_One( r );
456 
457   p_SetExp(p, j, km--, r); // y ^ (m)
458   p_SetExp(p, i, kn--, r); // x ^ (n)
459 //  p_SetExp(p, m_k, k << 1, r); // homogenization with var(m_k) ^ (2*k)
460 
461   p_Setm(p, r); // pResult = x^n * y^m
462 
463 
464   poly pResult = p;
465   poly pLast = p;
466 
467   int min = si_min(m, n);
468 
469   int k = 1;
470 
471   for(; k < min; k++ )
472   {
473     number t = n_Init(km + 1, r->cf);
474 //    n_InpMult(t, m_g, r->cf); // t = ((m - k) + 1) * gamma
475     n_InpMult(c, t, r->cf);   // c = c'* ((m - k) + 1) * gamma
476     n_Delete(&t, r->cf);
477 
478     t = n_Init(kn + 1, r->cf);
479     n_InpMult(c, t, r->cf);   // c = (c'* ((m - k) + 1) * gamma) * ((n - k) + 1)
480     n_Delete(&t, r->cf);
481 
482     t = n_Init(k, r->cf);
483     c = n_Div(c, t, r->cf);
484     n_Delete(&t, r->cf);
485 
486 // //    n_Normalize(c, r);
487 
488     t = n_Copy(c, r->cf); // not the last!
489 
490     p = p_NSet(t, r);
491 
492     p_SetExp(p, j, km--, r); // y ^ (m-k)
493     p_SetExp(p, i, kn--, r); // x ^ (n-k)
494 
495     p_SetExp(p, m_k, k << 1, r); // homogenization with var(m_k) ^ (2*k)
496 
497     p_Setm(p, r); // pResult = x^(n-k) * y^(m-k)
498 
499     pNext(pLast) = p;
500     pLast = p;
501   }
502 
503   assume(k == min);
504   assume((km == 0) || (kn == 0) );
505 
506   {
507 //    n_InpMult(c, m_g, r);   // c = c'* gamma
508 
509     if( km > 0 )
510     {
511       number t = n_Init(km + 1, r->cf);
512       n_InpMult(c, t, r->cf);   // c = (c'* gamma) * (m - k + 1)
513       n_Delete(&t, r->cf);
514     }
515 
516     if( kn > 0 )
517     {
518       number t = n_Init(kn + 1, r->cf);
519       n_InpMult(c, t, r->cf);   // c = (c'* gamma) * (n - k + 1)
520       n_Delete(&t, r->cf);
521     }
522 
523     number t = n_Init(k, r->cf); // c = ((c'* gamma) * ((n - k + 1) * (m - k + 1))) / k;
524     c = n_Div(c, t, r->cf);
525     n_Delete(&t, r->cf);
526   }
527 
528   p = p_NSet(c, r);
529 
530   p_SetExp(p, j, km, r); // y ^ (m-k)
531   p_SetExp(p, i, kn, r); // x ^ (n-k)
532 
533   p_SetExp(p, m_k, k << 1, r); // homogenization with var(m_k) ^ (2*k)
534 
535   p_Setm(p, r); //
536 
537   pNext(pLast) = p;
538 
539   CorrectPolyWRTOrdering(pResult, r);
540 
541   return pResult;
542 }
543 ///////////////////////////////////////////////////////////////////////////////////////////
544 
545 
546 
547 ///////////////////////////////////////////////////////////////////////////////////////////
ncSA_ShiftAx(int i,int j,int n,int m,const number m_shiftCoef,const ring r)548 static inline poly ncSA_ShiftAx(int i, int j, int n, int m, const number m_shiftCoef, const ring r)
549 {
550   // Char == 0, otherwise - problem!
551 
552   int k = m; // to 0
553 
554   number c = n_Init(1, r->cf); // k = m, C_k = 1
555   poly p = p_One( r);
556 
557   p_SetExp(p, j, k, r); // Y^{k}
558   p_SetExp(p, i, n, r);
559 
560   p_Setm(p, r); // pResult = C_k * x^n * y^k, k == m
561 
562 
563   poly pResult = p;
564   poly pLast = p;
565 
566   number nn =  n_Init(n, r->cf); // number(n)!
567   n_InpMult(nn, m_shiftCoef, r->cf); // nn = (alpha*n)
568 
569   --k;
570 
571   int mk = 1; // mk = (m - k)
572 
573   for(; k > 0; k-- )
574   {
575     number t = n_Init(k + 1, r->cf);  // t = k+1
576     n_InpMult(c, t, r->cf);           // c = c' * (k+1)
577     n_InpMult(c, nn, r->cf);          // c = (c' * (k+1)) * (alpha * n)
578 
579     n_Delete(&t, r->cf);
580     t = n_Init(mk++, r->cf);
581     c = n_Div(c, t, r->cf);           // c = ((c' * (k+1))  * (alpha * n)) / (m-k);
582     n_Delete(&t, r->cf);
583 
584 //    n_Normalize(c, r->cf);
585 
586     t = n_Copy(c, r->cf); // not the last!
587 
588     p = p_NSet(t, r);
589 
590     p_SetExp(p, j, k, r); // y^k
591     p_SetExp(p, i, n, r); // x^n
592 
593     p_Setm(p, r); // pResult = x^n * y^m
594 
595     pNext(pLast) = p;
596     pLast = p;
597   }
598 
599   assume(k == 0);
600 
601   {
602     n_InpMult(c, nn, r->cf);          // c = (c' * (0+1)) * (alpha * n)
603 
604     number t = n_Init(m, r->cf);
605     c = n_Div(c, t, r->cf);           // c = ((c' * (0+1))  * (alpha * n)) / (m-0);
606     n_Delete(&t, r->cf);
607   }
608 
609   n_Delete(&nn, r->cf);
610 
611   p = p_NSet(c, r);
612 
613   p_SetExp(p, j, k, r); // y^k
614   p_SetExp(p, i, n, r); // x^n
615 
616   p_Setm(p, r); //
617 
618   pNext(pLast) = p;
619 
620   CorrectPolyWRTOrdering(pResult, r);
621 
622   return pResult;
623 }
624 ///////////////////////////////////////////////////////////////////////////////////////////
ncSA_1xyAx0y0(const int i,const int j,const int n,const int m,const number m_shiftCoef,const ring r)625 static inline poly ncSA_1xyAx0y0(const int i, const int j, const int n, const int m, const number m_shiftCoef, const ring r)
626 {
627 #if OUTPUT
628   Print("ncSA_1xyAx0y0(var(%d)^{%d}, var(%d)^{%d}, A, r)!\n", j, m, i, n);
629   number t = n_Copy(m_shiftCoef, r);
630   PrintS("Parameter A: "); n_Write(t, r);
631   n_Delete(&t, r);
632 #endif
633 
634   return ncSA_ShiftAx(i, j, n, m, m_shiftCoef, r);
635 }
636 ///////////////////////////////////////////////////////////////////////////////////////////
ncSA_1xy0xBy0(const int i,const int j,const int n,const int m,const number m_shiftCoef,const ring r)637 static inline poly ncSA_1xy0xBy0(const int i, const int j, const int n, const int m, const number m_shiftCoef, const ring r)
638 {
639 #if OUTPUT
640   Print("ncSA_1xy0xBy0(var(%d)^{%d}, var(%d)^{%d}, B, r)!\n", j, m, i, n);
641   number t = n_Copy(m_shiftCoef, r);
642   PrintS("Parameter B: "); n_Write(t, r);
643   n_Delete(&t, r);
644 #endif
645 
646   return ncSA_ShiftAx(j, i, m, n, m_shiftCoef, r);
647 }
648 ///////////////////////////////////////////////////////////////////////////////////////////
649 ///////////////////////////////////////////////////////////////////////////////////////////
650 ///////////////////////////////////////////////////////////////////////////////////////////
651 ///////////////////////////////////////////////////////////////////////////////////////////
652 
653 
ncSA_Multiply(Enum_ncSAType type,const int i,const int j,const int n,const int m,const ring r)654 static inline poly ncSA_Multiply( Enum_ncSAType type, const int i, const int j, const int n, const int m, const ring r)
655 {
656 #if OUTPUT
657   Print("ncSA_Multiply(type: %d, ring, (var(%d)^{%d} * var(%d)^{%d}, r)!\n", (int)type, j, m, i, n);
658 #endif
659 
660   assume( type != _ncSA_notImplemented );
661   assume( (n > 0) && (m > 0) );
662 
663   if( type == _ncSA_1xy0x0y0 )
664     return ::ncSA_1xy0x0y0(i, j, n, m, r);
665 
666   if( type == _ncSA_Mxy0x0y0 )
667     return ::ncSA_Mxy0x0y0(i, j, n, m, r);
668 
669   if( type == _ncSA_Qxy0x0y0 )
670   {
671     const number q = p_GetCoeff(GetC(r, i, j), r);
672     return ::ncSA_Qxy0x0y0(i, j, n, m, q, r);
673   }
674 
675   const poly d = GetD(r, i, j);
676   const number g = p_GetCoeff(d, r);
677 
678   if( type == _ncSA_1xy0x0yG ) // Weyl
679     return ::ncSA_1xy0x0yG(i, j, n, m, g, r);
680 
681   if( type == _ncSA_1xy0x0yT2 ) // Homogenous Weyl...
682     return ::ncSA_1xy0x0yT2(i, j, n, m, p_IsPurePower(d, r), r);
683 
684   if( type == _ncSA_1xyAx0y0 ) // Shift 1
685     return ::ncSA_1xyAx0y0(i, j, n, m, g, r);
686 
687   if( type == _ncSA_1xy0xBy0 ) // Shift 2
688     return ::ncSA_1xy0xBy0(i, j, n, m, g, r);
689 
690   assume( type == _ncSA_notImplemented );
691 
692   return NULL;
693 }
694 
695 
Multiply(Enum_ncSAType type,const int i,const int j,const int n,const int m,const ring r)696 poly CFormulaPowerMultiplier::Multiply( Enum_ncSAType type, const int i, const int j, const int n, const int m, const ring r)
697 {
698   return ncSA_Multiply( type, i, j, n, m, r);
699 }
700 
701 
AnalyzePair(const ring r,int i,int j)702 Enum_ncSAType CFormulaPowerMultiplier::AnalyzePair(const ring r, int i, int j)
703 {
704   return ::AnalyzePairType( r, i, j);
705 }
706 
Multiply(int i,int j,const int n,const int m)707 poly CFormulaPowerMultiplier::Multiply( int i, int j, const int n, const int m)
708 {
709   return ncSA_Multiply( GetPair(i, j), i, j, n, m, GetBasering());
710 }
711 
712 
713 
714 
ncSA_1xy0x0y0(const int i,const int j,const int n,const int m,const ring r)715 poly CFormulaPowerMultiplier::ncSA_1xy0x0y0(const int i, const int j, const int n, const int m, const ring r)
716 {
717   return ::ncSA_1xy0x0y0(i, j, n, m, r);
718 }
719 
ncSA_Mxy0x0y0(const int i,const int j,const int n,const int m,const ring r)720 poly CFormulaPowerMultiplier::ncSA_Mxy0x0y0(const int i, const int j, const int n, const int m, const ring r)
721 {
722   return ::ncSA_Mxy0x0y0(i, j, n, m, r);
723 }
724 
ncSA_Qxy0x0y0(const int i,const int j,const int n,const int m,const number m_q,const ring r)725 poly CFormulaPowerMultiplier::ncSA_Qxy0x0y0(const int i, const int j, const int n, const int m, const number m_q, const ring r)
726 {
727   return ::ncSA_Qxy0x0y0(i, j, n, m, m_q, r);
728 }
729 
ncSA_1xy0x0yG(const int i,const int j,const int n,const int m,const number m_g,const ring r)730 poly CFormulaPowerMultiplier::ncSA_1xy0x0yG(const int i, const int j, const int n, const int m, const number m_g, const ring r)
731 {
732   return ::ncSA_1xy0x0yG(i, j, n, m, m_g, r);
733 }
734 
ncSA_1xy0x0yT2(const int i,const int j,const int n,const int m,const int k,const ring r)735 poly CFormulaPowerMultiplier::ncSA_1xy0x0yT2(const int i, const int j, const int n, const int m, const int k, const ring r)
736 {
737   return ::ncSA_1xy0x0yT2(i, j, n, m, k, r);
738 }
739 
ncSA_1xyAx0y0(const int i,const int j,const int n,const int m,const number m_shiftCoef,const ring r)740 poly CFormulaPowerMultiplier::ncSA_1xyAx0y0(const int i, const int j, const int n, const int m, const number m_shiftCoef, const ring r)
741 {
742   return ::ncSA_1xyAx0y0(i, j, n, m, m_shiftCoef, r);
743 }
744 
ncSA_1xy0xBy0(const int i,const int j,const int n,const int m,const number m_shiftCoef,const ring r)745 poly CFormulaPowerMultiplier::ncSA_1xy0xBy0(const int i, const int j, const int n, const int m, const number m_shiftCoef, const ring r)
746 {
747   return ::ncSA_1xy0xBy0(i, j, n, m, m_shiftCoef, r);
748 }
749 #endif
750