-5

I have a Polynomial and Rational class which manipulates polynomial and rational functions as vectors. I've defined non-member operators for *, /, +, and -, but I don't think I'm getting how to use them correctly (see code below):

#include<iostream>
#include<algorithm>
#include<iterator>
#include<functional>
#include<vector>
#include<cmath>

using namespace std;

class Polynomial
{
public:
    Polynomial();
    Polynomial(vector<int>coeffs);
    friend class Rational;
     Accessors
    int Degree() const;
    int Coefficient(int k) const;
    void print() const;
    int get_size() const;
    vector<int> get_vect() const; // THIS RETURNS coefficient.
    void set_vect(vector<int> input); // THIS SETS coefficient TO AN INPUTTED VECTOR OF INTEGERS.
    void constantMultiply(int x);
    void Transform();
    double evaluateAt(double x);

    Polynomial& operator++();
    Polynomial operator++ (int unused);
    Polynomial& operator--();
    Polynomial operator-- (int unused);
    Polynomial& operator+=(Polynomial name1);
    Polynomial& operator-=(Polynomial name2);
    Polynomial& operator*=(Polynomial name3);

private:
    vector<int> coefficient;
};

 poly1 + poly2
Polynomial Add(const Polynomial & poly1, const Polynomial & poly2);
 poly1 - poly2
Polynomial Subtract(const Polynomial & poly1, const Polynomial & poly2);
 poly1 * poly2
Polynomial Multiply(const Polynomial & poly1, const Polynomial & poly2);

int zero_detect( vector<int> a , int j);
vector<int> flip( vector<int> input );

class Rational
{
public:
    Rational();
    Rational(Polynomial p);
    Rational(Polynomial pN, Polynomial pD);
    double evaluateAt(double x);
    void print();
    Rational& operator++();
    Rational operator++(int unused);
    Rational& operator--();
    Rational operator--(int unused);
    Rational& operator+=(Rational name1);
    Rational& operator-=(Rational name1);
    Rational& operator*=(Rational name1);
    Rational& operator/=(Rational name1);
    Polynomial get_poly_top(); // SOME SIMPLE ACCESSORS.
    Polynomial get_poly_bot();
private:
    Polynomial top;
    Polynomial bot;
};

Polynomial operator+ (Polynomial a , Polynomial b);
Polynomial operator- (Polynomial a , Polynomial b);
Polynomial operator* (Polynomial a , Polynomial b);

Rational operator+ (Rational a , Rational b);
Rational operator- (Rational a , Rational b);
Rational operator* (Rational a , Rational b);
Rational operator/ (Rational a , Rational b);

bool operator== (Polynomial a , Polynomial b);
bool operator!= (Polynomial a , Polynomial b);
bool operator< (Polynomial a , Polynomial b);
bool operator> (Polynomial a , Polynomial b);
Polynomial sign_swap(Polynomial input); // THIS NEGATES HE COEFFICIENT CELLS, AND HELPS WITH DEFINING SUBTRACTION OFF OF ADDITION.

