/* * surf - visualizing algebraic curves and algebraic surfaces * Copyright (C) 1996-1997 Friedrich-Alexander-Universitaet * Erlangen-Nuernberg * 1997-2000 Johannes Gutenberg-Universitaet Mainz * Authors: Stephan Endrass, Hans Huelf, Ruediger Oertel, * Kai Schneider, Ralf Schmitt, Johannes Beigel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef CLMONOM_H #define CLMONOM_H #include #include #include "simple.h" #include "monomarith.h" // ---------------------------------------------------------------------------- // ------------- monomial class template -------------------------------------- // ---------------------------------------------------------------------------- template class Monom { protected: double a; // Coefficient int k[dimen]; // Exponent Field public: // default zero monomial Monom() : a(0.0) { for( int i = 0; i < dimen; i++ ) k[i] = 0; } // convert double to monom Monom (const double Coef) : a(Coef) { for( int i = 0; i < dimen; i++ ) k[i] = 0; } // copy monom Monom (const Monom& m) : a(m.a) { for( int i = 0; i < dimen; i++ ) k[i] = m.k[i]; } // copy monom from pointer Monom (const Monom* m) : a(m->a) { for( int i = 0; i < dimen; i++ ) k[i] = m->k[i]; } // copy monom from monomstruct Monom (const monxyz& m) : a(m.a) { k[0] = m.kx; k[1] = m.ky; } // -------------------------------------------------------------------------- // check equality of exponents int operator>=( const Monom &m ) const { int result = TRUE; for( int i = 0; (i < dimen) && (result == TRUE); i++ ) if( k[i] != m.k[i] ) result = FALSE; return result; } // check equality of monoms int operator==( const Monom &m ) const { return ( *this >= m ) && ( fabs( a - m.a) < epsilon ) ; } // assignment, copy monomial Monom& operator=( const Monom &m ) { a = m.a; for( int i = 0; i < dimen; i++ ) k[i] = m.k[i]; return *this; } // addition Monom& operator+=( const Monom &m ) { if( *this >= m ) a += m.a; return *this; } // monom multiplication with double Monom& operator*=( const double Mult ) { a *= Mult; return *this; } Monom operator*( const double Mult ) const { Monom Mneu ( *this ); Mneu.a *= Mult; return Mneu; } // multiplication with monom Monom& operator*=( const Monom &m ) { a *= m.a; for( int i = 0; i < dimen; i++ ) k[i] += m.k[i]; return *this; } Monom operator*( const Monom &m ) const { Monom Mneu ( *this ); Mneu *= m; return Mneu; } //--------------------------------------------------------------------------- // get degree of monomial int Degree() const { int result = 0; for( int i = 0; i < dimen; i++ ) result += k[i]; return result; } void Print(ostream &os) const { os << a; for( int i = 0; i < dimen; i++ ) os << "*" << (char) (i+'x') << "^" << k[i]; } // get absolute of coefficient double AbsCoeff() const { return fabs( a ); } // compare exponents of variable nr. var int CompareDeg( const Monom &m, const int Var ) const { if( Var >= dimen ) return FALSE; return (k[Var] == m.k[Var]); } // provide a comparation for sorting monomials // priority set to variable nr. var int Compare( const Monom &m, const int Var ) { if ( Var < 0 || Var > 1 ) return 0; if ( k[Var] == m.k[Var] ) return ( m.k[1-Var] - k[1-Var] ); return (m.k[Var] - k[Var]); } // derive a monomial in variable nr. var void Derive(const int Var) { if( Var < dimen ) { if( k[Var] > 0 ) { a *= k[Var]; k[Var]--; } else a = 0.0; } } // return exonent of variable nr. var int Exponent( int Var ) const { if( Var < dimen ) return k[Var]; return 0; } // set exponent void Exponent( int Var, int Expo ) { if( Var < dimen ) k[Var] = Expo; } // return and clear exponent int ExtractExponent( int Var ) { int result = 0; if( Var < dimen ) { result = k[Var]; k[Var] = 0; } return result; } // return coefficient double Coeff() const { return a; } // set coefficient void SetCoeff(const double cof) { a = cof; } void SwapXY() { int tmp = k[0]; k[0] = k[1]; k[1] = tmp; } friend class Polyxyz; // power function for monomials Monom computePower (int Exp) const { Monom Mneu; #ifdef SUN if ( a == 0.0 && Exp == 0 ) Mneu.a = 1.0; else #endif //SUN Mneu.a = pow( a, (double) Exp ); for( int i = 0; i < dimen; i++ ) Mneu.k[i] = k[i] * Exp; return Mneu; } }; template inline ostream &operator << (ostream &os, const Monom &m) { m.Print(os); return os; } template inline Monom pow (const Monom &monom, int s) { return monom.computePower(s); } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- typedef Monom<2> MonomXY; // ---------------------------------------------------------------------------- // ---------- derive trivariate monomial class -------------------------------- // ---------- and provide casting mon3 to mon2 -------------------------------- // ---------------------------------------------------------------------------- class MonomXYZ : public Monom<3> { public: MonomXYZ() : Monom<3>() {} MonomXYZ( const Monom<3> &m ) : Monom<3>( m ) {} MonomXYZ( const MonomXYZ *m ) : Monom<3>( m ) {} MonomXYZ( const monxyz &m ) : Monom<3>( m ) { k[2] = m.kz;} MonomXYZ( const double d ) : Monom<3>( d ) {} MonomXYZ( const MonomXY &m ) : Monom<3>(m.Coeff()) { k[0] = m.Exponent( 0 ); k[1] = m.Exponent( 1 ); k[2] = 0; } // casting operator operator MonomXY() { MonomXY Mneu; Mneu.SetCoeff( a ); Mneu.Exponent( 0, k[0] ); Mneu.Exponent( 1, k[1] ); return Mneu; } // provide comparation for sorting of trivariate monomials int Compare( const MonomXYZ &m, const int Var ) { if ( k[2] == m.k[2] ) return Monom<3>::Compare( m, Var ); return (m.k[2] - k[2]); } }; inline MonomXYZ pow (const MonomXYZ &m, int s) { return m.computePower(s); } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- #endif /* MONOMARITH_H */