|
Serwis Edukacyjny Nauczycieli I-LO w Tarnowie
Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy Wałaszek |
©2026 mgr Jerzy Wałaszek
|
W naszym serwisie jest nowszy artykuł o obliczaniu pierwiastków funkcji: "Metody numeryczne".
| SPIS TREŚCI |
| Podrozdziały |
Mamy daną funkcję \(f(x)\), dwa punkty startowe \(x_1\) oraz \(x_2\) i przedział \({[a,b]}\) poszukiwań pierwiastka, do którego należą punkty \(x_1\) i \(x_2.\) W przedziale poszukiwań pierwiastka funkcja musi spełniać następujące warunki:
Gdy funkcja \(f(x)\) spełnia podane warunki, to w przedziale \({[a,b]}\) istnieje pierwiastek i możemy go wyszukać metodą siecznych.
Metoda siecznych (ang. secant method) jest ulepszeniem metody regula falsi. W metodzie regula falsi żądamy, aby funkcja \(f(x)\) zawsze przyjmowała różne znaki na krańcach przedziału poszukiwań pierwiastka. Różne znaki gwarantują nam istnienie pierwiastka w tym przedziale. Otóż w metodzie siecznych taki wymóg nie jest konieczny (za wyjątkiem pierwszego obiegu). Do wyznaczenia kolejnego przybliżenia pierwiastka funkcji wykorzystujemy dwa poprzednio wyznaczone punkty:
Okazuje się, iż takie podejście do problemu znacznie przyspiesza znajdowanie pierwiastka funkcji. Prześledźmy graficznie tok postępowania:

Za początkowe punkty \(x_1\) i \(x_2\) przyjmujemy punkty krańcowe przedziału poszukiwań pierwiastka. Ponieważ funkcja zmienia znak w tym przedziale i jest określona oraz ciągła, mamy gwarancję istnienia pierwiastka. Z punktów wykresu funkcji dla \(x_1\) i \(x_2\) prowadzimy sieczną – na rysunku zaznaczoną kolorem zielonym. Punkt przecięcia się tej siecznej z osią OX daje nam następny punkt \(x_3\).

Drugą sieczną prowadzimy z punktów wykresu funkcji dla \(x_2\) oraz \(x_3\). Otrzymujemy punkt \(x_4\).

Trzecia sieczna prowadzona jest z punktów wykresu funkcji dla \(x_3\) i \(x_4\). Otrzymujemy kolejny punkt \(x_5\). Już widać, iż leży on bardzo blisko rzeczywistego pierwiastka funkcji.