int main(void)
{
    cout << "Welcome! Please input the coefficients of the first polynomial, p." << endl;
    cout << "When you are finished, enter -1234." << endl;

    vector<int> user_vect1;
    vector<int> user_vect2;

    int input1;
    do
    {
        cin >> input1;
        if(input1 == -1234)
        {
            continue;
        }
        else
        {
            user_vect1.push_back(input1);
        }
    }while(input1 != -1234); // THIS IS THE USER INPUT GADGET.

    cout << endl << endl;

    cout << "Your first polynomial is ";

    Polynomial user_poly1(user_vect1);
    Polynomial temp_poly1(user_vect1);
    user_poly1.print();

    cout << "." << endl;

    cout << "Its transform is ";

    user_poly1.Transform();
    user_poly1.print();

    cout << "." << endl << endl;

    cout << "Please input the coefficients of the second polynomial, q." << endl;

    int input2;
    do
    {
        cin >> input2;
        if(input2 == -1234)
        {
            continue;
        }
        else
        {
            user_vect2.push_back(input2);
        }
    }while(input2 != -1234);

    cout << endl << endl;

    cout << "Your second polynomial is ";

    Polynomial user_poly2(user_vect2);
    Polynomial temp_poly2(user_vect2); // I WANTED A TEMPORARY POLYNOMIAL BECAUSE user_poly(i) GETS TRANSFORMED LATER.
    user_poly2.print();

    cout << "." << endl;

    cout << "Its transform is ";

    user_poly2.Transform();
    user_poly2.print();

    cout << "." << endl << endl;

    cout << "p(x)+q(x) = ";
    /*FUNCTION CALL*/
    (temp_poly1+temp_poly2).print();
    cout << endl << endl;

    cout << "p(x)-q(x) = ";
    /* FUNCTION CALL */
    (temp_poly1-temp_poly2).print();
    cout << endl << endl;

    cout << "p(x)*q(x) = ";
    /*FUNCTION CALL */
    (temp_poly1*temp_poly2).print();
    cout << endl << endl;

    cout << "p(x)/q(x) = ";
    /*FUNCTION CALL*/
    Rational user_rat1(temp_poly1,temp_poly2);
    user_rat1.print();
    cout << endl << endl;

    cout << "p(x)/q(x) + p(x)*q(x) = ";
    /*FUNCTION CALL*/
    Rational user_rat2(temp_poly1+(temp_poly1)*(temp_poly2*temp_poly2),temp_poly2);
    (user_rat2).print();
    cout << endl << endl;

    cout << "p(x)+1 = ";
    /*FUNCTION CALL*/
    (++temp_poly1).print();
    cout << endl << endl;

    cout << "p(x)+2 = ";
    /*FUNCTION CALL*/
    (++temp_poly1).print();
    cout << endl << endl;
    --(--temp_poly1);

    cout << "(p(x)/q(x))*(1+x^2-3x^4) = ";
    /*FUNCTION CALL*/
    vector<int> temp_insert;
    temp_insert.push_back(1);
    temp_insert.push_back(0);
    temp_insert.push_back(1);
    temp_insert.push_back(0);
    temp_insert.push_back(-3); // HERE I'M PUSHING THE VALUES OF THE DESIRED POLYNOMIAL INTO temp_insert.
    Polynomial temporary(temp_insert);
    Rational temp_rat1(temporary);
    (user_rat1*temp_rat1).print(); // <-- RIGHT HERE IS THE BIGGEST ISSUE I'M HAVING. IT'S NOT .print() I DON'T THINK.
    cout << endl << endl;

    cout << "Does p(x) equal q(x)? ";
    /*FUNCTION CALL*/ //<--- Should be a function that is a void, but outputs "Yes." or "No."
    if( temp_poly1 == temp_poly2 )
    {
        cout << "Yes.";
    }
    else
    {
        cout << "No.";
    }
    cout << endl << endl;

    cout << "Is p(x) < q(x)? ";
    /*FUNCTION CALL*/ //<--- Should be a function that is a void, but outputs "Yes." or "No."
    if( temp_poly1 < temp_poly2 )
    {
        cout << "Yes.";
    }
    else
    {
        cout << "No.";
    }
    cout << endl << endl;

    cout << "p(2) = ";
    /*FUNCTION CALL*/
    temp_poly1.evaluateAt(2);
    cout << endl << endl;

    cout << "p(3)/q(3)= ";
    /*FUNCTION CALL*/
    double fun1 = temp_poly1.evaluateAt(3);
    double fun2 = temp_poly2.evaluateAt(3);
    cout << fun1/fun2;
    cout << endl << endl;
};

Polynomial::Polynomial()
{
    coefficient.push_back(0);
}

Polynomial::Polynomial(vector<int> coeffs)
{
    coefficient = coeffs;
}

int Polynomial::Degree() const
{
    int deg = 0;
    for (size_t i = 0; i < coefficient.size(); ++i)
    {
        if (coefficient[i] != 0)
        {
            deg = i;
        }
    }
    return deg;
}

int Polynomial::Coefficient(int k) const
{
    return coefficient[k + 1];
}

