Metoda stycznych

Metoda stycznych to algorytm numeryczny wyznaczający przybliżoną wartość miejsca zerowego funkcji z pewną dokładnością. Innym algorytmem, który można wykorzystać do wyznaczenia przybliżonej wartości miejsca zerowego funkcji jest algorytm bisekcji, który omówiono w e‑materiale Algorytmy numeryczne i przybliżonePdzAH5eTwAlgorytmy numeryczne i przybliżone.

  1. Działanie metody rozpoczyna się od wskazania punktu startowego x1, będącego pierwszym przybliżeniem miejsca zerowego. Punkt ten wybieramy z przedziału , w którym będzie znajdowało się dokładnie jedno miejsce zerowemiejsce zerowemiejsce zerowe funkcji.

  2. Następnym krokiem jest wyznaczenie kolejnego przybliżenia , które jest współrzędną  punktu przecięcia stycznej do wykresu funkcji w punkcie z osią . Przybliżenie to wyznaczamy według następującego wzoru:

x 2 = x 1 f ( x 1 ) f ( x 1 )

gdzie:

  • x1 – punkt startowy; przybliżona wartość miejsca zerowego funkcji f(x) w przedziale ;

  • x2 – przybliżona wartość miejsca zerowego funkcji f(x) w przedziale ; punkt przecięcia stycznej do wykresu funkcji w punkcie z osią ;

  • f(x1) – wartość funkcji f(x) w punkcie ;

  • f'(x1) – pochodna funkcji f(x) w punkcie .

Styczna jest geometryczną interpretacją pochodnej (więcej na ten temat znajdziesz między innymi w e‑materiałach Interpretacja geometryczna pochodnejP1Gw5Gpw2Interpretacja geometryczna pochodnej oraz Pochodna funkcji w punkciePlXFy9xdHPochodna funkcji w punkcie).

  1. Jeżeli:

    • różnica pomiędzy kolejnymi przybliżeniami jest mniejsza lub równa wybranej dokładności  lub

    • wartość funkcji w punkcie jest bliska 0,

kończymy algorytm z wynikiem – przybliżoną współrzędną miejsca zerowego funkcji jest z dokładnością . W przeciwnym wypadku wartość staje się nowym punktem startowym () i wracamy do kroku drugiego.

Implementacja algorytmu w języku C++

Napiszmy program realizujący algorytm wyznaczania miejsca zerowego funkcji w przedziale z dokładnością do trzech miejsc po przecinku.

f(x) = x3  5x

Na początek dołączamy niezbędne biblioteki. W trakcie pisania programu będziemy korzystali z funkcji fabs umożliwiającej obliczenie wartości bezwzględnejwartość bezwzględnawartości bezwzględnej wyrażenia. Dołączamy bibliotekę cmathcmathcmath, dzięki której będziemy mogli użyć tej funkcji.

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny cmath zamknij nawias ostrokątny. Linia 3. using namespace std średnik.

Tworzymy definicję funkcji o nazwie funkcja. Jej rolą jest obliczenie i zwrócenie wartości analizowanej funkcji w punkcie x zgodnie z wcześniej podanym wzorem.

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny cmath zamknij nawias ostrokątny. Linia 3. using namespace std średnik. Linia 5. double funkcja otwórz nawias okrągły double x zamknij nawias okrągły otwórz nawias klamrowy. Linia 6. return x asterysk x asterysk x minus 5 asterysk x średnik. Linia 7. zamknij nawias klamrowy.

W programie zdefiniujemy kolejną funkcję będącą pochodną funkcji, której miejsce zerowe chcemy wyznaczyć. Pochodna funkcji ma następujący wzór:

f(x) = 3x2  5

