// Metoda przybliżania pierwiastków funkcji f(x)=0, Metoda hybrydowa w oparciu o metody Newtona - Robsona i metode bisekcji
// Piotr Kowerzanow , Wydział FTiMS Politechnika Gdańska
// Bartosz Kowalczyk, Wydział FTiMS Politechnika Gdańska
// IS gr. lab. 2
// marzec , 2007
#include<iostream>
#include<cmath>
using namespace std;
float f(float x); // wartosc funkcji w punkcie
float fx(float x); //wartosc pierwszej pochodnej w punkcie
void bisekcja(float a, float b, int n, float eps); // procedura bisekcji
int main(){
float a,b; // granice przedziału
float c,t; // punkt startowy, t - zmienna pomocnicza dla c
float eps; //dokladnosc obliczeniowa
float x; //przyblizany pierwiastek
int n; // liczba przyblizeń
float d; // zmienna pomocnicza do badania dokładności
cout<<" Obliczanie przybliżenia pierwiastka funkcji : \n f(x)=x^4-4x^3-5x^2-4x+4"<<endl;
cout<<"Podaj przedzial : "<<endl;
cout<<"a : "; cin>>a;
cout<<"b : "; cin>>b;
cout<<"Liczba przyblizen : "; cin>>n;
do{
cout<<" Podaj punkt startowy: "; cin>>c;
}while(c<a||c>b);
t=c;
// do{
cout<<" Podaj dokladnosc obliczeniowa (eps<1): "; cin>>eps;
// }while(eps>1);
x=t;
for(int i=0 ; i<=n; i++) {
if(f(x)==0) break;
// if(fx(c)-1.e-6<=0){ cout<<"W trakcie obliczen pochodna rowna 0 !" <<endl; break;}
x=x-(f(x)/fx(x));
if(x<a||x>b) bisekcja(a,b,n,eps); // gdy wartosc wyskoczy poza przedzial nalezy zastosowac od razu met bisekcji
// badanie dokladnosci
d=fabs(x-t);
if(fabs(x)>1) d=d/fabs(x);
if(fabs(d)<=eps) if(fabs(fx(x))<=100*eps) {cout<<"Nie osiagnieto dokladnosci w n-krokach iteracji"<<endl; break; }
cout<<"x"<<i<<"= "<<x<<endl;
} //for
/*cout<<"Podaj przedzial(oddzielajac spacja) : "; cin>>a>>b;
cout<<"f(b)= "<<f(b)<<endl;
cout<<"fxx(b)= "<<fxx(b)<<endl;
cout<<"f(b)*fxx(b)= "<<f(b)*fxx(b)<<endl;*/
system("PAUSE");
}//main
float f(float x){return x*x*x*x-4*x*x*x-5*x*x-4*x+4;}
float fx(float x){ return 4*x*x*x-12*x*x-10*x-4;}
void bisekcja(float a, float b, int n, float eps){
float fa,fb; // wartosci funkcji w punktach
float fxx; // wartosc pochodnej w pt n zastapiona ilorazem roznicowym
float x; // wartosc pomocnicza/pierweiastek
float fx; //wartość funkcji f(x) w punkcie
fa=f(a);
fb=f(b);
if(fa*fb>0){ cout<<"bledne dane "<<endl; }
else if(fa*fb==0) { if(fa==0) {cout<<"pierwiastek rownaia: "<<a<<endl;}
else {cout<<"pierwiastek rownaia: "<<b<<endl;}
}else {
for(int i=0; i<=n;i++){ fxx=(fb-fa)/(b-a);
x=(a+b)/2;
fx=f(x);
cout<<"x= "<<x<<"fx= "<<fx<<endl;
if(fabs(fx/fxx)-eps<=0) cout<<"przerwane przy i= "<<i<<"x= "<<x<<endl;
else if(fx*fa<0){ b=x; fb=fx;}
else {a=x; fa=fx;}
} //for
}
} //bisekcja