source: git/libpolys/polys/pDebug.cc @ a40080

spielwiese
Last change on this file since a40080 was a40080, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
CHG: minor changes
  • Property mode set to 100644
File size: 9.8 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    pDebug.h
6 *  Purpose: implementation of debug related poly routines
7 *  Author:  obachman (Olaf Bachmann)
8 *  Created: 8/00
9 *  Version: $Id$
10 *******************************************************************/
11
12#ifndef PDEBUG_CC
13#define PDEBUG_CC
14
15#include <stdarg.h>
16#include <stdio.h>
17
18
19#include "config.h"
20#include <misc/auxiliary.h>
21
22
23#ifdef PDEBUG
24
25// do the following to always enforce checking of pSetm
26// #undef PDEBUG
27// #define PDEBUG 2
28
29#include <omalloc/omalloc.h>
30
31#include <polys/monomials/ring.h>
32#include <polys/monomials/p_polys.h>
33
34#include <coeffs/coeffs.h>
35
36/***************************************************************
37 *
38 * Error reporting
39 *
40 ***************************************************************/
41// avoid recursive calls
42static BOOLEAN d_poly_error_reporting = FALSE;
43BOOLEAN dPolyReportError(poly p, ring r, const char* fmt, ...)
44{
45  if (d_poly_error_reporting) return FALSE;
46  d_poly_error_reporting = TRUE;
47  va_list ap;
48  va_start(ap, fmt);
49
50  fprintf(stderr, "\n// ***dPolyError: ");
51  vfprintf(stderr, fmt, ap);
52  fprintf(stderr, "\n occured at\n");
53  omPrintCurrentBackTraceMax(stderr, 8);
54  if (p != NULL)
55  {
56    fprintf(stderr, " occured for poly: ");
57    p_wrp(p, r);
58    omPrintAddrInfo(stderr, p, " ");
59  }
60  dErrorBreak();
61  d_poly_error_reporting = FALSE;
62  return FALSE;
63}
64
65/***************************************************************
66 *
67 * checking for ring stuff
68 *
69 ***************************************************************/
70BOOLEAN p_LmCheckIsFromRing(poly p, ring r)
71{
72  if (p != NULL)
73  {
74    #if (OM_TRACK > 0) && defined(OM_TRACK_CUSTOM)
75    void* custom = omGetCustomOfAddr(p);
76    if (custom != NULL)
77    {
78      pPolyAssumeReturnMsg(custom == r ||
79                           // be more sloppy for qrings
80                           (r->qideal != NULL &&
81                            omIsBinPageAddr(p) &&
82                            omSizeWOfAddr(p)==r->PolyBin->sizeW) ||
83                           rSamePolyRep((ring) custom, r),
84                           "monomial not from specified ring",p,r);
85      return TRUE;
86    }
87    else
88    #endif
89    {
90      _pPolyAssumeReturn(omIsBinPageAddr(p) && omSizeWOfAddr(p)==r->PolyBin->sizeW,p,r);
91      return TRUE;
92    }
93    return FALSE;
94  }
95  return TRUE;
96}
97
98BOOLEAN p_CheckIsFromRing(poly p, ring r)
99{
100  while (p!=NULL)
101  {
102    pFalseReturn(p_LmCheckIsFromRing(p, r));
103    pIter(p);
104  }
105  return TRUE;
106}
107
108BOOLEAN p_CheckPolyRing(poly p, ring r)
109{
110  pAssumeReturn(r != NULL && r->PolyBin != NULL);
111  return p_CheckIsFromRing(p, r);
112}
113
114BOOLEAN p_LmCheckPolyRing(poly p, ring r)
115{
116  pAssumeReturn(r != NULL && r->PolyBin != NULL);
117  pAssumeReturn(p != NULL);
118  return p_LmCheckIsFromRing(p, r);
119}
120BOOLEAN p_CheckRing(ring r)
121{
122  pAssumeReturn(r != NULL && r->PolyBin != NULL);
123  return TRUE;
124}
125
126/***************************************************************
127 *
128 * Debugging/statistics of pDivisibleBy
129 *
130 ***************************************************************/
131BOOLEAN p_DebugLmDivisibleByNoComp(poly a, poly b, ring r)
132{
133  int i=r->N;
134
135  do
136  {
137    if (p_GetExp(a,i,r) > p_GetExp(b,i,r))
138      return FALSE;
139    i--;
140  }
141  while (i);
142#ifdef HAVE_RINGS
143  return n_DivBy(pGetCoeff(b), pGetCoeff(a), r->cf);
144#else
145  return TRUE;
146#endif
147     }
148
149
150/***************************************************************
151 *
152 * Misc things helpful for debugging
153 *
154 ***************************************************************/
155BOOLEAN pIsMonomOf(poly p, poly m)
156{
157  if (m == NULL) return TRUE;
158  while (p != NULL)
159  {
160    if (p == m) return TRUE;
161    pIter(p);
162  }
163  return FALSE;
164}
165BOOLEAN pHaveCommonMonoms(poly p, poly q)
166{
167  while (p != NULL)
168  {
169    if (pIsMonomOf(q, p))
170    {
171      return TRUE;
172    }
173    pIter(p);
174  }
175  return FALSE;
176}
177
178/***************************************************************
179 *
180 * Testing of polys
181 *
182 ***************************************************************/
183extern void p_Setm_General(poly p, ring r);
184
185static poly p_DebugInit(poly p, ring src_ring, ring dest_ring)
186{
187  poly d_p = p_Init(dest_ring);
188  int i;
189  assume(dest_ring->N == src_ring->N);
190
191  for (i=1; i<= src_ring->N; i++)
192  {
193    p_SetExp(d_p, i, p_GetExp(p, i, src_ring), dest_ring);
194  }
195  if (rRing_has_Comp(dest_ring))
196    p_SetComp(d_p, p_GetComp(p, src_ring), dest_ring);
197
198  p_Setm_General(d_p, dest_ring);
199  return d_p;
200}
201
202BOOLEAN _p_Test(poly p, ring r, int level)
203{
204  assume(r->cf !=NULL);
205
206  if (PDEBUG > level) level = PDEBUG;
207  if (level < 0 || p == NULL) return TRUE;
208
209  poly p_prev = NULL;
210
211  #ifndef OM_NDEBUG
212  // check addr with level+1 so as to check bin/page of addr
213  _pPolyAssumeReturnMsg(omTestBinAddrSize(p, (r->PolyBin->sizeW)*SIZEOF_LONG, level+1)
214                        == omError_NoError, "memory error",p,r);
215  #endif
216
217  pFalseReturn(p_CheckRing(r));
218
219  // this checks that p does not contain a loop: rather expensive O(length^2)
220  #ifndef OM_NDEBUG
221  if (level > 1)
222    pFalseReturn(omTestList(p, level) == omError_NoError);
223  #endif
224
225  int ismod = p_GetComp(p, r) != 0;
226
227  while (p != NULL)
228  {
229    // ring check
230    pFalseReturn(p_LmCheckIsFromRing(p, r));
231    #ifndef OM_NDEBUG
232    // omAddr check
233    _pPolyAssumeReturnMsg(omTestBinAddrSize(p, (r->PolyBin->sizeW)*SIZEOF_LONG, 1)
234                     == omError_NoError, "memory error",p,r);
235    #endif
236    // number/coef check
237    _pPolyAssumeReturnMsg(p->coef != NULL || (n_GetChar(r->cf) >= 2), "NULL coef",p,r);
238    #ifdef LDEBUG
239    r->cf->cfDBTest(p->coef,__FILE__,__LINE__,r->cf);
240    #endif
241    _pPolyAssumeReturnMsg(!n_IsZero(p->coef, r->cf), "Zero coef",p,r);
242
243    // check for valid comp
244    _pPolyAssumeReturnMsg(p_GetComp(p, r) >= 0 && (p_GetComp(p, r)<65000), "component out of range ?",p,r);
245    // check for mix poly/vec representation
246    _pPolyAssumeReturnMsg(ismod == (p_GetComp(p, r) != 0), "mixed poly/vector",p,r);
247
248    // special check for ringorder_s/S
249    if ((r->typ!=NULL) && (r->typ[0].ord_typ == ro_syzcomp))
250    {
251      long c1, cc1, ccc1, ec1;
252      sro_ord* o = &(r->typ[0]);
253
254      c1 = p_GetComp(p, r);
255      if (o->data.syzcomp.Components!=NULL)
256      {
257        cc1 = o->data.syzcomp.Components[c1];
258        ccc1 = o->data.syzcomp.ShiftedComponents[cc1];
259      }
260      else { cc1=0; ccc1=0; }
261      _pPolyAssumeReturnMsg(c1 == 0 || cc1 != 0, "Component <-> TrueComponent zero mismatch",p,r);
262      _pPolyAssumeReturnMsg(c1 == 0 || ccc1 != 0,"Component <-> ShiftedComponent zero mismatch",p,r);
263      ec1 = p->exp[o->data.syzcomp.place];
264      //pPolyAssumeReturnMsg(ec1 == ccc1, "Shifted comp out of sync. should %d, is %d");
265      if (ec1 != ccc1)
266      {
267        dPolyReportError(p,r,"Shifted comp out of sync. should %d, is %d",ccc1,ec1);
268        return FALSE;
269      }
270    }
271
272    // check that p_Setm works ok
273    if (level > 0)
274    {
275      poly p_should_equal = p_DebugInit(p, r, r);
276      _pPolyAssumeReturnMsg(p_ExpVectorEqual(p, p_should_equal, r), "p_Setm field(s) out of sync",p,r);
277      p_LmFree(p_should_equal, r);
278    }
279
280    // check order
281    if (p_prev != NULL)
282    {
283      int cmp = p_LmCmp(p_prev, p, r);
284      if (cmp == 0)
285      {
286        _pPolyAssumeReturnMsg(0, "monoms p and p->next are equal", p_prev, r);
287      }
288      else
289        _pPolyAssumeReturnMsg(p_LmCmp(p_prev, p, r) == 1, "wrong order", p_prev, r);
290
291      // check that compare worked sensibly
292      if (level > 1 && p_GetComp(p_prev, r) == p_GetComp(p, r))
293      {
294        int i;
295        for (i=r->N; i>0; i--)
296        {
297          if (p_GetExp(p_prev, i, r) != p_GetExp(p, i, r)) break;
298        }
299        _pPolyAssumeReturnMsg(i > 0, "Exponents equal but compare different", p_prev, r);
300      }
301    }
302    p_prev = p;
303    pIter(p);
304  }
305  return TRUE;
306}
307
308BOOLEAN _p_LmTest(poly p, ring r, int level)
309{
310  if (level < 0 || p == NULL) return TRUE;
311  poly pnext = pNext(p);
312  pNext(p) = NULL;
313  BOOLEAN test_res = _p_Test(p, r, level);
314  pNext(p) = pnext;
315  return test_res;
316}
317
318BOOLEAN _pp_Test(poly p, ring lmRing, ring tailRing, int level)
319{
320  if (PDEBUG > level) level = PDEBUG;
321  if (level < 0 || p == NULL) return TRUE;
322  if (pNext(p) == NULL || lmRing == tailRing) return _p_Test(p, lmRing, level);
323
324  pFalseReturn(_p_LmTest(p, lmRing, level));
325  pFalseReturn(_p_Test(pNext(p), tailRing, level));
326
327  // check that lm > Lm(tail)
328  if (level > 1)
329  {
330    poly lm = p;
331    poly tail = p_DebugInit(pNext(p), tailRing, lmRing);
332    poly pnext = pNext(lm);
333    pNext(lm) = tail;
334    BOOLEAN cmp = p_LmCmp(lm, tail, lmRing);
335    if (cmp != 1)
336      dPolyReportError(lm, lmRing, "wrong order: lm <= Lm(tail)");
337    p_LmFree(tail, lmRing);
338    pNext(lm) = pnext;
339    return (cmp == 1);
340  }
341  return TRUE;
342}
343
344#endif // PDEBUG
345
346#if defined(PDEBUG) || defined(PDIV_DEBUG)
347static unsigned long pDivisibleBy_number = 1;
348static unsigned long pDivisibleBy_FALSE = 1;
349static unsigned long pDivisibleBy_ShortFalse = 1;
350BOOLEAN pDebugLmShortDivisibleBy(poly p1, unsigned long sev_1, ring r_1,
351                               poly p2, unsigned long not_sev_2, ring r_2)
352{
353  _pPolyAssume(p_GetShortExpVector(p1, r_1) == sev_1, p1, r_1);
354  _pPolyAssume(p_GetShortExpVector(p2, r_2) == ~ not_sev_2, p2, r_2);
355
356  pDivisibleBy_number++;
357  BOOLEAN ret;
358  if (r_1 == r_2)
359    ret = p_LmDivisibleBy(p1, p2, r_1);
360  else
361    ret = p_LmDivisibleBy(p1, r_1, p2, r_2);
362
363  if (! ret) pDivisibleBy_FALSE++;
364  if (sev_1 & not_sev_2)
365  {
366    pDivisibleBy_ShortFalse++;
367    if (ret)
368      dReportError("p1 divides p2, but sev's are wrong");
369  }
370  return ret;
371}
372
373void pPrintDivisbleByStat()
374{
375  Print("#Tests: %ld; #FALSE %ld(%ld); #SHORT %ld(%ld)\n",
376        pDivisibleBy_number,
377        pDivisibleBy_FALSE, (unsigned long) ((double)pDivisibleBy_FALSE*((double) 100)/(double)pDivisibleBy_number),
378        pDivisibleBy_ShortFalse, (unsigned long) ((double)pDivisibleBy_ShortFalse*((double)100)/(double)pDivisibleBy_FALSE));
379}
380
381#endif // PDEBUG
382
383#endif // PDEBUG_CC
Note: See TracBrowser for help on using the repository browser.