/* * 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 CLMULTIPOLY_H #define CLMULTIPOLY_H #include #define VARIABLE_X 0 #define VARIABLE_Y 1 #define VARIABLE_Z 2 #include "monomarith.h" #include "polyarith.h" #include "Monomial.h" #include "UniVariatePolynom.h" template class MultiPoly { protected: int Number; int deg; Mon *Monomial; public: MultiPoly(); // empty polynom MultiPoly( const int ); // allocate number of monoms MultiPoly( const double ); // const poly MultiPoly( const Mon& ); // poly of one monom MultiPoly( const polyxyz alt ); // copy polyxyz MultiPoly( const MultiPoly& ); // copy Poly-class ~MultiPoly(); // ------------- operators -------------------------------------- MultiPoly& operator*=(const double Mult); MultiPoly& operator*=(const Mon &mon); MultiPoly& operator*=(const MultiPoly& Pol2); MultiPoly& operator=( const double var ); MultiPoly& operator=(const MultiPoly& Pol); MultiPoly& operator+=(const Mon &); MultiPoly& operator+=(const MultiPoly& ); MultiPoly operator*(const MultiPoly& Pol2) const; MultiPoly operator*(const Mon &m) const; int operator==( const MultiPoly& ) const; int operator!=( const MultiPoly& ) const; // ---------------- element functions ---------------------------- int GetDeg() const { return deg; } int GetNumber() const { return Number; } double MaxabsCoeff() const { double MaxabsCoeff=0; for( int i=0; i< Number; i++) if( Monomial[i].AbsCoeff() > MaxabsCoeff ) MaxabsCoeff = Monomial[i].AbsCoeff(); return MaxabsCoeff; } void Norm() { double a = MaxabsCoeff(); if(!(fabs(a) < epsilon)) *this *= (10.0/a) ; } Mon Monom(const int num) const { if ( num >= 0 && num < Number ) return Monomial[num]; return 0.0; } void Renew(int num) { Mon *store = 0; if ( num <= 0 ) { Number = 1; store = new Mon [1]; store[0] = 0.0; deg = 0; } else { store = new Mon [num]; for( int i=0; i < Number; i++) store[i] = Monomial[i]; Number = num; } delete [] Monomial; Monomial = store; } void SetDegree() { if( Number <= 0 ) deg = DEG_UNSPEC; else { int iDeg = 0; int maxDeg = -1; for( int i = 0; i < Number; i++ ) { iDeg = Monomial[i].Degree(); if( maxDeg < iDeg ) maxDeg = iDeg; } deg = maxDeg; } } int GetNumberOfDifferentExponents( int Var ) const { int Counter = 1; for( int i = 1; i < Number; i++ ) if(!Monomial[i].CompareDeg( Monomial[i-1], Var ) ) Counter++; return Counter; } int GetNumberOfDifferentExponents( int Var1, int Var2 ) const { int Counter = 1; for( int i = 1; i < Number; i++ ) if( !Monomial[i].CompareDeg( Monomial[i-1], Var2 ) || !Monomial[i].CompareDeg( Monomial[i-1], Var1 ) ) Counter++; return Counter; } int MaxDegreeOfVariable( int Var ) const { int result = 0; for( int i = 0; i < Number; i++ ) { if( result < Monomial[i].Exponent( Var ) ) result = Monomial[i].Exponent( Var ); } return result; } MultiPoly& Derive(const int Var) { for(int i = 0; i < Number; i++ ) Monomial[i].Derive( Var ); Collect(); return *this; } void Sort( const int ); void Shift(double,double,double); void Print (ostream &os) const; int Check(void) const; void Collect(void); void Subst( const MultiPoly* ); MultiPoly Subst( const MultiPoly&, const int ) const; void SwapXY(); MultiPoly Solve( const int ); MultiPoly CounterOfSolve( int ) const; MultiPoly NominatorOfSolve( int ) const; MultiPoly Subst( const MultiPoly&, const MultiPoly&, const int ) const; // friend MultiPoly pow( const MultiPoly& Poly, const int s ); MultiPoly computePower (const int s) const; friend class MappingMatrix; }; template inline ostream &operator<< (ostream &os, const MultiPoly &m) { m.Print(os); return os; } template inline MultiPoly pow( const MultiPoly& Poly, const int s ) { return Poly.computePower(s); } class Polyxy : public MultiPoly { public: Polyxy() : MultiPoly() {} Polyxy(const int num) : MultiPoly(num) {} Polyxy(const double val) : MultiPoly(val) {} Polyxy(const polyxyz alt) : MultiPoly(alt) {} Polyxy(const Polyxy& alt) : MultiPoly(alt) {} Polyxy(const MultiPoly& alt) : MultiPoly(alt) {} Polyxy(const MultiPoly& alt) : MultiPoly(alt.GetNumber()) { for(int i = 0; i < Number; i++ ) Monomial[i] = MonomXY( alt.Monom( i ) ); Collect(); } void Transform( Polyx*, int*, Polyx*, int ) const; }; class Polyxyz : public MultiPoly { public: Polyxyz() : MultiPoly() {} Polyxyz(const int num) : MultiPoly(num) {} Polyxyz(const polyxyz alt) : MultiPoly(alt) {} Polyxyz(const Polyxyz& alt) : MultiPoly(alt) {} Polyxyz(const MultiPoly& alt) : MultiPoly(alt) {} void Transform( Polyx*, int*, int*, Polyx*, int*, Polyx* ); void Perspective( const double z ); double evaluate (double x, double y, double z); }; #endif