Constructing plotting routine for a polynomial?

Given this 4th order polynomial, x^4 - 3x^3 -15x^2 +10x +30, use lab 17 to construct a plotting routine from x = -3.5 to x = +5.5.
increment 0.1, by replacing the return value of the function with a0 * pow(x,4) + a1 * pow(x,3) + a2 * pow(x,2) + a3*x +a4; (drop
the if, no worries about x=0) and define, a0, a1, a2, a3 ,a4 in the function with the values from the latter equation, be careful of
signs. The output to a file ( you name in its filename) needed for plotting in excel to plot this polynomial. Plot both axis with
appropriate values from the imported values.

How would I edit this code (Lab 17) to be able to plot for this new 4th degree polynomial ? I understand I have to define the coefficients of the polynomial, but to I define them at int, or as double on line 10 in parentheses?

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
#include<iostream>		//Required for cin, cout
#include<cmath>			
#include<fstream>		// to build data file to be used by Excel to plot
#include <string>		// for using filename and
using namespace std;
double ROBBINS (double x);	//Function Prototype
int
main ()
{
  double a, b, x_incr, new_x;	// Declare objects in main()
  int Number, loop;
  string filename;
  ofstream fout;		// declare object for sending data to the output file
  cout <<
    "enter the name of the data file to send data used for plotting, from this program\n";
  cin >> filename;
  fout.open (filename);		// open file for inputing data from this program
  cout << "Enter endpoint range a and b (a<b): of the function to be plotted \n";
  cin >> a >> b;
  cout <<
    "Enter the number of points you want over the range of 'a' to 'b'\n";
  cin >> Number;
  x_incr = (b - a) / Number;	// increment between the points based on number wanted
  loop = int (b - a) / x_incr;	// loop gives the for loop repetitions equal to number points wanted
  cout << loop;			// check that shows loop and Number are the same
  cout.setf (ios::fixed);
  cout.precision (6);		// Set Formats
  cout << "x and ROBBINSX \n";
  for (int k = 0; k <= loop; k++)
    {
      new_x = a + k * x_incr;
      cout << new_x << " " << ROBBINS (new_x) << endl;	//echo vales to screen
      fout << new_x << " " << ROBBINS (new_x) << endl;	// building data file for excel plotting
    }
  return 0;			// Exit program.
  fout.close ();
}				// end main unction used on the next slide 

double ROBBINS (double x)
  if (x == 0)			
    {
      return 1;		
    }			
  else
    {
      return -exp(fabs(x)/10) /fabs(x);
    }
}				// end of function 
Last edited on
As far as I can see, all you have to do is to remove lines 40-45 and 47. Then for L46 replace the return value of the function with a0 * pow(x,4) + a1 * pow(x,3) + a2 * pow(x,2) + a3*x +a4;

Within ROBBINS() define a0 as 1, a1 as -3, a2 as -15, a3 as 10 and a4 as 30.

Easy peasy!

Perhaps:

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
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cmath>

double ROBBINS(double x);

int main() {
	std::string filename;

	std::cout << "Enter the name of the data file to send data used for plotting, from this program: ";
	std::cin >> filename;

	std::ofstream fout(filename);

	if (!fout)
		return (std::cout << "Cannot open file\n"), 1;

	double a {}, b {};
	unsigned Number {};

	std::cout << "Enter endpoint range a and b (a < b) of the function to be plotted: ";
	std::cin >> a >> b;

	std::cout << "Enter the number of points you want over the range of 'a' to 'b': ";
	std::cin >> Number;

	const auto x_incr {(b - a) / Number};		// increment between the points based on number wanted
	const auto loop {unsigned((b - a) / x_incr)};	// loop gives the for loop repetitions equal to number points wanted

	//std::cout << loop;			// check that shows loop and Number are the same

	if (loop != Number)
		std::cout << "Warning! loop does not equal Number!\n";

	std::cout << std::fixed << std::setprecision(6);
	std::cout << "x and ROBBINSX \n";

	for (unsigned k {}; k <= loop; ++k) {
		const auto new_x {a + k * x_incr};

		std::cout << new_x << " " << ROBBINS(new_x) << '\n';
		fout << new_x << " " << ROBBINS(new_x) << '\n';
	}
}

double ROBBINS(double x) {
	const int a0 {1}, a1 {-3}, a2 {-15}, a3 {10}, a4 {30};

	return  a0 * std::pow(x, 4) + a1 * std::pow(x, 3) + a2 * std::pow(x, 2) + a3 * x + a4;
}

Last edited on
Do I replace the "double x" in ROBBINS with a0(1),a1(-3), etc? Because I tried doing that before and got an error stating that a0 was not declared.
See my revised post above with code.
How do you know the increment is 0.1? Is it 0.1 by default? Or does it depend on the values input on the keyboard?
Blueshark1 wrote:
How do you know the increment is 0.1? Is it 0.1 by default? Or does it depend on the values input on the keyboard?


