Sunteți pe pagina 1din 13

7

ECUAŢII ALGEBRICE ŞI TRANSCENDENTE

7.1 Separarea rădăcinilor

f (x) = 0
Ecuaţie algebrică – dacă f (x) este polinom.
Ecuaţia transcendentă – în caz contrar.

Rădăcină aproximativă – valoare ξ 0 apropiată de valoarea exactă ξ.


Definiţii neechivalente:

• numărul ξ 0 cu proprietatea |ξ 0 − ξ| < ε (ε > 0)

• numărul ξ 0 cu proprietatea |f (ξ 0 )| < ε.

y y

f(ξ 0)

f(ξ 0)

ξ0 ξ x ξ0 ξ x

(a) (b)

FIGURA 7.1. Cazuri de rădăcini aproximative care nu satisfac simultan criteriile |ξ 0 − ξ| < ε şi
|f (ξ 0 )| < ε.
Determinarea rădăcinilor reale:

1. separarea rădăcinilor – stabilirea unei partiţii xmin = x1 , x2 , . . . , xM = xmax –


orice [xm , xm+1 ] să conţină cel mult o rădăcină;

2. calculul rădăcinilor separate prin procedee iterative de rafinare.

Teorema 7.1 Dacă o funcţie continuă f (x) admite valori de semn opus la capetele unui
interval [a, b], adică f (a)f (b) < 0, atunci acel interval conţine cel puţin o rădăcină a
ecuaţiei f (x) = 0.

y y

f(b ) f(b)

f(a)

a
b x a b x
f(a)

(a) (b)

FIGURA 7.2. Exemple de rădăcini neseparate.

Separarea rădăcinilor:

• Determinarea semnelor funcţiei f (x) în punctele unei partiţii {xm }.

• Dacă [xm , xm+1 ] sunt suficient de mici, fiecare subinterval va conţine cel mult o
rădăcină.

• În intervalele cu f (xm )f (xm+1 ) > 0 nu va exista nici o rădăcină.

• În intervalele cu f (xm )f (xm+1 ) ≤ 0 va exista o singură rădăcină.

2
7.2 Metoda bisecţiei (metoda înjumătăţirii)
Fie f (x) continuă pe [a, b] şi fie ecuaţia:

f (x) = 0.

Presupunem că în urma separării rădăcinilor există cel mult o rădăcină ξ ∈ [a, b].

Împărţim [a, b] în mod repetat în părţi egale, păstrând semiintervalul [ai , bi ] la capetele
căruia funcţia are semne opuse.

f(a0)
ξ x0 b = b0
a = a0 x

f(a1)
ξ b1
a1 x1 x
f(b1)

f(a2)
ξ b2
a2 x
f(b2)

FIGURA 7.3. Procesul de înjumătăţire a intervalului de căutare în cazul metodei bisecţiei.

După i paşi rezultă [ai , bi ] astfel încât

f (ai )f (bi ) < 0.

Lungimea intervalului [ai , bi ] este:


b−a
bi − ai = .
2i
Înjumătăţind [ai , bi ] prin
ai + bi
xi =
2
rezultă fie rădăcina exactă ξ = xi , fie un nou interval [ai+1 , bi+1 ].

Procesul se încheie, considerând ca rădăcină aproximativă ξ 0 = xi , când


¯ ¯
¯ bi − ai ¯
¯ ¯
¯ xi ¯ ≤ ε sau |f (xi )| ≤ ε.

