source: git/Singular/pInline1.h @ 0f98876

fieker-DuValspielwiese
Last change on this file since 0f98876 was 0f98876, checked in by Olaf Bachmann <obachman@…>, 24 years ago
towards strat->tailRing git-svn-id: file:///usr/local/Singular/svn/trunk@4672 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    pInline1.h
6 *  Purpose: implementation of poly procs which iter over ExpVector
7 *  Author:  obachman (Olaf Bachmann)
8 *  Created: 8/00
9 *  Version: $Id: pInline1.h,v 1.9 2000-10-26 06:39:29 obachman Exp $
10 *******************************************************************/
11#ifndef PINLINE1_H
12#define PINLINE1_H
13
14#ifndef PDIV_DEBUG
15// define to enable debugging/statistics of pLmShortDivisibleBy
16#undef PDIV_DEBUG
17#endif
18#include <limits.h>
19
20#include "mod2.h"
21#include "structs.h"
22#include "p_MemCmp.h"
23#include "polys-impl.h"
24
25#if PDEBUG > 0 || defined(NO_PINLINE1)
26
27#define _p_LmCmpAction(p, q, r, actionE, actionG, actionS)  \
28do                                                          \
29{                                                           \
30  int _cmp = p_LmCmp(p,q,r);                                \
31  if (_cmp == 0) actionE;                                   \
32  if (_cmp == 1) actionG;                                   \
33  actionS;                                                  \
34}                                                           \
35while(0)
36
37#else
38
39#define _p_LmCmpAction(p, q, r, actionE, actionG, actionS)                      \
40 p_MemCmp_LengthGeneral_OrdGeneral(p->exp, q->exp, r->pCompLSize, r->ordsgn,    \
41                                   actionE, actionG, actionS)
42
43#endif
44
45#ifdef PDIV_DEBUG
46BOOLEAN pDebugLmShortDivisibleBy(poly p1, unsigned long sev_1, ring r_1,
47                                 poly p2, unsigned long not_sev_2, ring r_2);
48BOOLEAN p_DebugLmDivisibleByNoComp(poly a, poly b, ring r);
49#define pDivAssume  pAssume
50#else
51#define pDivAssume(x)   ((void)0)
52#endif
53
54#if !defined(NO_PINLINE1) || defined(PINLINE1_CC)
55
56#include "omalloc.h"
57#include "numbers.h"
58#include "p_polys.h"
59#include "p_MemAdd.h"
60#include "p_MemCopy.h"
61
62/***************************************************************
63 *
64 * Allocation/Initalization/Deletion
65 *
66 ***************************************************************/
67PINLINE1 poly p_Init(ring r, omBin bin)
68{
69  p_CheckRing1(r);
70  pAssume1(bin != NULL && r->PolyBin->sizeW == bin->sizeW);
71  poly p;
72  omTypeAlloc0Bin(poly, p, bin);
73  p_SetRingOfPoly(p, r);
74  return p;
75}
76PINLINE1 poly p_Init(ring r)
77{
78  return p_Init(r, r->PolyBin);
79}
80
81PINLINE1 poly p_LmInit(poly p, ring r)
82{
83  p_LmCheckPolyRing1(p, r);
84  poly np;
85  omTypeAllocBin(poly, np, r->PolyBin);
86  p_SetRingOfPoly(np, r);
87  p_ExpVectorCopy(np, p, r);
88  _pNext(np) = NULL;
89  _pSetCoeff0(np, NULL);
90  return np;
91}
92PINLINE1 poly p_LmInit(poly s_p, ring s_r, ring d_r)
93{
94  pAssume1(d_r != NULL);
95  return p_LmInit(s_p, s_r, d_r, d_r->PolyBin);
96}
97PINLINE1 poly p_LmInit(poly s_p, ring s_r, ring d_r, omBin d_bin)
98{
99  p_LmCheckPolyRing1(s_p, s_r);
100  p_CheckRing(d_r);
101  pAssume1(d_r->N <= s_r->N);
102  poly d_p = p_Init(d_r, d_bin);
103  for (int i=1; i<=d_r->N;i++)
104  {
105    p_SetExp(d_p, i, p_GetExp(s_p, i,s_r), d_r);
106  }
107  if (rRing_has_Comp(d_r))
108  {
109    p_SetComp(d_p, p_GetComp(s_p,s_r), d_r);
110  }
111  p_Setm(d_p, d_r);
112  return d_p;
113}
114PINLINE1 poly p_Head(poly p, ring r)
115{
116  if (p == NULL) return NULL;
117  p_LmCheckPolyRing1(p, r);
118  poly np;
119  omTypeAllocBin(poly, np, r->PolyBin);
120  p_SetRingOfPoly(np, r);
121  p_ExpVectorCopy(np, p, r);
122  _pNext(np) = NULL;
123  _pSetCoeff0(np, n_Copy(_pGetCoeff(p), r));
124  return np;
125}
126
127PINLINE1 poly p_LmShallowCopyDelete(poly p, const ring r, omBin bin)
128{
129  p_LmCheckPolyRing1(p, r);
130  pAssume1(bin->sizeW == r->PolyBin->sizeW);
131  poly new_p = p_New(r);
132  p_MemCopy_LengthGeneral(new_p->exp, p->exp, r->ExpLSize);
133  pSetCoeff0(new_p, pGetCoeff(p));
134  pNext(new_p) = pNext(p);
135  omFreeBinAddr(p);
136  return new_p;
137}
138
139/***************************************************************
140 *
141 * Operation on ExpVectors
142 *
143 ***************************************************************/
144// ExpVextor(d_p) = ExpVector(s_p)
145PINLINE1 void p_ExpVectorCopy(poly d_p, poly s_p, ring r)
146{
147  p_LmCheckPolyRing1(d_p, r);
148  p_LmCheckPolyRing1(s_p, r);
149  p_MemCopy_LengthGeneral(d_p->exp, s_p->exp, r->ExpLSize);
150}
151// ExpVector(p1) += ExpVector(p2)
152PINLINE1 void p_ExpVectorAdd(poly p1, poly p2, ring r)
153{
154  p_LmCheckPolyRing1(p1, r);
155  p_LmCheckPolyRing1(p2, r);
156#if PDEBUG >= 1
157  for (int i=1; i<=r->N; i++)
158    pAssume1((unsigned long) (p_GetExp(p1, i, r) + p_GetExp(p2, i, r)) <= r->bitmask);
159  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0);
160#endif
161 
162  p_MemAdd_LengthGeneral(p1->exp, p2->exp, r->ExpLSize);
163}
164// ExpVector(p1) -= ExpVector(p2)
165PINLINE1 void p_ExpVectorSub(poly p1, poly p2, ring r)
166{
167  p_LmCheckPolyRing1(p1, r);
168  p_LmCheckPolyRing1(p2, r);
169#if PDEBUG >= 1
170  for (int i=1; i<=r->N; i++)
171    pAssume1(p_GetExp(p1, i, r) >= p_GetExp(p2, i, r));
172  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0 ||
173          p_GetComp(p1, r) == p_GetComp(p2, r));
174#endif
175 
176  p_MemSub_LengthGeneral(p1->exp, p2->exp, r->ExpLSize);
177}
178// ExpVector(p1) += ExpVector(p2) - ExpVector(p3)
179PINLINE1 void p_ExpVectorAddSub(poly p1, poly p2, poly p3, ring r)
180{
181  p_LmCheckPolyRing1(p1, r);
182  p_LmCheckPolyRing1(p2, r);
183  p_LmCheckPolyRing1(p3, r);
184#if PDEBUG >= 1
185  for (int i=1; i<=r->N; i++)
186    pAssume1(p_GetExp(p1, i, r) + p_GetExp(p2, i, r) >= p_GetExp(p3, i, r));
187  pAssume1(p_GetComp(p1, r) == 0 || 
188           (p_GetComp(p2, r) - p_GetComp(p3, r) == 0) ||
189           (p_GetComp(p1, r) == p_GetComp(p2, r) - p_GetComp(p3, r)));
190#endif
191 
192  p_MemAddSub_LengthGeneral(p1->exp, p2->exp, p3->exp, r->ExpLSize);
193}
194// ExpVector(pr) = ExpVector(p1) + ExpVector(p2)
195PINLINE1 void p_ExpVectorSum(poly pr, poly p1, poly p2, ring r)
196{
197  p_LmCheckPolyRing1(p1, r);
198  p_LmCheckPolyRing1(p2, r);
199  p_LmCheckPolyRing1(pr, r);
200#if PDEBUG >= 1
201  for (int i=1; i<=r->N; i++)
202    pAssume1((unsigned long) (p_GetExp(p1, i, r) + p_GetExp(p2, i, r)) <= r->bitmask);
203  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0);
204#endif 
205
206  p_MemSum_LengthGeneral(pr->exp, p1->exp, p2->exp, r->ExpLSize);
207}
208// ExpVector(pr) = ExpVector(p1) - ExpVector(p2)
209PINLINE1 void p_ExpVectorDiff(poly pr, poly p1, poly p2, ring r)
210{
211  p_LmCheckPolyRing1(p1, r);
212  p_LmCheckPolyRing1(p2, r);
213  p_LmCheckPolyRing1(pr, r);
214#if PDEBUG >= 2
215  for (int i=1; i<=r->N; i++)
216    pAssume1(p_GetExp(p1, i, r) >= p_GetExp(p2, i, r));
217  pAssume1(!rRing_has_Comp(r) || p_GetComp(p1, r) == p_GetComp(p2, r));
218#endif
219 
220  p_MemDiff_LengthGeneral(pr->exp, p1->exp, p2->exp, r->ExpLSize);
221}
222
223PINLINE1 BOOLEAN p_ExpVectorEqual(poly p1, poly p2, ring r)
224{
225  p_LmCheckPolyRing1(p1, r);
226  p_LmCheckPolyRing1(p2, r);
227 
228  int i = r->ExpLSize;
229  unsigned long *ep = p1->exp;
230  unsigned long *eq = p2->exp;
231
232  do
233  {
234    i--;
235    if (ep[i] != eq[i]) return FALSE;
236  }
237  while (i);
238  return TRUE;
239}
240
241PINLINE1 unsigned long p_ExpVectorQuerSum(poly p, ring r)
242{
243  p_LmCheckPolyRing1(p, r);
244  unsigned long s = 0;
245  unsigned long i = r->N;
246 
247  do
248  {
249    s += p_GetExp(p, i, r);
250    i--;
251  }
252  while (i);
253  return s;
254}
255
256PINLINE1 void p_GetExpV(poly p, Exponent_t *ev, ring r)
257{
258  p_LmCheckPolyRing1(p, r);
259  for (int j = r->N; j; j--)
260      ev[j] = p_GetExp(p, j, r);
261
262  ev[0] = _p_GetComp(p, r);
263}
264PINLINE1 void p_SetExpV(poly p, Exponent_t *ev, ring r)
265{
266  p_LmCheckPolyRing1(p, r);
267  for (int j = r->N; j; j--)
268      p_SetExp(p, j, ev[j], r);
269
270  p_SetComp(p, ev[0],r);
271  p_Setm(p, r);
272}
273
274/***************************************************************
275 *
276 * Comparison w.r.t. monomial ordering
277 *
278 ***************************************************************/
279PINLINE1 int p_LmCmp(poly p, poly q, ring r)
280{
281  p_LmCheckPolyRing1(p, r);
282  p_LmCheckPolyRing1(q, r);
283
284  p_MemCmp_LengthGeneral_OrdGeneral(p->exp, q->exp, r->pCompLSize, r->ordsgn, 
285                                    return 0, return 1, return -1);
286}
287
288
289/***************************************************************
290 *
291 * divisibility
292 *
293 ***************************************************************/
294// return: FALSE, if there exists i, such that a->exp[i] > b->exp[i]
295//         TRUE, otherwise
296// (1) Consider long vars, instead of single exponents
297// (2) Clearly, if la > lb, then FALSE
298// (3) Suppose la <= lb, and consider first bits of single exponents in l:
299//     if TRUE, then value of these bits is la ^ lb
300//     if FALSE, then la-lb causes an "overflow" into one of those bits, i.e.,
301//               la ^ lb != la - lb
302static inline BOOLEAN _p_LmDivisibleByNoComp(poly a, poly b, ring r)
303{
304  int i=r->VarL_Size - 1;
305  unsigned long divmask = r->divmask;
306  unsigned long la, lb;
307 
308  if (r->VarL_LowIndex >= 0)
309  {
310    i += r->VarL_LowIndex;
311    do
312    {
313      la = a->exp[i];
314      lb = b->exp[i];
315      if ((la > lb) || 
316          (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
317      {
318        pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
319        return FALSE;
320      }
321      i--;
322    }
323    while (i>=r->VarL_LowIndex);
324  }
325  else
326  {
327    do
328    {
329      la = a->exp[r->VarL_Offset[i]];
330      lb = b->exp[r->VarL_Offset[i]];
331      if ((la > lb) || 
332          (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
333      {
334        pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
335        return FALSE;
336      }
337      i--;
338    }
339    while (i>=0);
340  }
341  pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == TRUE);
342  return TRUE;
343}
344
345static inline BOOLEAN _p_LmDivisibleByNoComp(poly a, ring r_a, poly b, ring r_b)
346{
347  int i=r_a->N;
348  pAssume1(r_a->N == r_b->N);
349
350  do
351  {
352    if (p_GetExp(a,i,r_a) > p_GetExp(b,i,r_b))
353      return FALSE;
354    i--;
355  }
356  while (i);
357  return TRUE;
358}
359static inline BOOLEAN _p_LmDivisibleBy(poly a, poly b, ring r)
360{
361  if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))
362    return _p_LmDivisibleByNoComp(a, b, r);
363  return FALSE;
364}
365static inline BOOLEAN _p_LmDivisibleBy(poly a, ring r_a, poly b, ring r_b)
366{
367  if (p_GetComp(a, r_a) == 0 || p_GetComp(a,r_a) == p_GetComp(b,r_b))
368    return _p_LmDivisibleByNoComp(a, r_a, b, r_b);
369  return FALSE;
370}
371PINLINE1 BOOLEAN p_LmDivisibleByNoComp(poly a, poly b, ring r)
372{
373  p_LmCheckPolyRing1(a, r);
374  p_LmCheckPolyRing1(b, r);
375  return _p_LmDivisibleByNoComp(a, b, r);
376}
377PINLINE1 BOOLEAN p_LmDivisibleBy(poly a, poly b, ring r)
378{
379  p_LmCheckPolyRing1(b, r);
380  pIfThen1(a != NULL, p_LmCheckPolyRing1(b, r));
381  if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))
382    return _p_LmDivisibleByNoComp(a, b, r);
383  return FALSE;
384}
385PINLINE1 BOOLEAN p_DivisibleBy(poly a, poly b, ring r)
386{
387  pIfThen1(b!=NULL, p_LmCheckPolyRing1(b, r));
388  pIfThen1(a!=NULL, p_LmCheckPolyRing1(a, r));
389 
390  if (a != NULL && (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r)))
391    return _p_LmDivisibleByNoComp(a,b,r);
392  return FALSE;
393}
394PINLINE1 BOOLEAN p_DivisibleBy(poly a, ring r_a, poly b, ring r_b)
395{
396  pIfThen1(b!=NULL, p_LmCheckPolyRing1(b, r_b));
397  pIfThen1(a!=NULL, p_LmCheckPolyRing1(a, r_a));
398  if (a != NULL) return _p_LmDivisibleBy(a, r_a, b, r_b);
399  return FALSE;
400}
401PINLINE1 BOOLEAN p_LmDivisibleBy(poly a, ring r_a, poly b, ring r_b)
402{
403  p_LmCheckPolyRing(a, r_a);
404  p_LmCheckPolyRing(b, r_b);
405  return _p_LmDivisibleBy(a, r_a, b, r_b);
406}
407PINLINE1 BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, 
408                                    poly b, unsigned long not_sev_b, ring r)
409{
410  p_LmCheckPolyRing1(a, r);
411  p_LmCheckPolyRing1(b, r);
412#ifndef PDIV_DEBUG
413  _pPolyAssume2(p_GetShortExpVector(a, r) == sev_a, a, r);
414  _pPolyAssume2(p_GetShortExpVector(b, r) == ~ not_sev_b, b, r);
415 
416  if (sev_a & not_sev_b) 
417  {
418    pAssume1(p_LmDivisibleByNoComp(a, b, r) == FALSE);
419    return FALSE;
420  }
421  return p_LmDivisibleBy(a, b, r);
422#else
423  return pDebugLmShortDivisibleBy(a, sev_a, r, b, not_sev_b, r);
424#endif
425}
426
427PINLINE1 BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, ring r_a,
428                                    poly b, unsigned long not_sev_b, ring r_b)
429{
430  p_LmCheckPolyRing1(a, r_a);
431  p_LmCheckPolyRing1(b, r_b);
432#ifndef PDIV_DEBUG
433  _pPolyAssume2(p_GetShortExpVector(a, r_a) == sev_a, a, r_a);
434  _pPolyAssume2(p_GetShortExpVector(b, r_b) == ~ not_sev_b, b, r_b);
435 
436  if (sev_a & not_sev_b) 
437  {
438    pAssume1(_p_LmDivisibleByNoComp(a, r_a, b, r_b) == FALSE);
439    return FALSE;
440  }
441  return _p_LmDivisibleBy(a, r_a, b, r_b);
442#else
443  return pDebugLmShortDivisibleBy(a, sev_a, r_a, b, not_sev_b, r_b);
444#endif
445}
446
447/***************************************************************
448 *
449 * Misc things on Lm
450 *
451 ***************************************************************/
452// test if the monomial is a constant as a vector component
453// i.e., test if all exponents are zero
454PINLINE1 BOOLEAN p_LmIsConstantComp(const poly p, const ring r)
455{
456  p_LmCheckPolyRing(p, r);
457  int i = r->VarL_Size - 1;
458 
459  do
460  {
461    if (p->exp[r->VarL_Offset[i]] != 0) 
462      return FALSE;
463    i--;
464  }
465  while (i >= 0);
466  return TRUE;
467}
468
469PINLINE1 BOOLEAN p_LmExpVectorAddIsOk(const poly p1, const poly p2, 
470                                      const ring r)
471{
472  p_LmCheckPolyRing(p1, r);
473  p_LmCheckPolyRing(p2, r);
474  unsigned long l1, l2, divmask = r->divmask;
475  int i;
476     
477  for (i=0; i<r->VarL_Size; i++)
478  {
479    l1 = p1->exp[r->VarL_Offset[i]];
480    l2 = p2->exp[r->VarL_Offset[i]];
481    // do the divisiblity trick
482    if ( (l1 > ULONG_MAX - l2) || 
483         (((l1 & divmask) ^ (l2 & divmask)) != ((l1 + l2) & divmask)))
484      return FALSE;
485  }
486  return TRUE;
487}
488
489PINLINE1 Exponent_t p_GetMaxExp(unsigned long l, ring r)
490{
491  long shift = (BIT_SIZEOF_LONG - r->BitsPerExp);
492  unsigned long max = 0;
493  Exponent_t e;
494 
495  for (;shift >= 0; shift -= r->BitsPerExp)
496  {
497    e = ((l >> shift) & r->bitmask);
498    if ((unsigned long) e > max) 
499      max = e;
500  }
501  return max;
502}
503
504#endif // !defined(NO_PINLINE1) || defined(PINLINE1_CC)
505#endif // PINLINE1_CC
506
Note: See TracBrowser for help on using the repository browser.