W programie nadajemy jej nazwę pochodna.

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny cmath zamknij nawias ostrokątny. Linia 3. using namespace std średnik. Linia 5. double funkcja otwórz nawias okrągły double x zamknij nawias okrągły otwórz nawias klamrowy. Linia 6. return x asterysk x asterysk x minus 5 asterysk x średnik. Linia 7. zamknij nawias klamrowy. Linia 9. double pochodna otwórz nawias okrągły double x zamknij nawias okrągły otwórz nawias klamrowy. Linia 10. return 3 asterysk x asterysk x minus 5 średnik. Linia 11. zamknij nawias klamrowy.

Możemy przejść do zdefiniowania funkcji realizującej kolejne przybliżenia. Jej przyjmowanymi parametrami są: punkt startowy xIndeks dolny 1 wartość błędu bezwzględnego ex oraz dokładność ey, czyli maksymalna różnica pomiędzy kolejnymi przybliżeniami, przy której możemy zakończyć algorytm.

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny cmath zamknij nawias ostrokątny. Linia 3. using namespace std średnik. Linia 5. double funkcja otwórz nawias okrągły double x zamknij nawias okrągły otwórz nawias klamrowy. Linia 6. return x asterysk x asterysk x minus 5 asterysk x średnik. Linia 7. zamknij nawias klamrowy. Linia 9. double pochodna otwórz nawias okrągły double x zamknij nawias okrągły otwórz nawias klamrowy. Linia 10. return 3 asterysk x asterysk x minus 5 średnik. Linia 11. zamknij nawias klamrowy. Linia 13. double metodaStycznych otwórz nawias okrągły double x1 przecinek double ex przecinek double ey zamknij nawias okrągły otwórz nawias klamrowy. Linia 14. zamknij nawias klamrowy.

Tworzymy zmienną xIndeks dolny 2 typu double. To w niej będą przechowywane kolejne przybliżenia. Na początek przypisujemy jej wartość xIndeks dolny 1.

W pętli do..while przypisujemy zmiennej x1 wartość x2. W tym momencie wartość zapisana w zmiennej xIndeks dolny 2 staje się nowym punktem startowym. Następnie zgodnie z przedstawionym wcześniej wzorem obliczamy miejsce zerowe i zapisujemy do zmiennej x2. Jeżeli różnica pomiędzy kolejnymi przybliżeniami (wartość bezwzględna, którą obliczamy funkcją fabs()) jest większa od dokładności przyjmowanej jako parametr, przechodzimy na początek pętli i ponawiamy obliczenia. W przeciwnym wypadku wychodzimy z pętli i na koniec zwracamy wartość zmiennej x2, czyli przybliżoną wartość miejsca zerowego funkcji. Wykonywanie pętli kończymy również w przypadku, gdy wartość funkcji dla podanego argumentu jest mniejsza lub równa dokładności, oznacza to również, że znaleźliśmy miejsce zerowe z zadowalającą dokładnością.

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny cmath zamknij nawias ostrokątny. Linia 3. using namespace std średnik. Linia 5. double funkcja otwórz nawias okrągły double x zamknij nawias okrągły otwórz nawias klamrowy. Linia 6. return x asterysk x asterysk x minus 5 asterysk x średnik. Linia 7. zamknij nawias klamrowy. Linia 9. double pochodna otwórz nawias okrągły double x zamknij nawias okrągły otwórz nawias klamrowy. Linia 10. return 3 asterysk x asterysk x minus 5 średnik. Linia 11. zamknij nawias klamrowy. Linia 13. double metodaStycznych otwórz nawias okrągły double x1 przecinek double ex przecinek double ey zamknij nawias okrągły otwórz nawias klamrowy. Linia 14. double x2 znak równości x1 średnik. Linia 16. do otwórz nawias klamrowy. Linia 17. x1 znak równości x2 średnik. Linia 18. x2 znak równości x1 minus funkcja otwórz nawias okrągły x1 zamknij nawias okrągły prawy ukośnik pochodna otwórz nawias okrągły x1 zamknij nawias okrągły średnik. Linia 19. zamknij nawias klamrowy while otwórz nawias okrągły fabs otwórz nawias okrągły x2 minus x1 zamknij nawias okrągły zamknij nawias ostrokątny ex ampersant ampersant funkcja otwórz nawias okrągły x2 zamknij nawias okrągły zamknij nawias ostrokątny ey zamknij nawias okrągły średnik. Linia 21. return x2 średnik. Linia 22. zamknij nawias klamrowy.

