source: git/kernel/pInline2.h @ 3a0e1a

spielwiese
Last change on this file since 3a0e1a was c92fb1, checked in by Motsak Oleksandr <motsak@…>, 15 years ago
*motsak: more LL interface git-svn-id: file:///usr/local/Singular/svn/trunk@11857 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 18.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    pInline2.h
6 *  Purpose: implementation of poly procs which are of constant time
7 *  Author:  obachman (Olaf Bachmann)
8 *  Created: 8/00
9 *  Version: $Id: pInline2.h,v 1.16 2009-05-29 13:57:35 motsak Exp $
10 *******************************************************************/
11#ifndef PINLINE2_H
12#define PINLINE2_H
13
14/***************************************************************
15 *
16 * Primitives for accessing and setting fields of a poly
17 *
18 ***************************************************************/
19#if !defined(NO_PINLINE2) || defined(PINLINE2_CC)
20
21#include "structs.h"
22#include "omalloc.h"
23#include "numbers.h"
24#include "p_Procs.h"
25#include "sbuckets.h"
26#ifdef HAVE_PLURAL
27#include "gring.h"
28#include "ring.h"
29#endif
30
31PINLINE2 number p_SetCoeff(poly p, number n, ring r)
32{
33  p_LmCheckPolyRing2(p, r);
34  n_Delete(&(p->coef), r);
35  (p)->coef=n;
36  return n;
37}
38
39// order
40PINLINE2 Order_t p_GetOrder(poly p, ring r)
41{
42  p_LmCheckPolyRing2(p, r);
43  if (r->typ==NULL) return ((p)->exp[r->pOrdIndex]);
44  int i=0;
45  loop
46  {
47    switch(r->typ[i].ord_typ)
48    {
49      case ro_wp_neg:
50        return (((long)((p)->exp[r->pOrdIndex]))-POLY_NEGWEIGHT_OFFSET);
51      case ro_syzcomp:
52      case ro_syz:
53      case ro_cp:
54        i++;
55        break;
56      //case ro_dp:
57      //case ro_wp:
58      default:
59        return ((p)->exp[r->pOrdIndex]);
60    }
61  }
62}
63
64PINLINE2 Order_t p_SetOrder(poly p, long o, ring r)
65{
66  p_LmCheckPolyRing2(p, r);
67  pAssume2(o >= 0);
68  if (r->typ==NULL) return ((p)->exp[r->pOrdIndex]=o);
69  int i=0;
70  loop
71  {
72    switch(r->typ[i].ord_typ)
73    {
74      case ro_wp_neg:
75        return (p)->exp[r->pOrdIndex]=o+POLY_NEGWEIGHT_OFFSET;
76      case ro_syzcomp:
77      case ro_syz:
78      case ro_cp:
79        i++;
80        break;
81      //case ro_dp:
82      //case ro_wp:
83      default:
84        return (p)->exp[r->pOrdIndex] = o;
85    }
86  }
87}
88
89// Setm
90PINLINE2 void p_Setm(poly p, const ring r)
91{
92  p_CheckRing2(r);
93  r->p_Setm(p, r);
94}
95
96// component
97PINLINE2  unsigned long p_SetComp(poly p, unsigned long c, ring r)
98{
99  p_LmCheckPolyRing2(p, r);
100  pAssume2(rRing_has_Comp(r));
101  __p_GetComp(p,r) = c;
102  return c;
103}
104PINLINE2 unsigned long p_IncrComp(poly p, ring r)
105{
106  p_LmCheckPolyRing2(p, r);
107  pAssume2(rRing_has_Comp(r));
108  return ++(__p_GetComp(p,r));
109}
110PINLINE2 unsigned long p_DecrComp(poly p, ring r)
111{
112  p_LmCheckPolyRing2(p, r);
113  pAssume2(rRing_has_Comp(r));
114  pPolyAssume2(__p_GetComp(p,r) > 0);
115  return --(__p_GetComp(p,r));
116}
117PINLINE2 unsigned long p_AddComp(poly p, unsigned long v, ring r)
118{
119  p_LmCheckPolyRing2(p, r);
120  pAssume2(rRing_has_Comp(r));
121  return __p_GetComp(p,r) += v;
122}
123PINLINE2 unsigned long p_SubComp(poly p, unsigned long v, ring r)
124{
125  p_LmCheckPolyRing2(p, r);
126  pAssume2(rRing_has_Comp(r));
127  pPolyAssume2(__p_GetComp(p,r) >= v);
128  return __p_GetComp(p,r) -= v;
129}
130PINLINE2 int p_Comp_k_n(poly a, poly b, int k, ring r)
131{
132  if ((a==NULL) || (b==NULL) ) return FALSE;
133  p_LmCheckPolyRing2(a, r);
134  p_LmCheckPolyRing2(b, r);
135  pAssume2(k > 0 && k <= r->N);
136  int i=k;
137  for(;i<=r->N;i++)
138  {
139    if (p_GetExp(a,i,r) != p_GetExp(b,i,r)) return FALSE;
140    //    if (a->exp[(r->VarOffset[i] & 0xffffff)] != b->exp[(r->VarOffset[i] & 0xffffff)]) return FALSE;
141  }
142  return TRUE;
143}
144
145#ifndef HAVE_EXPSIZES
146
147/// get a single variable exponent
148/// @Note:
149/// the integer VarOffset encodes:
150/// 1. the position of a variable in the exponent vector p->exp (lower 24 bits)
151/// 2. number of bits to shift to the right in the upper 8 bits (which takes at most 6 bits for 64 bit)
152/// Thus VarOffset always has 2 zero higher bits!
153PINLINE2 int p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
154{
155  pAssume2((VarOffset >> (24 + 6)) == 0);
156#if 0
157  int pos=(VarOffset & 0xffffff);
158  int bitpos=(VarOffset >> 24);
159  int exp=(p->exp[pos] >> bitmask) & iBitmask;
160  return exp;
161#else
162  return (int)
163         ((p->exp[(VarOffset & 0xffffff)] >> (VarOffset >> 24))
164          & iBitmask);
165#endif
166}
167
168
169/// set a single variable exponent
170/// @Note:
171/// VarOffset encodes the position in p->exp @see p_GetExp
172PINLINE2 int p_SetExp(poly p, const int e, const unsigned long iBitmask, const int VarOffset)
173{
174  pAssume2(e>=0);
175  pAssume2((unsigned long) e<=iBitmask);
176  pAssume2((VarOffset >> (24 + 6)) == 0);
177
178  // shift e to the left:
179  register int shift = VarOffset >> 24;
180  unsigned long ee = ((unsigned long)e) << shift /*(VarOffset >> 24)*/;
181  // find the bits in the exponent vector
182  register int offset = (VarOffset & 0xffffff);
183  // clear the bits in the exponent vector:
184  p->exp[offset]  &= ~( iBitmask << shift );
185  // insert e with |
186  p->exp[ offset ] |= ee;
187  return e;
188}
189
190
191#else // #ifdef HAVE_EXPSIZES // EXPERIMENTAL!!!
192
193PINLINE2 unsigned long BitMask(unsigned long bitmask, int twobits)
194{
195  // bitmask = 00000111111111111
196  // 0 must give bitmask!
197  // 1, 2, 3 - anything like 00011..11
198  pAssume2((twobits >> 2) == 0);
199  const unsigned long _bitmasks[4] = {-1, 0x7fff, 0x7f, 0x3};
200  return bitmask & _bitmasks[twobits]; 
201}
202
203
204/// @Note: we may add some more info (6 ) into VarOffset and thus encode
205PINLINE2 int p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
206{
207  int pos  =(VarOffset & 0xffffff);
208  int hbyte= (VarOffset >> 24); // the highest byte
209  int bitpos = hbyte & 0x3f; // last 6 bits
210  int bitmask = BitMask(iBitmask, hbyte >> 6);
211
212  int exp=(p->exp[pos] >> bitpos) & bitmask;
213  return exp;
214
215}
216
217PINLINE2 int p_SetExp(poly p, const int e, const unsigned long iBitmask, const int VarOffset)
218{
219  pAssume2(e>=0);
220  pAssume2((unsigned long) e <= BitMask(iBitmask, VarOffset >> 30));
221
222  // shift e to the left:
223  register int hbyte = VarOffset >> 24;
224  int bitmask = BitMask(iBitmask, hbyte >> 6);
225  register int shift = hbyte & 0x3f;
226  unsigned long ee = ((unsigned long)e) << shift;
227  // find the bits in the exponent vector
228  register int offset = (VarOffset & 0xffffff);
229  // clear the bits in the exponent vector:
230  p->exp[offset]  &= ~( bitmask << shift );
231  // insert e with |
232  p->exp[ offset ] |= ee;
233  return e;
234}
235
236#endif // #ifndef HAVE_EXPSIZES
237
238
239PINLINE2 int p_GetExp(const poly p, const ring r, const int VarOffset)
240{
241  p_LmCheckPolyRing2(p, r);
242  pAssume2(VarOffset != -1);
243  return p_GetExp(p, r->bitmask, VarOffset);
244}
245
246PINLINE2 int p_SetExp(poly p, const int e, const ring r, const int VarOffset)
247{
248  p_LmCheckPolyRing2(p, r);
249  pAssume2(VarOffset != -1);
250  return p_SetExp(p, e, r->bitmask, VarOffset);
251}
252
253
254
255/// get v^th exponent for a monomial
256PINLINE2 int p_GetExp(const poly p, const int v, const ring r)
257{
258  p_LmCheckPolyRing2(p, r);
259  pAssume2(v>0 && v <= r->N);
260  pAssume2(r->VarOffset[v] != -1);
261  return p_GetExp(p, r->bitmask, r->VarOffset[v]);
262}
263
264
265/// set v^th exponent for a monomial
266PINLINE2 int p_SetExp(poly p, const int v, const int e, const ring r)
267{
268  p_LmCheckPolyRing2(p, r);
269  pAssume2(v>0 && v <= r->N);
270  pAssume2(r->VarOffset[v] != -1);
271  return p_SetExp(p, e, r->bitmask, r->VarOffset[v]);
272}
273
274
275
276
277
278// the following should be implemented more efficiently
279PINLINE2  int p_IncrExp(poly p, int v, ring r)
280{
281  p_LmCheckPolyRing2(p, r);
282  int e = p_GetExp(p,v,r);
283  e++;
284  return p_SetExp(p,v,e,r);
285}
286PINLINE2  int p_DecrExp(poly p, int v, ring r)
287{
288  p_LmCheckPolyRing2(p, r);
289  int e = p_GetExp(p,v,r);
290  pAssume2(e > 0);
291  e--;
292  return p_SetExp(p,v,e,r);
293}
294PINLINE2  int p_AddExp(poly p, int v, int ee, ring r)
295{
296  p_LmCheckPolyRing2(p, r);
297  int e = p_GetExp(p,v,r);
298  e += ee;
299  return p_SetExp(p,v,e,r);
300}
301PINLINE2  int p_SubExp(poly p, int v, int ee, ring r)
302{
303  p_LmCheckPolyRing2(p, r);
304  int e = p_GetExp(p,v,r);
305  pAssume2(e >= ee);
306  e -= ee;
307  return p_SetExp(p,v,e,r);
308}
309PINLINE2  int p_MultExp(poly p, int v, int ee, ring r)
310{
311  p_LmCheckPolyRing2(p, r);
312  int e = p_GetExp(p,v,r);
313  e *= ee;
314  return p_SetExp(p,v,e,r);
315}
316
317PINLINE2 int p_GetExpSum(poly p1, poly p2, int i, ring r)
318{
319  p_LmCheckPolyRing2(p1, r);
320  p_LmCheckPolyRing2(p2, r);
321  return p_GetExp(p1,i,r) + p_GetExp(p2,i,r);
322}
323PINLINE2 int p_GetExpDiff(poly p1, poly p2, int i, ring r)
324{
325  return p_GetExp(p1,i,r) - p_GetExp(p2,i,r);
326}
327
328
329/***************************************************************
330 *
331 * Allocation/Initalization/Deletion
332 *
333 ***************************************************************/
334PINLINE2 poly p_New(ring r, omBin bin)
335{
336  p_CheckRing2(r);
337  pAssume2(bin != NULL && r->PolyBin->sizeW == bin->sizeW);
338  poly p;
339  omTypeAllocBin(poly, p, bin);
340  p_SetRingOfLm(p, r);
341  return p;
342}
343
344PINLINE2 poly p_New(ring r)
345{
346  return p_New(r, r->PolyBin);
347}
348
349PINLINE2 void p_DeleteLm(poly *p, ring r)
350{
351  pIfThen2(*p != NULL, p_LmCheckPolyRing2(*p, r));
352  poly h = *p;
353  if (h != NULL)
354  {
355    n_Delete(&_pGetCoeff(h), r);
356    *p = _pNext(h);
357    omFreeBinAddr(h);
358  }
359}
360PINLINE2 void p_DeleteLm(poly p, ring r)
361{
362  pIfThen2(p != NULL, p_LmCheckPolyRing2(p, r));
363  if (p != NULL)
364  {
365    n_Delete(&_pGetCoeff(p), r);
366    omFreeBinAddr(p);
367  }
368}
369PINLINE2 void p_LmFree(poly p, ring r)
370{
371  p_LmCheckPolyRing2(p, r);
372  omFreeBinAddr(p);
373}
374PINLINE2 void p_LmFree(poly *p, ring r)
375{
376  p_LmCheckPolyRing2(*p, r);
377  poly h = *p;
378  *p = pNext(h);
379  omFreeBinAddr(h);
380}
381PINLINE2 poly p_LmFreeAndNext(poly p, ring r)
382{
383  p_LmCheckPolyRing2(p, r);
384  poly pnext = pNext(p);
385  omFreeBinAddr(p);
386  return pnext;
387}
388PINLINE2 void p_LmDelete(poly p, ring r)
389{
390  p_LmCheckPolyRing2(p, r);
391  n_Delete(&_pGetCoeff(p), r);
392  omFreeBinAddr(p);
393}
394PINLINE2 void p_LmDelete(poly *p, ring r)
395{
396  p_LmCheckPolyRing2(*p, r);
397  poly h = *p;
398  *p = pNext(h);
399  n_Delete(&pGetCoeff(h), r);
400  omFreeBinAddr(h);
401}
402PINLINE2 poly p_LmDeleteAndNext(poly p, ring r)
403{
404  p_LmCheckPolyRing2(p, r);
405  poly pnext = _pNext(p);
406  n_Delete(&_pGetCoeff(p), r);
407  omFreeBinAddr(p);
408  return pnext;
409}
410
411/***************************************************************
412 *
413 * Misc routines
414 *
415 ***************************************************************/
416PINLINE2 int p_Cmp(poly p1, poly p2, ring r)
417{
418  if (p2==NULL)
419    return 1;
420  if (p1==NULL)
421    return -1;
422  return p_LmCmp(p1,p2,r);
423}
424
425PINLINE2 unsigned long p_GetMaxExp(poly p, ring r)
426{
427  return p_GetMaxExp(p_GetMaxExpL(p, r), r);
428}
429
430PINLINE2 unsigned long
431p_GetMaxExp(const unsigned long l, const ring r, const int number_of_exps)
432{
433  unsigned long bitmask = r->bitmask;
434  unsigned long max = (l & bitmask);
435  unsigned long j = number_of_exps - 1;
436
437  if (j > 0)
438  {
439    unsigned long i = r->BitsPerExp;
440    long e;
441    loop
442    {
443      e = ((l >> i) & bitmask);
444      if ((unsigned long) e > max)
445        max = e;
446      j--;
447      if (j==0) break;
448      i += r->BitsPerExp;
449    }
450  }
451  return max;
452}
453
454PINLINE2 unsigned long p_GetMaxExp(const unsigned long l, const ring r)
455{
456  return p_GetMaxExp(l, r, r->ExpPerLong);
457}
458
459PINLINE2 unsigned long
460p_GetTotalDegree(const unsigned long l, const ring r, const int number_of_exps)
461{
462  const unsigned long bitmask = r->bitmask;
463  unsigned long sum = (l & bitmask);
464  unsigned long j = number_of_exps - 1;
465
466  if (j > 0)
467  {
468    unsigned long i = r->BitsPerExp;
469    loop
470    {
471      sum += ((l >> i) & bitmask);
472      j--;
473      if (j==0) break;
474      i += r->BitsPerExp;
475    }
476  }
477  return sum;
478}
479
480PINLINE2 unsigned long
481p_GetTotalDegree(const unsigned long l, const ring r)
482{
483  return p_GetTotalDegree(l, r, r->ExpPerLong);
484}
485
486/***************************************************************
487 *
488 * Dispatcher to r->p_Procs, they do the tests/checks
489 *
490 ***************************************************************/
491// returns a copy of p
492PINLINE2 poly p_Copy(poly p, const ring r)
493{
494#ifdef PDEBUG
495  poly pp= r->p_Procs->p_Copy(p, r);
496  p_Test(pp,r);
497  return pp;
498#else
499  return r->p_Procs->p_Copy(p, r);
500#endif
501}
502
503PINLINE2 poly p_Copy(poly p, const ring lmRing, const ring tailRing)
504{
505#ifndef PDEBUG
506  if (tailRing == lmRing)
507    return tailRing->p_Procs->p_Copy(p, tailRing);
508#endif
509  if (p != NULL)
510  {
511    poly pres = p_Head(p, lmRing);
512    pNext(pres) = tailRing->p_Procs->p_Copy(pNext(p), tailRing);
513    return pres;
514  }
515  else
516    return NULL;
517}
518
519// deletes *p, and sets *p to NULL
520PINLINE2 void p_Delete(poly *p, const ring r)
521{
522  r->p_Procs->p_Delete(p, r);
523}
524
525PINLINE2 void p_Delete(poly *p,  const ring lmRing, const ring tailRing)
526{
527#ifndef PDEBUG
528  if (tailRing == lmRing)
529  {
530    tailRing->p_Procs->p_Delete(p, tailRing);
531    return;
532  }
533#endif
534  if (*p != NULL)
535  {
536    if (pNext(*p) != NULL)
537      tailRing->p_Procs->p_Delete(&pNext(*p), tailRing);
538    p_LmDelete(p, lmRing);
539  }
540}
541
542PINLINE2 poly p_ShallowCopyDelete(poly p, const ring r, omBin bin)
543{
544  p_LmCheckPolyRing2(p, r);
545  pAssume2(r->PolyBin->sizeW == bin->sizeW);
546  return r->p_Procs->p_ShallowCopyDelete(p, r, bin);
547}
548
549// returns p+q, destroys p and q
550PINLINE2 poly p_Add_q(poly p, poly q, const ring r)
551{
552  int shorter;
553  return r->p_Procs->p_Add_q(p, q, shorter, r);
554}
555
556PINLINE2 poly p_Add_q(poly p, poly q, int &lp, int lq, const ring r)
557{
558  int shorter;
559  poly res = r->p_Procs->p_Add_q(p, q, shorter, r);
560  lp = (lp + lq) - shorter;
561  return res;
562}
563
564// returns p*n, destroys p
565PINLINE2 poly p_Mult_nn(poly p, number n, const ring r)
566{
567  if (n_IsOne(n, r))
568    return p;
569  else
570    return r->p_Procs->p_Mult_nn(p, n, r);
571}
572
573PINLINE2 poly p_Mult_nn(poly p, number n, const ring lmRing,
574                        const ring tailRing)
575{
576#ifndef PDEBUG
577  if (lmRing == tailRing)
578  {
579    return p_Mult_nn(p, n, tailRing);
580  }
581#endif
582  poly pnext = pNext(p);
583  pNext(p) = NULL;
584  p = lmRing->p_Procs->p_Mult_nn(p, n, lmRing);
585  pNext(p) = tailRing->p_Procs->p_Mult_nn(pnext, n, tailRing);
586  return p;
587}
588
589// returns p*n, does not destroy p
590PINLINE2 poly pp_Mult_nn(poly p, number n, const ring r)
591{
592  if (n_IsOne(n, r))
593    return p_Copy(p, r);
594  else
595    return r->p_Procs->pp_Mult_nn(p, n, r);
596}
597
598// returns Copy(p)*m, does neither destroy p nor m
599PINLINE2 poly pp_Mult_mm(poly p, poly m, const ring r)
600{
601  if (p_LmIsConstant(m, r))
602    return pp_Mult_nn(p, pGetCoeff(m), r);
603  else
604  {
605    poly last;
606    return r->p_Procs->pp_Mult_mm(p, m, r, last);
607  }
608}
609
610// returns p*m, destroys p, const: m
611PINLINE2 poly p_Mult_mm(poly p, poly m, const ring r)
612{
613  if (p_LmIsConstant(m, r))
614    return p_Mult_nn(p, pGetCoeff(m), r);
615  else
616    return r->p_Procs->p_Mult_mm(p, m, r);
617}
618
619// return p - m*Copy(q), destroys p; const: p,m
620PINLINE2 poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, const ring r)
621{
622#ifdef HAVE_PLURAL
623  if (rIsPluralRing(r))
624  {
625    int lp, lq;
626    poly spNoether;
627    return nc_p_Minus_mm_Mult_qq(p, m, q, lp, lq, spNoether, r);
628  }
629#endif
630
631  int shorter;
632  poly last;
633
634  return r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last); // !!!
635}
636
637PINLINE2 poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
638                                 poly spNoether, const ring r)
639{
640#ifdef HAVE_PLURAL
641  if (rIsPluralRing(r))
642     return nc_p_Minus_mm_Mult_qq(p, m, q, lp, lq, spNoether, r);
643#endif
644
645  int shorter;
646  poly last,res;
647  res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, spNoether, r, last);
648  lp = (lp + lq) - shorter;
649  return res;
650}
651
652PINLINE2 poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, const ring r)
653{
654  int shorter;
655  return r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r);
656}
657
658PINLINE2 poly pp_Mult_Coeff_mm_DivSelect(poly p, int &lp, const poly m, const ring r)
659{
660  int shorter;
661  poly pp = r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r);
662  lp -= shorter;
663  return pp;
664}
665
666// returns -p, destroys p
667PINLINE2 poly p_Neg(poly p, const ring r)
668{
669  return r->p_Procs->p_Neg(p, r);
670}
671
672extern poly  _p_Mult_q(poly p, poly q, const int copy, const ring r);
673// returns p*q, destroys p and q
674PINLINE2 poly p_Mult_q(poly p, poly q, const ring r)
675{
676  if (p == NULL)
677  {
678    r->p_Procs->p_Delete(&q, r);
679    return NULL;
680  }
681  if (q == NULL)
682  {
683    r->p_Procs->p_Delete(&p, r);
684    return NULL;
685  }
686
687  if (pNext(p) == NULL)
688  {
689#ifdef HAVE_PLURAL
690    if (rIsPluralRing(r))
691      q = nc_mm_Mult_p(p, q, r);
692    else
693#endif /* HAVE_PLURAL */
694      q = r->p_Procs->p_Mult_mm(q, p, r);
695
696    r->p_Procs->p_Delete(&p, r);
697    return q;
698  }
699
700  if (pNext(q) == NULL)
701  {
702  // NEEDED
703#ifdef HAVE_PLURAL
704/*    if (rIsPluralRing(r))
705      p = gnc_p_Mult_mm(p, q, r); // ???
706    else*/
707#endif /* HAVE_PLURAL */
708      p = r->p_Procs->p_Mult_mm(p, q, r);
709
710    r->p_Procs->p_Delete(&q, r);
711    return p;
712  }
713#ifdef HAVE_PLURAL
714  if (rIsPluralRing(r))
715    return _nc_p_Mult_q(p, q, r);
716  else
717#endif
718  return _p_Mult_q(p, q, 0, r);
719}
720
721// returns p*q, does neither destroy p nor q
722PINLINE2 poly pp_Mult_qq(poly p, poly q, const ring r)
723{
724  poly last;
725  if (p == NULL || q == NULL) return NULL;
726
727  if (pNext(p) == NULL)
728  {
729#ifdef HAVE_PLURAL
730    if (rIsPluralRing(r))
731      return nc_mm_Mult_pp(p, q, r);
732#endif
733    return r->p_Procs->pp_Mult_mm(q, p, r, last);
734  }
735
736  if (pNext(q) == NULL)
737  {
738    return r->p_Procs->pp_Mult_mm(p, q, r, last);
739  }
740
741  poly qq = q;
742  if (p == q)
743    qq = p_Copy(q, r);
744
745  poly res;
746#ifdef HAVE_PLURAL
747  if (rIsPluralRing(r))
748    res = _nc_pp_Mult_qq(p, qq, r);
749  else
750#endif
751    res = _p_Mult_q(p, qq, 1, r);
752
753  if (qq != q)
754    p_Delete(&qq, r);
755  return res;
756}
757
758// returns p + m*q destroys p, const: q, m
759PINLINE2 poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
760                                const ring r)
761{
762#ifdef HAVE_PLURAL
763  if (rIsPluralRing(r))
764    return nc_p_Plus_mm_Mult_qq(p, m, q, lp, lq, r);
765#endif
766
767// this should be implemented more efficiently
768  poly res, last;
769  int shorter;
770  number n_old = pGetCoeff(m);
771  number n_neg = n_Copy(n_old, r);
772  n_neg = n_Neg(n_neg, r);
773  pSetCoeff0(m, n_neg);
774  res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last);
775  lp = (lp + lq) - shorter;
776  pSetCoeff0(m, n_old);
777  n_Delete(&n_neg, r);
778  return res;
779}
780
781PINLINE2 poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, const ring r)
782{
783  int lp = 0, lq = 0;
784  return p_Plus_mm_Mult_qq(p, m, q, lp, lq, r);
785}
786
787PINLINE2 poly p_Merge_q(poly p, poly q, const ring r)
788{
789  return r->p_Procs->p_Merge_q(p, q, r);
790}
791
792PINLINE2 poly p_SortAdd(poly p, const ring r, BOOLEAN revert)
793{
794  if (revert) p = pReverse(p);
795  return sBucketSortAdd(p, r);
796}
797
798PINLINE2 poly p_SortMerge(poly p, const ring r, BOOLEAN revert)
799{
800  if (revert) p = pReverse(p);
801  return sBucketSortMerge(p, r);
802}
803
804/***************************************************************
805 *
806 * I/O
807 *
808 ***************************************************************/
809PINLINE2 char*     p_String(poly p, ring p_ring)
810{
811  return p_String(p, p_ring, p_ring);
812}
813PINLINE2 char*     p_String0(poly p, ring p_ring)
814{
815  return p_String0(p, p_ring, p_ring);
816}
817PINLINE2 void      p_Write(poly p, ring p_ring)
818{
819  p_Write(p, p_ring, p_ring);
820}
821PINLINE2 void      p_Write0(poly p, ring p_ring)
822{
823  p_Write0(p, p_ring, p_ring);
824}
825PINLINE2 void      p_wrp(poly p, ring p_ring)
826{
827  p_wrp(p, p_ring, p_ring);
828}
829#endif // !defined(NO_PINLINE2) || defined(POLYS_IMPL_CC)
830#endif // PINLINE2_H
Note: See TracBrowser for help on using the repository browser.