c++ drugi wynik wielomianu

c++ drugi wynik wielomianu
Y3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 15
0

Hej!
Mam pewien problem. Przyznam od razu, nie jestem zbyt dobra z c++ czy z matmy. Mam znaleźć miejsca zerowe wielomianu (używając metody Newtona). Znalazłam kod, trochę go przerobiłam...Program dobrze oblicza, ale tylko jedno miejsce zerowe. Jak są dwa, nadal wyświetla tylko jedno. Czy mógłby mi ktoś pomóc, przerobić go, aby otrzymać pozostałe?
Kod:

Kopiuj
#include <iostream>
#include <math.h>
#include <iomanip>

using namespace std;

int sWielomianu, p, q;
float liczbaStopni[100];


float algHor(int k, float x){ //algorytm Hornera - obliczanie wartosci wielomianu
    if (k == sWielomianu){
        return liczbaStopni[sWielomianu];}
    else{
        return algHor(k + 1,x)* x + liczbaStopni[k];}
}


float algSTs(int j){           //Algorytm Show-Trauba funkcja pomocnicza s(j)
    return (sWielomianu - j) % q;
}

float algSTR(int j){           //Algorytm Show-Trauba funkcja pomocnicza r(j)
    if (j % q == 0)
        return q;
    else
        return 0;
}

float T(int i, int j, float x){ //Algorytm Show-Trauba - glowna funkcja
    if (x == 0)                    
        return liczbaStopni[j];
    else
        if (j == -1)
            return liczbaStopni[sWielomianu - i - 1]* pow(x,algSTs(i + 1));
        else
    if (i == j)
        return liczbaStopni[sWielomianu] * pow(x,algSTs(0));
    else
        return T(i-1, j-1, x)+T(i-1, j, x) * pow(x,algSTR(i - j));
}

float pochodna(int stopien, float punkt){
    if (punkt == 0)
        return T(sWielomianu,stopien,punkt);
    else return T(sWielomianu,stopien,punkt) / pow(punkt,stopien%q);
}

main(){

    int k;
    int iteracja = 1000; // Liczba interacji
    float poczatek, koniec, wynik;
    p = 1;
    q = sWielomianu + 1;

 
    cout << "\nPodaj stopien wielomianu: ";
    cin >> sWielomianu;
        if (sWielomianu > 100){
            cout << "Za duzy stopien" << endl;
        }
        if (sWielomianu < 2){
            cout << "Za maly stopien";
        }

    cout << "\nPodaj teraz wspolczynniki wielomianu (zaczynij od tego z najwieksza potega).\n";
    for(k = sWielomianu; k >= 0; k--){
        cout <<"a" << k << " - ";
        cin >> liczbaStopni[k];
    }

    cout << "\nPodaj poczatek przedzialu: ";
    cin >> poczatek;
    cout << "Podaj koniec przedzialu: ";
    cin >> koniec;


    if (pochodna(2,poczatek)*algHor(0,poczatek)>0){
            wynik = poczatek;
    } else {
        wynik = koniec;
    }

    for (k = 1; k <= iteracja; k++){
        wynik = wynik - (algHor(0,wynik)/pochodna(1,wynik));
        if (algHor(0,wynik)==0){
            break;
        }
    }


    if (algHor(0,wynik) == 0){
        cout << "\nDokladny pierwiastek wynosi: " << setprecision(5) <<  wynik << endl;
    } else{

        cout << "\nPrzyblizony pierwiastek wynosi: "  << setprecision(5) << wynik << endl;
    }

    return(0);
}

enedil
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1028
2

Jak masz np. wielomian (x-2) * (x-5), i zaczynasz szukać na przedziale [0, 10], i znajdziesz, że x = 2 jest pierwiastkiem, to potem należy sprawdzić, czy na przedziale [0, 2) oraz na (2, 10] jest pierwiastek. Nie ma, z tego co mi wiadomo metody na dowiedzenie się, czy istnieje jakikolwiek pierwiastek (dla dowolnej funkcji rzeczywistej).

A ten algorytm Shaw-Trauba to wywal do śmieci, do niczego tutaj nie jest potrzebny, znasz chyba w końcu wzór na pochodną wielomianu?

No i, przepraszam, kod jest nieco tragiczny (o czym chyba wiesz zresztą), ale no, dbaj o takie rzeczy jak chociażby należyte wcięcia. W brzydkim kodzie ciężej znajdywać błędy.

AK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3561
1
enedil napisał(a):

No i, przepraszam, kod jest nieco tragiczny (o czym chyba wiesz zresztą), ale no, dbaj o takie rzeczy jak chociażby dbanie o należyte wcięcia. W brzydkim kodzie ciężej znajdywać błędy.

Dodał bym: nazwy zmiennych: nie wydaje mi się, by liczbaStopni[] było dobrą. raczej stopnieWielomianu[]
Zm globalne są złe. O ile tablicę warunkowo można wybaczyć, to p,q już nie

MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
1

Uczyli cię w szkole dzielić wielomiany?
Jak masz wielomian W(x) dla którego znalazłaś miesce zerowe x1 to można to zapisać jako:
W(x) = F(x) \cdot (x - x_1)
Gdzie F(x) to wielomian stopnia o jeden mniejszy niż W(x).

Dzielenie wielomianów, przypomina dzielnie pisemne liczb, ale jest łatwiejsze (nie trzeba się przejmować przeniesieniem).

Jak wyliczysz F(x) to dla niego znowu możesz szukać miejsc zerowych.

Swoją droga dziel kod na mniejsze funkcje, będzie łatwiej.

Y3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 15
0

@MarekR22:
Dziękuję bardzo!
Jest to możliwe zrobienie tego z tym kodem? Czy muszę jakoś od początku go napisać?

_13th_Dragon
  • Rejestracja: dni
  • Ostatnio: dni
0

Nie, tu używasz inną metodę niż w zadaniu.

Y3
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 15
0

@_13th_Dragon: Ok, dziękuję. Ps. Napisałam na priv.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.