3
/*---------------------------- Metoda bisectiei ---------------------------*/
#include <stdio.h>
#include <math.h>
/*=========================================================================*/
float func(float x)
{
return (x+2)*(x+1)*x*(x-1)*(x-2);
}
/*=========================================================================*/
int Bisect(float Func(float), float a, float b, float *x)
/*---------------------------------------------------------------------------
Determina un zero real al unei functii reale prin metoda bisectiei
Func - functia utilizator
a, b - limitele intervalului de cautare
*x - zeroul gasit (iesire)
Returneaza indicele de eroare: 0 - executie normala
1 - nr. maxim de iteratii depasit
2 - intervalul nu contine o radacina
---------------------------------------------------------------------------*/
{
const float eps = 1e-6; /* criteriu relativ de precizie */
const int itmax = 100; /* nr. maxim de iteratii */
float fa, fx;
int it;
/* zeroul este unul din capete ? */
fa = Func(*x=a); if (fabs(fa) <= eps) return 0;
fx = Func(*x=b); if (fabs(fx) <= eps) return 0;
if (fa*fx > 0) return 2; /* intervalul nu contine o radacina */
for (it=1; it<=itmax; it++) {
*x = (a + b)/2; /* noua aproximatie */
fx = Func(*x);
if (fa*fx > 0) a = *x; else b = *x; /* alege noul interval */
if (((b-a) <= eps*fabs(*x)) || (fabs(fx) <= eps)) return 0;
}
printf("Bisect: nr. maxim de iteratii depasit !\n");
return 1;
}
/*=========================================================================*/
void main()
{
float a, b, h, x, xmin, xmax;
printf("xmin = "); scanf("%f",&xmin);
printf("xmax = "); scanf("%f",&xmax);
printf("h = "); scanf("%f",&h);
a = xmin;
while (a < xmax) {
b = a + h;
if ((Bisect(func,a,b,&x) == 0) && (x != b)) printf(" x = %f \n",x);
a = b;
}
}

În main este partiţionat intervalul de căutare [xmin , xmax ] în subintervale de lungime h


pentru separarea rădăcinilor.

4
7.3 Metoda poziţiei false (metoda corzii)
În general mai eficientă decât metoda bisecţiei.
Avantajoasă însă tot numai pentru determinarea grosieră a rădăcinilor reale.

f(bi )

ai xi
ξ bi x
y = f(x)
f(ai )

FIGURA 7.4. Împărţirea intervalului de căutare prin intermediul corzii care uneşte punctele
(ai , f (ai )) şi (bi , f (bi )) în cazul metodei poziţiei false.

Se înlocuieşte funcţia cu coarda – punctul de intersecţie xi cu axa absciselor:

xi − ai −f (ai ) ai f (bi ) − bi f (ai )


= ⇒ xi = .
bi − ai f (bi ) − f (ai ) f (bi ) − f (ai )

După un anumit număr de paşi:

• fie o rădăcină exactă ξ = xi , astfel încât f (xi ) = 0

• fie o secvenţă de intervale [a0 , b0 ], [a1 , b1 ], . . . , [ai , bi ], . . . cu

ai+1 = ai , bi+1 = xi , dacă f (ai )f (xi ) < 0


ai+1 = xi , bi+1 = bi , dacă f (ai )f (xi ) > 0,

astfel încât
f (ai+1 )f (bi+1 ) < 0.

5
/*=========================================================================*/
int FalsPos(float Func(float), float a, float b, float *x)
/*---------------------------------------------------------------------------
Determina un zero real al unei functii reale prin metoda pozitiei false
Func - functia utilizator
a, b - limitele intervalului de cautare
*x - zeroul gasit (iesire)
Returneaza indicele de eroare: 0 - executie normala
1 - nr. maxim de iteratii depasit
2 - intervalul nu contine o radacina
---------------------------------------------------------------------------*/
{
const float eps = 1e-6; /* criteriu relativ de precizie */
const int itmax = 100; /* nr. maxim de iteratii */
float dx, fa, fb, fx;
int it;
/* zeroul este unul din capete ? */
fa = Func(*x=a); if (fabs(fa) <= eps) return 0;
fb = Func(*x=b); if (fabs(fb) <= eps) return 0;
if (fa*fb > 0) return 2; /* intervalul nu contine o radacina */
for (it=1; it<=itmax; it++) {
*x = (a*fb - b*fa)/(fb - fa); /* noua aproximatie */
fx = Func(*x);
if (fa*fx > 0) { /* alege noul interval */
dx = *x - a; a = *x; fa = fx;
} else {
dx = b - *x; b = *x; fb = fx;
}
if ((fabs(dx) <= eps*fabs(*x)) || (fabs(fx) <= eps)) return 0;
}
printf("FalsPos: nr. maxim de iteratii depasit !\n");
return 1;
}