What do you think
x_incr = (b - a) / Number;
does?


BTW, it seems counterintuitive to define your polynomial with a0 multiplying the 4th power and a4 multiplying the 0th power (constant).

And the fact that it is written as a power (exponent) ... doesn't mean you should evaluate polynomials like that.
Last edited on
Why ROBBINS? Anyway, here's a possibility with variable names that make more sense to me at least. Making it a .csv file via the comma isn't mandatory but makes it 'conventionally' easier for the spreadsheet import.

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
#include <iostream>
#include<cmath>
#include<fstream>
#include <string>

using namespace std;

double ROBBINS (double x);

int main ()
{
    string filename;
    cout << "Enter file name: ";
    cin >> filename;
    
   
    ofstream file(filename);
    if( !file.is_open() )
    {
        cout << "File not opened\n";
        exit(1);
    }
    
    
    double X1{-3.5}, X2{3.5}, no_points{0};
    cout << "Enter range: ";
    cin >> X1 >> X2;
    cout << "Enter number of points: ";
    cin >> no_points;
    
    
    double spacing{0.1}, x{0};
    spacing = (X2 - X1) / (no_points);
    
    
    for (int k = 0; k <= no_points; k++)
    {
        x = X1 + k * spacing;
        
        cout << x << ',' << ROBBINS (x) << '\n';
        file << x << ',' << ROBBINS (x) << '\n';
    }
    
    file.close();
    return 0;
}
double ROBBINS (double x)
{
    int a[]{30, 10, -15, -3, 1};
    size_t sz{sizeof(a)/sizeof(int)};
    double sum{0};
    
    for(int i = 0; i < sz; i++)
    {
        sum += a[i] * pow(x,i);
    }
    
    return sum;
}


Enter file name: sample.csv
Enter range: -3.3 3.5
Enter number of points: 20
-3.3,60.0531
-2.96,23.5446
-2.62,1.90817
-2.28,-8.19558
-1.94,-9.78516
-1.6,-5.5584
-1.26,2.1076
-0.92,11.1565
-0.58,19.8525
-0.24,26.7808
0.1,30.8471
0.44,31.2779
0.78,27.6205
1.12,19.7427
1.46,7.83331
1.8,-7.5984
2.14,-25.7223
2.48,-45.3876
2.82,-65.1226
3.16,-83.1353
3.5,-97.3125
Program ended with exit code: 0


https://imgur.com/a/SN1IkPc
Last edited on
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
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

double poly( const vector<double> &c, double x )
{
   double p = 0;
   for ( int i = c.size() - 1; i >= 0; i-- ) p = c[i] + x * p;
   return p;
}

int main()
{
   vector<double> c = { 30, 10, -15, -3, 1 };
   string filename;
   double a, b;
   int n;

   cout << "Enter filename for output: ";   cin >> filename;
   ofstream out( filename );

   cout << "Enter a, b, n (for n outputs in [a,b]): ";   cin >> a >> b >> n;
   double dx = ( b - a ) / ( n - 1 );
   for ( int i = 0; i < n; i++ )
   {
      double x = a + i * dx, y = poly( c, x );
      cout << x << '\t' << y << '\n';
       out << x << '\t' << y << '\n';
   }
}


Enter filename for output: data.dat
Enter a, b, n (for n outputs in [a,b]): -3.5 5.5 19
-3.5    89.9375
-3      27
-2.5    -2.8125
-2      -10
-1.5    -3.5625
-1      9
-0.5    21.6875
0       30
0.5     30.9375
1       23
1.5     6.1875
2       -18
2.5     -46.5625
3       -75
3.5     -97.3125
4       -106
4.5     -92.0625
5       -45
5.5     47.1875



To save importing it into Excel you can plot data.dat with gnuplot:

p "data.dat" w l

or slightly minimalist Python:

1
2
3
4
5
6
7
8
import numpy as np
import matplotlib.pyplot as plt

filename = input( "Enter filename: " )
x, y = np.loadtxt( filename, unpack=True )
fig, ax = plt.subplots()
ax.plot( x, y )
plt.show()


Last edited on
And the fact that it is written as a power (exponent) ... doesn't mean you should evaluate polynomials like that.


Possibly like this - which avoids the overhead of pow() and only calculates the next term based upon the previous:

1
2
3
4
5
6
7
8
9
10
11
ouble ROBBINS(double x) {
	const double a[] {1, -3, -15, 10, 30};
	double val {a[4]}, x1 {1};

	for (unsigned i {4}; i > 0; --i) {
		x1 *= x;
		val += x1 * a[i - 1];
	}

	return val;
}

Last edited on
Registered users can post here. Sign in or register to post.