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

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