După fiecare partiţionare a intervalului se reactualizează nu numai capetele intervalului,


ci şi valorile corespunzătoare ale funcţiei, f (ai ) şi f (bi ).

6
7.4 Metoda aproximaţiilor succesive
Una dintre metode numerice foarte importante – utilizabilă pt. rafinarea rădăcinilor.
Presupunem că f (x) este continuă pe [a, b] şi se cere rezolvarea ecuaţiei:
f (x) = 0,
Se pune sub forma echivalentă:
x = ϕ(x).

Pornind de la aproximaţia iniţială x0 pentru rădăcina ξ → şirul de aproximaţii succesive:


xi+1 = ϕ(xi ), i = 0, 1, 2, . . .
Dacă şirul este convergent → ∃ ξ = lim xi .
Dacă ϕ(x) este continuă → ξ = ϕ(ξ) – rădăcina ecuaţiei

y y
y = ϕ(x)
y = ϕ(x)

x0 x2 ξ x3 x1 x x0 x1 x2 ξ x
(a) (b)
y y
y = ϕ(x)
y = ϕ(x)

x2 x0 ξ x1 x3 x ξ x0 x1 x2 x3 x
(c) (d)

FIGURA 7.5. Procese iterative în metoda aproximaţiilor succesive aplicată ecuaţiei x = ϕ(x)
pentru: a) −1 < ϕ0 (x) < 0; b) 0 < ϕ0 (x) < 1; c) ϕ0 (x) < −1; d) ϕ0 (x) > 1.

Rădăcină reală ξ pt. x = ϕ(x) – abscisa punctului de intersecţie dintre y = ϕ(x) şi y = x.
Procesul este convergent (metoda aplicabilă) numai în intervalele unde
|ϕ0 (x)| < 1.

7
Teorema 7.2 Fie ecuaţia
x = ϕ(x),
cu funcţia ϕ(x) definită şi derivabilă pe [a, b]. Dacă este satisfăcută inegalitatea

|ϕ0 (x)| ≤ λ < 1

pentru orice x ∈ [a, b], atunci şirul de iterare definit de relaţia

xi+1 = ϕ(xi ), i = 0, 1, 2, . . .

converge către rădăcina (unică dacă există) ξ ∈ [a, b] a ecuaţiei, indiferent de valoarea
iniţială x0 .

Cu cât e mai mic λ, cu atât mai rapid converge procesul către rădăcina ξ

f (x) = 0 poate fi înlocuită cu ecuaţia echivalentă:

x = x − f (x) adică ϕ(x) = x − f (x).

Procesul iterativ:
xi+1 = xi − f (xi ), i = 0, 1, 2, . . .
Condiţie de convergenţă:

δ i ≡ |∆xi /xi+1 | ≤ ε sau |∆xi | ≤ ε|xi+1 |

Corecţia rădăcinii:
∆xi ≡ xi+1 − xi = −f (xi ).

Exemplu:
x − e−x = 0.

• Dacă se alege f (x) = x − e−x

ϕ(x) = e−x
|ϕ0 (x)| = e−x < 1.

Procesul converge către x = 0.567143.

• Dacă se alege f (x) = e−x − x

ϕ(x) = 2x − e−x
|ϕ0 (x)| = 2 + e−x > 1.

Procesul diverge rapid.