Na koniec w głównej funkcji programu main() wywołujemy funkcję metodaStycznych z punktem startowym 3 i przybliżeniem oraz błędem bezwzględnym równymi 0,001. Wynik tego wywołania, pomnożony przez 1000, zapisujemy w zmiennej typu całkowitego przyblizenie. Dzięki temu wynik zostanie zaokrąglony do części całkowitej i w momencie, gdy do zmiennej wynik zapiszemy przybliżenie podzielone przez 1000, otrzymamy zaokrąglenie do części tysięcznej.

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny cmath zamknij nawias ostrokątny. Linia 3. using namespace std średnik. Linia 5. double funkcja otwórz nawias okrągły double x zamknij nawias okrągły otwórz nawias klamrowy. Linia 6. return x asterysk x asterysk x minus 5 asterysk x średnik. Linia 7. zamknij nawias klamrowy. Linia 9. double pochodna otwórz nawias okrągły double x zamknij nawias okrągły otwórz nawias klamrowy. Linia 10. return 3 asterysk x asterysk x minus 5 średnik. Linia 11. zamknij nawias klamrowy. Linia 13. double metodaStycznych otwórz nawias okrągły double x1 przecinek double ex przecinek double ey zamknij nawias okrągły otwórz nawias klamrowy. Linia 14. double x2 znak równości x1 średnik. Linia 16. do otwórz nawias klamrowy. Linia 17. x1 znak równości x2 średnik. Linia 18. x2 znak równości x1 minus funkcja otwórz nawias okrągły x1 zamknij nawias okrągły prawy ukośnik pochodna otwórz nawias okrągły x1 zamknij nawias okrągły średnik. Linia 19. zamknij nawias klamrowy while otwórz nawias okrągły fabs otwórz nawias okrągły x2 minus x1 zamknij nawias okrągły zamknij nawias ostrokątny ex ampersant ampersant funkcja otwórz nawias okrągły x2 zamknij nawias okrągły zamknij nawias ostrokątny ey zamknij nawias okrągły średnik. Linia 21. return x2 średnik. Linia 22. zamknij nawias klamrowy. Linia 24. int main otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 25. int przyblizenie znak równości metodaStycznych otwórz nawias okrągły 3 przecinek 0 kropka 0001 przecinek 0 kropka 0001 zamknij nawias okrągły asterysk 1000 średnik. Linia 26. double wynik znak równości przyblizenie prawy ukośnik 1000 kropka 0 średnik. Linia 28. cout otwórz nawias ostrokątny otwórz nawias ostrokątny wynik otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik. Linia 30. return 0 średnik. Linia 31. zamknij nawias klamrowy.

Wynikiem przedstawionego programu i jednocześnie miejscem zerowym funkcjif(x) = x3  5x w przedziale [1, 3] jest x = 2,236.

Pamiętaj, że zbieżnośćzbieżnośćzbieżność nie zawsze musi zachodzić. Jeżeli źle dobierzemy punkt startowy, algorytm stycznej nie zwróci wyniku. W takim wypadku program może np. nigdy się nie kończyć, ponieważ w każdej iteracji będzie  się oddalał od znalezienia miejsca zerowego.

Słownik

cmath
cmath

biblioteka zawierająca deklaracje funkcji matematycznych, takich jak potęgowanie, pierwiastkowanie czy obliczanie wartości bezwzględnej

miejsce zerowe
miejsce zerowe

argument funkcji, dla której przyjmuje ona wartość 0

wartość bezwzględna
wartość bezwzględna

odległość danej liczby od zera na osi liczbowej

zbieżność
zbieżność

własność mówiąca o tym, że dany problem posiada rozwiązanie, do którego przybliżamy się wraz ze wzrostem liczby wykonanych iteracji