source: git/kernel/npolygon.cc @ b938f4

spielwiese
Last change on this file since b938f4 was b938f4, checked in by mlee <martinlee84@…>, 13 years ago
added const ring r argument to all ring dependend functions commented out MAX_INT_VAL in mod2.h
  • Property mode set to 100644
File size: 15.2 KB
Line 
1// ----------------------------------------------------------------------------
2//  npolygon.cc
3//  begin of file
4//  Stephan Endrass, endrass@mathematik.uni-mainz.de
5//  23.7.99
6// ----------------------------------------------------------------------------
7
8#define  NPOLYGON_CC
9
10#include <kernel/mod2.h>
11
12#ifdef HAVE_SPECTRUM
13
14#ifdef   NPOLYGON_PRINT
15#include <iostream.h>
16#ifndef   NPOLYGON_IOSTREAM
17#include <stdio.h>
18#endif
19#endif
20
21//#include <polys/polys.h>
22#include <polys/monomials/p_polys.h>
23#include <polys/monomials/ring.h>
24
25#include <kernel/GMPrat.h>
26#include <kernel/kmatrix.h>
27#include <kernel/npolygon.h>
28#include <kernel/structs.h>
29
30// ----------------------------------------------------------------------------
31//  Allocate memory for a linear form of  k  terms
32// ----------------------------------------------------------------------------
33
34void    linearForm::copy_new( int k )
35{
36  if( k > 0 )
37  {
38    c = new Rational[k];
39
40    #ifndef NBDEBUG
41    if( c == (Rational*)NULL )
42    {
43      #ifdef  NPOLYGON_PRINT
44      #ifdef  NPOLYGON_IOSTREAM
45        cerr <<
46        "void linearForm::copy_new( int k ): no memory left ...\n" ;
47      #else
48        fprintf( stderr,
49        "void linearForm::copy_new( int k ): no memory left ...\n");
50      #endif
51      #endif
52      HALT();
53    }
54    #endif
55  }
56  else if( k == 0 )
57  {
58    c = (Rational*)NULL;
59  }
60  else if( k < 0 )
61  {
62    #ifdef  NPOLYGON_PRINT
63    #ifdef  NPOLYGON_IOSTREAM
64      cerr <<
65      "void linearForm::copy_new( int k ): k < 0 ...\n";
66    #else
67      fprintf( stderr,
68      "void linearForm::copy_new( int k ): k < 0 ...\n" );
69    #endif
70    #endif
71
72    HALT();
73  }
74}
75
76// ----------------------------------------------------------------------------
77//  Delete the memory of a linear form
78// ----------------------------------------------------------------------------
79
80void    linearForm::copy_delete( void )
81{
82  if( c != (Rational*)NULL && N > 0 )
83    delete [] c;
84  copy_zero( );
85}
86
87// ----------------------------------------------------------------------------
88//  Initialize deep from another linear form
89// ----------------------------------------------------------------------------
90
91void    linearForm::copy_deep( const linearForm &l )
92{
93  copy_new( l.N );
94  for( int i=l.N-1; i>=0; i-- )
95  {
96    c[i] = l.c[i];
97  }
98  N = l.N;
99}
100
101// ----------------------------------------------------------------------------
102//  Copy constructor
103// ----------------------------------------------------------------------------
104
105linearForm::linearForm( const linearForm &l )
106{
107  copy_deep( l );
108}
109
110// ----------------------------------------------------------------------------
111//  Destructor
112// ----------------------------------------------------------------------------
113
114linearForm::~linearForm( )
115{
116  copy_delete( );
117}
118
119// ----------------------------------------------------------------------------
120//  Define `=` to be a deep copy
121// ----------------------------------------------------------------------------
122
123linearForm & linearForm::operator = ( const linearForm &l )
124{
125  copy_delete( );
126  copy_deep( l );
127
128  return *this;
129}
130
131// ----------------------------------------------------------------------------
132//  ostream for linear form
133// ----------------------------------------------------------------------------
134
135#ifdef  NPOLYGON_PRINT
136
137ostream & operator << ( ostream &s,const linearForm &l )
138{
139  for( int i=0; i<l.N; i++ )
140  {
141    if( l.c[i] != (Rational)0 )
142    {
143      if( i > 0 && l.c[i] >= (Rational)0 )
144      {
145        #ifdef NPOLYGON_IOSTREAM
146          s << "+";
147        #else
148          fprintf( stdout,"+" );
149        #endif
150      }
151
152      s << l.c[i];
153
154      #ifdef NPOLYGON_IOSTREAM
155        s << "*x" << i+1;
156      #else
157        fprintf( stdout,"*x%d",i+1 );
158      #endif
159    }
160  }
161  return s;
162}
163
164#endif
165
166// ----------------------------------------------------------------------------
167//  Equality of linear forms
168// ----------------------------------------------------------------------------
169
170int     operator == ( const linearForm &l1,const linearForm &l2 )
171{
172  if( l1.N!=l2.N )
173    return  FALSE;
174  for( int i=l1.N-1; i >=0 ; i-- )
175  {
176    if( l1.c[i]!=l2.c[i] )
177      return  FALSE;
178  }
179  return  TRUE;
180}
181
182
183// ----------------------------------------------------------------------------
184//  Newton weight of a monomial
185// ----------------------------------------------------------------------------
186
187Rational linearForm::weight( poly m, const ring r ) const
188{
189  Rational ret=(Rational)0;
190
191  for( int i=0,j=1; i<N; i++,j++ )
192  {
193    ret += c[i]*(Rational)p_GetExp( m,j,r );
194  }
195
196  return ret;
197}
198
199// ----------------------------------------------------------------------------
200//  Newton weight of a polynomial
201// ----------------------------------------------------------------------------
202
203Rational linearForm::pweight( poly m, const ring r ) const
204{
205  if( m==(poly)NULL )
206    return  (Rational)0;
207
208  Rational    ret = weight( m, r );
209  Rational    tmp;
210
211  for( m=pNext(m); m!=(poly)NULL; pIter(m) )
212  {
213    tmp = weight( m, r );
214    if( tmp<ret )
215    {
216      ret = tmp;
217    }
218  }
219
220  return ret;
221}
222
223// ----------------------------------------------------------------------------
224//  Newton weight of a monomial shifted by the product of the variables
225// ----------------------------------------------------------------------------
226
227Rational linearForm::weight_shift( poly m, const ring r ) const
228{
229  Rational ret=(Rational)0;
230
231  for( int i=0,j=1; i<N; i++,j++ )
232  {
233    ret += c[i]*(Rational)( p_GetExp( m,j,r ) + 1 );
234  }
235
236  return ret;
237}
238
239// ----------------------------------------------------------------------------
240//  Newton weight of a monomial (forgetting the first variable)
241// ----------------------------------------------------------------------------
242
243Rational linearForm::weight1( poly m, const ring r ) const
244{
245  Rational ret=(Rational)0;
246
247  for( int i=0,j=2; i<N; i++,j++ )
248  {
249    ret += c[i]*(Rational)p_GetExp( m,j,r );
250  }
251
252  return ret;
253}
254
255// ----------------------------------------------------------------------------
256//  Newton weight of a monomial shifted by the product of the variables
257//  (forgetting the first variable)
258// ----------------------------------------------------------------------------
259
260Rational linearForm::weight_shift1( poly m, const ring r ) const
261{
262  Rational ret=(Rational)0;
263
264  for( int i=0,j=2; i<N; i++,j++ )
265  {
266    ret += c[i]*(Rational)( p_GetExp( m,j,r ) + 1 );
267  }
268
269  return ret;
270}
271
272
273// ----------------------------------------------------------------------------
274//  Test if all coefficients of a linear form are positive
275// ----------------------------------------------------------------------------
276
277int linearForm::positive( void )
278{
279  for( int i=0; i<N; i++ )
280  {
281    if( c[i] <= (Rational)0 )
282    {
283      return FALSE;
284    }
285  }
286  return  TRUE;
287}
288
289
290// ----------------------------------------------------------------------------
291//  Allocate memory for a newton polygon of  k  linear forms
292// ----------------------------------------------------------------------------
293
294void    newtonPolygon::copy_new( int k )
295{
296  if( k > 0 )
297  {
298    l = new linearForm[k];
299
300    #ifndef NDEBUG
301      if( l == (linearForm*)NULL )
302      {
303        #ifdef  NPOLYGON_PRINT
304          #ifdef  NPOLYGON_IOSTREAM
305            cerr <<
306            "void newtonPolygon::copy_new( int k ): no memory left ...\n";
307          #else
308            fprintf( stderr,
309            "void newtonPolygon::copy_new( int k ): no memory left ...\n" );
310          #endif
311        #endif
312
313        HALT();
314      }
315    #endif
316  }
317  else if( k == 0 )
318  {
319    l = (linearForm*)NULL;
320  }
321  else if( k < 0 )
322  {
323    #ifdef  NPOLYGON_PRINT
324      #ifdef  NPOLYGON_IOSTREAM
325        cerr << "void newtonPolygon::copy_new( int k ): k < 0 ...\n";
326      #else
327        fprintf( stderr,
328        "void newtonPolygon::copy_new( int k ): k < 0 ...\n" );
329      #endif
330    #endif
331
332    HALT();
333  }
334}
335
336// ----------------------------------------------------------------------------
337//  Delete the memory of a Newton polygon
338// ----------------------------------------------------------------------------
339
340void    newtonPolygon::copy_delete( void )
341{
342  if( l != (linearForm*)NULL && N > 0 )
343    delete [] l;
344  copy_zero( );
345}
346
347// ----------------------------------------------------------------------------
348//  Initialize deep from another Newton polygon
349// ----------------------------------------------------------------------------
350
351void    newtonPolygon::copy_deep( const newtonPolygon &np )
352{
353  copy_new( np.N );
354  for( int i=0; i<np.N; i++ )
355  {
356    l[i] = np.l[i];
357  }
358  N = np.N;
359}
360
361// ----------------------------------------------------------------------------
362//  Copy constructor
363// ----------------------------------------------------------------------------
364
365newtonPolygon::newtonPolygon( const newtonPolygon &np )
366{
367  copy_deep( np );
368}
369
370// ----------------------------------------------------------------------------
371//  Destructor
372// ----------------------------------------------------------------------------
373
374newtonPolygon::~newtonPolygon( )
375{
376  copy_delete( );
377}
378
379// ----------------------------------------------------------------------------
380//  We define `=` to be a deep copy
381// ----------------------------------------------------------------------------
382
383newtonPolygon & newtonPolygon::operator = ( const newtonPolygon &np )
384{
385  copy_delete( );
386  copy_deep( np );
387
388  return *this;
389}
390
391// ----------------------------------------------------------------------------
392//  Initialize a Newton polygon from a polynomial
393// ----------------------------------------------------------------------------
394
395newtonPolygon::newtonPolygon( poly f, const ring s )
396{
397  copy_zero( );
398
399  int *r=new int[s->N];
400  poly *m=new poly[s->N];
401
402
403  KMatrix<Rational> mat(s->N,s->N+1 );
404
405  int i,j,stop=FALSE;
406  linearForm sol;
407
408  // ---------------
409  //  init counters
410  // ---------------
411
412  for( i=0; i<s->N; i++ )
413  {
414    r[i] = i;
415  }
416
417  m[0] = f;
418
419  for( i=1; i<s->N; i++ )
420  {
421    m[i] = pNext(m[i-1]);
422  }
423
424  // -----------------------------
425  //  find faces (= linear forms)
426  // -----------------------------
427
428  do
429  {
430    // ---------------------------------------------------
431    //  test if monomials p.m[r[0]]m,...,p.m[r[p.vars-1]]
432    //  are linearely independent
433    // ---------------------------------------------------
434
435    for( i=0; i<s->N; i++ )
436    {
437      for( j=0; j<s->N; j++ )
438      {
439        //    mat.set( i,j,pGetExp( m[r[i]],j+1 ) );
440        mat.set( i,j,p_GetExp( m[i],j+1,s ) );
441      }
442      mat.set( i,j,1 );
443    }
444
445    if( mat.solve( &(sol.c),&(sol.N) ) == s->N )
446    {
447      // ---------------------------------
448      //  check if linearForm is positive
449      //  check if linearForm is extremal
450      // ---------------------------------
451
452      if( sol.positive( ) && sol.pweight( f,s ) >= (Rational)1 )
453      {
454        // ----------------------------------
455        //  this is a face or the polyhedron
456        // ----------------------------------
457
458        add_linearForm( sol );
459        sol.c = (Rational*)NULL;
460        sol.N = 0;
461      }
462    }
463
464    // --------------------
465    //  increment counters
466    // --------------------
467
468    for( i=1; r[i-1] + 1 == r[i] && i < s->N; i++ );
469
470    for( j=0; j<i-1; j++ )
471    {
472      r[j]=j;
473    }
474
475    if( i>1 )
476    {
477      m[0]=f;
478      for( j=1; j<i-1; j++ )
479      {
480        m[j]=pNext(m[j-1]);
481      }
482    }
483    r[i-1]++;
484    m[i-1]=pNext(m[i-1]);
485
486    if( m[s->N-1] == (poly)NULL )
487    {
488      stop = TRUE;
489    }
490  } while( stop == FALSE );
491}
492
493#ifdef  NPOLYGON_PRINT
494
495ostream & operator << ( ostream &s,const newtonPolygon &a )
496{
497  #ifdef NPOLYGON_IOSTREAM
498    s << "Newton polygon:" << endl;
499  #else
500    fprintf( stdout,"Newton polygon:\n" );
501  #endif
502
503  for( int i=0; i<a.N; i++ )
504  {
505    s << a.l[i];
506
507    #ifdef NPOLYGON_IOSTREAM
508      s << endl;
509    #else
510      fprintf( stdout,"\n" );
511    #endif
512  }
513
514  return s;
515}
516
517#endif
518
519// ----------------------------------------------------------------------------
520//  Add a face to the newton polygon
521// ----------------------------------------------------------------------------
522
523void    newtonPolygon::add_linearForm( const linearForm &l0 )
524{
525  int           i;
526  newtonPolygon np;
527
528  // -------------------------------------
529  //  test if linear form is already here
530  // -------------------------------------
531
532  for( i=0; i<N; i++ )
533  {
534    if( l0==l[i] )
535    {
536      return;
537    }
538  }
539
540  np.copy_new( N+1 );
541  np.N = N+1;
542
543  for( i=0; i<N; i++ )
544  {
545    np.l[i].copy_shallow( l[i] );
546    l[i].copy_zero( );
547  }
548
549  np.l[N] = l0;
550
551  copy_delete( );
552  copy_shallow( np );
553  np.copy_zero( );
554
555  return;
556}
557
558// ----------------------------------------------------------------------------
559//  Newton weight of a monomial
560// ----------------------------------------------------------------------------
561
562Rational  newtonPolygon::weight( poly m, const ring r ) const
563{
564  Rational ret = l[0].weight( m,r );
565  Rational tmp;
566
567  for( int i=1; i<N; i++ )
568  {
569    tmp = l[i].weight( m,r );
570
571    if( tmp < ret )
572    {
573      ret = tmp;
574    }
575  }
576  return ret;
577}
578
579// ----------------------------------------------------------------------------
580//  Newton weight of a monomial shifted by the product of the variables
581// ----------------------------------------------------------------------------
582
583Rational  newtonPolygon::weight_shift( poly m, const ring r ) const
584{
585  Rational ret = l[0].weight_shift( m, r );
586  Rational tmp;
587
588  for( int i=1; i<N; i++ )
589  {
590    tmp = l[i].weight_shift( m, r );
591
592    if( tmp < ret )
593    {
594      ret = tmp;
595    }
596  }
597  return ret;
598}
599
600// ----------------------------------------------------------------------------
601//  Newton weight of a monomial (forgetting the first variable)
602// ----------------------------------------------------------------------------
603
604Rational  newtonPolygon::weight1( poly m, const ring r ) const
605{
606  Rational ret = l[0].weight1( m, r );
607  Rational tmp;
608
609  for( int i=1; i<N; i++ )
610  {
611    tmp = l[i].weight1( m, r );
612
613    if( tmp < ret )
614    {
615      ret = tmp;
616    }
617  }
618  return ret;
619}
620
621// ----------------------------------------------------------------------------
622//  Newton weight of a monomial shifted by the product of the variables
623//  (forgetting the first variable)
624// ----------------------------------------------------------------------------
625
626Rational  newtonPolygon::weight_shift1( poly m, const ring r ) const
627{
628  Rational ret = l[0].weight_shift1( m, r );
629  Rational tmp;
630
631  for( int i=1; i<N; i++ )
632  {
633    tmp = l[i].weight_shift1( m, r );
634
635    if( tmp < ret )
636    {
637      ret = tmp;
638    }
639  }
640  return ret;
641}
642
643/*
644// ----------------------------------------------------------------------------
645//  Chcek if the polynomial belonging to the Newton polygon
646//  is semiquasihomogeneous (sqh)
647// ----------------------------------------------------------------------------
648
649int     newtonPolygon::is_sqh( void ) const
650{
651  return ( N==1 ? TRUE : FALSE );
652}
653
654// ----------------------------------------------------------------------------
655//  If the polynomial belonging to the Newton polygon is sqh,
656//  return its weights vector
657// ----------------------------------------------------------------------------
658
659Rational*   newtonPolygon::sqh_weights( void ) const
660{
661  return ( N==1 ? l[0].c : (Rational*)NULL );
662}
663
664int    newtonPolygon::sqh_N( void ) const
665{
666  return ( N==1 ? l[0].N : 0 );
667}
668*/
669
670#endif /* HAVE_SPECTRUM */
671// ----------------------------------------------------------------------------
672//  npolygon.cc
673//  end of file
674// ----------------------------------------------------------------------------
675
Note: See TracBrowser for help on using the repository browser.