Polyval and polyder C++ equivalencies

I have only been using C++ for several weeks and I am trying to write a program that will use the polyval (evaluate a polynomial at a given value) and polyder (differentiate a polynomial) functions so that they behave just like they do in Matlab. Both my polyval and polyder functions are returning the number zero and I can not figure out where my error is. Any suggestions are appreciated, thank you.


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
#include <iostream>
#include <cmath>
using namespace std;

float polyval(float*, int, float);
void polyder(float*, int, float*);

int main(void) {
    
    int n;
    float x, dp;
    
    cout << "Enter polynomial order: ";
    cin >> n;
    float* p = new float[n+1];
    
    cout << "Enter coefficients, starting with the highest power: ";
    for (int i=0; i<n+1; i++) cin >> p[i];

    cout << "Enter x = ";
    cin >> x;
    
    cout << "Value = " << polyval(p, n, x) << endl;
    
    cout << "Derivative = " << dp << endl;
    
    return 0;
}


float polyval(float* p, int n, float x) {
    float px=0;
    
    for (int i=n; i<0; i--) {
        int e=i;
        
        for (int i=0; i<n+1; i++)
            px = px + p[i]*pow(x,e);
        
    }
    return px;
}


void polyder(float* p, int n, float* dp) {
    dp={0};
    for(int i=0; i<n; i++) {
        dp[i] = p[i+1] * (i+1);
    }
    
}
Line 34: the end condition.

Line 46: dp is a pointer, so you make it a null pointer?
For line 34, I changed the "i < 0" to "i > 0" and I am now getting a nonzero number but still not the correct answer.

For line 46, what do you mean by dp is a pointer? I want dp to be the derivative of the polynomial p, so dp should be an array. Am I telling C++ the correct way to differentiate a polynomial?

Thank you for your help.
The polyval has a nested loop. Both loops introduce 'i'. I'm not sure whether the inner masks the outer or not.

Lets assume it does. Lets assume that n=2. Now we can unroll the loops to make it easier to see what happens:
px = p[0]*pow(x,2) + p[1]*pow(x,2) + p[2]*pow(x,2) + p[0]*pow(x,1) + p[1]*pow(x,1) + p[2]*pow(x,1);
Is that what it should be?


You don't call polyder. That part of your main is essentially:
1
2
3
4
5
6
int main()
{
  float dp; // uninitialized, undefined value
  cout << "Derivative = " << dp << endl;
  return 0;
}

Note: int main(void) is non-standard signature for main; use int main().


Line 45 says clearly float * dp and therefore 'dp' in the function is a pointer. Pointer holds an address. Parameter's value is set by the caller. Your function can change the address hold by pointer, but then it does not point to the same memory location as the caller gave and the caller cannot possibly know what you will do in that other memory location.


Note: you do allocate a memory block dynamically on line 15, but you don't deallocate it at the end of the program. You could use a smart pointer (std::unique_ptr) instead of plain pointer. Smart pointer deallocates the memory it points to when it exits the scope.

However, a better solution is to use std::vector and pass the vector to functions by reference. Vector has size attribute and therefore you won't have to pass 'n' separately to the functions.
No that doesn't make sense at all. So I tried doing this:
1
2
3
4
5
6
7
8
void polyder(float* p, int n, float* dp) 
{
    dp={0};
    for(int i=0; i=n; i++) 
   
        dp += (n - i) * pow(p[i], ((n - i) - 1));
    
}

But I am getting an error saying Invalid operands to binary expressing ('float *' and 'double').

Since the function can only return one number and dp needs to be an array of length n, I want it to change the values of the float* dp in the input of the function.
Last edited on
I have figured out the polyval function but I am still unsure how to code the polyder function.
You have:
1
2
3
4
5
6
    int n;
    cout << "Enter polynomial order: ";
    cin >> n;
    float* p = new float[n+1];
    cout << "Enter coefficients, starting with the highest power: ";
    for (int i=0; i<n+1; i++) cin >> p[i];

With vector and input check:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
size_t order;
cout << "Enter polynomial order: ";
cin >> order;
std::vector<float> coeffs;
coeffs.reserve( order+1 );
float coef;
size_t i = 0;
cout << "Enter coefficients, starting with the highest power: ";
while ( i <= order && cin >> coef )
{
  coeffs.push_back( coef );
  ++i;
}
if ( coeffs.size() < order + 1 )
{
  cout << "Input error; not enough coefficients.\n";
}


The polyval could now be:
float polyval( const std::vector<float> & array, float x );

Your original polyder appears to compute the coefficients for a lesser order polynomial. Therefore:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
std::vector<float> polyder( const std::vector<float> & array )
{
  if ( 1 < array.size() )
  {
    std::vector<float> result( array.begin(), array.begin() + array.size() - 1 ); // range constructor
    const size_t order = result.size();
    for ( size_t i = 0; i < order; ++i )
    {
      result[ i ] *= order - i;
    }
    return result;
  }
  else
  {
    return std::vector<float>; // empty vector
  }
}


That you can call from main:
1
2
3
cout << "Func value: " << polyval( coeffs, x ) << '\n';
std::vector<float> diffs = polyder( coeffs );
cout << "Diff value: " << polyval( diffs, x ) << '\n';

Topic archived. No new replies allowed.