Author Topic: class polynomial  (Read 7306 times)

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
class polynomial
« on: March 27, 2011, 02:41:10 AM »
Another common student request is for class polynomial ...

Here is the polynomial.h file ... (followed by the test program file) ...

Code: [Select]
// polynomial.h // 2011-03-27 //

#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H

#include <iostream>
#include <fstream>
#include <sstream>      // to 'smooth' input from keyboard ...
#include <string>
#include <vector>
#include <cmath>        // for pow( base, index )
//using namespace std;
using std::ostream;
using std::istream;
using std::istringstream;
using std::string;
using std::vector;
using std::cout;
using std::endl;
using std::flush;

// a simple way to dodge the overhead of defining a template <class T>
// polynomial here ...
typedef double my_type;

const int MAX_TERMS_ON_LINE = 8;

class polynomial
{
    friend ostream& operator<< (ostream& os, const polynomial& p);
    friend istream& operator>> (istream& os, polynomial& p);

public:
    polynomial();
    polynomial(int d);
    polynomial( const polynomial& );  // copy constructor

    int degree() const;

    polynomial& operator= ( const polynomial& ); // assignment

    polynomial& operator+= (const polynomial& p);
    polynomial operator+ (const polynomial& p) const;

    polynomial operator- () const; // unary operator ...
    polynomial operator- (const polynomial& p) const;
    polynomial& operator-= (const polynomial& p);

    polynomial operator* (const polynomial& p) const;

    polynomial dif() const;
    polynomial antidif() const;

    bool operator== (const polynomial& p) const;
    my_type operator() (my_type x) const; //  ... evaluate poly for this x

    my_type& operator[] ( int i )  { return coefficients[i]; }
    my_type operator[] ( int i ) const { return coefficients[i]; }

private:
    vector < my_type > coefficients;
    void trim()
    {
        int i, d = degree();
        for( i = d; i >= 0; --i )
            if( coefficients[i] != 0 ) break;
        if( d - i ) coefficients.resize( i+1 );
    }
};


// friend functions defined here ...

// Just enter zero for a coef. if that 'degree' does not exit (but a higher does)
// and ... just press 'Enter' to exit input loop ...
istream& operator>> (istream& is, polynomial& p)
{
    int t=0;
    my_type tmp;
    string tmpStr;
    p.coefficients.clear();
    for( ;; )
    {
        cout << "Input coef[" << t++ << "]: " << flush;
        getline( is, tmpStr );
        if( t>1 && tmpStr == "" ) { --t; break; }
        istringstream iss( tmpStr );
        tmp = 0;
        iss >> tmp;
        p.coefficients.push_back( tmp );
    }

    int d = p.degree();
    //don't allow leading terms with zero coeff's
    if( d+1 != t ) p.coefficients.resize(d+1);
    return is;
}

ostream& operator<< (ostream& os, const polynomial& p)
{
    bool firstPassDone = false;
    my_type coeff;

    for(int c = 0, i = p.degree(); i >= 0; --i)
    {
        if(p[i] != 0 || (i == 0 && ! firstPassDone))
        {
            coeff = p[i];
            if(coeff < 0) coeff = -coeff;

            if(firstPassDone)
            {
                cout << ' ' << (p[i] < 0 ? '-' : '+') << ' ';
                if(i == 0 || coeff != 1) { c++; os << coeff; }
            }
            else
            {
                if(i == 0 || coeff != 1) { c++; os << p[i]; }
                else if(p[i] < 0) os << '-';
            }

            if(i > 0)
            {
                os << 'x';
                if(i > 1) os << '^' << i;
            }
            firstPassDone = true;
        }
        if(c == MAX_TERMS_ON_LINE && i != 0) { c=0; os << endl; }
    }
    return os;
}


// Constructor: creates a zero polynomial with maximum degree 0.
polynomial::polynomial() : coefficients(1)
{
    //coefficients = vector< my_type >(1);
    //coefficients[0] = 0; // done by ctor above
}

// Constructor: creates a zero polynomial with maximum degree d.
polynomial::polynomial(int d) : coefficients(d+1)
{
    //coefficients = vector< my_type >(d+1);
    //for(int i = 0; i <= d; ++i) coefficients[i] = 0; // done by ctor above
}

// Constructor: copy constructor
polynomial::polynomial(const polynomial& p)
{
    coefficients = p.coefficients; // uses vector =
}

// Member function to compute the real degree of a polynomial.
int polynomial::degree() const
{
    for(int i = coefficients.size() - 1; i >= 0; --i)
   if( coefficients[i] != 0 ) return i;
    // if reach here ...
    return 0;
}