8
/*-------------------- Metoda aproximatiilor succesive --------------------*/
#include <stdio.h>
#include <math.h>
/*=========================================================================*/
float func(float x)
{
return x - exp(-x);
}
/*=========================================================================*/
int Iter(float Func(float), float *x)
/*---------------------------------------------------------------------------
Determina un zero real al unei functii reale prin metoda aproximatiilor
succesive
Func - functia utilizator
*x - aproximatie initiala (la intrare), zeroul gasit (la iesire)
Returneaza indicele de eroare: 0 - executie normala
1 - nr. maxim de iteratii depasit
2 - proces divergent
---------------------------------------------------------------------------*/
{
const float eps = 1e-6; /* criteriu relativ de precizie */
const int itmax = 100; /* nr. maxim de iteratii */
float dx, f;
int it;
dx = -Func(*x); /* initializeaza corectia */
for (it=1; it<=itmax; it++) {
f = Func(*x);
if (fabs(f) > fabs(dx)) goto divergent; /* compara noua corectie */
dx = -f; /* actualizeaza corectia */
*x += dx; /* noua aproximatie */
if (fabs(dx) <= eps*fabs(*x)) return 0; /* testeaza convergenta */
}
printf("Iter: nr. maxim de iteratii depasit !\n");
return 1;
divergent:
printf("Iter: proces divergent !\n");
return 2;
}
/*=========================================================================*/
void main()
{
float x;
/* Caz test:
x - exp(-x) = 0, x0 = 0
Zeroul: 0.567143
*/
printf("x0 = "); scanf("%f",&x);
if (Iter(func,&x) == 0) printf("x = %f \n",x);
}

9
7.5 Metoda lui Newton
Metoda Newton-Raphson sau metoda tangentei – eficienţă deosebită.
Presupunem f (x) continuă pe [a, b] şi

f (x) = 0

are o rădăcină reală ξ ∈ [a, b], iar f 0 (x) şi f 00 (x) sunt continue şi păstrează semnul.

y y

y = f(x) y = f(x)

a ξ x0 = a ξ b
x2 x1 x0 = b x x1 x

(a) (b)

FIGURA 7.6. Determinarea aproximaţiilor succesive în metoda Newton-Raphson. În cazul (b)


f (x0 )f 00 (x0 ) < 0 şi convergenţa este mai lentă.

Aproximaţie iniţială x0 pt. ξ.


Aproximaţie îmbunătăţită x1 ducând tangenta la y = f (x) în (x0 , f (x0 )):

f (x0 ) f (x0 )
f 0 (x0 ) = ⇒ x1 = x0 − .
x0 − x1 f 0 (x0 )
Procesul iterativ:
f (xi )
xi+1 = xi − , i = 0, 1, 2, . . .
f 0 (xi )
Funcţia de iterare:
f (x)
ϕ(x) = x − .
f 0 (x)
Condiţia de convergenţă (ca în metoda aproximaţiilor succesive):

|ϕ0 (x)| < 1.


Criteriu de convergenţă:

δ i ≡ |∆xi /xi+1 | ≤ ε sau |∆xi | ≤ ε|xi+1 |.

Corecţia rădăcinii:
∆xi ≡ xi+1 − xi = −f (xi )/f 0 (xi ).

10
/*=========================================================================*/
int Newton(float Func(float,float *), float *x)
/*---------------------------------------------------------------------------
Determina un zero real al unei functii reale prin metoda Newton-Raphson
utilizand derivata analitica
---------------------------------------------------------------------------*/
{
const float eps = 1e-6; /* criteriu relativ de precizie */
const int itmax = 100; /* nr. maxim de iteratii */
float df, dx, f;
int it;
for (it=1; it<=itmax; it++) {
f = Func(*x,&df); /* functia si derivata */
dx = (fabs(df) > eps) ? -f/df : -f; /* corectia radacinii */
*x += dx; /* noua aproximatie */
if (fabs(dx) <= eps*fabs(*x)) return 0; /* test convergenta */
}
printf("Newton: nr. maxim de iteratii depasit !\n");
return 1;
}

