Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Tomasz Janik
- #include <cmath>
- #include <iomanip>
- #include <vector>
- #include <stdlib.h>
- #include<iostream>
- using namespace std;
- class FindRoot {
- private:
- double(*function)(double);
- double pointLeft;
- double pointRight;
- int numberOfIterations;
- double epsilon;
- double delta;
- bool checkSigns(double valueA, double valueB) {
- return ((valueA >= 0 && valueB >= 0) || (valueA < 0 && valueB < 0));
- }
- double nextSecant(double prev1, double prev2, double prev1Value, double prev2Value) {
- return (prev2Value * prev1 - prev1Value * prev2) / (prev2Value - prev1Value);
- //return prev1 - (prev1Value * (prev1 - prev2)) / (prev1Value - prev2Value);
- //return (prev1Value * prev2 - prev2Value * prev1) / (prev1Value - prev2Value);
- }
- bool precissionStop(double value) {
- return abs(value) <= this->epsilon;
- }
- public:
- FindRoot(double(*f)(double), double a, double b, int M, double epsilon, double delta) {
- this->function = f;
- this->pointLeft = a;
- this->pointRight = b;
- this->numberOfIterations = M;
- this->epsilon = epsilon;
- this->delta = delta;
- }
- double solve() {
- double valueA = function(pointLeft);
- double valueB = function(pointRight);
- if (precissionStop(valueA))
- return pointLeft;
- if (precissionStop(valueB))
- return pointRight;
- while ((abs(pointLeft - pointRight) > delta) && checkSigns(valueA, valueB)) {
- double temp = nextSecant(pointLeft, pointRight, valueA, valueB);
- valueA = valueB;
- pointLeft = pointRight;
- valueB = function(temp);
- pointRight = temp;
- if (precissionStop(valueB)) {
- return temp;
- }
- }
- while ((abs(pointLeft - pointRight) > delta) && abs(pointRight - pointLeft) > 1.0f / 128.0f) {
- double c = (pointLeft + pointRight) / 2;
- double value = function(c);
- if (precissionStop(value)) return c;
- if (checkSigns(valueA, value)) {
- pointLeft = c;
- valueA = value;
- }
- else {
- pointRight = c;
- valueB = value;
- }
- }
- while ((abs(pointLeft - pointRight) > delta)) {
- double temp = nextSecant(pointLeft, pointRight, valueA, valueB);
- valueA = valueB;
- pointLeft = pointRight;
- valueB = function(temp);
- pointRight = temp;
- if (precissionStop(valueB)) {
- return temp;
- }
- }
- return pointRight;
- }
- };
- double wyznaczMiejsceZerowe(double(*f)(double), double a, double b, int M, double epsilon, double delta) {
- FindRoot solver(f, a, b, M, epsilon, delta);
- return solver.solve();
- }
- double wielomian(double x) { return (((x - 6)*x + 11)*x) - 6; }
- double wielomianSinExp(double x)
- {
- return ((((x - 6)*x + 11)*x) - 4 + sin(15 * x))*exp(-x * x);
- }
- double kwadrat(double x) { return (x*x - 2); }
- double kwadrat100(double x) { return 1e100*(x*x - 2); }
- double kwadrat_10(double x) { return 1e-10*(x*x - 2); }
- int main() {
- cout.precision(17); // Spodziewany wynik
- cout << wyznaczMiejsceZerowe(wielomian, 0, 4, 20, 1e-15, 1e-14) << endl; // 1 lub 2 lub 3
- cout << wyznaczMiejsceZerowe(wielomian, 0, 40, 20, 1e-15, 1e-14) << endl; // 1 lub 2 lub 3
- cout << wyznaczMiejsceZerowe(wielomian, 1, 2, 2, 1e-15, 1e-14) << endl; // 1 lub 2
- cout << wyznaczMiejsceZerowe(wielomian, -150, 1.9, 20, 1e-15, 1e-14) << endl; // 1
- cout << wyznaczMiejsceZerowe(wielomian, 1.5, 2.99, 20, 1e-15, 1e-14) << endl; // 2
- cout << wyznaczMiejsceZerowe(wielomian, 2.01, 40, 20, 1e-15, 1e-14) << endl; // 3
- cout << wyznaczMiejsceZerowe(wielomian, 1.5, 6, 20, 1e-15, 1e-14) << endl; // 1 lub 2 lub 3
- cout << wyznaczMiejsceZerowe(wielomianSinExp, -1, 3, 60, 1e-60, 1e-14) << endl; // 0.43636925909804245
- cout << wyznaczMiejsceZerowe(wielomianSinExp, -3, 3, 60, 1e-160, 1e-14) << endl; // 0.43636925909804245
- cout << wyznaczMiejsceZerowe(kwadrat, 0, 4, 15, 1e-11, 1e-14) << endl; // 1.414213562373095
- cout << wyznaczMiejsceZerowe(kwadrat100, 0, 4, 15, 1e-11, 1e-14) << endl; // 1.414213562373095
- cout << wyznaczMiejsceZerowe(kwadrat_10, 0, 4, 10, 1e-10, 1e-14) << endl; // każdy punkt z przedziału [1, 1.73205]
- cout << wyznaczMiejsceZerowe(kwadrat_10, 0, 4, 15, 1e-160, 1e-14) << endl; // 1.414213562373095
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement