source: git/Singular/npolygon.cc @ 7885020

fieker-DuValspielwiese
Last change on this file since 7885020 was 7885020, checked in by Hans Schönemann <hannes@…>, 25 years ago
* hannes: integrated "spectrum" by Stefan Endrass, inactive by default (Makefile.in claptmpl.cc feResource.cc iparith.cc mod2.h.in tok.h GMPrat.h GMPrat.cc kmatrix.h multicnt.h multicnt.cc npolygon.h npolygon.cc semic.h semic.cc spectrum.h spectrum.cc splist.h splist.cc) git-svn-id: file:///usr/local/Singular/svn/trunk@3423 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 16.5 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 "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.h"
22#include "GMPrat.h"
23#include "kmatrix.h"
24#include "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 << "void linearForm::copy_new( int k )";
42                cerr << ": no memory left ..." << endl;
43            #else
44                fprintf( stderr,"void linearForm::copy_new( int k )" );
45                fprintf( stderr,": no memory left ...\n" );
46            #endif
47            #endif
48
49            exit( 1 );
50        }
51        #endif
52    }
53    else if( k == 0 )
54    {
55        c = (Rational*)NULL;
56    }
57    else if( k < 0 )
58    {
59        #ifdef  NPOLYGON_PRINT
60        #ifdef  NPOLYGON_IOSTREAM
61            cerr << "void linearForm::copy_new( int k )";
62            cerr << ": k < 0 ..." << endl;
63        #else
64            fprintf( stderr,"void linearForm::copy_new( int k )" );
65            fprintf( stderr,": k < 0 ...\n" );
66        #endif
67        #endif
68
69        exit( 1 );
70    }
71}
72
73// ----------------------------------------------------------------------------
74//  Delete the memory of a linear form
75// ----------------------------------------------------------------------------
76
77void    linearForm::copy_delete( void )
78{
79    if( c != (Rational*)NULL && N > 0 ) 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=0; i<l.N; 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    {
170        return  FALSE;
171    }
172
173    for( int i=0; i<l1.N; i++ )
174    {
175        if( l1.c[i]!=l2.c[i] )
176        {
177            return  FALSE;
178        }
179    }
180
181    return  TRUE;
182}
183
184
185// ----------------------------------------------------------------------------
186//  Newton weight of a monomial
187// ----------------------------------------------------------------------------
188
189Rational linearForm::weight( poly m ) const
190{
191    Rational ret=(Rational)0;
192
193    for( int i=0,j=1; i<N; i++,j++ )
194    {
195        ret += c[i]*(Rational)pGetExp( m,j );
196    }
197
198    return ret;
199}
200
201// ----------------------------------------------------------------------------
202//  Newton weight of a polynomial
203// ----------------------------------------------------------------------------
204
205Rational linearForm::pweight( poly m ) const
206{
207    if( m==(poly)NULL )
208    {
209        return  (Rational)0;
210    }
211
212    Rational    ret = weight( m );
213    Rational    tmp;
214
215    for( m=m->next; m!=(poly)NULL; m=m->next )
216    {
217        tmp = weight( m );
218
219        if( tmp<ret )
220        {
221            ret = tmp;
222        }
223    }
224
225    return ret;
226}
227
228// ----------------------------------------------------------------------------
229//  Newton weight of a monomial shifted by the product of the variables
230// ----------------------------------------------------------------------------
231
232Rational linearForm::weight_shift( poly m ) const
233{
234    Rational ret=(Rational)0;
235
236    for( int i=0,j=1; i<N; i++,j++ )
237    {
238        ret += c[i]*(Rational)( pGetExp( m,j ) + 1 );
239    }
240
241    return ret;
242}
243
244// ----------------------------------------------------------------------------
245//  Newton weight of a monomial (forgetting the first variable)
246// ----------------------------------------------------------------------------
247
248Rational linearForm::weight1( poly m ) const
249{
250    Rational ret=(Rational)0;
251
252    for( int i=0,j=2; i<N; i++,j++ )
253    {
254        ret += c[i]*(Rational)pGetExp( m,j );
255    }
256
257    return ret;
258}
259
260// ----------------------------------------------------------------------------
261//  Newton weight of a monomial shifted by the product of the variables
262//  (forgetting the first variable)
263// ----------------------------------------------------------------------------
264
265Rational linearForm::weight_shift1( poly m ) const
266{
267    Rational ret=(Rational)0;
268
269    for( int i=0,j=2; i<N; i++,j++ )
270    {
271        ret += c[i]*(Rational)( pGetExp( m,j ) + 1 );
272    }
273
274    return ret;
275}
276
277
278// ----------------------------------------------------------------------------
279//  Test if all coefficients of a linear form are positive
280// ----------------------------------------------------------------------------
281
282int linearForm::positive( void )
283{
284    for( int i=0; i<N; i++ )
285    {
286        if( c[i] <= (Rational)0 )
287        {
288            return FALSE;
289        }
290    }
291    return  TRUE;
292}
293
294
295// ----------------------------------------------------------------------------
296//  Allocate memory for a newton polygon of  k  linear forms
297// ----------------------------------------------------------------------------
298
299void    newtonPolygon::copy_new( int k )
300{
301    if( k > 0 )
302    {
303        l = new linearForm[k];
304
305        #ifndef NDEBUG
306        if( l == (linearForm*)NULL )
307        {
308            #ifdef  NPOLYGON_PRINT
309            #ifdef  NPOLYGON_IOSTREAM
310                cerr << "void newtonPolygon::copy_new( int k )";
311                cerr << ": no memory left ..." << endl;
312            #else
313                fprintf( stderr,"void newtonPolygon::copy_new( int k )" );
314                fprintf( stderr,": no memory left ...\n" );
315            #endif
316            #endif
317
318            exit( 1 );
319        }
320        #endif
321    }
322    else if( k == 0 )
323    {
324        l = (linearForm*)NULL;
325    }
326    else if( k < 0 )
327    {
328        #ifdef  NPOLYGON_PRINT
329        #ifdef  NPOLYGON_IOSTREAM
330            cerr << "void newtonPolygon::copy_new( int k )";
331            cerr << ": k < 0 ..." << endl;
332        #else
333            fprintf( stderr,"void newtonPolygon::copy_new( int k )" );
334            fprintf( stderr,": k < 0 ...\n" );
335        #endif
336        #endif
337
338        exit( 1 );
339    }
340}
341
342// ----------------------------------------------------------------------------
343//  Delete the memory of a Newton polygon
344// ----------------------------------------------------------------------------
345
346void    newtonPolygon::copy_delete( void )
347{
348    if( l != (linearForm*)NULL && N > 0 ) delete [] l;
349    copy_zero( );
350}
351
352// ----------------------------------------------------------------------------
353//  Initialize deep from another Newton polygon
354// ----------------------------------------------------------------------------
355
356void    newtonPolygon::copy_deep( const newtonPolygon &np )
357{
358    copy_new( np.N );
359    for( int i=0; i<np.N; i++ )
360    {
361        l[i] = np.l[i];
362    }
363    N = np.N;
364}
365
366// ----------------------------------------------------------------------------
367//  Copy constructor
368// ----------------------------------------------------------------------------
369
370newtonPolygon::newtonPolygon( const newtonPolygon &np )
371{
372    copy_deep( np );
373}
374
375// ----------------------------------------------------------------------------
376//  Destructor
377// ----------------------------------------------------------------------------
378
379newtonPolygon::~newtonPolygon( )
380{
381    copy_delete( );
382}
383
384// ----------------------------------------------------------------------------
385//  We define `=` to be a deep copy
386// ----------------------------------------------------------------------------
387
388newtonPolygon & newtonPolygon::operator = ( const newtonPolygon &np )
389{
390    copy_delete( );
391    copy_deep( np );
392
393    return *this;
394}
395
396// ----------------------------------------------------------------------------
397//  Initialize a Newton polygon from a polynomial
398// ----------------------------------------------------------------------------
399
400newtonPolygon::newtonPolygon( poly f )
401{
402    copy_zero( );
403
404    int *r=new int[pVariables];
405    poly *m=new poly[pVariables];
406
407
408    KMatrix<Rational> mat( pVariables,pVariables+1 );
409
410    int i,j,stop=FALSE;
411    linearForm sol;
412
413    // ---------------
414    //  init counters
415    // ---------------
416
417    for( i=0; i<pVariables; i++ )
418    {
419        r[i] = i;
420    }
421
422    m[0] = f;
423
424    for( i=1; i<pVariables; i++ )
425    {
426        m[i] = m[i-1]->next;
427    }
428
429    // -----------------------------
430    //  find faces (= linear forms)
431    // -----------------------------
432
433        do
434        {
435            // ---------------------------------------------------
436              //  test if monomials p.m[r[0]]m,...,p.m[r[p.vars-1]]
437            //  are linearely independent
438            // ---------------------------------------------------
439
440            for( i=0; i<pVariables; i++ )
441            {
442                for( j=0; j<pVariables; j++ )
443                {
444                  //    mat.set( i,j,pGetExp( m[r[i]],j+1 ) );
445                    mat.set( i,j,pGetExp( m[i],j+1 ) );
446                }
447                mat.set( i,j,1 );
448            }
449
450            if( mat.solve( &(sol.c),&(sol.N) ) == pVariables )
451            {
452                // ---------------------------------
453                //  check if linearForm is positive
454                //  check if linearForm is extremal
455                // ---------------------------------
456
457                if( sol.positive( ) && sol.pweight( f ) >= (Rational)1 )
458                {
459                    // ----------------------------------
460                    //  this is a face or the polyhedron
461                    // ----------------------------------
462
463                    add_linearForm( sol );
464                    sol.c = (Rational*)NULL;
465                    sol.N = 0;
466                }
467            }
468
469            // --------------------
470            //  increment counters
471            // --------------------
472
473            for( i=1; r[i-1] + 1 == r[i] && i < pVariables; i++ );
474
475            for( j=0; j<i-1; j++ )
476            {
477                r[j]=j;
478            }
479
480            if( i>1 )
481            {
482                m[0]=f;
483                for( j=1; j<i-1; j++ )
484                {
485                    m[j]=m[j-1]->next;
486                }
487            }
488            r[i-1]++;
489            m[i-1]=m[i-1]->next;
490
491            if( m[pVariables-1] == (poly)NULL )
492            {
493                stop = TRUE;
494            }
495        }
496        while( stop == FALSE );
497}
498
499#ifdef  NPOLYGON_PRINT
500
501ostream & operator << ( ostream &s,const newtonPolygon &a )
502{
503    #ifdef NPOLYGON_IOSTREAM
504        s << "Newton polygon:" << endl;
505    #else
506        fprintf( stdout,"Newton polygon:\n" );
507    #endif
508
509    for( int i=0; i<a.N; i++ )
510    {
511        s << a.l[i];
512
513        #ifdef NPOLYGON_IOSTREAM
514           s << endl;
515        #else
516            fprintf( stdout,"\n" );
517        #endif
518    }
519
520    return s;
521}
522
523#endif
524
525// ----------------------------------------------------------------------------
526//  Add a face to the newton polygon
527// ----------------------------------------------------------------------------
528
529void    newtonPolygon::add_linearForm( const linearForm &l0 )
530{
531    int           i;
532    newtonPolygon np;
533
534    // -------------------------------------
535    //  test if linear form is already here
536    // -------------------------------------
537
538    for( i=0; i<N; i++ )
539    {
540        if( l0==l[i] )
541        {
542            return;
543        }
544    }
545
546    np.copy_new( N+1 );
547    np.N = N+1;
548
549    for( i=0; i<N; i++ )
550    {
551        np.l[i].copy_shallow( l[i] );
552        l[i].copy_zero( );
553    }
554
555    np.l[N] = l0;
556
557    copy_delete( );
558    copy_shallow( np );
559    np.copy_zero( );
560
561    return;
562}
563
564// ----------------------------------------------------------------------------
565//  Newton weight of a monomial
566// ----------------------------------------------------------------------------
567
568Rational  newtonPolygon::weight( poly m ) const
569{
570    Rational ret = l[0].weight( m );
571    Rational tmp;
572
573    for( int i=1; i<N; i++ )
574    {
575        tmp = l[i].weight( m );
576
577        if( tmp < ret )
578        {
579            ret = tmp;
580        }
581    }
582    return ret;
583}
584
585// ----------------------------------------------------------------------------
586//  Newton weight of a monomial shifted by the product of the variables
587// ----------------------------------------------------------------------------
588
589Rational  newtonPolygon::weight_shift( poly m ) const
590{
591    Rational ret = l[0].weight_shift( m );
592    Rational tmp;
593
594    for( int i=1; i<N; i++ )
595    {
596        tmp = l[i].weight_shift( m );
597
598        if( tmp < ret )
599        {
600            ret = tmp;
601        }
602    }
603    return ret;
604}
605
606// ----------------------------------------------------------------------------
607//  Newton weight of a monomial (forgetting the first variable)
608// ----------------------------------------------------------------------------
609
610Rational  newtonPolygon::weight1( poly m ) const
611{
612    Rational ret = l[0].weight1( m );
613    Rational tmp;
614
615    for( int i=1; i<N; i++ )
616    {
617        tmp = l[i].weight1( m );
618
619        if( tmp < ret )
620        {
621            ret = tmp;
622        }
623    }
624    return ret;
625}
626
627// ----------------------------------------------------------------------------
628//  Newton weight of a monomial shifted by the product of the variables
629//  (forgetting the first variable)
630// ----------------------------------------------------------------------------
631
632Rational  newtonPolygon::weight_shift1( poly m ) const
633{
634    Rational ret = l[0].weight_shift1( m );
635    Rational tmp;
636
637    for( int i=1; i<N; i++ )
638    {
639        tmp = l[i].weight_shift1( m );
640
641        if( tmp < ret )
642        {
643            ret = tmp;
644        }
645    }
646    return ret;
647}
648
649/*
650// ----------------------------------------------------------------------------
651//  Chcek if the polynomial belonging to the Newton polygon
652//  is semiquasihomogeneous (sqh)
653// ----------------------------------------------------------------------------
654
655int     newtonPolygon::is_sqh( void ) const
656{
657    return ( N==1 ? TRUE : FALSE );
658}
659
660// ----------------------------------------------------------------------------
661//  If the polynomial belonging to the Newton polygon is sqh,
662//  return its weights vector
663// ----------------------------------------------------------------------------
664
665Rational*   newtonPolygon::sqh_weights( void ) const
666{
667    return ( N==1 ? l[0].c : (Rational*)NULL );
668}
669
670int    newtonPolygon::sqh_N( void ) const
671{
672    return ( N==1 ? l[0].N : 0 );
673}
674*/
675
676#endif /* HAVE_SPECTRUM */
677// ----------------------------------------------------------------------------
678//  npolygon.cc
679//  end of file
680// ----------------------------------------------------------------------------
681
Note: See TracBrowser for help on using the repository browser.