source: git/libpolys/polys/pDebug.cc @ 0635d51

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