Ostatnią sieczną prowadzimy z punktów wykresu funkcji dla \(x_4\) i \(x_5\). Otrzymany punkt \(x_6\) jest już dostatecznie blisko pierwiastka funkcji. Zwróć uwagę, iż kolejne punkty \(x_i\) zbliżają się do siebie.
Jeśli punkty początkowe \(x_1\), \(x_2\) zostaną źle dobrane, to algorytm może nie dać rozwiązania. Dlatego stosujemy w nim dodatkowy licznik obiegów pętli wyznaczającej kolejne przybliżenia pierwiastka funkcji. Jeśli po wykonaniu zadanej liczby obiegów (u nas \(64\)) nie zostanie znalezione rozwiązanie, to algorytm przerywa obliczenia z odpowiednim komunikatem. Obliczenia również będą przerwane w przypadku, gdy algorytm stwierdzi, iż sieczna jest równoległa do osi OX. Poprawnym warunkiem zakończenia algorytmu jest:
Wykonanie algorytmu siecznych rozpoczynamy od odczytu dwóch punktów \(x_1\) oraz \(x_2\). Punkty te posłużą do wyznaczenia pierwszej siecznej. Nie muszą one obejmować przedziału, w którym funkcja zmienia znak, jednakże jest to wskazane.
Dla obu punktów obliczamy wartości funkcji umieszczając je w zmiennych odpowiednio \(f_1\) i \(f_2\). Ponieważ algorytm siecznych może nie dać rozwiązania, stosujemy proste zabezpieczenie w postaci zliczania wykonanych obiegów pętli. Zmienna \(i\) pełni rolę licznika tych obiegów. Obiegi zliczane są wstecz. Na początku w zmiennej \(i\) określamy maksymalną ilość obiegów, po których algorytm zaprzestanie wykonywać obliczenia pierwiastka.
Rozpoczynamy pętlę obliczającą kolejne przybliżenia pierwiastka funkcji. Pętla kończy się w jednym z trzech przypadków:
Na początku pętli wyznaczamy nowe przybliżenie pierwiastka \(x_0\) oraz wartość funkcji w tym punkcie \(f_0\). Do wyznaczenia \(x_0\) stosujemy wzór siecznych, który wykorzystuje dwa ostatnio wyliczone przybliżenia pierwiastka \(x_1\) i \(x_2\).
Jeśli \(f_0\) jest dostatecznie bliskie zeru, to \(x_0\) jest przybliżonym pierwiastkiem, wypisujemy \(x_0\) i kończymy algorytm.
W przeciwnym razie przesuwamy \(x_1\) i \(x_0\) odpowiednio do \(x_2\) i \(x_1\) wraz z wartościami funkcji w tych punktach i kontynuujemy pętlę. Przesunięcie wartości funkcji \(f_1\) i \(f_0\) zwalnia nas od konieczności ich ponownego wyliczania.
Programy wyznaczają miejsce zerowe funkcji:
Pierwiastków należy poszukiwać w przedziałach \({[-1;0]}\) i \({[1;2]}\).
C++// Program znajduje miejsce
// zerowe funkcji f(x)
// za pomocą algorytmu
// siecznych
// ------------------------
// (C)2006 mgr J.Wałaszek
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
using namespace std;
// dokładność porównania z zerem
const double EPS0 = 0.0000000001;
// dokładność wyznaczenia pierwiastka
const double EPSX = 0.0000000001;
// Funkcja, której miejsce zerowe obliczamy
// f(x) = x^3*(x+sin(x^2-1)-1)-1
// <-1,0> i <1,2>
//-----------------------------------------
double f(double x)
{
return x * x * x * (x + sin(x * x - 1)
- 1) - 1;
}
//---------------
// Program główny
//---------------
int main()
{
double x0,x1,x2,f0,f1,f2;
int i;
cout << setprecision(8)
<< fixed
<< "Obliczanie pierwiastka funkcji\n"
" Metoda Siecznych\n"
"f(x) = x^3*(x+sin(x^2-1)-1)-1\n"
"------------------------------\n"
" (C)2006 mgr Jerzy Walaszek\n\n"
"Podaj dwa wstepne punkty x1 i x2:\n\n";
cout << "x1 = "; cin >> x1;
cout << "x2 = "; cin >> x2;
cout << "\nWYNIK:\n\n";
f1 = f(x1);
f2 = f(x2);
i = 64;
while(i && (fabs(x1 - x2) > EPSX))
{
if(fabs(f1 - f2) < EPS0)
{
cout << "Zle punkty startowe\n";
i = 0;
break;
}
x0 = x1 - f1 * (x1 - x2) / (f1 - f2);
f0 = f(x0);
if(fabs(f0) < EPS0) break;
x2 = x1; f2 = f1;
x1 = x0; f1 = f0;
if(!(--i))
cout << "Przekroczony limit obiegow\n";
}
if(i)
cout << "x0 = "
<< setw(15) << x0 << endl;
cout << "\n\n";
system("pause");
return 0;
}
|
Pascal// Program znajduje miejsce
// zerowe funkcji f(x)
// za pomocą algorytmu
// siecznych
// ------------------------
// (C)2006 mgr J.Wałaszek
program mzf1;
uses math;
const
// dokładność porównania z zerem
EPS0 = 0.0000000001;
// dokładność wyznaczenia pierwiastka
EPSX = 0.0000000001;
// Funkcja, której miejsce zerowe obliczamy
// f(x) = x^3*(x+sin(x^2-1)-1)-1
// <-1,0> i <1,2>
//-----------------------------------------
function f(x : real) : double;
begin
Result := x * x * x * (x + sin(x * x -
1) - 1) - 1;
end;
//---------------
// Program główny
//---------------
var
x0,x1,x2,f0,f1,f2 : double;
i : integer;
begin
writeln('Obliczanie pierwiastka funkcji');
writeln(' Metoda Siecznych');
writeln('f(x) = x^3*(x+sin(x^2-1)-1)-1');
writeln('------------------------------');
writeln(' (C)2006 mgr Jerzy Walaszek');
writeln;
writeln('Podaj dwa wstepne punkty x1 i x2:');
writeln;
write('x1 = '); readln(x1);
write('x2 = '); readln(x2);
writeln;
writeln('WYNIK:');
writeln;
f1 := f(x1);
f2 := f(x2);
i := 64;
while (i > 0) and
(abs(x1 - x2) > EPSX) do
begin
if abs(f1 - f2) < EPS0 then
begin
writeln('Zle punkty startowe');
i := 0;
break;
end;
x0 := x1 - f1 * (x1 - x2) / (f1 - f2);
f0 := f(x0);
if abs(f0) < EPS0 then break;
x2 := x1; f2 := f1;
x1 := x0; f1 := f0;
dec(i);
if i = 0 then
writeln('Przekroczony limit obiegow');
end;
if i > 0 then writeln('x0 = ',x0:15:8);
writeln;
writeln('Nacisnij Enter...');
readln;
end.
|
Basic' Program znajduje miejsce
' zerowe funkcji f(x)
' za pomocą algorytmu
' siecznych
'-------------------------
' (C)2006 mgr J.Wałaszek
Declare Function f(ByVal x _
As Double) _
As Double
' dokładność porównania z zerem
Const EPS0 As Double = 0.0000000001
' dokładność wyznaczenia pierwiastka
Const EPSX As Double = 0.0000000001
'---------------
' Program główny
'---------------
Dim As double x0, x1, x2, f0, f1, f2
Dim i As Integer
Print "Obliczanie pierwiastka funkcji"
Print " Metoda Siecznych"
Print "f(x) = x^3*(x+sin(x^2-1)-1)-1"
Print "------------------------------"
Print " (C)2006 mgr Jerzy Walaszek"
Print
Print "Podaj dwa wstepne punkty x1 i x2:"
Print
Input "x1 = ", x1
Input "x2 = ", x2
Print
Print "WYNIK:"
Print
f1 = f(x1)
f2 = f(x2)
i = 64
While (i > 0) And (Abs(x1 - x2) > EPSX)
If Abs(f1 - f2) < EPS0 Then
Print "Zle punkty startowe"
i = 0
Exit While
End If
x0 = x1 - f1 * (x1 - x2) / (f1 - f2)
f0 = f(x0)
If Abs(f0) < EPS0 Then Exit While
x2 = x1 : f2 = f1
x1 = x0 : f1 = f0
i -= 1
If i = 0 Then _
Print "Przekroczony limit obiegow"
Wend
If i > 0 Then _
Print Using "x0 = ######.########"; x0
Print
Print "Nacisnij Enter..."
Sleep
End
' Funkcja, której miejsce
' zerowe obliczamy
' f(x) = x^3*(x+sin(x^2-1)-1)-1
' <-1,0> i <1,2>
'------------------------------
Function f(ByVal x As Double) _
As Double
Return x * x * x * _
(x + Sin(x * x - 1) - 1) - 1
End Function
|
| Wynik: |
Obliczanie pierwiastka funkcji
Metodą Siecznych
f(x) = x^3*(x+sin(x^2-1)-1)-1
------------------------------
(C)2026 mgr Jerzy Wałaszek
Podaj dwa wstępne punkty x1 i x2:
x1 = 1
x2 = 2
WYNIK:
x0 = 1.18983299
Naciśnij Enter...
|
JavaScript<html>
<head>
</head>
<body>
<div style="overflow-x: auto; overflow-y: hidden;"
align="center">
<table
border="0"
cellpadding="4"
style="border-collapse:
collapse">
<tr>
<td nowrap>
<form
name="frmbincode"
style="text-align: center;
background-color:
#E7E7DA;">
<b><big>
Obliczanie<br>
pierwiastka funkcji<br>
metodą Siecznych
</big></b><br><br>
f(x) = x<sup>3</sup>(x +
sin(x<sup>2</sup>-1)-1)-1<br>
<br>
(C)2026
mgr Jerzy Wałaszek
I LO w Tarnowie
<hr>
Wpisz do pól edycyjnych<br>
dwa punkty startowe<br>
<br>
x<sub>1</sub> =
<input
type="text"
name="inp_x1"
size="16"
value="1"
style="text-align:
right">
<br>
x<sub>2</sub> =
<input
type="text"
name="inp_x2"
size="16"
value="2"
style="text-align:
right">
<hr>
<input
type="button"
value="Szukaj"
name="B1"
onclick="main()">
<hr>
<b>Wynik:</b>
<div id="out">.</div>
</form>
</td>
</tr>
</table>
</div>
<script language=javascript>
// Program znajduje miejsce
// zerowe funkcji f(x)
// za pomocą algorytmu siecznych
//------------------------------
// (C)2006 mgr J.Wałaszek
// I LO w Tarnowie
// dokładność porównania
// z zerem
var EPS0 = 0.0000000001
// dokładność wyznaczenia
// pierwiastka
var EPSX = 0.0000000001
// Funkcja, której miejsce
// zerowe obliczamy
// f(x) = x^3*(x+sin(x^2-1)-1)-1
// <-1,0> i <1,2>
function f(x)
{
return x * x * x *
(x + Math.sin(x *
x - 1) - 1) - 1
}
//---------------
// Program główny
//---------------
function main()
{
var x0,x1,x2,f0,f1,f2,i,t
x1 = parseFloat(document
.frmbincode.inp_x1.value)
x2 = parseFloat(document
.frmbincode.inp_x2.value)
if(isNaN(x1) || isNaN(x2))
t = "<font color=red><b>" +
"Nieprawidłowe dane!" +
"</b></font>"
else
{
f1 = f(x1)
f2 = f(x2)
i = 64 // limit obiegów
while(i &&
(Math.abs(x1 - x2)
> EPSX))
{
if(Math.abs(f1 - f2) < EPS0)
{
t = "<font color=red><b>" +
"Złe punkty startowe!" +
"</b></font>"
i = 0;
break;
}
x0 = x1 - f1 * (x1 - x2) /
(f1 - f2)
f0 = f(x0)
if(Math.abs(f0) < EPS0)
break
x2 = x1
f2 = f1
x1 = x0
f1 = f0
if(!(--i))
t = "<font color=red><b>" +
"Przekroczony limit obiegów!" +
"</b></font>";
}
if(i) t = "x<sub>0</sub> = " + x0
}
document.getElementById("out")
.innerHTML = t
}
</script>
</body>
</html>
|
Tutaj możesz przetestować działanie prezentowanego skryptu. Przykładowa funkcja posiada pierwiastki w przedziałach \({[-1;0]}\) i \({[1;2]}\).
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.