// assignment ...
polynomial& polynomial::operator= (const polynomial& p)
{
    if( this != &p ) // i.e. ... if NOT the same ...
    {
        coefficients = p.coefficients;
    }
    return *this;
}
// first define += ...
polynomial& polynomial::operator+= (const polynomial& p)
{
    int a = degree();
    int b = p.degree();
    int i;
    if( a >= b )
    {
        for( i=0; i<=b; ++i )
            coefficients[i] = coefficients[i]+ p[i];
    }
    else
    {
        coefficients.resize(b+1);
        for( i=0; i<=a; ++i )
            coefficients[i] = coefficients[i] + p[i];
        for( ; i<=b; ++i )
            coefficients[i] = p[i];
    }
    return *this;
}
// then can easily do ...
polynomial polynomial::operator+ (const polynomial& p) const
{
    polynomial tmp( *this );
    return tmp += p;
}

// first define ...
// unary operator ... returns  -values to all coeff's
polynomial polynomial::operator- () const
{
    polynomial tmp( *this );
    for( int i = coefficients.size()-1; i >= 0; --i )
        tmp[i] = - coefficients[i];
    return tmp;;
}
// then can easily do  ...
polynomial polynomial::operator- (const polynomial& p) const
{
    polynomial tmp( *this );
    tmp = -p + tmp;
    tmp.trim();
    return tmp;
}
// and ...
polynomial& polynomial::operator-= (const polynomial& p)
{
    *this += -p;
    this->trim();
    return *this;
}

polynomial polynomial::operator* (const polynomial& p) const
{
    int a = degree();
    int b = p.degree();
    polynomial tmp(a+b);

    for( int i=0; i<=a; ++i )
        for( int j=0; j<=b; ++j )
            tmp.coefficients[i+j] += coefficients[i] * p[j];
    tmp.trim();
    return tmp;
}


polynomial polynomial::dif() const
{
    int a = degree();
    if( a == 0 ) return polynomial(); // zero polynomial
    polynomial tmp(a-1);
    for( int i = a-1; i >=0; --i )
        tmp[i] = (i+1)* coefficients[i+1];
    return tmp;
}

polynomial polynomial::antidif() const
{
    int a = degree();
    polynomial tmp(a+1);
    for( int i = a+1; i > 0; --i )
        tmp[i] = coefficients[i-1]/double(i);
    return tmp;
}


bool polynomial::operator== (const polynomial& p) const
{
    int a = degree();
    if( a != p.degree() ) return false;

    for( int i=0; i<=a; ++i )
        if( coefficients[i] !=  p[i] ) return false;

    return true;
}

my_type polynomial::operator() (my_type x) const
{
    my_type sum = 0;
    for( int i = degree(); i >= 0; --i)
        sum += coefficients[i]*pow( x, i );
    return sum;
}

#endif
« Last Edit: June 03, 2013, 04:35:36 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: class polynomial
« Reply #1 on: March 27, 2011, 02:42:31 AM »
And now the test file for the above class polynomial ...

Code: [Select]
// polynomial.h_test.cpp // 2011-03-27 //


#include "polynomial.h"
// includes <iostream>, <fstream>, <sstream>, <string>, <vector>, <cmath>
//          using namespace std;

// for keyboard entry of valid typename T ...
template< typename T >
T takeIn( const string& prompt )
{
    //using std::cout; // included above ... in global namespace by polynomial.h
    //using std::flush;
    using std::cin;
    for( ;; )
    {
        cout << prompt << flush;
        T tmp;
        if( cin >> tmp )
        {
            cin.sync();
            return tmp;
        }
        // else
        cin.clear();
        cin.sync();
        cout << "Entry ERROR!  Try again ...\n";
    }
}


 //////////////////
// used in main ...

const string MENU =
"What would you like to do?\n"
    "\t(G)ive a value to a polynomial (and print it)\n"
    "\t(S)how the two polynomials\n"
    "\t(T)est equality of the two polynomials\n"
    "\t(A)dd or s(U)btract or (M)ultiply the two polynomials\n"
    "\t(D)ifferentiate or (I)ntegrate the two polynomials\n"
    "\t(E)valuate the two polynomials at a given value of x\n"
    "\t(F)ind value of the derivative of polynomials at given x\n"
    "\tfi(N}d value of the iNtegral of polynomials from 0 to given x\n"
    "\t(V)iew result of default copy constructor for polynomials\n"
    "\t(Q)uit\n"
    "Your choice: ";

