Untitled
unknown
plain_text
2 years ago
7.4 kB
4
Indexable
// Includem bibliotecile necesare #include <iostream> #include <math.h> #include <stdio.h> #include <stdlib.h> using namespace std; // Declaram constanta numarului maxim de iteratii permise const int MAX_ITERATIONS=1000; double(*f)(double), (*fn)(double), (*fd)(double); // Prima functie a) double f1(double x) { return log10(1+x)+x-1.5; } // A doua functie b) double f2(double x) { return pow(x,3)+(25*x)-37; } // Derivata primei functii double fd1(double x) { return (1/(1+x)*log(10)); } // Derivata celei de-al doilea functii double fd2(double x) { return 3*pow(x,2)+25; } // Forma echivalenta a primei ecuatii alesa in mod special // ca sa satisfaca conditia suficienta de convergenta double phi1(double x) { return 1.5-log10(1+x); } // Forma echivalenta a celei de-a doilea ecuatii alesa in mod // special ca sa satisfaca conditia suficienta de convergenta double phi2(double x) { return (pow(x,3)-37)/25; } // Metoda aproximatiilor succesive void SITER() { // Initiam contorul iteratiilor int k=0; // Declaram variabilele necesare // inclusiv eroarea epsilon=10^(-6) double x0,x1,eps=0.000001; cout<<"Introduceti valoarea initiala x0="; cin>>x0; // Deschidem un ciclu infinit while(1) { x1=fn(x0); // Incrementam contorul iteratiilor k++; // Verificam daca metoda converge if(abs(x1-x0)<eps) { cout<<"Radacina este: "<<x0<<endl; cout<<"Numarul de iteratii: "<<k<<endl; break; } // Adaugam verificarea pentru cazul in care metoda nu converge if(k>MAX_ITERATIONS) { cout<<"Eroare! Metoda nu converge dupa "<<MAX_ITERATIONS<<" iteratii."<<endl; break; } x0=x1; } } // Metoda injumatatirii intervalului (bisectiei) void BISECT() { // Initiam contorul iteratiilor int k=0; // Declaram variabilele necesare // inclusiv exactitatea epsilon=10^(-2) double a,b,c=0,eps=0.01; cout<<"Introduceti intervalul:"<<endl; cout<<"a="; cin>>a; cout<<"b="; cin>>b; // Deschidem instructiunea repetitiva ciclica cu conditia // ca c aproximeaza radacina r cu eroarea dorita while(abs(b-a)>=eps) { // Incrementam contorul iteratiilor k++; // Operatia de injumatatire (recomandata) // ce nu ne scoate in afara intervalului c=a+((b-a)/2); // Verificam convergenta if(k>MAX_ITERATIONS) { cout<<"Eroare! Metoda nu a convergat dupa "<<MAX_ITERATIONS<<" iteratii!"<<endl; return; } // Valoarea c este chiar radacina cautata if(f(c)==0) break; // Daca radacina reala se gaseste in intervalul [a,c] acolo unde // functia ia valori de semne contrare la capetele intervalului else if(f(a)*f(c)<0) b=c; // Daca radacina reala se gaseste in intervalul [c,b] acolo unde // functia ia valori de semne contrare la capetele intervalului else if(f(c)*f(b)<0) a=c; else { // Afisam mesajul de eroare daca metoda nu converge cout<<"Metoda nu converge! Alege alt interval sau schimba functia"<<endl; return; } } cout<<"Radacina este: "<<c<<endl; cout<<"Numarul de iteratii: "<<k<<endl; } // Metoda tangentelor (Newton) void NEWTON() { // Initiam contorul iteratiilor int k=0; // Declaram variabilele necesare // inclusiv precizia epsilon=10^(-6) double x0,x1,eps=0.000001; cout<<"Introduceti valoarea initiala x0="; cin>>x0; // Deschidem un ciclu pentru iteratii while(k<MAX_ITERATIONS) { x1=x0-f(x0)/fd(x0); // Incrementam contorul iteratiilor k++; if(abs(x1-x0)<eps) { cout<<"Radacina este: "<<x0<<endl; cout<<"Numarul de iteratii: "<<k<<endl; break; } x0=x1; } // Verificam daca metoda a convergat if(k==MAX_ITERATIONS) { cout<<"Eroare! Metoda nu a convergat dupa "<<MAX_ITERATIONS<<" iteratii!"<<endl; cout<<"Incercati cu o alta valoare initiala x0"<<endl; cout<<"Sau verificati functia f si derivata fd"<<endl; } } // Metoda secantelor void SECANT() { // Initiam contorul iteratiilor int k=0; // Declaram variabilele necesare // inclusiv exactitatea epsilon=10^(-6) double x1,x2,x3=0,y,eps=0.000001; cout<<"Introduceti intervalul:"<<endl; cout<<"a="; cin>>x1; cout<<"b="; cin>>x2; do { // Incrementam contorul iteratiilor k++; y=x3; // Forma recomandata a formulei (evita neutralizarea termenilor) x3=x2-(f(x2)*(x2-x1)/(f(x2)-f(x1))); x1=x2; x2=x3; // Verificam daca metoda converge if(k>MAX_ITERATIONS) { cout<<"Eroare! Metoda secantelor nu converge"<<endl; cout<<"in numarul maxim de iteratii permis!"<<endl; return; } } while(fabs(y-x3)>=eps); cout<<"Radacina este: "<<x3<<endl; cout<<"Numarul de iteratii: "<<k<<endl; } // Metoda de selectare a functiei void selectFunction() { cout<<"1) log10(1+x)+x-1.5"<<endl; cout<<"2) pow(x,3)+(25*x)-37"<<endl; // Declaram variabila optiunii selectate int opt; cout<<"Introduceti optiunea: "; do { opt=getchar(); } while(opt<'1' || opt>'2'); // Efectuam atribuirile necesare (dupa caz) switch(opt) { case'1': { f=f1; // functia fn=phi1; // echivalenta fd=fd1; // derivata break; } case'2': { f=f2; // functia fn=phi2; // echivalenta fd=fd2; // derivata break; } } } // Functia de selectare (meniu) int meniu() { if(f==f1) cout<<"Functia curenta selectata: log10(1+x)+x-1.5\n"<<endl; else cout<<"Functia curenta selectata: pow(x,3)+(25*x)-37\n"<<endl; cout<<"1. Selecatarea altei functii"<<endl; cout<<"2. Metoda aproximatiei succesive"<<endl; cout<<"3. Metoda injumatatirii intervalului (bisectiei)"<<endl; cout<<"4. Metoda tangentelor (Newton)"<<endl; cout<<"5. Metoda secantelor"<<endl; cout<<"6. Iesire din program\n"<<endl; // Declaram variabila optiunii selectate int opt; cout<<"Introduceti optiunea: "; do { opt=getchar(); } while(opt<'1' || opt>'6'); return opt-'0'; } // Programul principal int main() { // Declaram variabila optiunii selectate int opt; // Stabilim prima ecuatie ca selectata f=f1; // functia fn=phi1; // echivalenta fd=fd1; // derivata do { switch(opt=meniu()) { case 1: { selectFunction(); break; } case 2: { SITER(); break; } case 3: { BISECT(); break; } case 4: { NEWTON(); break; } case 5: { SECANT(); break; } } } while(opt!=6); }
Editor is loading...
Leave a Comment