void Polynomial::print() const
{
    for( size_t i = 0 ; i < coefficient.size() ; ++i )
    {
        if( coefficient[i] == 0 )
        {
            continue;
        }
        else
        {
            if( i == 0 )
            {
                cout << coefficient[i];
            }
            else
            {
                if(zero_detect(coefficient, i) == i)
                {
                    if( coefficient[i] == 1 || coefficient[i] == -1 )
                    {
                        if( coefficient[i] == 1)
                        {
                            cout << "";
                        }
                        else
                        {
                            cout << "-";
                        }
                    }
                    else
                    {
                        cout << coefficient[i];
                    }
                    if( i == 1 )
                    {
                        cout << "x";
                    }
                    else
                    {
                        cout << "x^" << i;
                    }
                }
                else
                {
                    cout << "+";
                    if( coefficient[i] == 1 || coefficient[i] == -1 )
                    {
                        if( coefficient[i] == 1)
                        {
                            cout << "";
                        }
                        else
                        {
                            cout << "-";
                        }
                    }
                    else
                    {
                        cout << coefficient[i];
                    }
                    if( i == 1 )
                    {
                        cout << "x";
                    }
                    else
                    {
                        cout << "x^" << i;
                    }
                }
            }
        }   
    }
}

int Polynomial::get_size() const
{
    return coefficient.size();
}

vector<int> Polynomial::get_vect() const
{
    return coefficient;
}

void Polynomial::constantMultiply(int x)
{
    for( size_t i = 0 ; i < coefficient.size() ; ++i )
    {
        coefficient[i] *= x;
    }
}

void Polynomial::Transform()
{
    vector<int> transform;
    for( size_t i = 1 ; i < coefficient.size() ; ++i )
    {
        transform.push_back(coefficient[i]*i);
    }
    coefficient = transform;
}

double Polynomial::evaluateAt(double x)
{
    double product=0;
    for(size_t i = 0 ; i < coefficient.size() ; ++i )
    {
        product += (double)coefficient[i]*pow(x,(double)i);
    }
    return product;
}

Polynomial Add(const Polynomial& poly1, const Polynomial& poly2)
{
    vector<int> Poly1 = poly1.get_vect();
    vector<int> Poly2 = poly2.get_vect();
    vector<int> Poly3;

    if( Poly1.size() < Poly2.size() )
    {
        for(size_t i = Poly1.size() ; i< Poly2.size() ; ++i )
        {
            Poly1.push_back(0);
        }
    }
    else if( Poly1.size() > Poly2.size() )
    {
        for(size_t i = Poly2.size() ; i< Poly1.size() ; ++i )
        {
            Poly2.push_back(0);
        }
    }
    for( size_t i = 0 ; i < max(Poly1.size(),Poly2.size()) ; ++i )
    {
        Poly3.push_back(Poly1[i]+Poly2[i]);
    }
    return Poly3;
}

Polynomial Subtract(const Polynomial & poly1, const Polynomial & poly2)
{
    vector<int> Poly1 = poly1.get_vect();
    vector<int> Poly2 = poly2.get_vect();
    vector<int> Poly3;

    if( Poly1.size() < Poly2.size() )
    {
        for(size_t i = Poly1.size() ; i< Poly2.size() ; ++i )
        {
            Poly1.push_back(0);
        }
    }
    else if( Poly1.size() > Poly2.size() )
    {
        for(size_t i = Poly2.size() ; i< Poly1.size() ; ++i )
        {
            Poly2.push_back(0);
        }
    }
    for( size_t i = 0 ; i < max(Poly1.size(),Poly2.size()) ; ++i )
    {
        Poly3.push_back(Poly1[i]-Poly2[i]);
    }
    return Poly3;
}

Polynomial Multiply(const Polynomial & poly1, const Polynomial & poly2)
{
    if( poly2.get_size()==1 && poly2.Coefficient(0)==1)
    {
        return poly1;
    }
    else
    {
        vector<int> Poly1 = poly1.get_vect();
        vector<int> Poly2 = poly2.get_vect();
        vector<int> Poly3;

        Poly3.resize(Poly1.size() + Poly2.size() - 1, 0);

        for (size_t i = 0; i != Poly1.size(); i++)
            for (size_t j = 0; j != Poly2.size(); j++)
                Poly3[i+j] += Poly1[i] * Poly2[j];

        return Poly3;
    }
}

int zero_detect( vector<int> a , int j)
{
    int count=0;
    for( size_t i = 0 ; i < j ; ++i )
    {
        if( a[i] == 0 )
        {
            ++count;
        }
    }
    return count;
}

Rational::Rational()
{
    vector<int> temp;
    temp.push_back(0);
    top.set_vect(temp);
    ++bot;
}

Rational::Rational(Polynomial p)
{
    top = p;
    ++bot;
}

Rational::Rational(Polynomial pN, Polynomial pD)
{
    top = pN;
    bot = pD;
}