void showMenuDoTests()
{
    //using std::cout; // included above ...
    //using std::flush;
    using std::cin;
    cout << "***Welcome to our polynomial test program***\n\n";
   
   // We will have two polynomials ... both are initialized to 0.
    polynomial poly1, poly2;

    char ch;
    do
    {
    cout << MENU << flush;
    cin >> ch;
    cin.sync();

    if(ch == 'g' || ch == 'G')
        {
       int n = takeIn< int >( "Give a value to which polynomial (1 or 2)? " );
       if(n == 1)
           {
           cout << "You picked 1 ... <Press 'Enter' to exit>\n";
           cin >> poly1;
       }
       else
           {
           cout << "You picked 2 ... <Press 'Enter' to exit>\n";
           cin >> poly2;
       }

           cout << "Polynomial number ";
           if(n == 1)
           {
                cout << "1 now equals\n";
                cout << poly1;
           }
           else
           {
                cout << "2 now equals\n";
                cout << poly2;
           }
           cout << endl;
    }
    else if(ch == 'a' || ch == 'A')
        {
        cout << poly1 << "\n + \n" << poly2 << "\nis\n";
        cout << poly1 + poly2 << endl;
    }
    else if(ch == 'u' || ch == 'U')
        {
        cout << poly1 << "\n - \n" << poly2 << "\nis\n";
        cout << poly1 - poly2 << endl;
    }
    else if(ch == 'm' || ch == 'M')
        {
        cout << poly1 << "\n * \n" << poly2 << "\nis\n";
        cout << poly1 * poly2 << endl;
    }

    else if(ch == 's' || ch == 'S')
        {
        cout << "The two polynomials are ...\n"
                 << poly1 << "\n and \n" << poly2 << endl;
    }
    else if(ch == 't' || ch == 'T')
        {
        cout << "The two polynomials are ";
        if( poly1 == poly2 )
            {
      cout << "equal";
        }
        else
            {
      cout << "not equal";
        }
        cout << ".\n";
    }
    else if(ch == 'e' || ch == 'E')
        {
        my_type x = takeIn<my_type>
            ("Evaluate the polynomials for which value of x? ");
        cout << "p1 = " << poly1 << endl;
        cout << "p1(" << x << ") = " << poly1(x) << endl;
        cout << "p2 = " << poly2 << endl;
        cout << "p2(" << x << ") = " << poly2(x) << endl;
    }
    else if(ch == 'd' || ch == 'D')
        {
        cout << poly1 << " ... Dif. is: \n" << poly1.dif() <<endl
                 << poly2 << " ... Dif. is: \n" << poly2.dif() << endl;
        }
    else if(ch == 'f' || ch == 'F')
        {
        my_type x = takeIn<my_type>
            ("The value of first derivative of polynomials at this x ... ");

        cout << "d(p1) = " << poly1.dif() << endl;
        cout << "d(p1)(" << x << ") = " << poly1.dif()(x) << endl;
        cout << "d(p2) = " << poly2.dif() << endl;
        cout << "d(p2)(" << x << ") = " << poly2.dif()(x) << endl;
    }
    else if(ch == 'i' || ch == 'I')
        {
        cout << poly1 << " ... Integral is: \n" << poly1.antidif() << endl
                 << poly2 << " ... Integral is: \n" << poly2.antidif() << endl;
        }
    else if(ch == 'n' || ch == 'N')
        {
        my_type x = takeIn<my_type>
            ("The value of first integral of polynomials at this x = ");

        cout << "integral(p1) = " << poly1.antidif() << endl;
        cout << "integral(p1)(0 to " << x << ") = "
                 << poly1.antidif()(x) << endl;
        cout << "integral(p2) = " << poly2.antidif() << endl;
        cout << "integral(p2)(0 to " << x << ") = "
                 << poly2.antidif()(x) << endl;
    }
    else if(ch == 'v' || ch == 'V')
        {
        cout << poly1;
        polynomial p1Copy( poly1 );
        cout << " ... New copy is: \n" << p1Copy << endl;
        cout << poly2;
        polynomial p2Copy = poly2;
        cout << " ... New copy is: \n" << p2Copy<< endl;
    }
    else if( !( ch == 'q' || ch == 'Q' ))
        {
        cout << "\nError: unknown option. Please try again.\n";
    }

    cout << endl;;

    }while( !( ch == 'q' || ch == 'Q' ));
}

int main()
{
    showMenuDoTests();
}
« Last Edit: March 28, 2011, 02:35:13 AM by David »