Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <math.h>
- #include <vector>
- #include <stdexcept>
- struct Section {
- double leftBorder;
- double rightBorder;
- };
- std::vector<Section> sections;
- std::vector<double> roots;
- const double EPS = 0.001;
- double f1(double x); // [0 ; 1] root is 0.1
- double f2(double x); // just y = x
- double f3(double x); // [1.5 ; 3.14] root is 2
- double f4(double x); // just y = sin(x)
- double f5(double x); // just x*x
- typedef double (*pointFunc)(double x);
- double derivative(pointFunc f, double x);
- double doubleDerivative(pointFunc f, double x);
- double halfDivisionMethod(pointFunc f, const Section & section);
- double chordMethod(pointFunc f, const Section & section);
- double newtonMethod(pointFunc f, const Section & section);
- double interationMethod(pointFunc f, const Section & section);
- typedef double(*pointMethod)(pointFunc f, const Section & section);
- int main() {
- // Воод исходных данных и разбиение функции на интервалы (отделение корней)
- const pointFunc f = f1;
- int n = 0;
- double leftBorder = 0.0;
- double rightBorder = 0.0;
- initInput:
- printf("Input left border: ");
- scanf("%lf", &leftBorder);
- printf("Input right border: ");
- scanf("%lf", &rightBorder);
- printf("Input amount of sections: ");
- scanf("%d", &n);
- if (rightBorder <= leftBorder) {
- puts("Error: incorrect input of section borders! Try again!\n");
- goto initInput;
- }
- if (n <= 0) {
- puts("Error: incorrect input amount of sections! Try again!\n");
- goto initInput;
- }
- double x = leftBorder;
- double h = (rightBorder - leftBorder) / double(n);
- while (x < rightBorder)
- {
- if (f(x) * f(x + h) <= 0)
- sections.push_back({ x, x + h });
- x += h;
- }
- if (sections.empty()) {
- printf("Error: something went wrong trying to get sections.");
- printf("Ensure equation have roots or increase N.");
- getchar();
- getchar();
- exit(1);
- }
- puts("");
- // Выбор метода решения и вычисление корней
- pointMethod method = NULL;
- backToChoice:
- puts("Choose method: ");
- puts("Print 1 to use half division method.");
- puts("Print 2 to use chord method.");
- puts("Print 3 to use Newton method.");
- puts("Print 4 to use iteration method.");
- int choice = 0;
- scanf("%d", &choice);
- switch (choice)
- {
- case 1:
- method = halfDivisionMethod;
- break;
- case 2:
- method = chordMethod;
- break;
- case 3:
- method = newtonMethod;
- break;
- case 4:
- method = interationMethod;
- break;
- default:
- puts("There is no such method! Choose again!\n");
- goto backToChoice;
- }
- while (!sections.empty()) {
- try {
- roots.push_back(method(f, sections.back()));
- }
- catch (std::runtime_error& e) {
- printf("Error: %s", e.what());
- getchar();
- getchar();
- exit(1);
- }
- sections.pop_back();
- }
- puts("");
- // Вывод результатов и тестирование
- printf("Roots: ");
- for (int i = 0; i != roots.size(); ++i)
- printf("%f ", roots.at(i));
- puts("\n");
- while (!roots.empty()) {
- double currentRoot = roots.back();
- if (fabs(f(currentRoot)) > EPS*2)
- printf("Test failed: %f is not root of the equation! f(%f) = %f\n", currentRoot, currentRoot, f(currentRoot));
- else
- printf("Test passed.\n");
- roots.pop_back();
- }
- puts("");
- // Конец программы
- puts("End of program. Press enter to exit.");
- getchar();
- getchar();
- return 0;
- }
- double f1(double x) {
- return exp(x) - 10 * x;
- }
- double f2(double x) {
- return 2 * x;
- }
- double f3(double x) {
- return x * x - 5 * sin(x);
- }
- double f4(double x)
- {
- return sin(x);
- }
- double f5(double x)
- {
- return x*x;
- }
- double derivative(pointFunc f, double x)
- {
- const double h = 0.005;
- return (f(x) - f(x + h)) / h;
- }
- double doubleDerivative(pointFunc f, double x)
- {
- const double h = 0.005;
- return (f(x + h) - 2 * f(x) + f(x - h)) / (h * h);
- }
- double halfDivisionMethod(pointFunc f, const Section & section) {
- int iterationsCounter = 0;
- double a = section.leftBorder;
- double b = section.rightBorder;
- double x = (a + b) / 2.0;
- double yLeft = f(a), yRight = f(b), yCenter = f(x);
- while (fabs(yRight - yLeft) > EPS && iterationsCounter != 10000) {
- if (yCenter * yRight < 0) {
- a = x;
- yLeft = f(a);
- }
- else {
- b = x;
- yRight = f(b);
- }
- x = (a + b) / 2.0;
- yCenter = f(x);
- ++iterationsCounter;
- }
- if (iterationsCounter == 10000) {
- throw std::runtime_error("Half division method does not respond.");
- }
- return x;
- }
- double chordMethod(pointFunc f, const Section & section) {
- int iterationsCounter = 0;
- double a = section.leftBorder;
- double b = section.rightBorder;
- double result = 0.0;
- double yLeft = f(a), yRight = f(b);
- if ((yLeft*doubleDerivative(f ,a)) > 0)
- {
- while (fabs(b - ((b - a) / (yRight - yLeft))*yRight - b) > EPS && iterationsCounter != 100000)
- {
- b = b - ((b - a) / (yRight - yLeft))*yRight;
- ++iterationsCounter;
- yRight = f(b);
- }
- result = b;
- }
- else
- {
- while (fabs(a - ((b - a) / (yRight - yLeft))*yLeft - a) > EPS && iterationsCounter != 100000)
- {
- a = a - ((b - a) / (yRight - yLeft))*yLeft;
- ++iterationsCounter;
- yLeft = f(a);
- }
- result = a;
- }
- if (iterationsCounter == 100000) {
- throw std::runtime_error("Chord method does not respond.");
- }
- return result;
- }
- double newtonMethod(pointFunc f, const Section & section)
- {
- return 0.0;
- }
- double interationMethod(pointFunc f, const Section & section)
- {
- return 0.0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement