Giving a slightly wrong input (Finding Increasing/Decreasing Interval of a Polynomial function)

Hello, I am trying to make a code which will input a function from the user and then will give the interval of function in which it is decreasing, as well as the interval in which it is increasing..

Following is the code, I made
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
#include <cmath>
using namespace std;
float *resize(float *, int &);
int increasingfun(float[], int &);
int decreasingfun(float[], int &);

int main()
{
	stringstream f;
	float in, po;
	float *input = NULL;
	float *power = NULL;
	int insize = 0, posize = 0;
	bool increase = false, decrease = false, ch = false;
	int check, c = 0;
	cout << "Enter Variable's Constant: ";
	cin >> in;
	cout << "Enter Variable's Power: ";
	cin >> po;
	while (1)
	{
		input = resize(input, insize);
		input[insize - 1] = in;
		power = resize(power, posize);
		power[posize - 1] = po;
		if (in > 0)
			f << "+";
		f << setprecision(2) << in;
		if (po != 0)
		{
			f << "x";
			if (po != 1)
			{
				f << "^";
				f << po;
			}
		}
		system("cls");
		cout << "Your Current Function: " << f.str() << endl << endl;
		cout << "Enter Variable's Constant: ";
		cin >> in;
		if (in == 0)
			break;
		cout << "Enter Variable's Power: ";
		cin >> po;
	}
	float y[100], arr[10];
	for (int i = 0, j = -50; i < 100; i++, j++)
	{
		y[i] = 0;
		for (int z = 0; z < insize; z++)
		{
			y[i] = y[i] + (input[z] * pow(j, power[z]));
		}
		if ((isnan(y[i])) || (isinf(y[i])))
			y[i] = -500000;
	}
	for (int i = 0; i < 99; i++)
	{
		while (y[i] == -500000)
			i++;
		if (y[i] < y[i + 1])
		{
			if (i == 0)
			{
				increase = true;
				cout << "Increasing Interval: "
					<< "(-infinity, ";
			}
			else
			{
				if (!increase)
				{
					cout << "Increasing Interval: "
						<< "[" << i - 50 << ", ";
				}
				else if (y[i - 1] == -500000)
				{
					for (float a = 0.1; a < 1; a = a + 0.1, c++)
					{
						arr[c] = 0;
						for (int z = 0; z < insize; z++)
						{
							arr[c] = arr[c] + (input[z] * pow(((i - 50)*a), power[z]));
						}
						if (!((isnan(arr[c])) || (isinf(arr[c]))))
						{
							if (c == 0)
								cout << " U (" << i - 50 << ", ";
							else
								cout << " U [" << i - 50 + a << ", ";
							break;
						}
					}
				}
				else
				{
					cout << " U [" << i - 50 << ", ";
				}
			}
			c = 0;
			check = increasingfun(y, i);
			if (check == -1)
				cout << "+infinity)";
			else if (y[i] == -500000)
			{
				for (float a = 0.1; a < 1; a = a + 0.1, c++)
				{
					arr[c] = 0;
					for (int z = 0; z < insize; z++)
					{
						arr[c] = arr[c] + (input[z] * pow(((i - 51)*a), power[z]));
					}
					if ((isnan(arr[c])) || (isinf(arr[c])))
					{
						if (c >= 0 && c <= 8)
							cout << i - 51 << "]";
						else
							cout << i - 50 - a << "] ";
						ch = true;
						break;
					}
				}
				if (ch == false)
					cout << i - 50 << ") ";
			}
			else
				cout << i - 50 << "]";
			increase = true;
		}

	}
	c = 0;
	ch = false;
	for (int i = 0; i < 99; i++)
	{
		while (y[i] == -500000)
			i++;
		if (y[i] > y[i + 1])
		{
			if (i == 0)
			{
				decrease = true;
				cout << "Decreasing Interval: "
					<< "(-infinity, ";
			}
			else
			{
				if (!decrease)
				{
					cout << "Decreasing Interval: "
						<< "[" << i - 50 << ", ";
				}
				else if (y[i - 1] == -500000)
				{
					for (float a = 0.1; a < 1; a = a + 0.1, c++)
					{
						arr[c] = 0;
						for (int z = 0; z < insize; z++)
						{
							arr[c] = arr[c] + (input[z] * pow(((i - 50)*a), power[z]));
						}
						if (!((isnan(arr[c])) || (isinf(arr[c]))))
						{
							if (c == 0)
								cout << " U (" << i - 51 << ", ";
							else
								cout << " U [" << i - 51 + a << ", ";
							break;
						}
					}
				}
				else
				{
					cout << " U [" << i - 50 << ", ";
				}
			}
			c = 0;
			check = decreasingfun(y, i);
			if (check == -1)
				cout << "+infinity)";
			else if (y[i] == -500000)
			{
				for (float a = 0.1; a < 1; a = a + 0.1, c++)
				{
					arr[c] = 0;
					for (int z = 0; z < insize; z++)
					{
						arr[c] = arr[c] + (input[z] * pow(((i - 51)*a), power[z]));
					}
					if ((isnan(arr[c])) || (isinf(arr[c])))
					{
						if (c >= 0 && c <= 8)
							cout << i - 51 << "]";
						else
							cout << i - 50 - a << "] ";
						ch = true;
						break;
					}
				}
				if (ch == false)
					cout << i - 50 << ") ";
			}
			else
				cout << i - 50 << "]";
			decrease = true;
		}

	}
	cout << endl << endl;
	/*for (int i = 48; i < 100; i++)
	{
		cout << y[i] << " ";
	}*/
	cout << endl;
	cout << endl;
	system("pause");
	return 0;
}
float *resize(float *array, int &size)
{
	float *temp;

		temp = new float[size + 1];
	for (int i = 0; i < size; i++)
		temp[i] = array[i];
	size++;
	delete[] array;
	return temp;
}
int increasingfun(float y[], int &i)
{
	for (i; i < 99; i++)
	{
		if (y[i] < y[i + 1])
			continue;
		if (y[i] == -500000)
			return i;
		return i;
	}
	return -1;
}
int decreasingfun(float y[], int &i)
{
	for (i; i < 99; i++)
	{
		if (y[i] > y[i + 1])
			continue;
		if (y[i] == -500000)
			return i;
		return i;
	}
	return -1;
}



