source: git/libpolys/polys/pDebug.cc @ 6bec87

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