source: git/kernel/pDebug.cc @ 3332cc6

spielwiese
Last change on this file since 3332cc6 was 3332cc6, checked in by Hans Schönemann <hannes@…>, 16 years ago
*hannes: n_Test git-svn-id: file:///usr/local/Singular/svn/trunk@10026 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • 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: pDebug.cc,v 1.6 2007-05-07 16:23:04 Singular Exp $
10 *******************************************************************/
11
12#ifndef PDEBUG_CC
13#define PDEBUG_CC
14#include <stdarg.h>
15#include <stdio.h>
16
17
18#include "mod2.h"
19#ifdef PDEBUG
20
21// do the following to always enforce checking of pSetm
22// #undef PDEBUG
23// #define PDEBUG 2
24
25#include "p_polys.h"
26#include "febase.h"
27#include "omalloc.h"
28#include "ring.h"
29#include "numbers.h"
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  {
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)==r->PolyBin->sizeW) ||
84                           rEqual((ring) custom, r, FALSE),
85                           "monomial not from specified ring");
86      return TRUE;
87    }
88    else
89    {
90      pPolyAssumeReturn(omIsBinPageAddr(p) && omSizeWOfAddr(p)==r->PolyBin->sizeW);
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_RINGMODN
143  if (currRing->cring == 2)
144  {
145    WarnS("Not implemenet, 2007-05-03 12:22:46");
146  }
147#endif
148#ifdef HAVE_RING2TOM
149  if (r->cring == 1) {
150     long lside = (long) pGetCoeff(a);
151     long rside = (long) pGetCoeff(b);
152     while (lside%2 == 0 && rside%2 == 0) {
153       lside = lside / 2;
154       rside = rside / 2;
155     }
156     return (lside%2 != 0);
157  }
158  else
159#endif 
160     return TRUE;
161}
162
163
164/***************************************************************
165 *
166 * Misc things helpful for debugging
167 *
168 ***************************************************************/
169BOOLEAN pIsMonomOf(poly p, poly m)
170{
171  if (m == NULL) return TRUE;
172  while (p != NULL)
173  {
174    if (p == m) return TRUE;
175    pIter(p);
176  }
177  return FALSE;
178}
179BOOLEAN pHaveCommonMonoms(poly p, poly q)
180{
181  while (p != NULL)
182  {
183    if (pIsMonomOf(q, p))
184    {
185      return TRUE;
186    }
187    pIter(p);
188  }
189  return FALSE;
190}
191
192/***************************************************************
193 *
194 * Testing of polys
195 *
196 ***************************************************************/
197extern void p_Setm_General(poly p, ring r);
198
199static poly p_DebugInit(poly p, ring src_ring, ring dest_ring)
200{
201  poly d_p = p_Init(dest_ring);
202  int i;
203  assume(dest_ring->N == src_ring->N);
204
205  for (i=1; i<= src_ring->N; i++)
206  {
207    p_SetExp(d_p, i, p_GetExp(p, i, src_ring), dest_ring);
208  }
209  if (rRing_has_Comp(dest_ring))
210    p_SetComp(d_p, p_GetComp(p, src_ring), dest_ring);
211
212  p_Setm_General(d_p, dest_ring);
213  return d_p;
214}
215
216BOOLEAN _p_Test(poly p, ring r, int level)
217{
218  assume(r->cf !=NULL);
219
220  if (PDEBUG > level) level = PDEBUG;
221  if (level < 0 || p == NULL) return TRUE;
222
223  poly p_prev = NULL;
224
225  // check addr with level+1 so as to check bin/page of addr
226  pPolyAssumeReturnMsg(omTestBinAddrSize(p, (r->PolyBin->sizeW)*SIZEOF_LONG, level+1)
227                        == omError_NoError, "memory error");
228
229  pFalseReturn(p_CheckRing(r));
230
231  // this checks that p does not contain a loop: rather expensive O(length^2)
232  if (level > 1)
233    pFalseReturn(omTestList(p, level) == omError_NoError);
234
235  int ismod = p_GetComp(p, r) > 0;
236
237  while (p != NULL)
238  {
239    // ring check
240    pFalseReturn(p_LmCheckIsFromRing(p, r));
241    // omAddr check
242    pPolyAssumeReturnMsg(omTestBinAddrSize(p, (r->PolyBin->sizeW)*SIZEOF_LONG, 1)
243                     == omError_NoError, "memory error");
244    // number/coef check
245    pPolyAssumeReturnMsg(p->coef != NULL || (n_GetChar(r) >= 2), "NULL coef");
246    #ifdef LDEBUG
247    r->cf->nDBTest(p->coef,__FILE__,__LINE__);
248    #endif
249    pPolyAssumeReturnMsg(!n_IsZero(p->coef, r), "Zero coef");
250
251    // check for valid comp
252    pPolyAssumeReturnMsg(p_GetComp(p, r) >= 0 && (p_GetComp(p, r)<65000), "component out of range ?");
253    // check for mix poly/vec representation
254    pPolyAssumeReturnMsg(ismod == (p_GetComp(p, r) > 0), "mixed poly/vector");
255
256    // special check for ringorder_s/S
257    if ((r->order!=NULL) &&(r->order[1] == ringorder_S))
258    {
259      long c1, cc1, ccc1, ec1;
260      sro_ord* o = &(r->typ[1]);
261
262      c1 = p_GetComp(p, r);
263      cc1 = o->data.syzcomp.Components[c1];
264      ccc1 = o->data.syzcomp.ShiftedComponents[cc1];
265      pPolyAssumeReturnMsg(c1 == 0 || cc1 != 0, "Component <-> TrueComponent zero mismatch");
266      pPolyAssumeReturnMsg(c1 == 0 || ccc1 != 0,"Component <-> ShiftedComponent zero mismatch");
267      ec1 = p->exp[r->typ[1].data.syzcomp.place];
268      pPolyAssumeReturnMsg(ec1 == ccc1, "Shifted comp out of sync. should %d, is %d");
269    }
270
271    // check that p_Setm works ok
272    if (level > 0)
273    {
274      poly p_should_equal = p_DebugInit(p, r, r);
275      pPolyAssumeReturnMsg(p_ExpVectorEqual(p, p_should_equal, r), "p_Setm field(s) out of sync");
276      p_LmFree(p_should_equal, r);
277    }
278
279    // check order
280    if (p_prev != NULL)
281    {
282      int cmp = p_LmCmp(p_prev, p, r);
283      if (cmp == 0)
284      {
285        _pPolyAssumeReturnMsg(0, "monoms p and p->next are equal", p_prev, r);
286      }
287      else
288        _pPolyAssumeReturnMsg(p_LmCmp(p_prev, p, r) == 1, "wrong order", p_prev, r);
289
290      // check that compare worked sensibly
291      if (level > 1 && p_GetComp(p_prev, r) == p_GetComp(p, r))
292      {
293        int i;
294        for (i=r->N; i>0; i--)
295        {
296          if (p_GetExp(p_prev, i, r) != p_GetExp(p, i, r)) break;
297        }
298        _pPolyAssumeReturnMsg(i > 0, "Exponents equal but compare different", p_prev, r);
299      }
300    }
301    p_prev = p;
302    pIter(p);
303  }
304  return TRUE;
305}
306
307BOOLEAN _p_LmTest(poly p, ring r, int level)
308{
309  if (level < 0 || p == NULL) return TRUE;
310  poly pnext = pNext(p);
311  pNext(p) = NULL;
312  BOOLEAN test_res = _p_Test(p, r, level);
313  pNext(p) = pnext;
314  return test_res;
315}
316
317BOOLEAN _pp_Test(poly p, ring lmRing, ring tailRing, int level)
318{
319  if (PDEBUG > level) level = PDEBUG;
320  if (level < 0 || p == NULL) return TRUE;
321  if (pNext(p) == NULL || lmRing == tailRing) return _p_Test(p, lmRing, level);
322
323  pFalseReturn(_p_LmTest(p, lmRing, level));
324  pFalseReturn(_p_Test(pNext(p), tailRing, level));
325
326  // check that lm > Lm(tail)
327  if (level > 1)
328  {
329    poly lm = p;
330    poly tail = p_DebugInit(pNext(p), tailRing, lmRing);
331    poly pnext = pNext(lm);
332    pNext(lm) = tail;
333    BOOLEAN cmp = p_LmCmp(lm, tail, lmRing);
334    if (cmp != 1)
335      dPolyReportError(lm, lmRing, "wrong order: lm <= Lm(tail)");
336    p_LmFree(tail, lmRing);
337    pNext(lm) = pnext;
338    return (cmp == 1);
339  }
340  return TRUE;
341}
342
343#endif // PDEBUG
344
345#include "pInline1.h"
346
347#if defined(PDEBUG) || defined(PDIV_DEBUG)
348static unsigned long pDivisibleBy_number = 1;
349static unsigned long pDivisibleBy_FALSE = 1;
350static unsigned long pDivisibleBy_ShortFalse = 1;
351BOOLEAN pDebugLmShortDivisibleBy(poly p1, unsigned long sev_1, ring r_1,
352                               poly p2, unsigned long not_sev_2, ring r_2)
353{
354  _pPolyAssume(p_GetShortExpVector(p1, r_1) == sev_1, p1, r_1);
355  _pPolyAssume(p_GetShortExpVector(p2, r_2) == ~ not_sev_2, p2, r_2);
356
357  pDivisibleBy_number++;
358  BOOLEAN ret;
359  if (r_1 == r_2)
360    ret = p_LmDivisibleBy(p1, p2, r_1);
361  else
362    ret = p_LmDivisibleBy(p1, r_1, p2, r_2);
363
364  if (! ret) pDivisibleBy_FALSE++;
365  if (sev_1 & not_sev_2)
366  {
367    pDivisibleBy_ShortFalse++;
368    if (ret)
369      dReportError("p1 divides p2, but sev's are wrong");
370  }
371  return ret;
372}
373
374void pPrintDivisbleByStat()
375{
376  Print("#Tests: %d; #FALSE %d(%d); #SHORT %d(%d)\n",
377        pDivisibleBy_number,
378        pDivisibleBy_FALSE, (unsigned long) ((double)pDivisibleBy_FALSE*((double) 100)/(double)pDivisibleBy_number),
379        pDivisibleBy_ShortFalse, (unsigned long) ((double)pDivisibleBy_ShortFalse*((double)100)/(double)pDivisibleBy_FALSE));
380}
381
382#endif // PDEBUG
383
384#endif // PDEBUG_CC
Note: See TracBrowser for help on using the repository browser.