source: git/kernel/spectrum.cc @ 3835a88

spielwiese
Last change on this file since 3835a88 was 3835a88, checked in by mlee <martinlee84@…>, 13 years ago
added const ring r to ring dependend functions
  • Property mode set to 100644
File size: 12.3 KB
RevLine 
[35aab3]1// ----------------------------------------------------------------------------
2//  spectrum.cc
3//  begin of file
4//  Stephan Endrass, endrass@mathematik.uni-mainz.de
5//  23.7.99
6// ----------------------------------------------------------------------------
7
8#define SPECTRUM_CC
9
[599326]10#include <kernel/mod2.h>
[35aab3]11
12#ifdef HAVE_SPECTRUM
13
14#ifdef  SPECTRUM_PRINT
15#include <iostream.h>
16#ifndef  SPECTRUM_IOSTREAM
17#include <stdio.h>
18#endif
19#endif
20
[b1dfaf]21#include <omalloc/mylimits.h>
[35aab3]22
[0f401f]23#include <coeffs/numbers.h>
[3835a88]24#include <polys/monomials/p_polys.h>
25#include <polys/simpleideals.h>
[210e07]26#include <misc/intvec.h>
27#include <polys/monomials/ring.h>
[3835a88]28//extern ring currRing;
[599326]29
[3835a88]30#include <kernel/kstd1.h>
31#include <kernel/stairc.h>
[599326]32#include <kernel/multicnt.h>
33#include <kernel/GMPrat.h>
34#include <kernel/kmatrix.h>
35#include <kernel/npolygon.h>
36#include <kernel/splist.h>
37#include <kernel/semic.h>
[35aab3]38
39// ----------------------------------------------------------------------------
40//  test if the polynomial  h  has a term of total degree d
41// ----------------------------------------------------------------------------
42
[3835a88]43BOOLEAN hasTermOfDegree( poly h, int d, const ring r )
[35aab3]44{
45  do
46  {
[3835a88]47    if( p_Totaldegree( h,r )== d )
[35aab3]48      return  TRUE;
49    pIter(h);
50  }
[beef52]51  while( h!=NULL );
[35aab3]52
53  return  FALSE;
54}
55
56// ----------------------------------------------------------------------------
57//  test if the polynomial  h  has a constant term
58// ----------------------------------------------------------------------------
59
[3835a88]60static BOOLEAN inline hasConstTerm( poly h, const ring r )
[35aab3]61{
[3835a88]62  return  hasTermOfDegree(h,0,r);
[35aab3]63}
64
65// ----------------------------------------------------------------------------
66//  test if the polynomial  h  has a linear term
67// ----------------------------------------------------------------------------
68
[3835a88]69static BOOLEAN inline hasLinearTerm( poly h, const ring r )
[35aab3]70{
[3835a88]71  return  hasTermOfDegree(h,1,r);
[35aab3]72}
73
74// ----------------------------------------------------------------------------
75//  test if the ideal  J  has a lead monomial on the axis number  k
76// ----------------------------------------------------------------------------
77
[3835a88]78BOOLEAN hasAxis( ideal J,int k, const ring r )
[35aab3]79{
80  int i;
81
82  for( i=0; i<IDELEMS(J); i++ )
83  {
[3835a88]84    if (p_IsPurePower( J->m[i],r ) == k) return TRUE;
[35aab3]85  }
86  return  FALSE;
87}
88
89// ----------------------------------------------------------------------------
90//  test if the ideal  J  has  1  as a lead monomial
91// ----------------------------------------------------------------------------
92
[3835a88]93int     hasOne( ideal J, const ring r )
[35aab3]94{
95  int i;
96
97  for( i=0; i<IDELEMS(J); i++ )
98  {
[3835a88]99    if (p_IsConstant(J->m[i],r)) return TRUE;
[35aab3]100  }
101  return  FALSE;
102}
103// ----------------------------------------------------------------------------
104//  test if  m  is a multiple of one of the monomials of  f
105// ----------------------------------------------------------------------------
106
[3835a88]107int     isMultiple( poly f,poly m, const ring r )
[35aab3]108{
[beef52]109  while( f!=NULL )
[35aab3]110  {
111    // ---------------------------------------------------
112    //  for a local order  f|m  is only possible if  f>=m
113    // ---------------------------------------------------
114
[3835a88]115    if( p_LmCmp( f,m,r )>=0 )
[35aab3]116    {
[3835a88]117      if( p_LmDivisibleByNoComp( f,m,r ) )
[35aab3]118      {
119        return  TRUE;
120      }
121      else
122      {
123        pIter( f );
124      }
125    }
126    else
127    {
128      return FALSE;
129    }
130  }
131
132  return  FALSE;
133}
134
135// ----------------------------------------------------------------------------
136//  compute the minimal monomial of minimmal  weight>=max_weight
137// ----------------------------------------------------------------------------
138
[3835a88]139poly    computeWC( const newtonPolygon &np,Rational max_weight, const ring r )
[35aab3]140{
[3835a88]141  poly m  = p_One(r);
[beef52]142  poly wc = NULL;
[35aab3]143  int  mdegree;
144
[3835a88]145  for( int i=1; i<=r->N; i++ )
[35aab3]146  {
147    mdegree = 1;
[3835a88]148    p_SetExp( m,i,mdegree,r );
[35aab3]149    // pSetm( m );
150    // np.weight_shift does not need pSetm( m ), postpone it
151
[3835a88]152    while(  np.weight_shift( m,r )<max_weight )
[35aab3]153    {
154      mdegree++;
[3835a88]155      p_SetExp( m,i,mdegree,r );
[35aab3]156      // pSetm( m );
157      // np.weight_shift does not need pSetm( m ), postpone it
158    }
[3835a88]159    p_Setm( m,r );
[35aab3]160
[3835a88]161    if( i==1 || p_Cmp( m,wc,r )<0 )
[35aab3]162    {
[3835a88]163      p_Delete( &wc,r );
164      wc = p_Head( m,r );
[35aab3]165    }
166
[3835a88]167    p_SetExp( m,i,0,r );
[35aab3]168  }
169
[3835a88]170  p_Delete( &m,r );
[35aab3]171
172  return  wc;
173}
174
175// ----------------------------------------------------------------------------
176//  deletes all monomials of  f  which are less than  hc
177// ----------------------------------------------------------------------------
178
[3835a88]179static inline  poly    normalFormHC( poly f,poly hc, const ring r )
[35aab3]180{
181  poly    *ptr = &f;
182
[beef52]183  while( (*ptr)!=NULL )
[35aab3]184  {
[3835a88]185    if( p_LmCmp( *ptr,hc,r )>=0 )
[35aab3]186    {
187      ptr = &(pNext( *ptr ));
188    }
189    else
190    {
[3835a88]191      p_Delete( ptr,r );
[35aab3]192      return  f;
193    }
194  }
195
196  return f;
197}
198
199// ----------------------------------------------------------------------------
200//  deletes all monomials of  f  which are multiples of monomials of  Z
201// ----------------------------------------------------------------------------
202
[3835a88]203static inline  poly    normalFormZ( poly f,poly Z, const ring r )
[35aab3]204{
205  poly    *ptr = &f;
206
[beef52]207  while( (*ptr)!=NULL )
[35aab3]208  {
[3835a88]209    if( !isMultiple( Z,*ptr,r ) )
[35aab3]210    {
211      ptr = &(pNext( *ptr ));
212    }
213    else
214    {
[3835a88]215      p_LmDelete(ptr,r);
[35aab3]216    }
217  }
218
219  return f;
220}
221
222// ?? HS:
223// Looks for the shortest polynomial f in stdJ which is divisible
224// by the monimial m, return its index in stdJ
225// ----------------------------------------------------------------------------
226//  Looks for the first polynomial f in stdJ which satisfies m=LT(f)*eta
227//  for a monomial eta. The return eta*f-m and cancel all monomials
228//  which are smaller than the highest corner hc
229// ----------------------------------------------------------------------------
230
[3835a88]231static inline  int     isLeadMonomial( poly m,ideal stdJ, const ring r )
[35aab3]232{
233  int     length = INT_MAX;
234  int     result = -1;
235
236  for( int i=0; i<IDELEMS(stdJ); i++ )
237  {
[3835a88]238    if( p_Cmp( stdJ->m[i],m,r )>=0 && p_DivisibleBy( stdJ->m[i],m,r ) )
[35aab3]239    {
240      int     tmp = pLength( stdJ->m[i] );
241
242      if( tmp < length )
243      {
244        length = tmp;
245        result = i;
246      }
247    }
248  }
249
250  return  result;
251}
252
253// ----------------------------------------------------------------------------
254//  set the exponent of a monomial t an integer array
255// ----------------------------------------------------------------------------
256
[3835a88]257static void    setExp( poly m,int *r, const ring s )
[35aab3]258{
[3835a88]259  for( int i=s->N; i>0; i-- )
[35aab3]260  {
[3835a88]261    p_SetExp( m,i,r[i-1],s );
[35aab3]262  }
[3835a88]263  p_Setm( m,s );
[35aab3]264}
265
266// ----------------------------------------------------------------------------
267//  check if the ordering is a reverse wellordering, i.e. every monomial
268//  is smaller than only finitely monomials
269// ----------------------------------------------------------------------------
270
[3835a88]271static BOOLEAN isWell( const ring r )
[35aab3]272{
[3835a88]273  int b = rBlocks( r );
[35aab3]274
275  if( b==3 &&
[3835a88]276      ( r->order[0] == ringorder_ds ||
277        r->order[0] == ringorder_Ds ||
278        r->order[0] == ringorder_ws ||
279        r->order[0] == ringorder_Ws ) )
[35aab3]280  {
281    return  TRUE;
282  }
283  else if( b>=3
[3835a88]284  && (( r->order[0] ==ringorder_a
285        && r->block1[0]==r->N )
286    || (r->order[0]==ringorder_M
287        && r->block1[0]==r->N*r->N )))
[35aab3]288  {
[3835a88]289    for( int i=r->N-1; i>=0; i-- )
[35aab3]290    {
[3835a88]291      if( r->wvhdl[0][i]>=0 )
[35aab3]292      {
293        return  FALSE;
294      }
295    }
296    return  TRUE;
297  }
298
299  return  FALSE;
300}
301
302// ----------------------------------------------------------------------------
303//  compute all monomials not in  stdJ  and their normal forms
304// ----------------------------------------------------------------------------
305
[3835a88]306void    computeNF( ideal stdJ,poly hc,poly wc,spectrumPolyList *NF, const ring r )
[35aab3]307{
308  int         carry,k;
[3835a88]309  multiCnt    C( r->N,0 );
[beef52]310  poly        Z = NULL;
[35aab3]311
[3835a88]312  int         well = isWell(r);
[35aab3]313
314  do
315  {
[3835a88]316    poly    m = p_One(r);
317    setExp( m,C.cnt,r );
[35aab3]318
319    carry = FALSE;
320
[3835a88]321    k = isLeadMonomial( m,stdJ,r );
[35aab3]322
323    if( k < 0 )
324    {
325      // ---------------------------
326      //  m  is not a lead monomial
327      // ---------------------------
328
[beef52]329      NF->insert_node( m,NULL );
[35aab3]330    }
[3835a88]331    else if( isMultiple( Z,m,r ) )
[35aab3]332    {
333      // ------------------------------------
334      //  m  is trivially in the ideal  stdJ
335      // ------------------------------------
336
[3835a88]337      p_Delete( &m,r );
[35aab3]338      carry = TRUE;
339    }
[3835a88]340    else if( p_Cmp( m,hc,r ) < 0 || p_Cmp( m,wc,r ) < 0 )
[35aab3]341    {
342      // -------------------
343      //  we do not need  m
344      // -------------------
345
[3835a88]346      p_Delete( &m,r );
[35aab3]347      carry = TRUE;
348    }
349    else
350    {
351      // --------------------------
352      //  compute lazy normal form
353      // --------------------------
354
[3835a88]355      poly    multiplicant = p_Divide( m,stdJ->m[k],r );
356      pGetCoeff( multiplicant ) = n_Init(1,r->cf);
[35aab3]357
[3835a88]358      poly    nf = p_Mult_mm( p_Copy( stdJ->m[k],r ), multiplicant,r );
[35aab3]359
[3835a88]360      p_Delete( &multiplicant,r );
[35aab3]361
[3835a88]362      nf = normalFormHC( nf,hc,r );
[35aab3]363
[beef52]364      if( pNext( nf )==NULL )
[35aab3]365      {
366        // ----------------------------------
367        //  normal form of  m  is  m  itself
368        // ----------------------------------
369
[3835a88]370        p_Delete( &nf,r );
[35aab3]371        NF->delete_monomial( m );
[3835a88]372        Z = p_Add_q( Z,m,r );
[35aab3]373        carry = TRUE;
374      }
375      else
376      {
[3835a88]377        nf = normalFormZ( nf,Z,r );
[35aab3]378
[beef52]379        if( pNext( nf )==NULL )
[35aab3]380        {
381          // ----------------------------------
382          //  normal form of  m  is  m  itself
383          // ----------------------------------
384
[3835a88]385          p_Delete( &nf,r );
[35aab3]386          NF->delete_monomial( m );
[3835a88]387          Z = p_Add_q( Z,m,r );
[35aab3]388          carry = TRUE;
389        }
390        else
391        {
392          // ------------------------------------
393          //  normal form of  m  is a polynomial
394          // ------------------------------------
395
[3835a88]396          p_Norm( nf,r );
[35aab3]397          if( well==TRUE )
398          {
399            NF->insert_node( m,nf );
400          }
401          else
402          {
403            poly    nfhard = kNF( stdJ,(ideal)NULL,pNext( nf ),0,0 );
[3835a88]404            nfhard = normalFormHC( nfhard,hc,r );
405            nfhard = normalFormZ ( nfhard,Z,r );
[35aab3]406
[beef52]407            if( nfhard==NULL )
[35aab3]408            {
409              NF->delete_monomial( m );
[3835a88]410              Z = p_Add_q( Z,m,r );
[35aab3]411              carry = TRUE;
412            }
413            else
414            {
[3835a88]415              p_Delete( &pNext( nf ),r );
[35aab3]416              pNext( nf ) = nfhard;
417              NF->insert_node( m,nf );
418            }
419          }
420        }
421      }
422    }
423  }
424  while( C.inc( carry ) );
425
426  // delete single monomials
427
428  BOOLEAN  not_finished;
429
430  do
431  {
432    not_finished = FALSE;
433
434    spectrumPolyNode  *node = NF->root;
435
436    while( node!=(spectrumPolyNode*)NULL )
437    {
[beef52]438      if( node->nf!=NULL && pNext( node->nf )==NULL )
[35aab3]439      {
440        NF->delete_monomial( node->nf );
441        not_finished = TRUE;
442        node = (spectrumPolyNode*)NULL;
443      }
444      else
445      {
446        node = node->next;
447      }
448    }
449  } while( not_finished );
450
[3835a88]451  p_Delete( &Z,r );
[35aab3]452}
453
454// ----------------------------------------------------------------------------
455//  check if  currRing is local
456// ----------------------------------------------------------------------------
457
[3835a88]458BOOLEAN ringIsLocal( const ring r )
[35aab3]459{
[3835a88]460  poly    m   = p_One(r);
461  poly    one = p_One(r);
[35aab3]462  BOOLEAN res=TRUE;
463
[3835a88]464  for( int i=r->N; i>0; i-- )
[35aab3]465  {
[3835a88]466    p_SetExp( m,i,1,r );
467    p_Setm( m,r );
[35aab3]468
[3835a88]469    if( p_Cmp( m,one,r )>0 )
[35aab3]470    {
471      res=FALSE;
472      break;
473    }
[3835a88]474    p_SetExp( m,i,0,r );
[35aab3]475  }
476
[3835a88]477  p_Delete( &m,r );
478  p_Delete( &one,r );
[35aab3]479
480  return  res;
481}
482
483// ----------------------------------------------------------------------------
484// print error message corresponding to spectrumState state:
485// ----------------------------------------------------------------------------
486void spectrumPrintError(spectrumState state)
487{
488  switch( state )
489  {
490    case spectrumZero:
491      WerrorS( "polynomial is zero" );
492      break;
493    case spectrumBadPoly:
494      WerrorS( "polynomial has constant term" );
495      break;
496    case spectrumNoSingularity:
497      WerrorS( "not a singularity" );
498      break;
499    case spectrumNotIsolated:
500      WerrorS( "the singularity is not isolated" );
501      break;
502    case spectrumNoHC:
503      WerrorS( "highest corner cannot be computed" );
504      break;
505    case spectrumDegenerate:
506      WerrorS( "principal part is degenerate" );
507      break;
508    case spectrumOK:
509      break;
510
511    default:
512      WerrorS( "unknown error occurred" );
513      break;
514  }
515}
516#endif /* HAVE_SPECTRUM */
517// ----------------------------------------------------------------------------
518//  spectrum.cc
519//  end of file
520// ----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.