This code seems to work perfectly fine for functions which don't involve infinity or undefined values.... I entered some if conditions and with the help of them, I managed to tackle the undefined values as well and now it is giving correct output for functions such as x^0.5.
However, the problem is still occurring for functions which involve infinity values, especially the functions such as x^-2, x^-4, x^-6 and etc.
A correct output of the function x^-2 would be,

1
2
Decreasing Interval: (-infinity, 0)
Increasing Interval: (0, +infinity)


but instead, it is giving me this output,
1
2
Increasing Interval: (-infinity, -1]
Decreasing Interval: [-1, 0)  U [0.1, +infinity)


From what I saw, my code seems to be fine and it shouldn't give this error. As per my code (look from Line 139 to 212), this is what it should calculate for the values of x from -1 to 0
1
2
3
4
For x = -1, y = 1
For x = -0.9, y = 1.234
For x = -0.8, y = 1.56
and so on


The values are clearly increasing and hence, it shouldn't be included in the decreasing interval... But I don't know why :/

Plus, it is also starting the increasing interval from [0.1] where in reality, it should start from (0, +infinity)
Can anyone help identify the problem, please? Thank you!
Last edited on
Well from a purely structural problem, your main() is over 200 lines long.
That in itself puts people off from reading it, and makes it hard for you to analyse in any meaningful way.

The whole thing needs to be split into a number of functions, some of which needs to be split into further sub-functions.

> int increasingfun(float y[], int &i)
You do realise that these modify your loop parameter in main as well right?

> float *resize(float *array, int &size)
Just use a std::vector
There is no need for a roll-your-own expanding array.

What is the maximum practical limit on the number of terms you're going to enter anyway?
10 to 20?
This would suffice for a long time.

const int MAX_TERMS = 50;
float input[MAX_TERMS];
float power[MAX_TERMS];

You should also define some constants for all those 50, 100, 10, -500000 magic numbers you have scattered through the code.

I'm sorry, I didn't really divide it into Functions. I was thinking of doing it later however, haven't done it yet because I need to get the code working first.

Yes, I do realize that increasingfun and decreasingfun will modify the loop parameter... and I want it to modify it.

We haven't studied vectors yet so can't really use them.


Um, alright, I think I can change those with some constants. Okay.
And thank you for the response though! I will get to work as soon as possible...

