# source:git/Singular/pInline2.h@f5d749

spielwiese
Last change on this file since f5d749 was f5d749, checked in by Olaf Bachmann <obachman@…>, 23 years ago
• Property mode set to `100644`
File size: 13.6 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.22 2000-12-05 13:01:11 obachman 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 "tok.h"
22#include "omalloc.h"
23#include "numbers.h"
24#include "p_Procs.h"
25
26PINLINE2 number p_SetCoeff(poly p, number n, ring r)
27{
28  p_LmCheckPolyRing2(p, r);
29  n_Delete(&(p->coef), r);
30  (p)->coef=n;
31  return n;
32}
33
34// order
35PINLINE2 Order_t p_GetOrder(poly p, ring r)
36{
37  p_LmCheckPolyRing2(p, r);
38  if (r->typ==NULL) return ((p)->exp[r->pOrdIndex]);
39  int i=0;
40  loop
41  {
42    switch(r->typ[i].ord_typ)
43    {
44      case ro_wp_neg:
45        return (((long)((p)->exp[r->pOrdIndex]))-((long) POLY_NEGWEIGHT_OFFSET));
46      case ro_syzcomp:
47      case ro_syz:
48      case ro_cp:
49        i++;
50        break;
51      //case ro_dp:
52      //case ro_wp:
53      default:
54        return ((p)->exp[r->pOrdIndex]);
55    }
56  }
57}
58
59PINLINE2 Order_t p_SetOrder(poly p, long o, ring r)
60{
61  p_LmCheckPolyRing2(p, r);
62  pAssume2(o >= 0);
63  if (r->typ==NULL) return ((p)->exp[r->pOrdIndex]=o);
64  int i=0;
65  loop
66  {
67    switch(r->typ[i].ord_typ)
68    {
69      case ro_wp_neg:
70        return (p)->exp[r->pOrdIndex]=o+POLY_NEGWEIGHT_OFFSET;
71      case ro_syzcomp:
72      case ro_syz:
73      case ro_cp:
74        i++;
75        break;
76      //case ro_dp:
77      //case ro_wp:
78      default:
79        return (p)->exp[r->pOrdIndex] = o;
80    }
81  }
82  return (p)->exp[r->pOrdIndex] = o;
83}
84
85// Setm
86PINLINE2 void p_Setm(poly p, ring r)
87{
88  p_CheckRing2(r);
89  r->p_Setm(p, r);
90}
91
92// component
93PINLINE2  unsigned long p_SetComp(poly p, unsigned long c, ring r)
94{
95  p_LmCheckPolyRing2(p, r);
96  pAssume2(rRing_has_Comp(r));
97  __p_GetComp(p,r) = c;
98  return c;
99}
100PINLINE2 unsigned long p_IncrComp(poly p, ring r)
101{
102  p_LmCheckPolyRing2(p, r);
103  pAssume2(rRing_has_Comp(r));
104  return ++(__p_GetComp(p,r));
105}
106PINLINE2 unsigned long p_DecrComp(poly p, ring r)
107{
108  p_LmCheckPolyRing2(p, r);
109  pAssume2(rRing_has_Comp(r));
110  pPolyAssume2(__p_GetComp(p,r) > 0);
111  return --(__p_GetComp(p,r));
112}
113PINLINE2 unsigned long p_AddComp(poly p, unsigned long v, ring r)
114{
115  p_LmCheckPolyRing2(p, r);
116  pAssume2(rRing_has_Comp(r));
117  return __p_GetComp(p,r) += v;
118}
119PINLINE2 unsigned long p_SubComp(poly p, unsigned long v, ring r)
120{
121  p_LmCheckPolyRing2(p, r);
122  pAssume2(rRing_has_Comp(r));
123  pPolyAssume2(__p_GetComp(p,r) >= v);
124  return __p_GetComp(p,r) -= v;
125}
126
127// exponent
128// r->VarOffset encodes the position in p->exp (lower 24 bits)
129// and number of bits to shift to the right in the upper 8 bits
130PINLINE2 Exponent_t p_GetExp(poly p, int v, ring r)
131{
132  p_LmCheckPolyRing2(p, r);
133  pAssume2(v > 0 && v <= r->N);
134  return (p->exp[(r->VarOffset[v] & 0xffffff)] >> (r->VarOffset[v] >> 24))
136}
137PINLINE2 Exponent_t p_SetExp(poly p, int v, int e, ring r)
138{
139  p_LmCheckPolyRing2(p, r);
140  pAssume2(v>0 && v <= r->N);
141  pAssume2(e>=0);
143
144  // shift e to the left:
145  register int shift = r->VarOffset[v] >> 24;
146  unsigned long ee = ((unsigned long)e) << shift /*(r->VarOffset[v] >> 24)*/;
147  // clear the bits in the exponent vector:
148  register int offset = (r->VarOffset[v] & 0xffffff);
149  p->exp[offset]  &=
150    ~( r->bitmask << shift );
151  // insert e with |
152  p->exp[ offset ] |= ee;
153  return e;
154}
155
156// the following should be implemented more efficiently
157PINLINE2  Exponent_t p_IncrExp(poly p, int v, ring r)
158{
159  p_LmCheckPolyRing2(p, r);
160  Exponent_t e = p_GetExp(p,v,r);
161  e++;
162  return p_SetExp(p,v,e,r);
163}
164PINLINE2  Exponent_t p_DecrExp(poly p, int v, ring r)
165{
166  p_LmCheckPolyRing2(p, r);
167  Exponent_t e = p_GetExp(p,v,r);
168  pAssume2(e > 0);
169  e--;
170  return p_SetExp(p,v,e,r);
171}
172PINLINE2  Exponent_t p_AddExp(poly p, int v, Exponent_t ee, ring r)
173{
174  p_LmCheckPolyRing2(p, r);
175  Exponent_t e = p_GetExp(p,v,r);
176  e += ee;
177  return p_SetExp(p,v,e,r);
178}
179PINLINE2  Exponent_t p_SubExp(poly p, int v, Exponent_t ee, ring r)
180{
181  p_LmCheckPolyRing2(p, r);
182  Exponent_t e = p_GetExp(p,v,r);
183  pAssume2(e >= ee);
184  e -= ee;
185  return p_SetExp(p,v,e,r);
186}
187PINLINE2  Exponent_t p_MultExp(poly p, int v, Exponent_t ee, ring r)
188{
189  p_LmCheckPolyRing2(p, r);
190  Exponent_t e = p_GetExp(p,v,r);
191  e *= ee;
192  return p_SetExp(p,v,e,r);
193}
194
195PINLINE2 Exponent_t p_GetExpSum(poly p1, poly p2, int i, ring r)
196{
197  p_LmCheckPolyRing2(p1, r);
198  p_LmCheckPolyRing2(p2, r);
199  return p_GetExp(p1,i,r) + p_GetExp(p2,i,r);
200}
201PINLINE2 Exponent_t p_GetExpDiff(poly p1, poly p2, int i, ring r)
202{
203  return p_GetExp(p1,i,r) - p_GetExp(p2,i,r);
204}
205
206
207/***************************************************************
208 *
209 * Allocation/Initalization/Deletion
210 *
211 ***************************************************************/
212PINLINE2 poly p_New(ring r, omBin bin)
213{
214  p_CheckRing2(r);
215  pAssume2(bin != NULL && r->PolyBin->sizeW == bin->sizeW);
216  poly p;
217  omTypeAllocBin(poly, p, bin);
218  p_SetRingOfLm(p, r);
219  return p;
220}
221
222PINLINE2 poly p_New(ring r)
223{
224  return p_New(r, r->PolyBin);
225}
226
227PINLINE2 void p_DeleteLm(poly *p, ring r)
228{
229  pIfThen2(*p != NULL, p_LmCheckPolyRing2(*p, r));
230  poly h = *p;
231  if (h != NULL)
232  {
233    n_Delete(&_pGetCoeff(h), r);
234    *p = _pNext(h);
236  }
237}
238PINLINE2 void p_DeleteLm(poly p, ring r)
239{
240  pIfThen2(p != NULL, p_LmCheckPolyRing2(p, r));
241  if (p != NULL)
242  {
243    n_Delete(&_pGetCoeff(p), r);
245  }
246}
247PINLINE2 void p_LmFree(poly p, ring r)
248{
249  p_LmCheckPolyRing2(p, r);
251}
252PINLINE2 void p_LmFree(poly *p, ring r)
253{
254  p_LmCheckPolyRing2(*p, r);
255  poly h = *p;
256  *p = pNext(h);
258}
259PINLINE2 poly p_LmFreeAndNext(poly p, ring r)
260{
261  p_LmCheckPolyRing2(p, r);
262  poly pnext = pNext(p);
264  return pnext;
265}
266PINLINE2 void p_LmDelete(poly p, ring r)
267{
268  p_LmCheckPolyRing2(p, r);
269  n_Delete(&_pGetCoeff(p), r);
271}
272PINLINE2 void p_LmDelete(poly *p, ring r)
273{
274  p_LmCheckPolyRing2(*p, r);
275  poly h = *p;
276  *p = pNext(h);
277  n_Delete(&pGetCoeff(h), r);
279}
280PINLINE2 poly p_LmDeleteAndNext(poly p, ring r)
281{
282  p_LmCheckPolyRing2(p, r);
283  poly pnext = _pNext(p);
284  n_Delete(&_pGetCoeff(p), r);
286  return pnext;
287}
288
289/***************************************************************
290 *
291 * Misc routines
292 *
293 ***************************************************************/
294PINLINE2 int p_Cmp(poly p1, poly p2, ring r)
295{
296  if (p2==NULL)
297    return 1;
298  if (p1==NULL)
299    return -1;
300  return p_LmCmp(p1,p2,r);
301}
302
303PINLINE2 Exponent_t p_GetMaxExp(poly p, ring r)
304{
305  return p_GetMaxExp(p_GetMaxExpL(p, r), r);
306}
307
308PINLINE2 Exponent_t
309p_GetMaxExp(const unsigned long l, const ring r, const int number_of_exps)
310{
312  unsigned long max = (l & bitmask);
313  unsigned long j = number_of_exps - 1;
314
315  if (j > 0)
316  {
317    unsigned long i = r->BitsPerExp;
318    Exponent_t e;
319    while(1)
320    {
321      e = ((l >> i) & bitmask);
322      if ((unsigned long) e > max)
323        max = e;
324      j--;
325      if (j==0) break;
326      i += r->BitsPerExp;
327    }
328  }
329  return max;
330}
331
332PINLINE2 Exponent_t p_GetMaxExp(const unsigned long l, const ring r)
333{
334  return p_GetMaxExp(l, r, r->ExpPerLong);
335}
336
337PINLINE2 unsigned long
338p_GetTotalDegree(const unsigned long l, const ring r, const int number_of_exps)
339{
341  unsigned long sum = (l & bitmask);
342  unsigned long j = number_of_exps - 1;
343
344  if (j > 0)
345  {
346    unsigned long i = r->BitsPerExp;
347    while(1)
348    {
349      sum += ((l >> i) & bitmask);
350      j--;
351      if (j==0) break;
352      i += r->BitsPerExp;
353    }
354  }
355  return sum;
356}
357
358PINLINE2 unsigned long
359p_GetTotalDegree(const unsigned long l, const ring r)
360{
361  return p_GetTotalDegree(l, r, r->ExpPerLong);
362}
363
364/***************************************************************
365 *
366 * Dispatcher to r->p_Procs, they do the tests/checks
367 *
368 ***************************************************************/
369// returns a copy of p
370PINLINE2 poly p_Copy(poly p, const ring r)
371{
372  return r->p_Procs->p_Copy(p, r);
373}
374
375PINLINE2 poly p_Copy(poly p, const ring lmRing, const ring tailRing)
376{
377#ifndef PDEBUG
378  if (tailRing == lmRing)
379    return tailRing->p_Procs->p_Copy(p, tailRing);
380#endif
381  if (p != NULL)
382  {
383    poly pres = p_Head(p, lmRing);
384    pNext(pres) = tailRing->p_Procs->p_Copy(pNext(p), tailRing);
385    return pres;
386  }
387  else
388    return NULL;
389}
390
391// deletes *p, and sets *p to NULL
392PINLINE2 void p_Delete(poly *p, const ring r)
393{
394  r->p_Procs->p_Delete(p, r);
395}
396
397PINLINE2 void p_Delete(poly *p,  const ring lmRing, const ring tailRing)
398{
399#ifndef PDEBUG
400  if (tailRing == lmRing)
401  {
402    tailRing->p_Procs->p_Delete(p, tailRing);
403    return;
404  }
405#endif
406  if (*p != NULL)
407  {
408    if (pNext(*p) != NULL)
409      tailRing->p_Procs->p_Delete(&pNext(*p), tailRing);
410    p_LmDelete(p, lmRing);
411  }
412}
413
414PINLINE2 poly p_ShallowCopyDelete(poly p, const ring r, omBin bin)
415{
416  p_LmCheckPolyRing2(p, r);
417  pAssume2(r->PolyBin->sizeW == bin->sizeW);
418  return r->p_Procs->p_ShallowCopyDelete(p, r, bin);
419}
420
421// returns p+q, destroys p and q
422PINLINE2 poly p_Add_q(poly p, poly q, const ring r)
423{
424  int shorter;
425  return r->p_Procs->p_Add_q(p, q, shorter, r);
426}
427
428PINLINE2 poly p_Add_q(poly p, poly q, int &lp, int lq, const ring r)
429{
430  int shorter;
431  poly res = r->p_Procs->p_Add_q(p, q, shorter, r);
432  lp = (lp + lq) - shorter;
433  return res;
434}
435
436// returns p*n, destroys p
437PINLINE2 poly p_Mult_nn(poly p, number n, const ring r)
438{
439  return r->p_Procs->p_Mult_nn(p, n, r);
440}
441
442PINLINE2 poly p_Mult_nn(poly p, number n, const ring lmRing,
443                        const ring tailRing)
444{
445#ifndef PDEBUG
446  if (lmRing == tailRing)
447  {
448    return p_Mult_nn(p, n, tailRing);
449  }
450#endif
451  poly pnext = pNext(p);
452  pNext(p) = NULL;
453  p = lmRing->p_Procs->p_Mult_nn(p, n, lmRing);
454  pNext(p) = tailRing->p_Procs->p_Mult_nn(pnext, n, tailRing);
455  return p;
456}
457
458// returns p*n, does not destroy p
459PINLINE2 poly pp_Mult_nn(poly p, number n, const ring r)
460{
461  return r->p_Procs->pp_Mult_nn(p, n, r);
462}
463
464// returns Copy(p)*m, does neither destroy p nor m
465PINLINE2 poly pp_Mult_mm(poly p, poly m, const ring r)
466{
467  poly last;
468  return r->p_Procs->pp_Mult_mm(p, m, r, last);
469}
470
471// returns p*m, destroys p, const: m
472PINLINE2 poly p_Mult_mm(poly p, poly m, const ring r)
473{
474  return r->p_Procs->p_Mult_mm(p, m, r);
475}
476
477// return p - m*Copy(q), destroys p; const: p,m
478PINLINE2 poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, const ring r)
479{
480  int shorter;
481  poly last;
482  return r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last);
483}
484PINLINE2 poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
485                                 poly spNoether, const ring r)
486{
487  int shorter;
488  poly last;
489  poly res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, spNoether, r, last);
490  lp = (lp + lq) - shorter;
491  return res;
492}
493
494PINLINE2 poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, const ring r)
495{
496  return r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, r);
497}
498
499// returns -p, destroys p
500PINLINE2 poly p_Neg(poly p, const ring r)
501{
502  return r->p_Procs->p_Neg(p, r);
503}
504
505extern poly  _p_Mult_q(poly p, poly q, const int copy, const ring r);
506// returns p*q, destroys p and q
507PINLINE2 poly p_Mult_q(poly p, poly q, const ring r)
508{
509  if (p == NULL)
510  {
511    r->p_Procs->p_Delete(&q, r);
512    return NULL;
513  }
514  if (q == NULL)
515  {
516    r->p_Procs->p_Delete(&p, r);
517    return NULL;
518  }
519
520  if (pNext(p) == NULL)
521  {
522#ifdef HAVE_PLURAL
523    if (rIsPluralRing(r))
524      q = r->p_Procs->nc_mm_Mult_p(p, q, r);
525    else
526#endif HAVE_PLURAL
527      q = r->p_Procs->p_Mult_mm(q, p, r);
528
529    r->p_Procs->p_Delete(&p, r);
530    return q;
531  }
532
533  if (pNext(q) == NULL)
534  {
535    p = r->p_Procs->p_Mult_mm(p, q, r);
536    r->p_Procs->p_Delete(&q, r);
537    return p;
538  }
539
540  return _p_Mult_q(p, q, 0, r);
541}
542
543// returns p*q, does neither destroy p nor q
544PINLINE2 poly pp_Mult_qq(poly p, poly q, const ring r)
545{
546  poly last;
547  if (p == NULL || q == NULL) return NULL;
548
549  if (pNext(p) == NULL)
550    return r->p_Procs->pp_Mult_mm(q, p, r, last);
551
552  if (pNext(q) == NULL)
553    return r->p_Procs->pp_Mult_mm(p, q, r, last);
554
555  poly qq = q;
556  if (p == q)
557    qq = p_Copy(q, r);
558
559  poly res = _p_Mult_q(p, qq, 1, r);
560  if (qq != q)
561    p_Delete(&qq, r);
562  return res;
563}
564
565// returns p + m*q destroys p, const: q, m
566// this should be implemented more efficiently
567PINLINE2 poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, const ring r)
568{
569  poly res, last;
570  int shorter;
571  number n_old = pGetCoeff(m);
572  number n_neg = n_Copy(n_old, r);
573  n_neg = n_Neg(n_neg, r);
574  pSetCoeff0(m, n_neg);
575
576  res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last);
577  pSetCoeff0(m, n_old);
578  n_Delete(&n_neg, r);
579  return res;
580}
581
582PINLINE2 poly p_Merge_q(poly p, poly q, const ring r)
583{
584  return r->p_Procs->p_Merge_q(p, q, r);
585}
586
587/***************************************************************
588 *
589 * I/O
590 *
591 ***************************************************************/
592PINLINE2 char*     p_String(poly p, ring p_ring)
593{
594  return p_String(p, p_ring, p_ring);
595}
596PINLINE2 char*     p_String0(poly p, ring p_ring)
597{
598  return p_String0(p, p_ring, p_ring);
599}
600PINLINE2 void      p_Write(poly p, ring p_ring)
601{
602  p_Write(p, p_ring, p_ring);
603}
604PINLINE2 void      p_Write0(poly p, ring p_ring)
605{
606  p_Write0(p, p_ring, p_ring);
607}
608PINLINE2 void      p_wrp(poly p, ring p_ring)
609{
610  p_wrp(p, p_ring, p_ring);
611}
612#endif // !defined(NO_PINLINE2) || defined(POLYS_IMPL_CC)
613#endif // PINLINE2_H
614
Note: See TracBrowser for help on using the repository browser.