source: git/kernel/npolygon.cc @ 210e07

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