// FILE: poly2.h // CLASS PROVIDED: // class polynomial (in the namespace main_savitch_3) // A polynomial has one variable x, real number coefficients, and // non-negative integer exponents. Such a polynomial can be viewed // as having the form: // A[n]*x^n + A[n-1]*x^(n-1) + ... A[2]*x^2 + A[1]*x + A[0] // where the A[n] are the real number coefficients and x^i represents // the variable x raised to the i power. The coefficient A[0] is // called the "constant" or "zeroth" term of the polynomial. // // NOTES TO STUDENT: // 1. This version works by storing the coefficients in // a doubly-linked list with each node holding the coefficient and // exponent for one term. The terms are kept in order from smallest // to largest exponent. Each polynomial also maintains a pointer to the // most recently accessed node. // 2. Note that two functions have been implemented as inline functions // in this file (the degree and operator() functions). // 3. An implementation of the make_gif function is available for // students to use at www.cs.colorado.edu/~main/projects/polygif.cxx. // // CONSTRUCTOR for the polynomial class // POSTCONDITION: This polynomial has been create with all zero // coefficients, except for coefficient c for the specified exponent. // When used as a default constructor (using default values for // both arguments), the result is a polynomial with all zero // coefficients. // // MODIFICATION MEMBER FUNCTIONS for the polynomial class // void add_to_coef(double amount, unsigned int exponent) // POSTCONDITION: Adds the given amount to the coefficient of the // specified exponent. // // void assign_coef(double coefficient, unsigned int exponent) // POSTCONDITION: Sets the coefficient for the specified exponent. // // void clear( ) // POSTCONDITION: All coefficients of this polynomial are set to zero. // // CONSTANT MEMBER FUNCTIONS for the polynomial class // double coefficient(unsigned int exponent) const // POSTCONDITION: Returns coefficient at specified exponent of this // polynomial. // // unsigned int degree( ) const // POSTCONDITION: The function returns the value of the largest exponent // with a non-zero coefficient. // If all coefficients are zero, then the function returns zero. // // polynomial derivative( ) const // POSTCONDITION: The return value is the first derivative of this // polynomial. // // double eval(double x) const // POSTCONDITION: The return value is the value of this polynomial with the // given value for the variable x. // // void find_root( // double& answer, // bool& success, // unsigned int& iterations, // double starting_guess = 0, // unsigned int maximum_iterations = 100, // double epsilon = 1e-8 // ) // const // PRECONDITION: epsilon > 0. // POSTCONDITION: This function uses Newton's method to search for a root // of the polynomial (i.e., a value of x for which the polynomial is zero). // The method requires some starting guess for the value of the root. This // guess is improved over a series of iterations (with the maximum allowed // iterations defined by the parameter maximum_iterations). There are three // possible outcomes: // 1. SUCCESS: // The method hits a near-root (a value of x for which the absolute // value of the polynomial is no more than epsilon). In this case, the // function sets answer to equal this near-root, success is set to true, // and iterations is set to the number of iterations required. // 2. FLAT FAILURE: // Newton's method fails because the guess hits a very flat area of the // polynomial (a point where first derivative is no more than epsilon). // In this case, the function sets answer equal to the guess that caused // flat failure, success is set to false, and iterations is the number // of iterations carried out (which will be less than // maximum_iterations). // 3. MAXIMUM ITERATIONS REACHED: // The maximum number of iterations is reached without success or flat // failure. In this case, the function sets answer to the last guess // tried, success is set to false, and iterations is set to // maximum_iterations. // // unsigned int next_term(unsigned int e) const // POSTCONDITION: The return value is the next exponent n which is LARGER // than e such that coefficient(n) != 0. // If there is no such term, then the return value is zero. // // unsigned int previous_term(unsigned int e) const // POSTCONDITION: The return value is the next exponent n which is SMALLER // than e such that coefficient(n) != 0. // If there is no such term, then the return value is UINT_MAX // from . // // CONSTANT OPERATORS for the polynomial class // double operator( ) (double x) const // Same as the eval member function. // // NON-MEMBER BINARY OPERATORS for the polynomial Class // polynomial operator -(const polynomial& p1, const polynomial& p2) // POSTCONDITION: return-value is a polynomial with each coefficient // equal to the difference of the coefficients of p1 & p2 for any given // exponent. // // polynomial operator +(const polynomial& p1, const polynomial& p2) // POSTCONDITION: return-value is a polynomial with each coefficient // equal to the sum of the coefficients of p1 & p2 for any given // exponent. // // polynomial operator *(const polynomial& p1, const polynomial& p2) // POSTCONDITION: Each term of p1 has been multiplied by each term of p2, // and the answer is the sum of all these term-by-term products. // For example, if p1 is 2x^2 + 3x + 4 and p2 is 5x^2 - 1x + 7, then the // return value is 10x^4 + 13x^3 + 31x^2 + 17x + 28. // // NON-MEMBER OUTPUT FUNCTIONS for the polynomial Class // ostream& operator << (ostream& out, const polynomial& p) // POSTCONDITION: The polynomial has been printed to ostream out, which, // in turn, has been returned to the calling function. // // void make_gif( // const polynomial& p, // const char filename[ ], // double low_x, // double high_x, // double low_y, // double high_y // ) // PRECONDITION: filename is a legal filename for a gif file. // Also (low_x < high_x) && (low_y < high_y). // POSTCONDITION: A gif file has been written to the specified filename // with a graphical representation of the polynomial in the specified // ranges (low_x...high_x and low_y...high_y). // // DYNAMIC MEMORY // Since this class uses dynamic memory, the copy constructor and assignment // operator are overridden, and there is a destructor implemented. Also, // if there is insufficient dynamic memory, the following functions throw // a bad_alloc exception: the constructors, assignment, reserve, add_to_coef, // assign_coef, and any function that returns a polynomial. #ifndef POLY2_H #define POLY2_H #include // Provides NULL #include // Provides ostream // If your compiler does not support namespaces, then please delete the // following line and the set of brackets that follow. namespace main_savitch_5 { class polynode { public: // CONSTRUCTOR: Creates a node containing a specified initial // coefficient (init_coef), initial exponent (init_exponent), and // initial links forward and backward (init_fore and init_back). polynode( double init_coef = 0.0, unsigned int init_exponent = 0, polynode* init_fore = NULL, polynode* init_back = NULL ) { coef_field = init_coef; exponent_field = init_exponent; link_fore = init_fore; link_back = init_back; } // Member functions to set the fields: void set_coef(double new_coef) { coef_field = new_coef; } void set_exponent(unsigned int new_exponent) { exponent_field = new_exponent; } void set_fore(polynode* new_fore) { link_fore = new_fore; } void set_back(polynode* new_back) { link_back = new_back; } // Const member functions to retrieve current coefficient or exponent: double coef( ) const { return coef_field; } unsigned int exponent( ) const { return exponent_field; } // Two slightly different member functions to retrieve each link: const polynode* fore( ) const { return link_fore; } polynode* fore( ) { return link_fore; } const polynode* back( ) const { return link_back; } polynode* back( ) { return link_back; } private: double coef_field; unsigned int exponent_field; polynode *link_fore; polynode *link_back; }; class polynomial { public: // CONSTRUCTORS and DESTRUCTOR polynomial(double c = 0.0, unsigned int exponent = 0); polynomial(const polynomial& source); ~polynomial( ); // MODIFICATION MEMBER FUNCTIONS void operator =(const polynomial& source); void add_to_coef(double amount, unsigned int exponent); void assign_coef(double coefficient, unsigned int exponent); void clear( ); // CONSTANT MEMBER FUNCTIONS double coefficient(unsigned int exponent) const; unsigned int degree( ) const { return current_degree; } polynomial derivative( ) const; double eval(double x) const; void find_root( double& answer, bool& success, unsigned int& iterations, double guess = 0, unsigned int maximum_iterations = 100, double epsilon = 1e-8 ) const; unsigned int next_term(unsigned int e) const; unsigned int previous_term(unsigned int e) const; // CONSTANT OPERATORS double operator( ) (double x) const { return eval(x); } private: polynode *head_ptr; // Head pointer for list of terms polynode *tail_ptr; // Tail pointer for list of terms mutable polynode *recent_ptr; // Most recently used term unsigned int current_degree; // Current degree of the polynomial // A private member function to aid the other functions: void set_recent(unsigned int exponent) const; }; // NON-MEMBER BINARY OPERATORS polynomial operator +(const polynomial& p1, const polynomial& p2); polynomial operator -(const polynomial& p1, const polynomial& p2); polynomial operator *(const polynomial& p1, const polynomial& p2); // NON-MEMBER OUTPUT FUNCTIONS std::ostream& operator << (std::ostream& out, const polynomial& p); void make_gif( const polynomial& p, const char filename[ ], double low_x, double high_x, double low_y, double high_y ); } #endif