I am working on a class called polynomial, and one of the things I need to do in the class is find the derivative of polynomials. I use an array of doubles to represent the polynomials, such that the index corresponds to the power of 'x' and the data at that index corresponds to the coefficient. For example;
a0(x^0)+a1(x^1)+a2(x^2)...+an-1(x^n-1)+an(x^n)
is represented in an array of doubles as:
double fx[n];
fx[0] = a0
fx[1] = a1
...
fx[n] = an
To implement a derivative I am using the power rule, basically multiplying the index by the coefficient and store that in another array with the index decremented by one.
f'(x^3+3x^2+6x+2) = 3x^2+6x+6. <- another polynomial
Here is my code thus far. The relevant members are data* fx which holds the coefficients of the polynomial, and the polynomial* deriv which is supposed to point to that polynomials derivative. I am implementing a derivative chain down to x^1 in a recursive way, using the private constructor polynomial(const polynomial&, unsigned);
header file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
#ifndef _POLY_H_
#define _POLY_H_
#include <iostream>
#include <iomanip>
using namespace std;
const unsigned timeout = 200;
const unsigned displayPrecision = 3;
class polynomial
{
double* fx;
unsigned polyDegree;
double* critPnts;
unsigned numCritPnts;
double* realRoots;
unsigned numRealRoots;
polynomial* deriv;
polynomial(const polynomial&, unsigned);
public:
polynomial(const double*, unsigned);
polynomial(const polynomial&);
~polynomial();
void solve(unsigned precision = 0.001);
polynomial retrieveF(unsigned);
void write();
friend ostream& operator<< (ostream& os, const polynomial& p);
};
#endif
|
implementation file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
#include "polynomial.h"
polynomial::polynomial(const double* func, unsigned l)
:polyDegree(l),critPnts(NULL), numCritPnts(0), realRoots(NULL), numRealRoots(0), deriv(NULL)
{
fx = new double[l];
for(int i = 0; i <= l; i++)
{
fx[i] = func[i];
}
}
polynomial::polynomial(const polynomial& f, unsigned l)
:polyDegree(l),critPnts(NULL), numCritPnts(0), realRoots(NULL), numRealRoots(0), deriv(NULL)
{
fx = new double[l];
for(int i = 1; i <= l; i++)
{
fx[i-1] = f.fx[i] * i;
}
cout << *this << endl;
}
polynomial::polynomial(const polynomial& f)
{
fx = new double(f.polyDegree);
critPnts = new double(f.numCritPnts);
realRoots = new double(f.numRealRoots);
polyDegree = f.polyDegree;
numCritPnts = f.numCritPnts;
numRealRoots = f.numRealRoots;
for(int i = 0; i <= polyDegree; i++)
{
fx[i] = f.fx[i];
}
for(int i = 0; i <= numCritPnts; i++)
{
fx[i] = f.fx[i];
}
for(int i = 0; i <= numRealRoots ; i++)
{
fx[i] = f.fx[i];
}
}
polynomial::~polynomial()
{
polynomial* temp = this;
do
{
delete[] temp->fx;
delete[] temp->critPnts;
delete[] temp->realRoots;
temp = temp->deriv;
} while (temp != NULL);
}
void polynomial::solve(unsigned precision)
{
if (polyDegree == 0)
{
return;
}
if (polyDegree > 1)
{
deriv = new polynomial(*this, polyDegree-1);
deriv->solve();
}
}
polynomial polynomial::retrieveF(unsigned)
{
}
void polynomial::write()
{
}
ostream& operator<< (ostream& os, const polynomial& p)
{
if(p.polyDegree >= 2)
{
os << fixed << setprecision(displayPrecision) << p.fx[p.polyDegree] << "x^" << p.polyDegree << " ";
}
for (int i = p.polyDegree-1; i >= 2; i--)
{
if (p.fx[i] > 0)
{
os << "+ " << fixed << setprecision(displayPrecision) << p.fx[i] << "x^" << i << " ";
}
else
{
os << "- " << fixed << setprecision(displayPrecision) << p.fx[i]* -1 << "x^" << i << " ";
}
}
if (p.fx[1] > 0)
{
os << "+ " << fixed << setprecision(displayPrecision) << p.fx[1] << "x ";
}
else
{
os << "- " << fixed << setprecision(displayPrecision) << p.fx[1]* -1 << "x ";
}
if (p.fx[0] > 0)
{
os << "+ " << fixed << setprecision(displayPrecision) << p.fx[0];
}
else
{
os << "- " << fixed << setprecision(displayPrecision) << p.fx[1]* -1;
}
}
|
main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
#include <iostream>
#include "polynomial.h"
int main()
{
double test[5] = {1.0,-2.0,3.0,-4.0,5.0};
polynomial p(test, 4);
cout << p << endl;
p.solve();
cin.get();
return 0;
}
|
The ouput I get to the screen looks like this:
5.000x^4 - 4.00x^3 + 3.000x^2 - 2.000x + 1.000
0.000x^3 - 12.000x^2 + 6.000x - -6.000
0.000x^2 - 24.000x + 6
+0.000x - -0.000
|
If I removed the fixed flag the elements that are showing up as zeros show up as rather odd numbers instead, something like 2.714e-308 or something similar. This is really odd and I don't know exactly why.
I am getting a warning about using this instruction
deriv->solve()
. I have a default unsigned parameter that is intended to be used to set the precision of another feature I haven't implemented. I am getting the warning:
[warning]converting to 'unsigned int' from 'double' |
.
I don't really know what that means or if that is somehow effecting my code. If someone could help me implement the same concept in a better way I would appreciate it, as I suspect it is the cause of my problem somehow.
Thank you for any help. I am really stuck and could use a point in the right direction.