double Rational::evaluateAt(double x)
{
    return top.evaluateAt(x)/bot.evaluateAt(x);
}

void Rational::print()
{
    top.print();
    cout << " / ";
    bot.print();
}

Polynomial operator+ (Polynomial a , Polynomial b)
{
    return Add(a,b);
}
Polynomial operator- (Polynomial a , Polynomial b)
{
    return Subtract(a,b);
}
Polynomial operator* (Polynomial a , Polynomial b)
{
    return Multiply(a,b);
}

Rational operator+ (Rational a , Rational b)
{
    Rational c((a.get_poly_top()*b.get_poly_bot())+(b.get_poly_top()*a.get_poly_bot()), a.get_poly_bot()*b.get_poly_bot());
    return c;
}
Rational operator- (Rational a , Rational b)
{
    Rational c((a.get_poly_top()*b.get_poly_bot())+(sign_swap(b.get_poly_top()*a.get_poly_bot())), a.get_poly_bot()*b.get_poly_bot());
    return c;
}
Rational operator* (Rational a , Rational b)
{
    Rational c(a.get_poly_top()*b.get_poly_top(), a.get_poly_bot()*b.get_poly_bot());
    return c;
}
Rational operator/ (Rational a , Rational b)
{
    Rational c(a.get_poly_top()*b.get_poly_bot(), a.get_poly_bot()*b.get_poly_top());
    return c;
}

Rational& Rational::operator++()
{
    Rational c(bot, bot);
    return *this+c;
}

Rational Rational::operator++(int unused)
{
    Rational copy(*this);
    Rational c(bot, bot);
    *this = *this+c;
    return copy;
}
Rational& Rational::operator--()
{
    Rational c(bot, bot);
    return *this-c;
}

Rational Rational::operator--(int unused)
{
    Rational copy(*this);
    Rational c(bot, bot);
    *this = *this-c;
    return copy;
}

bool operator== (Polynomial a , Polynomial b)
{
    vector<int>temp1=a.get_vect();
    vector<int>temp2=b.get_vect();
    if( a.Degree() != b.Degree() )
    {
        return false;
    }
    else
    {
        for(size_t i = 0 ; i<a.get_size() ; ++i)
        {
            if( temp1[i]!= temp2[i])
            {
                return false;
            }
        }
        return true;
    }
}
bool operator!= (Polynomial a , Polynomial b)
{
    return !(a==b);
}
bool operator< (Polynomial a , Polynomial b)
{
    if(a.Degree() < b.Degree())
    {
        return true;
    }
    else
    {
        return false;
    }
}
bool operator> (Polynomial a , Polynomial b)
{
    if(a.Degree() > b.Degree())
    {
        return true;
    }
    else
    {
        return false;
    }
}

Polynomial Rational::get_poly_top()
{
    return top;
}

Polynomial Rational::get_poly_bot()
{
    return bot;
}

Polynomial sign_swap(Polynomial input)
{
    vector<int> temp = input.get_vect();
    for(size_t i = 0 ; i<input.get_size() ; ++i )
    {
        temp[i] *=-1;
    }
    input.set_vect(temp);
    return input;
}

void Polynomial::set_vect(vector<int> input)
{
    coefficient = input;
}

Polynomial& Polynomial::operator++()
{
    coefficient[0]++;
    return *this;
}
Polynomial Polynomial::operator++ (int unused) // &
{
    Polynomial copy(*this);
    coefficient[0]++;
    return copy;
}
Polynomial& Polynomial::operator--()
{
    coefficient[0]--;
    return *this;
}
Polynomial Polynomial::operator-- (int unused) // &
{
    Polynomial copy(*this);
    coefficient[0]--;
    return copy;
}
Polynomial& Polynomial::operator+=(Polynomial name1)
{
    return Add(*this, name1);
}
Polynomial& Polynomial::operator-=(Polynomial name2)
{
    return Subtract(*this, name2);
}
Polynomial& Polynomial::operator*=(Polynomial name3)
{
    return Multiply(*this, name3);  
}

I get an error that says I've got an out-of-range issue with some vector process in the code.


Note:

If you are taking a programming class, and this happens to be your assignment, then please do not copy and paste this code into your source and use it for your own benefit. Instead, use it as a foundation to build off of if you're having trouble.


