# Solving non linear equations 1.0

Sep 15th, 2020
127
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. #define _CRT_SECURE_NO_WARNINGS
2. #include <stdio.h>
3. #include <math.h>
4. #include <vector>
5. #include <stdexcept>
6.
7.
8.
9. struct Section {
10.     double leftBorder;
11.     double rightBorder;
12. };
13.
14.
15.
16. std::vector<Section> sections;
17. std::vector<double> roots;
18.
19.
20.
21. const double EPS = 0.001;
22.
23.
24.
25. double f1(double x); // [0 ; 1] root is 0.1
26. double f2(double x); // just y = x
27. double f3(double x); // [1.5 ; 3.14] root is 2
28. double f4(double x); // just y = sin(x)
29. double f5(double x); // just x*x
30.
31. typedef double (*pointFunc)(double x);
32.
33.
34. double derivative(pointFunc f, double x);
35. double doubleDerivative(pointFunc f, double x);
36.
37.
38.
39. double halfDivisionMethod(pointFunc f, const Section & section);
40. double chordMethod(pointFunc f, const Section & section);
41. double newtonMethod(pointFunc f, const Section & section);
42. double interationMethod(pointFunc f, const Section & section);
43.
44. typedef double(*pointMethod)(pointFunc f, const Section & section);
45.
46.
47.
48. int main() {
49.     // Воод исходных данных и разбиение функции на интервалы (отделение корней)
50.     const pointFunc f = f1;
51.     int n = 0;
52.     double leftBorder = 0.0;
53.     double rightBorder = 0.0;
54.
55.     initInput:
56.     printf("Input left border: ");
57.     scanf("%lf", &leftBorder);
58.     printf("Input right border: ");
59.     scanf("%lf", &rightBorder);
60.     printf("Input amount of sections: ");
61.     scanf("%d", &n);
62.
63.     if (rightBorder <= leftBorder) {
64.         puts("Error: incorrect input of section borders! Try again!\n");
65.         goto initInput;
66.     }
67.     if (n <= 0) {
68.         puts("Error: incorrect input amount of sections! Try again!\n");
69.         goto initInput;
70.     }
71.
72.     double x = leftBorder;
73.     double h = (rightBorder - leftBorder) / double(n);
74.
75.     while (x < rightBorder)
76.     {
77.         if (f(x) * f(x + h) <= 0)
78.             sections.push_back({ x, x + h });
79.         x += h;
80.     }
81.
82.     if (sections.empty()) {
83.         printf("Error: something went wrong trying to get sections.");
84.         printf("Ensure equation have roots or increase N.");
85.         getchar();
86.         getchar();
87.         exit(1);
88.     }
89.     puts("");
90.
91.
92.
93.     // Выбор метода решения и вычисление корней
94.     pointMethod method = NULL;
95.     backToChoice:
96.     puts("Choose method: ");
97.     puts("Print 1 to use half division method.");
98.     puts("Print 2 to use chord method.");
99.     puts("Print 3 to use Newton method.");
100.     puts("Print 4 to use iteration method.");
101.     int choice = 0;
102.     scanf("%d", &choice);
103.     switch (choice)
104.     {
105.     case 1:
106.         method = halfDivisionMethod;
107.         break;
108.     case 2:
109.         method = chordMethod;
110.         break;
111.     case 3:
112.         method = newtonMethod;
113.         break;
114.     case 4:
115.         method = interationMethod;
116.         break;
117.     default:
118.         puts("There is no such method! Choose again!\n");
119.         goto backToChoice;
120.     }
121.
122.     while (!sections.empty()) {
123.         try {
124.             roots.push_back(method(f, sections.back()));
125.         }
126.         catch (std::runtime_error& e) {
127.             printf("Error: %s", e.what());
128.             getchar();
129.             getchar();
130.             exit(1);
131.         }
132.         sections.pop_back();
133.     }
134.     puts("");
135.
136.
137.
138. // Вывод результатов и тестирование
139. printf("Roots: ");
140. for (int i = 0; i != roots.size(); ++i)
141. printf("%f   ", roots.at(i));
142. puts("\n");
143.
144. while (!roots.empty()) {
145.     double currentRoot = roots.back();
146.     if (fabs(f(currentRoot)) > EPS*2)
147.         printf("Test failed: %f is not root of the equation! f(%f) = %f\n", currentRoot, currentRoot, f(currentRoot));
148.     else
149.         printf("Test passed.\n");
150.     roots.pop_back();
151. }
152. puts("");
153.
154.
155.
156. // Конец программы
157. puts("End of program. Press enter to exit.");
158. getchar();
159. getchar();
160. return 0;
161. }
162.
163.
164. double f1(double x) {
165.     return exp(x) - 10 * x;
166. }
167.
168. double f2(double x) {
169.     return 2 * x;
170. }
171.
172. double f3(double x) {
173.     return x * x - 5 * sin(x);
174. }
175.
176. double f4(double x)
177. {
178.     return sin(x);
179. }
180.
181. double f5(double x)
182. {
183.     return x*x;
184. }
185.
186.
187. double derivative(pointFunc f, double x)
188. {
189.     const double h = 0.005;
190.     return (f(x) - f(x + h)) / h;
191. }
192.
193. double doubleDerivative(pointFunc f, double x)
194. {
195.     const double h = 0.005;
196.     return (f(x + h) - 2 * f(x) + f(x - h)) / (h * h);
197. }
198.
199. double halfDivisionMethod(pointFunc f, const Section & section) {
200.     int iterationsCounter = 0;
201.     double a = section.leftBorder;
202.     double b = section.rightBorder;
203.     double x = (a + b) / 2.0;
204.     double yLeft = f(a), yRight = f(b), yCenter = f(x);
205.
206.     while (fabs(yRight - yLeft) > EPS  && iterationsCounter != 10000) {
207.         if (yCenter * yRight < 0) {
208.             a = x;
209.             yLeft = f(a);
210.         }
211.         else {
212.             b = x;
213.             yRight = f(b);
214.         }
215.
216.         x = (a + b) / 2.0;
217.         yCenter = f(x);
218.         ++iterationsCounter;
219.     }
220.
221.     if (iterationsCounter == 10000) {
222.         throw std::runtime_error("Half division method does not respond.");
223.     }
224.
225.     return x;
226. }
227.
228. double chordMethod(pointFunc f, const Section & section) {
229.     int iterationsCounter = 0;
230.     double a = section.leftBorder;
231.     double b = section.rightBorder;
232.     double result = 0.0;
233.     double yLeft = f(a), yRight = f(b);
234.
235.
236.     if ((yLeft*doubleDerivative(f ,a)) > 0)
237.     {
238.         while (fabs(b - ((b - a) / (yRight - yLeft))*yRight - b) > EPS && iterationsCounter != 100000)
239.         {
240.             b = b - ((b - a) / (yRight - yLeft))*yRight;
241.             ++iterationsCounter;
242.             yRight = f(b);
243.         }
244.         result = b;
245.     }
246.     else
247.     {
248.         while (fabs(a - ((b - a) / (yRight - yLeft))*yLeft - a) > EPS && iterationsCounter != 100000)
249.         {
250.             a = a - ((b - a) / (yRight - yLeft))*yLeft;
251.             ++iterationsCounter;
252.             yLeft = f(a);
253.         }
254.         result = a;
255.     }
256.
257.
258.     if (iterationsCounter == 100000) {
259.         throw std::runtime_error("Chord method does not respond.");
260.     }
261.
262.     return result;
263. }
264.
265. double newtonMethod(pointFunc f, const Section & section)
266. {
267.     return 0.0;
268. }
269.
270. double interationMethod(pointFunc f, const Section & section)
271. {
272.     return 0.0;
273. }
274.
RAW Paste Data