// ---------------------------------------------------------------------------- // npolygon.cc // begin of file // Stephan Endrass, endrass@mathematik.uni-mainz.de // 23.7.99 // ---------------------------------------------------------------------------- #define NPOLYGON_CC #ifdef HAVE_CONFIG_H #include "singularconfig.h" #endif /* HAVE_CONFIG_H */ #include #ifdef HAVE_SPECTRUM #ifdef NPOLYGON_PRINT #include #ifndef NPOLYGON_IOSTREAM #include #endif #endif //#include #include #include #include #include #include #include // ---------------------------------------------------------------------------- // Allocate memory for a linear form of k terms // ---------------------------------------------------------------------------- void linearForm::copy_new( int k ) { if( k > 0 ) { c = new Rational[k]; #ifndef NBDEBUG if( c == (Rational*)NULL ) { #ifdef NPOLYGON_PRINT #ifdef NPOLYGON_IOSTREAM cerr << "void linearForm::copy_new( int k ): no memory left ...\n" ; #else fprintf( stderr, "void linearForm::copy_new( int k ): no memory left ...\n"); #endif #endif HALT(); } #endif } else if( k == 0 ) { c = (Rational*)NULL; } else if( k < 0 ) { #ifdef NPOLYGON_PRINT #ifdef NPOLYGON_IOSTREAM cerr << "void linearForm::copy_new( int k ): k < 0 ...\n"; #else fprintf( stderr, "void linearForm::copy_new( int k ): k < 0 ...\n" ); #endif #endif HALT(); } } // ---------------------------------------------------------------------------- // Delete the memory of a linear form // ---------------------------------------------------------------------------- void linearForm::copy_delete( void ) { if( c != (Rational*)NULL && N > 0 ) delete [] c; copy_zero( ); } // ---------------------------------------------------------------------------- // Initialize deep from another linear form // ---------------------------------------------------------------------------- void linearForm::copy_deep( const linearForm &l ) { copy_new( l.N ); for( int i=l.N-1; i>=0; i-- ) { c[i] = l.c[i]; } N = l.N; } // ---------------------------------------------------------------------------- // Copy constructor // ---------------------------------------------------------------------------- linearForm::linearForm( const linearForm &l ) { copy_deep( l ); } // ---------------------------------------------------------------------------- // Destructor // ---------------------------------------------------------------------------- linearForm::~linearForm( ) { copy_delete( ); } // ---------------------------------------------------------------------------- // Define `=` to be a deep copy // ---------------------------------------------------------------------------- linearForm & linearForm::operator = ( const linearForm &l ) { copy_delete( ); copy_deep( l ); return *this; } // ---------------------------------------------------------------------------- // ostream for linear form // ---------------------------------------------------------------------------- #ifdef NPOLYGON_PRINT ostream & operator << ( ostream &s,const linearForm &l ) { for( int i=0; i 0 && l.c[i] >= (Rational)0 ) { #ifdef NPOLYGON_IOSTREAM s << "+"; #else fprintf( stdout,"+" ); #endif } s << l.c[i]; #ifdef NPOLYGON_IOSTREAM s << "*x" << i+1; #else fprintf( stdout,"*x%d",i+1 ); #endif } } return s; } #endif // ---------------------------------------------------------------------------- // Equality of linear forms // ---------------------------------------------------------------------------- int operator == ( const linearForm &l1,const linearForm &l2 ) { if( l1.N!=l2.N ) return FALSE; for( int i=l1.N-1; i >=0 ; i-- ) { if( l1.c[i]!=l2.c[i] ) return FALSE; } return TRUE; } // ---------------------------------------------------------------------------- // Newton weight of a monomial // ---------------------------------------------------------------------------- Rational linearForm::weight( poly m, const ring r ) const { Rational ret=(Rational)0; for( int i=0,j=1; i 0 ) { l = new linearForm[k]; #ifndef NDEBUG if( l == (linearForm*)NULL ) { #ifdef NPOLYGON_PRINT #ifdef NPOLYGON_IOSTREAM cerr << "void newtonPolygon::copy_new( int k ): no memory left ...\n"; #else fprintf( stderr, "void newtonPolygon::copy_new( int k ): no memory left ...\n" ); #endif #endif HALT(); } #endif } else if( k == 0 ) { l = (linearForm*)NULL; } else if( k < 0 ) { #ifdef NPOLYGON_PRINT #ifdef NPOLYGON_IOSTREAM cerr << "void newtonPolygon::copy_new( int k ): k < 0 ...\n"; #else fprintf( stderr, "void newtonPolygon::copy_new( int k ): k < 0 ...\n" ); #endif #endif HALT(); } } // ---------------------------------------------------------------------------- // Delete the memory of a Newton polygon // ---------------------------------------------------------------------------- void newtonPolygon::copy_delete( void ) { if( l != (linearForm*)NULL && N > 0 ) delete [] l; copy_zero( ); } // ---------------------------------------------------------------------------- // Initialize deep from another Newton polygon // ---------------------------------------------------------------------------- void newtonPolygon::copy_deep( const newtonPolygon &np ) { copy_new( np.N ); for( int i=0; i; newtonPolygon::newtonPolygon( poly f, const ring s ) { copy_zero( ); int *r=new int[s->N]; poly *m=new poly[s->N]; KMatrix mat(s->N,s->N+1 ); int i,j,stop=FALSE; linearForm sol; // --------------- // init counters // --------------- for( i=0; iN; i++ ) { r[i] = i; } m[0] = f; for( i=1; iN; i++ ) { m[i] = pNext(m[i-1]); } // ----------------------------- // find faces (= linear forms) // ----------------------------- do { // --------------------------------------------------- // test if monomials p.m[r[0]]m,...,p.m[r[p.vars-1]] // are linearely independent // --------------------------------------------------- for( i=0; iN; i++ ) { for( j=0; jN; j++ ) { // mat.set( i,j,pGetExp( m[r[i]],j+1 ) ); mat.set( i,j,p_GetExp( m[i],j+1,s ) ); } mat.set( i,j,1 ); } if( mat.solve( &(sol.c),&(sol.N) ) == s->N ) { // --------------------------------- // check if linearForm is positive // check if linearForm is extremal // --------------------------------- if( sol.positive( ) && sol.pweight( f,s ) >= (Rational)1 ) { // ---------------------------------- // this is a face or the polyhedron // ---------------------------------- add_linearForm( sol ); sol.c = (Rational*)NULL; sol.N = 0; } } // -------------------- // increment counters // -------------------- for( i=1; r[i-1] + 1 == r[i] && i < s->N; i++ ); for( j=0; j1 ) { m[0]=f; for( j=1; jN-1] == (poly)NULL ) { stop = TRUE; } } while( stop == FALSE ); } #ifdef NPOLYGON_PRINT ostream & operator << ( ostream &s,const newtonPolygon &a ) { #ifdef NPOLYGON_IOSTREAM s << "Newton polygon:" << endl; #else fprintf( stdout,"Newton polygon:\n" ); #endif for( int i=0; i