Any help with resolving this rational multiplication issue, or anything else that seems inefficient, redundant, useless, etc. would be much appreciated. Thank you. :-)


The Problem:

I've created a Rational class that is friend to a Polynomial class, and the one-argument constructor Rational( Polynomial p) sets its top polynomial top to p, which is of data type Polynomial, and sets its bottom polynomial bot to 1, which is of the same data type as top. I've created a Rational object in main using this one-argument constructor passing in a vector I generated manually in main, but when I try to print the product of two rational objects--the first one, user_rat1, being a two-argument type construction with top=p and bot=1 (1 the polynomial)--I get an error saying the bounds of the vector are out of range. I don't see why...

Loie Benedicte
  • 149
  • 1
  • 10
  • That is a lot of code... – Borgleader Aug 14 '13 at 23:27
  • So what about the title? –  Aug 14 '13 at 23:28
  • If you have any questions, please ask. If you'd like a copy of the document with the instructions on how this whole thing is supposed to fit together, then ask, and I can send you a copy. – Loie Benedicte Aug 14 '13 at 23:28
  • If you're looking for a code review, then please use http://codereview.stackexchange.com. If you're looking for help with a bug, then could you please clarify exactly what the issue is, what debugging you've done so far, and then reduce this to a [minimal test-case](http://sscce.org)? – Oliver Charlesworth Aug 14 '13 at 23:30
  • 1
    Your note is irrelevant. Content on SO uses a Creative Commons Wiki License. In any case, someone copying that for their assignment would be screwed in one way or another anyway. – chris Aug 14 '13 at 23:36
  • In the code lies the clarification, but for your convenience I'll state it here: Rational object multiplication fails. I don't know why, yet. – Loie Benedicte Aug 14 '13 at 23:38
  • Perhaps with a bit of creativity, the note can be seen as not irrelevant. – Loie Benedicte Aug 14 '13 at 23:39
  • `(user_rat1*temp_rat1).print(); // <-- RIGHT HERE IS THE BIGGEST ISSUE I'M HAVING. IT'S NOT .print() I DON'T THINK.` – Loie Benedicte Aug 14 '13 at 23:41
  • If I'm being to vague/broad let me know. I can spell it out for you. – Loie Benedicte Aug 14 '13 at 23:41
  • non-constructive comment, eternal disrespect – Loie Benedicte Aug 14 '13 at 23:43
  • 1
    @LoieBenedicte: The problem is that you've pasted hundreds of lines of code, a vague description of the problem, and no apparent attempt at debugging thus far. Please see http://sscce.org. – Oliver Charlesworth Aug 14 '13 at 23:43

2 Answers2

1

Made sure that you understand the coefficients array/vector's index mean the exponent.

I can suggest for you to use another int data type that hold your degree (for any poly). (in addition you can add another int data type that hold the currentDegree = the highest degree in the poly that != 0).

For example, if you want to create new Polynomial with highest degree = 4.

Polynomial::Polynomial(int degree){
    this->degree = degree;
    if(degree == 0)
        this->coeffs = new double();
    else if (degree > 1)
        this->coeffs = new double[degree+1];
    else if (degree == 1)
        this->coeffs = new double();
    for(int i=0;i<=degree;i++)
        this->coeffs[i] = 0;
    actualDegree = 0;
}

in addition, you can add another constructor when you get array for example:

Polynomial::Polynomial(double* coeffs, int degree){
    this->degree = degree;
    this->actualDegree = 0;
    this->coeffs = new double[degree+1];
    for(int i=0;i<=degree;i++){
        this->coeffs[i] = coeffs[i];
        if (coeffs[i] != 0 && i > actualDegree)
            actualDegree = i;
    }
}

That will help you in functions when you use any object from Polynomial to know your degree for any object you working with. If you want you can even made the constructor as template for int\double (but dont forget to set it in class to the pointer)

0

Source:

Polynomial Multiply(const Polynomial & poly1, const Polynomial & poly2)
{
    if( poly2.get_size()==1 && poly2.Coefficient(0)==1)

The problemic method:

int Polynomial::Coefficient(int k) const
{
    return coefficient[k + 1];
}

If the size is 1 then you can only reach the coefficient[0] and k + 1 here is 1. You may meant:

int Polynomial::Coefficient(int k) const
{
    return coefficient[k];
}
KugBuBu
  • 630
  • 5
  • 21