(Though still haven't figured out a way to solve the original problem of mine :( )
> I was thinking of doing it later however, haven't done it yet because I need to get the code working first.
Cleaning up the structure IS the way to make it work.

The very act of going through the process of figuring out what should be a function can show you where you're going wrong.

This code seems to work perfectly fine for functions which don't involve infinity or undefined values
I doubt. Just executed it and...
Enter Variable's Constant: 5
Enter Variable's Power: 3
Your Current Function: +5x^3

Enter Variable's Constant: 1
Enter Variable's Power: 2
Your Current Function: +5x^3+1x^2

Enter Variable's Constant: 0
Increasing Interval: (-infinity, +infinity)

... the result is too "coarse". Look at it near the two roots (I use a virtual HP40gs graphing calculator, find it in here: https://www.hpcalc.org/torrents/hpemulators.torrent or here: https://krul.finf.uni-hannover.de/~sammyshp/hpcalc.org-mirror/HP_Emulators.7z).

If your program is for polynomial function only I suggest to use the Horner scheme, see https://en.wikipedia.org/wiki/Horner%27s_method
It may be easily modified to derive polynoms, or do polynomial divisions (when you found a root for example).

In addition, if not a graphing calculator a CAS may be of some help, something like Reduce https://reduce-algebra.sourceforge.io/

Edit: to comply with the rules of this list ("no advertisement" in this case) I replaced the link to a graphing calculator with one that is not sold any more.
Last edited on
[edit - tag code as code, not output]
You're actually hurting yourself by avoiding infinite values, especially because you lose the sense of whether it was +infinity or -infinity.

haven't [divided it into functions] yet because I need to get the code working first.
You're going about it backwards. You'll find that it's easier to get the code working if you divide it into functions first. That way you can test one function at a time

Here's a modified version of your code. When it switches direction it remembers the start of the interval. This still suffers from the problem that MikeStgt mentions. And it should be divided into functions. It can probably be further improved.

I assume that you haven't studied calculus yet. With calculus, you can find the intervals exactly.

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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
#include <cmath>
using namespace std;
float *resize(float *, int &);
int increasingfun(float[], int &);
int decreasingfun(float[], int &);

int
main()
{
    stringstream f;
    float in, po;
    float *input = NULL;
    float *power = NULL;
    int insize = 0, posize = 0;
    bool increase = false, decrease = false;

    // Read terms until they enter zero for constant
    // Store the constants & powers in "input" and "power"
    cout << "Enter Variable's Constant: ";
    cin >> in;
    cout << "Enter Variable's Power: ";
    cin >> po;
    while (1) {
	input = resize(input, insize);
	input[insize - 1] = in;
	power = resize(power, posize);
	power[posize - 1] = po;
	if (in > 0)
	    f << "+";
	f << setprecision(2) << in;
	if (po != 0) {
	    f << "x";
	    if (po != 1) {
		f << "^";
		f << po;
	    }
	}
	system("cls");
	cout << "Your Current Function: " << f.str() << endl << endl;
	cout << "Enter Variable's Constant: ";
	cin >> in;
	if (in == 0)
	    break;
	cout << "Enter Variable's Power: ";
	cin >> po;
    }


    // Compute the values from -50 to 50 and store in y.
    // If the value becomes NAN or infinite then store -500000
    float y[100];
    for (int i = 0, j = -50; i < 100; i++, j++) {
	y[i] = 0;
	for (int z = 0; z < insize; z++) {
	    y[i] = y[i] + (input[z] * pow(j, power[z]));
	    // If it becomes infinite then assume it will stay there.
	    if (isinf(y[i])) break;	// dmh
	}
    }

    // Find increasing intervals.
    // assume the direction from y[0] to y[1] continues to -infinity
    increase = (y[0] < y[1]);
    string startInterval = "(-infinity";
    int stop = 1;
    for (int i = 0; i < 99; i++) {
	if (increase) {
	    if (y[i] < y[i + 1]) {	// going up!
		stop =i+1;
	    } else {		// it turned down
		cout << "Increasing Interval: "
		     << startInterval
		     << ", " << stop-50 << ")\n";
		increase = false;
	    }
	} else {
	    if (y[i] < y[i + 1]) {	// going up!
		stringstream ss;
		ss << '(' << i-50;
		startInterval = ss.str();
		stop = i+1;
		increase = true;
	    } else {
		// down or flat. Do nothing
	    }
	}
    }

    // If you were increasing at the end then assume it
    // continues to infinity
    if (increase) {
	cout << "Increasing Interval: "
	     << startInterval
	     << ", infinity)\n";
    }
    
    // Now check for decreasing intervals. This is analagous to above
    // assume the direction from y[0] to y[1] continues to -infinity
    decrease = (y[0] > y[1]);
    startInterval = "(-infinity";
    stop = 1;
    for (int i = 0; i < 99; i++) {
	if (decrease) {
	    if (y[i] > y[i + 1]) {	// still going down
		stop =i+1;
	    } else {		// it turned up
		cout << "Decreasing Interval: "
		     << startInterval
		     << ", " << stop-50 << ")\n";
		decrease = false;
	    }
	} else {
	    if (y[i] > y[i + 1]) {	// going down. Set start interval
		stringstream ss;
		ss << '(' << i-50;
		startInterval = ss.str();
		stop = i+1;
		decrease = true;
	    } else {
		// up or flat. Do nothing
	    }
	}
    }

    // If you were decreasing at the end then assume it
    // continues to infinity
    if (decrease) {
	cout << "Decreasing Interval: "
	     << startInterval
	     << ", infinity)\n";
    }

    system("pause");
    return 0;
}

float *
resize(float *array, int &size)
{
    float *temp;

    temp = new float[size + 1];
    for (int i = 0; i < size; i++)
	temp[i] = array[i];
    size++;
    delete[]array;
    return temp;
}

Last edited on
Topic archived. No new replies allowed.