Untitled

mail@pastecode.io avatar
unknown
plain_text
7 months ago
7.4 kB
0
Indexable
Never
// 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);
}
Leave a Comment