/*=========================================================================*/
int NewtonNumDeriv(float Func(float), float *x)
/*---------------------------------------------------------------------------
Determina un zero real al unei functii reale prin metoda Newton-Raphson
utilizand derivarea numerica
---------------------------------------------------------------------------*/
{
const float eps = 1e-6; /* criteriu relativ de precizie */
const int itmax = 100; /* nr. maxim de iteratii */
float df, dx, f;
int it;
for (it=1; it<=itmax; it++) {
f = Func(*x);
dx = *x ? 1e-4*fabs(*x) : 1e-4; /* pasul de derivare */
df = (Func(*x+dx)-f)/dx; /* derivata numerica */
dx = (fabs(df) > eps) ? -f/df : -f; /* corectia radacinii */
*x += dx; /* noua aproximatie */
if (fabs(dx) <= eps*fabs(*x)) return 0; /* test convergenta */
}
printf("NewtonNumDeriv: nr. maxim de iteratii depasit !\n");
return 1;
}

Exemplu:
x − e−x = 0.

float func(float x, float *df)


{
*df = 1 + exp(-x);
return x - exp(-x);
}

Metoda lui Newton converge ¯ către rădăcina x = 0.567143


¯ indiferent de semnul lui f (x).
0 ¯ −x −x −x 2 ¯
În ambele cazuri |ϕ (x)| = ¯e (x − e )/ (1 + e ) ¯ < 1 pentru orice x pozitiv.

Metoda lui Newton converge în general mai rapid decât metoda aproximaţiilor succesive.

11
7.6 Metoda secantei
Asemănătoare metodei Newton-Raphson – nu necesită evaluarea derivatei funcţiei.

a ξ
x2 x1 x0 = b x

y = f(x)

FIGURA 7.7. Determinarea aproximaţiilor succesive în metoda secantei.

Tangenta este aproximată de coarda care uneşte punctele pt. două estimări anterioare.
Dezavantaj – rădăcina nu rămâne izolată. Nu este garantată convergenţa.
Din formula metodei Newton-Raphson:
f (xi ) f (xi ) − f (xi−1 )
xi+1 = xi − , f 0 (xi ) ≈
f 0 (xi ) xi − xi−1
Relaţia de recurenţă (implică trei aproximaţii succesive ale rădăcinii):
xi − xi−1
xi+1 = xi − f (xi ) ,
f (xi ) − f (xi−1 )
x1 se poate obţine din x0 aplicând metoda aproximaţiilor succesive:
x1 = x0 − f (x0 ),
/*=========================================================================*/
int Secant(float Func(float), float *x)
{
const float eps = 1e-6; /* criteriu relativ de precizie */
const int itmax = 100; /* nr. maxim de iteratii */
float df, dx, f, f0, x0;
int it;
x0 = *x; f0 = Func(x0);
*x = x0 - f0; /* prima aproximatie */
for (it=1; it<=itmax; it++) {
f = Func(*x);
df = (f-f0)/(*x-x0); /* derivata aproximativa */
x0 = *x; f0 = f; /* memoreaza abscisa si functia */
dx = (fabs(df) > eps) ? -f/df : -f; /* corectia radacinii */
*x += dx; /* noua aproximatie */
if (fabs(dx) <= eps*fabs(*x)) return 0; /* test convergenta */
}
printf("Secant: nr. maxim de iteratii depasit !\n");
return 1;
}

12
Bibliography

[1] J. Ortega şi W. Rheinboldt, Iterative Solution of Nonlinear Equations in Several Vari-
ables (Academic Press, New York, 1970).

[2] N.S. Bakhvalov, Numerical Methods (MIR Publishers, Moskow, 1977).

[3] Gh. Dodescu, Metode numerice în algebră, Editura tehnică, Bucureşti, 1979).

[4] M. Toma şi I. Odăgescu, Metode numerice şi subroutine, Editura tehnică, Bucureşti,
1980).

[5] B.P. Demidovich şi I.A. Maron, Computational Mathematics (MIR Publishers,
Moskow, 1981).

[6] R.L. Burden şi J.D. Faires, Numerical Analysis, Third Edition (Prindle, Weber &
Schmidt, Boston, 1985).

[7] W.H. Press, S.A. Teukolsky, W.T. Vetterling şi B.P. Flannery, Numerical Recipes in
C: The Art of Scientific Computing, Second Edition (Cambridge University Press,
Cambridge, 1992).

S-ar putea să vă placă și