Sunteți pe pagina 1din 25

Metode de rezolvare a ecuaţiilor neliniare

1. Metoda înjumătăţirii intervalului

Cea mai simplă metodă de rezolvare a ecuaţiilor neliniare este metoda


înjumătăţirii intervalului. Această metodă se aplică dacă pe intervalul dat
există în mod sigur o singură rădăcină. Dacă [a,b] este intervalul pe care se
studiază problema, atunci condiţia de mai sus se poate scrie: f(a) · f(b) < 0.
Se calculează punctul c de la mijlocul intervalului şi se determină în care din
cele două jumătăţi se află rădăcina. Astfel, dacă f(a) · f(c) < 0, rădăcina se
află în intervalul [a,c], iar în caz contrar în intervalul [b,c]. Se aplică acelaşi
procedeu pentru noul interval de mai multe ori până când se obţine un
interval în jurul rădăcinii mai mic decât o eroare admisă .

Algoritmul descris mai sus se poate scrie astfel:


1. Se declară funcţia f(x).
2. Se declară marginile intervalului a şi b şi eroarea .
3. Dacă f(a) · f(b) > 0 atunci intervalul este ales greşit. STOP.
4. Se calculează c = ( a + b ) / 2.
5. Dacă f(c) = 0 atunci rădăcina exactă este c. Se scrie c. STOP.
6. Dacă f(a) · f(c) > 0 atunci a = c altfel b = c.
7. Dacă ( b - a ) <  atunci se scrie rădăcina aproximativă c = ( a + b ) / 2 şi
se opresc calculele, altfel se reia întreg procesul de la pasul 4.
package ecuatiineliniare;

public class Bisectie {

/// se declara functia


public static double f(double x){
return Math.log(x) + x;
}
public static void main(String[] args) {
// TODO Auto-generated method stub

/// se declara variabilele a, b, c, eps


double a = 0.001, b=2, c, eps = 1e-6;
/// daca f(a)*f(b) < 0 atunci se poate aplica metoda pe
acest interval, altfel trebuie ales alt interval
if(f(a)*f(b) < 0){
do{
/// se calculeaza c=(a+b)/2
c = (a + b)/2;

/// daca f(a)*f(c) < 0 atunci b=c, altfel a=c


if(f(a)*f(c)<0){

1
b=c;
} else {
a=c;
}
}
while(Math.abs(f(c))>eps);
/// daca |f(c)| < eps atunci se scrie radacina
System.out.println("Metoda injumatatirii
intervalului");
System.out.println("Radacina = "+Double.toString(c));
} else {
System.out.println("Interval ales gresit!!!");
}
}

}
2. Metoda coardei variabile

In cadrul acestei metode algoritmul de rezolvare este oarecum similar,


deosebirea fiind aceea că se foloseşte o altă formulă pentru împărţirea
intervalelor. Ea se obţine din intersecţia coardei care uneşte punctele de la
capetele curbei cu axa Ox.

Punctul c se află la intersecţia coardei care uneşte punctele (a, f(a)) şi


(b, f(b)) cu axa Ox. Acest punct se determină rezolvând sistemul:
 y  f (a ) f ( b)  f ( a )
 
 xa ba

y  0

soluţia fiind bineînţeles x = c. După determinarea punctului c se determină


în care subinterval se află soluţia şi se face substituţia a = c, sau b = c, şi se
repetă acest algoritm până când se obţine |f(c)|<.

Algoritmul este identic cu cel prezentat mai sus, singurele deosebiri


fiind la punctul 4 unde se schimbă formula de calcul pentru c şi la testul
final.
package ecuatiineliniare;

public class secanta {

/**
* @param args

*/
public static double f(double x){
return Math.log(x)+x;
}

2
public static void main(String[] args) {
// TODO Auto-generated method stub
/// se declara variabilele a, b, c, eps
double a = 0.001, b=2, c, eps = 1e-6;
if(f(a)*f(b) < 0){
do{
/// se calculeaza c=(a+b)/2
c = a-f(a)*(b-a)/f(b)-f(a);

/// daca f(a)*f(c) < 0 atunci b=c, altfel a=c


if(f(a)*f(c)<0){
b=c;
} else {
a=c;
}
}
while(Math.abs(f(c))>eps);
/// daca |f(c)| < eps atunci se scrie radacina
System.out.println("Metoda injumatatirii
intervalului");
System.out.println("Radacina = "+Double.toString(c));
} else {
System.out.println("Interval ales gresit!!!");
}
}

Rezolvarea unui sistem de ecuaţii liniare

3
Pentru rezolvarea sistemelor de ecuaţii liniare există mai multe
metode, unele exacte, altele aproximative. Pentru sistemele cu număr mare
de ecuaţii metodele aproximative sunt mai eficiente, deoarece sunt mai rapid
convergente. Metodele exacte se bazează pe transformarea matricilor
coeficienţilor şi de aceea sunt indicate în cazul sistemelor mai mici de
ecuaţii.
Un sistem de ecuaţii liniare se poate scrie sub formă matricială astfel:
 a11 a12 . a1n   x1   b1 
     
 a 21 a 22 . a 2 n   x 2   b2 
 
 . . . .   .  .
     
 a n1 an2 . a nn   x n   bn 
sau mai simplu:
A X  B
unde A este o matrice pătrată şi se numeşte matricea coeficienţilor, X este
vectorul necunoscutelor, iar B este vectorul termenilor liberi.
Una din metodele exacte de rezolvare a sistemelor de ecuaţii liniare
are la bază transformarea succesivă a matricii coeficienţilor astfel încât să se
obţină 1 pe diagonala principală şi 0 sub diagonală. Acest lucru se obţine
prin înmulţirea la stânga cu o matrice M pătrată convenabil aleasă, în mai
multe etape. Astfel în urma primei înmulţiri se va obţine 0 pe prima coloană,
cu excepţia primului coeficient, care va fi 1.
 1 a12
'
. a1' n   x1   b1' 
 '
    
 0 a 22 . a'2 n   x 2   b2' 
. .  
. .   .  .
     
 0 a'n 2 . a'nn   x n   bn' 
După cea de-a doua înmulţire se va transforma coloana a doua.
 1 "
a 12 . "
a1   x1 
 "
n
  
 0 1 . a2n  x2
 .     
. . .  . 
   
 0 0 . a"
nn   xn 
Se repetă tot acest proces până la ultima coloană. Pentru a nu se
modifica vectorul termenilor liberi, matricea M se va înmulţi şi cu matricea
coloană B.
In urma efectuării ultimei înmulţiri sistemul va arăta astfel:
 1 a12 . a1n   x1   b1 
     
0 1 . a 2 n   x 2   b2 
 
. . . .   .  .
     
0 0 . 1   x n   bn 

4
Matricea M îşi va modifica forma de fiecare dată. Astfel, pentru
transformarea coloanei j a matricii A, termenii matricei M se vor calcula
după cum urmează:
 matricea M va fi identică cu matricea unitate, mai puţin coloana j.
 pentru coloana j deasupra diagonalei termenii vor fi egali cu 0.
 termenul de pe diagonală va fi: m[j][j] = 1 / a[j][j].
 termenii de sub diagonală vor fi: m[i][j] = -a[i][j] / a[j][j].
1 . 0 . 0
 
. . 0 . .
. 1
. . .
 a jj 
M  aij 
. .  . .
 a jj 
 a nj 
0 .  . 1
 a jj
 
In aceste relaţii a[i][j] reprezintă elementele matricii A.
După ce matricea coeficienţilor a fost transformată se calculează
vectorul necunoscutelor X în ordine descrescătoare cu relaţia:
n
xi  bi  a ij xj ; i  n ,1
j  i 1

Algoritmul de rezolvare a sistemelor de ecuaţii prin această metodă


este reprezentat mai jos:

1. Se declară matricea pătrată A[n][n] şi vectorul termenilor liberi B[n]


2. j = 1
3. Se calculează matricea M pentru coloana j.
4. Se înmulţeşte matricea M cu matricea A. Rezultatul i se va atribui matricii
A.
5. Se înmulţeşte matricea M cu vectorul B. Rezultatul i se va atribui
vectorului B.
6. Dacă j < n se măreşte j cu o unitate şi se reia de la pasul 3. Dacă nu, se
trece la pasul 7.
7. Se calculează vectorul necunoscutelor x[i].
8. Se afişează vectorul necunoscutelor x[i].
package sisteme;

public class EliminareGauss {

public static void main(String[] args) {

// se declara matricile a si b ca date de intrare

5
double[][] a = {{1, 2, 1, 3, 4},
{2, 1, 5, 9, 8},
{5, 0, 6, 4, 3},
{2, 5, 8, 9, 8},
{7, 3, 4, 2, 7}};
double[] b = {11, 25, 18, 32, 23};
// se declara variabilele m, a_aux, x, b_aux
double[][] m= new double[5][5];
double[][] a_aux=new double[5][5];
double[] x= new double[5];
double[] b_aux= new double[5];
// se declara variabilele i, j, k, pas, n
int i, j, k, pas, n=5;
// pentru pas de la primul pana la ultimul
for(pas=0; pas<n; pas++){
// se construieste matricea m pentru pasul pas
for(i=0; i<n; i++){
for(j=0; j<n; j++)
m[i][j] = 0;
m[i][i] = 1;
}
m[pas][pas]=1/a[pas][pas];
for(i=pas+1; i<n; i++)
m[i][pas] = -a[i][pas] / a[pas][pas];
// se inmulteste matricea m cu a
for(i=0; i<n; i++)
for(j=0; j<n; j++){
a_aux[i][j] = 0;
for(k=0; k<n; k++)
a_aux[i][j] += m[i][k] * a[k][j];
}
// rezultatul se va atribui lui a
for(i=0; i<n; i++)
for(j=0; j<n; j++)
a[i][j] = a_aux[i][j];

// for(i=0; i<n; i++){


// for(j=0; j<n; j++)
// System.out.print("\t"+ Double.toString(a[i]
[j]));
// System.out.print("\n");
// }

// se inmulteste matricea m cu b
for(i=0; i<n; i++){
b_aux[i] = 0;
for(k=0; k<n; k++)
b_aux[i] += m[i][k] * b[k];
}
// rezultatul se va atribui lui b
for(i=0; i<n; i++)
b[i] = b_aux[i];
// se trece la pasul urmator
}

// se afiseaza matricea a transformata


for(i=0; i<n; i++){

6
for(j=0; j<n; j++)
System.out.print(a[i][j]);
System.out.println("");
}
for(i=0; i<n; i++)
System.out.println(b[i]);
// se calculeaza vectorul x
for(i=n-1; i>=0; i--){
x[i] = b[i];
for(j=i+1; j<n; j++)
x[i] -= a[i][j] * x[j];
}
// se afiseaza vectorul x
for(i=0; i<n; i++)
System.out.println(x[i]);
}

Interpolarea liniară a unei funcţii

7
Atunci când se cunoaşte expresia analitică a unei funcţii y = f(x) unde
x ia valori pe un domeniu, se poate calcula valoarea ei pentru orice x din
domeniul de definiţie. In realitate de multe ori apar cazuri când nu se
cunoaşte expresia analitică, ci doar câteva puncte prin care trece funcţia
respectivă. Se pune problema de a determina valoarea funcţiei şi pentru alte
valori intercalate între punctele date. Aceasta constituie interpolarea.
Cea mai simplă metodă este interpolarea liniară. Ea prezintă
dezavantajul că aproximează cel mai grosolan o funcţie prin segmente de
dreaptă, dar este cea mai rapidă pentru că efectuează cele mai puţine calcule.
Dacă se dau două puncte (x1, y1) şi (x2, y2), ecuaţia dreptei care trece
prin aceste puncte este:
y  y1 y 2  y1

x  x1 x 2  x1

Cu această relaţie se poate calcula valoarea y pentru orice punct x


aflat între cele două puncte x1 şi x2:

x  x1
y  y1    y 2  y1 
x 2  x1

In cazul în care se dau mai multe puncte, se procedează la liniarizarea


pe porţiuni. Astfel se iau două câte două puncte şi se aplică formula de mai
sus.

Algoritmul de programare se poate reprezenta astfel:

1. Se declară numărul de puncte cunoscute n.


2. Se declară valorile lui x şi y pentru punctele cunoscute: x[i] şi y[i] pentru i
= 0..n-1.
3. Se citeşte valoarea lui x în care vrem să determinăm funcţia y.
4. Intr-un ciclu for cu j luând valori de la 0 la n-2 se compară dacă x > x[j] şi
x < x[j+1], pentru a şti în care subinterval ne aflăm. Valoarea lui j pentru
care se satisface condiţia se memorează într-o variabilă k.
5. Se calculează y cu relaţia de mai sus unde x 1 = x[k], y1 = y[k], x2 =
x[k+1], y2 = y[k+1].
6. Se scrie y
7. STOP

Interpolarea Spline

8
La interpolarea Lagrange gradul polinomului care se obţine este cu atât mai
mare cu cât numărul de puncte este mai mare. Aceasta implică un număr
mare de calcule. Spre deosebire de polinoamele Lagrange, în cazul funcţiilor
Spline se lucrează cu un polinom de gradul trei pentru a accelera viteza de
calcul.
Forma generală a unui polinom de gradul III este: P(t) = at 3 + bt2 + ct
+ d. Acest lucru se poate scrie sub formă matricială astfel:

t 3 
 2
t
P a b c d   
t 
 
1
In plan un punct este reprezentat prin coordonatele x(t) şi y(t), iar în
spaţiu intervine şi coordonata z(t). In continuare se va lucra doar în funcţie
de parametrul t, urmând ca în final să se treacă la coordonatele x şi y. Se pot
aranja lucrurile astfel încât pentru cele două puncte de la capetele unui
interval să se obţină o reprezentare astfel: pentru primul punct să-i
corespundă lui t valoarea 0, iar pentru al doilea punct să-i corespundă lui t
valoarea 1.
Coeficienţii a, b, c, d se obţin din 4 condiţii şi anume la capetele
intervalului se dau şi valorile coordonatelor punctelor şi derivatele, pentru a
se obţine racordarea graficului. Aceasta înseamnă că se cunosc P(0), P(1),
P'(0) şi P'(1), unde P'(t) este polinomul derivat: P'(t) = 3at 2 + 2bt + c. Din
cele patru condiţii se obţin coeficienţii:
a  2 P (1)  P  (1)  P  ( 0)  2 P ( 0)
b  3 P (1 )  P  (1)  2 P  ( 0)  3 P ( 0)


c  P  ( 0)
d
  P ( 0)

care se pot scrie sub formă matricială:

2 3 0 1
 2 3 0 0
a b c d    P ( 0) P (1) P  ( 0) P  (1)  
1 2 1

0
 
1 1 0 0

In aceste condiţii polinomul P devine:

9
2 3 0 1  t 3 
 2 3 0 0 t 2 
P (t )   P (0) P (1) P  (0) P (1)   
1 2 1 0  t 
   
1 1 0 0  1 
In practică această relaţie se foloseşte astfel:
 se dau punctele de la marginea intervalului, adică P(0) şi P(1)
 se dau sau se calculează derivatele la capetele intervalului P'(0) şi P'(1)
 se alege un număr de puncte în care vrem să interpolăm funcţia dându-i
valori echidistante lui t în intervalul [0,1]
 Se calculează polinomul P(t) în aceste puncte
Dacă avem mai multe intervale, se aplică acelaşi algoritm pentru
fiecare interval luat în parte.
La reprezentarea în plan polinomul P este de fapt un vector cu două
componente x(t) şi y(t), iar la reprezentarea în spaţiu este un vector cu trei
componente x(t), y(t) şi z(t).
Pentru calculul derivatei într-un punct se consideră dreptele care se
obţin unind punctul respectiv cu cele două puncte vecine, din stânga şi din
dreapta. Se face media unghiurilor acestor drepte cu axa Ox orizontală,
obţinându-se unghiul . Componentele polinomului derivat vor fi x' =
k·cos() şi y' = k·sin (), unde k se alege în urma unor încercări. Valorile
uzuale sunt între 1 şi 3. (Observaţie: pentru valoarea k=0 se obţine chiar
interpolarea liniară). Pentru punctele extreme vom avea doar un singur
vecin, şi se ia unghiul respectiv.

Algoritmul de interpolare cu funcţii Spline va fi următorul:

1. Se dau n puncte în care se cunoaşte funcţia


2. Se dă numărul de puncte m în care vrem să determinăm funcţia interpolată
3. Se calculează derivatele în punctele cunoscute
4. Se deschide un ciclu for cu i de la 0 până la n-1
5. Punctul corespunzător lui t = 0 va fi cel cu indicele i, iar pentru t = 1 va fi
cel cu indicele i+1, şi se vor lua ca atare polinoamele P şi P'.
6. Se deschide un ciclu for cu j de la 0 până la m
7. Se calculează t = j / m
8. Se calculează x(t) şi y(t) cu ultima relaţie, unde x(t) şi y(t) sunt
componentele polinomului P(t)
9. Se închide ciclul cu j
10. Se închide ciclul cu i.
11. STOP

10
package interpolare;

public class Spline {

// Se dau n puncte �n care se cunoaste functia


double[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
double[] y = {9, 8, 5, 8, 4, 6, 2, 3, 5, 1};
int n=10;
// Se da numarul de puncte m �n care vrem sa determinam functia
interpolata
int m=50;

double[] xArray = new double[500];


double[] yArray = new double[500];
int nrPuncte;

void setNrPuncte(int nr){


nrPuncte = nr;
}
int getNrPuncte(){
return nrPuncte;
}

public Spline(){
double[][] M1 = new double[2][4];
double[][] M2 = {{2, -3, 0, 1},
{-2, 3, 0, 0},
{1, -2, 1, 0},
{1, -1, 0, 0}};
double[] M3 = new double[4];
double[] M23 = new double[4];
double xx, yy;
int crt=0;

// Se calculeaza derivatele �n punctele cunoscute


double alfa1=0;
double alfa2=0;
double alfa=0;
double s=2;
double[] xp = new double[10];
double[] yp = new double[10];

for(int i=0; i<n; i++){


if(i>0)
alfa1 = Math.atan2((y[i]-y[i-1]),(x[i]-x[i-1]));
if(i<(n-1))
alfa2 = Math.atan2((y[i+1]-y[i]),(x[i+1]-x[i]));
if(i==0)
alfa = alfa2;
else if(i==(n-1))
alfa = alfa1;
else
alfa = (alfa1 + alfa2)/2;
xp[i] = s*Math.cos(alfa);
yp[i] = s*Math.sin(alfa);

11
}
// Se deschide un ciclu for cu i de la 0 p�na la n-1
for(int i=0; i<(n-1); i++){
// Punctul corespunzator lui t = 0 va fi cel cu indicele i, iar
pentru t = 1 va fi cel cu indicele i+1, si se vor lua ca atare
polinoamele P si P'.
M1[0][0]=x[i]; M1[0][1]=x[i+1]; M1[0][2]=xp[i]; M1[0]
[3]=xp[i+1];
M1[1][0]=y[i]; M1[1][1]=y[i+1]; M1[1][2]=yp[i]; M1[1]
[3]=yp[i+1];

// Se deschide un ciclu for cu j de la 0 p�na la m


for(int j=0; j<m; j++){
// Se calculeaza t = j / m
double t=(double)j/m;
M3[0] = t*t*t; M3[1] = t*t; M3[2] = t; M3[3]
= 1;

// Se calculeaza x(t) si y(t) cu ultima relatie,


unde x(t) si y(t) sunt componentele polinomului P(t)
for(int k=0; k<4; k++){
M23[k]=0;
for(int l=0; l<4; l++){
M23[k] += M2[k][l]* M3[l];
}
}
xx = 0;
yy = 0;
for(int k=0; k<4; k++){
xx += M1[0][k]*M23[k];
yy += M1[1][k]*M23[k];
}
xArray[crt] = xx;
yArray[crt] = yy;
crt++;
// Se inchide ciclul cu j
}
// Se inchide ciclul cu i.
}
setNrPuncte(crt);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Spline sp = new Spline();
for(int i=0; i<sp.getNrPuncte(); i++){
System.out.println(Double.toString(sp.xArray[i])
+"\t"+Double.toString(sp.yArray[i]));
}
}

}
Desenarea graficului functiei
package interpolare;

12
import java.awt.*;
import javax.swing.*;

public class GraficSpline extends JFrame {

/**
*
*/
private static final long serialVersionUID = 1235237784941049108L;
int Xmax = 800;
int Ymax = 600;
int XScale = 50;
int YScale = 50;

public GraficSpline(){
this.setSize(Xmax, Ymax);
}

public void paint(Graphics g){


super.paint(g);
g.draw3DRect(10, 30, Xmax - 20, Ymax - 40, true);
Spline sp = new Spline();
int x0, y0, x1, y1;
int xOffset = (Xmax - XScale*10)/2;
int yOffset = Ymax - (Ymax - YScale*10)/2;
for(int i=0; i<(sp.getNrPuncte()-1); i++){
x0 = xOffset + (int)(XScale*sp.xArray[i]);
y0 = yOffset - (int)(YScale*sp.yArray[i]);
x1 = xOffset + (int)(XScale*sp.xArray[i+1]);
y1 = yOffset - (int)(YScale*sp.yArray[i+1]);
g.drawLine(x0, y0, x1, y1);
if(i%50 == 0){
g.drawOval(x0-2, y0-2, 4, 4);
}
if(i == (sp.getNrPuncte()-2)){
g.drawOval(x1-2, y1-2, 4, 4);
}
}
}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
GraficSpline grSp = new GraficSpline();
grSp.setVisible(true);
}

13
Integrarea numerică

In cazurile în care trebuie calculată integrala definită a unei funcţii,


aceasta se poate calcula analitic, sau numeric. Din păcate, nu toate funcţiile
sunt uşor de integrat, de aceea metodele numerice se folosesc din ce în ce
mai mult. Dezavantajele metodelor numerice de integrare constau în faptul
că ele nu sunt exacte şi introduc erori, dar aceste erori pot fi evaluate şi
minimizate pe cât posibil. Aceste erori depind de metoda folosită. Cea mai
simplă dintre metodele de integrare este metoda dreptunghiurilor.
Integrala definită a unei funcţii f(x) pe un interval [a,b] reprezintă aria
de sub grafic. In cadrul metodelor numerice de integrare se aleg nişte puncte

14
xi, echidistante pe intervalul dat, şi aria graficului se împarte astfel în fâşii
paralele. La metoda dreptunghiurilor se aproximează aria unei fâşii cu aria
dreptunghiului corespunzător, iar întreaga integrală va fi suma ariilor acestor
fâşii. Dacă intervalul corespunzător este [xi, xi+1], atunci aria dreptunghiului
respectiv este:

Si   xi 1  xi   f ( xi )

în cazul în care înălţimea dreptunghiului este valoarea funcţiei din stânga


intervalului. Dacă se alege valoarea din dreapta intervalului, în formula de
mai sus se va înlocui f(xi) cu f(xi+1). O altă variantă este cea cu valoarea de la
mijlocul intervalului f((xi+xi+1)/2). Aceste variante se pot vedea în figura de
mai jos.

O altă metodă este cea a trapezelor, caz în care aria fâşiei se


înlocuieşte cu aria unui trapez. In acest caz se obţine:

15
f ( x i )  f ( x i 1 )
S i   x i 1  x i  
2

In acest caz eroarea de aproximare a integralei este mai mică decât la metoda
dreptunghiurilor. Dacă se aproximează graficul funcţiei pe intervalul [xi, xi+1]
cu o parabolă se obţine metoda lui Simpson, caz în care formula de calcul
este:

xi  xi 1
f ( xi )  2 f ( )  f ( x i 1 )
Si  ( xi 1  xi )  2
4

La formula lui Simpson eroarea de aproximare este cea mai mică.

Algoritmul de integrare numerică este următorul:

1. S declară funcţia care trebuie integrată şi intervalul [a,b] de definiţie


2. Se alege numărul de puncte n al reţelei şi se calculează pasul reţelei: h =
(b-a) / n.
3. Se iniţializează I = 0.
4. Se deschide un ciclu for cu i de la 0 la n-1 inclusiv.
5. Se calculează xi = a + i * h şi xi+1 = xi + h.
6. Se calculează I = I + S unde S se calculează cu una din formulele descrise
mai sus.
7. Se închide ciclul.
8. Se scrie I.
9. STOP
package integrare;

public class Trapez {

/**
* @param args
*/

public static double fct(double x){


double rez;
rez = Math.sin(x);
return rez;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int n=500;
double a=0;
double b=Math.PI;

16
double h=(b-a)/n;
double x;
double integrala=0;
double integ2 = 0;
for(int i=0; i<n; i++){
x = a + i*h;
integrala += (fct(x) + fct(x+h)) / 2;
if((i%2)==0){
integ2 += (fct(x) + fct(x+2*h)) / 2;
}
}
integrala *= h;
integ2 *= 2*h;
System.out.println("Rezultatul = "+
Double.toString(integrala));
System.out.println("Rezultatul 2 = "+
Double.toString(integ2));
System.out.println("Rezultatul corectat = "+
Double.toString(integrala + (integrala - integ2)/3));
}}

Rezolvarea ecuaţiilor diferenţiale prin metoda Runge-Kutta


dy
O ecuaţie diferenţială se poate pune sub forma  f ( t , y ) şi
dt
reprezintă tangenta la graficul funcţiei y(t) care trebuie determinată. Spre
deosebire de metodele analitice la care rezolvarea înseamnă determinarea
expresiei analitice, la metodele numerice se determină valorile lui y pentru
valorile discretizate ale lui t. Astfel intervalul de definiţie al lui t se împarte
într-un număr de subintervale cu pasul h, iar valorile discretizate ale lui t se
vor nota cu ti. Pentru rezolvare trebuie cunoscute de asemenea condiţiile
iniţiale, adică valoarea lui y la momentul t = 0. Cunoscând tangenta la grafic
se determină punctul următor şi procesul se repetă.
Relaţia care determină valoarea yi+1 în funcţie de yi la metoda Runge-
Kutta de ordinul 4 este:
h
y i 1  y i   k1  2 k 2  2 k 3  k 4 
6
unde:
k 1  f ( t i , yi )
 h h
k 2  f  t i  , yi  k 1 
 2 2
 h h
k 3  f  t i  , yi  k 2 
 2 2
k 4  f  t i  h, y i  k 3 h 
Eroarea depinde de pasul h, de aceea este bine să se aleagă un pas cât
mai mic, dar nu foarte mic pentru a nu creşte timpul de calcul. Pentru

17
început se va împărţi intervalul lui t în 50 de subintervale, urmând ca după
aceea să se aleagă mai multe puncte dacă este posibil.
Algoritmul de rezolvare prin această metodă se poate concretiza
astfel:
1. Se declară funcţia f(t,y) şi intervalul de definiţie [a,b] pentru t.
2. Se scrie condiţia iniţială y(0).
3. Se alege numărul de puncte n
4. Se calculează pasul h=(b-a)/n.
5. Se deschide un ciclu for cu i de la 0 la n-1
6. Se calculează k1, k2, k3, k4.
7. Se calculează yi+1 cu relaţia de mai sus.
8. Se scrie valoarea lui yi+1.
9. Se închide ciclul.
package ecuatiidiferentiale;

public class RungeKutta {

/**
* @param args
*/
int n=100;
static double[] xArray = new double[100];
static double[] yArray = new double[100];

public static double u(double t){


double frecventa = 50;
return 10*Math.sin(2*Math.PI*frecventa*t);
}

public static double f(double t, double y){


double R = 0.1, L = 0.001;
return (u(t) - R*y)/L;
}

public RungeKutta(){
int i;
double t = 0, tf = 0.1, y=0, h, k1, k2, k3, k4;
h = (tf - t) / n;
for(i=0; i<n; i++){
t = i*h;
k1 = f(t, y);
k2 = f(t+h/2, y+k1*h/2);
k3 = f(t+h/2, y+k2*h/2);
k4 = f(t+h, y+k3*h);
y += h/6 * (k1+2*k2+2*k3+k4);
xArray[i] = t+h;
yArray[i] = y;
}

18
double getXmax(){
double xmax = 0;
for(int i=0; i<n; i++){
if(xmax < xArray[i]) xmax = xArray[i];
}
return xmax;
}

double getXmin(){
double xmin = 0;
for(int i=0; i<n; i++){
if(xmin > xArray[i]) xmin = xArray[i];
}
return xmin;
}

double getYmax(){
double ymax = 0;
for(int i=0; i<n; i++){
if(ymax < yArray[i]) ymax = yArray[i];
}
return ymax;
}

double getYmin(){
double ymin = 0;
for(int i=0; i<n; i++){
if(ymin > yArray[i]) ymin = yArray[i];
}
return ymin;
}

public static void main(String[] args) {


// TODO Auto-generated method stub
RungeKutta rk = new RungeKutta();
for(int i=0; i<rk.n; i++){

System.out.println(Double.toString(RungeKutta.xArray[i])
+"\t"+Double.toString(RungeKutta.yArray[i]));
}
}

Desenarea graficului functiei


package ecuatiidiferentiale;

import java.awt.*;
import javax.swing.*;

public class GraficRungeKutta extends JFrame {

/**
* @param args
*/
private static final long serialVersionUID = 1235237784941049199L;

19
int Xmax = 800;
int Ymax = 600;
int XScale = 500;
int YScale = 250;
int xOffset = 150;
int yOffset = 300;

public GraficRungeKutta(){
this.setSize(Xmax, Ymax);
}

public void paint(Graphics g){


super.paint(g);
g.draw3DRect(10, 30, Xmax - 20, Ymax - 40, true);
g.draw3DRect(50, 50, 700, 500, true);
RungeKutta rk = new RungeKutta();
g.drawLine(50, yOffset-10, 750, yOffset-10);
g.drawLine(155, 50, 155, 550);
int x0, y0, x1, y1;
double xmax = rk.getXmax();
double ymax = rk.getYmax();
double ymin = rk.getYmin();
if(ymax < Math.abs(ymin)) ymax = Math.abs(ymin);
for(int i=0; i<(rk.n-1); i++){
x0 = xOffset + (int)
(XScale*RungeKutta.xArray[i]/xmax);
y0 = yOffset - (int)
(YScale*RungeKutta.yArray[i]/ymax);
x1 = xOffset + (int)
(XScale*RungeKutta.xArray[i+1]/xmax);
y1 = yOffset - (int)
(YScale*RungeKutta.yArray[i+1]/ymax);
g.drawLine(x0, y0, x1, y1);
}
}

public static void main(String[] args) {


// TODO Auto-generated method stub
GraficRungeKutta grk = new GraficRungeKutta();
grk.setVisible(true);
}

20
Rezolvarea sistemelor de ecuaţii diferenţiale prin metoda Runge-Kutta

Un sistem de ecuaţii diferenţiale se poate pune sub forma:

dyi
 f i ( t , y1 , y 2 ,.., yn ), i  1.. n
dt

Spre deosebire de cazul unei singure ecuaţii diferenţiale, la sistemele de ecuaţii


diferenţiale, coeficienţii de la metoda Runge-Kutta vor fi nişte vectori cu n valori. Astfel
în relaţia care determină setul de valori la momentul următor de timp în funcţie de în
funcţie de valorile la momentul actual de timp:

h
y i 1  y i   k1  2 k 2  2 k 3  k 4 
6
mărimile y şi k1, k2, k3, k4 vor fi nişte vectori cu n valori:

k1, j  f j (t i , yi , j )
 h h
k 2 , j  f j  t i  , yi , j  k 1, j 
 2 2
 h h
k 3, j  f j  t i  , y i , j  k 2 , j 
 2 2

k 4 , j  f j t i  h , y i , j  k 3, j h 
Algoritmul de rezolvare prin această metodă se poate concretiza astfel:

1. Se declară funcţiile fi(t,yj) şi intervalul de definiţie [a,b] pentru t.


2. Se scrie condiţia iniţială yi(0).
3. Se alege numărul de puncte n
4. Se calculează pasul h=(b-a)/n.
5. Se deschide un ciclu for cu i de la 0 la n-1
6. Se deschide un ciclu for cu j de la 1 la numărul de ecuaţii diferenţiale.

21
7. Se calculează k1
8. Se deschide un ciclu for cu j de la 1 la numărul de ecuaţii diferenţiale.
9. Se calculează k2
10. Se deschide un ciclu for cu j de la 1 la numărul de ecuaţii diferenţiale.
11. Se calculează k3
12. Se deschide un ciclu for cu j de la 1 la numărul de ecuaţii diferenţiale.
13. Se calculează k4
14. Se calculează yi+1 cu relaţia de mai sus.
15. Se scrie valoarea lui yi+1.
16. Se închide ciclul pentru i.
17. STOP
package ecuatiidiferentiale;

public class SistemRungeKutta {

/**
* @param args
*/

static double R = 0.1, L = 0.001, C=0.001;


static double[] xArray = new double[100];
static double[][] yArray = new double[2][100];
int n=100;

public static double u(double t){


double frecventa = 50;
// return 10*Math.sin(2*Math.PI*frecventa*t);
return 10;
}
public static double f1(double t, double y1, double y2){
return y2/C;
}
public static double f2(double t, double y1, double y2){
return (u(t) - R*y2 - y1)/L;
}

double getXmax(){
double xmax = 0;
for(int i=0; i<n; i++){
if(xmax < xArray[i]) xmax = xArray[i];
}
return xmax;
}

double getXmin(){
double xmin = 0;
for(int i=0; i<n; i++){
if(xmin > xArray[i]) xmin = xArray[i];
}
return xmin;
}

double getYmax(){

22
double ymax = 0;
for(int i=0; i<n; i++){
if(ymax < yArray[0][i]) ymax = yArray[0][i];
}
return ymax;
}

double getYmin(){
double ymin = 0;
for(int i=0; i<n; i++){
if(ymin > yArray[0][i]) ymin = yArray[0][i];
}
return ymin;
}

public SistemRungeKutta(){
int i;
double t = 0, tf = 0.05, h;
double[] y={0, -10};
double[] k1=new double[2];
double[] k2=new double[2];
double[] k3=new double[2];
double[] k4=new double[2];
h = (tf - t) / n;
for(i=0; i<n; i++){
t = i*h;
k1[0] = f1(t, y[0], y[1]);
k1[1] = f2(t, y[0], y[1]);
k2[0] = f1(t+h/2, y[0]+k1[0]*h/2, y[1]+k1[1]*h/2);
k2[1] = f2(t+h/2, y[0]+k1[0]*h/2, y[1]+k1[1]*h/2);
k3[0] = f1(t+h/2, y[0]+k2[0]*h/2, y[1]+k2[1]*h/2);
k3[1] = f2(t+h/2, y[0]+k2[0]*h/2, y[1]+k2[1]*h/2);
k4[0] = f1(t+h, y[0]+k3[0]*h, y[1]+k3[1]*h);
k4[1] = f2(t+h, y[0]+k3[0]*h, y[1]+k3[1]*h);
for(int j=0; j<2; j++){
y[j] += h/6 * (k1[j]+2*k2[j]+2*k3[j]+k4[j]);
yArray[j][i] = y[j];
}
xArray[i] = t+h;
}

public static void main(String[] args) {


// TODO Auto-generated method stub
SistemRungeKutta srk = new SistemRungeKutta();
for(int i=0; i<srk.n; i++){

System.out.println(Double.toString(SistemRungeKutta.xArray[i])
+"\t"+Double.toString(SistemRungeKutta.yArray[0][i])
+"\t"+Double.toString(SistemRungeKutta.yArray[1][i]));
}

23
Desenarea graficului functiei
package ecuatiidiferentiale;

import java.awt.*;
import javax.swing.*;

public class GraficSistemRungeKutta extends JFrame {

/**
* @param args
*/
private static final long serialVersionUID = 1235237784941049199L;
int Xmax = 800;
int Ymax = 600;
int XScale = 500;
int YScale = 250;
int xOffset = 150;
int yOffset = 300;

public GraficSistemRungeKutta(){
this.setSize(Xmax, Ymax);
}

public void paint(Graphics g){


super.paint(g);
g.draw3DRect(10, 30, Xmax - 20, Ymax - 40, true);
g.draw3DRect(50, 50, 700, 500, true);
SistemRungeKutta srk = new SistemRungeKutta();
g.drawLine(50, yOffset, 750, yOffset);
g.drawLine(155, 50, 155, 550);
int x0, y0, x1, y1;
double xmax = srk.getXmax();
double ymax = srk.getYmax();
double ymin = srk.getYmin();
if(ymax < Math.abs(ymin)) ymax = Math.abs(ymin);
for(int i=0; i<(srk.n-1); i++){
x0 = xOffset + (int)
(XScale*SistemRungeKutta.xArray[i]/xmax);
y0 = yOffset - (int)(YScale*SistemRungeKutta.yArray[0]
[i]/ymax);
x1 = xOffset + (int)
(XScale*SistemRungeKutta.xArray[i+1]/xmax);
y1 = yOffset - (int)(YScale*SistemRungeKutta.yArray[0]
[i+1]/ymax);
g.drawLine(x0, y0, x1, y1);
}
}

public static void main(String[] args) {


// TODO Auto-generated method stub
GraficSistemRungeKutta gsrk = new GraficSistemRungeKutta();
gsrk.setVisible(true);
}

24
25

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

  • AMSI Lab2.1
    AMSI Lab2.1
    Document7 pagini
    AMSI Lab2.1
    Andrei Barbalat
    Încă nu există evaluări
  • AMSI Lab5.colaborare
    AMSI Lab5.colaborare
    Document5 pagini
    AMSI Lab5.colaborare
    Andrei Barbalat
    Încă nu există evaluări
  • AMSI Lab6.Clasa
    AMSI Lab6.Clasa
    Document4 pagini
    AMSI Lab6.Clasa
    Andrei Barbalat
    Încă nu există evaluări
  • AMOO Lab2 Use Case
    AMOO Lab2 Use Case
    Document5 pagini
    AMOO Lab2 Use Case
    sergiu
    Încă nu există evaluări
  • AMSI Curs
    AMSI Curs
    Document74 pagini
    AMSI Curs
    Andrei Barbalat
    Încă nu există evaluări
  • AMSI Lab1.1
    AMSI Lab1.1
    Document3 pagini
    AMSI Lab1.1
    Andrei Barbalat
    Încă nu există evaluări
  • AMSI Lab7.Stari
    AMSI Lab7.Stari
    Document4 pagini
    AMSI Lab7.Stari
    Andrei Barbalat
    Încă nu există evaluări
  • Proiect de Curs AMSI
    Proiect de Curs AMSI
    Document24 pagini
    Proiect de Curs AMSI
    Andrei Barbalat
    Încă nu există evaluări
  • Rs PR
    Rs PR
    Document10 pagini
    Rs PR
    Andrei Barbalat
    Încă nu există evaluări
  • AMSI Lab8.activitati
    AMSI Lab8.activitati
    Document5 pagini
    AMSI Lab8.activitati
    Andrei Barbalat
    Încă nu există evaluări
  • AMSI Lab9.componente
    AMSI Lab9.componente
    Document4 pagini
    AMSI Lab9.componente
    Andrei Barbalat
    Încă nu există evaluări
  • AMSI Lab4.secventa
    AMSI Lab4.secventa
    Document5 pagini
    AMSI Lab4.secventa
    Andrei Barbalat
    Încă nu există evaluări
  • Examen
    Examen
    Document6 pagini
    Examen
    Andrei Barbalat
    Încă nu există evaluări
  • Etica Prof
    Etica Prof
    Document59 pagini
    Etica Prof
    MishaL94
    Încă nu există evaluări
  • GRUPUL
    GRUPUL
    Document21 pagini
    GRUPUL
    Maria Cucereavîi
    Încă nu există evaluări
  • Contra Man I Pul Are
    Contra Man I Pul Are
    Document5 pagini
    Contra Man I Pul Are
    Andrei Barbalat
    Încă nu există evaluări
  • Cerinte Proiect
    Cerinte Proiect
    Document4 pagini
    Cerinte Proiect
    Dumitru
    Încă nu există evaluări
  • Calităţi Personale Şi Comunicarea
    Calităţi Personale Şi Comunicarea
    Document25 pagini
    Calităţi Personale Şi Comunicarea
    Sergiu Dreglea
    50% (4)
  • L3 Sav
    L3 Sav
    Document3 pagini
    L3 Sav
    Andrei Barbalat
    Încă nu există evaluări
  • Lab 1 V11
    Lab 1 V11
    Document6 pagini
    Lab 1 V11
    Andrei Barbalat
    Încă nu există evaluări
  • Lab 2
    Lab 2
    Document6 pagini
    Lab 2
    Andrei Barbalat
    Încă nu există evaluări
  • Cerinte Proiect
    Cerinte Proiect
    Document4 pagini
    Cerinte Proiect
    Dumitru
    Încă nu există evaluări
  • MODEL PROIECT de An BAZE DE DATE
    MODEL PROIECT de An BAZE DE DATE
    Document7 pagini
    MODEL PROIECT de An BAZE DE DATE
    Andrei Barbalat
    Încă nu există evaluări
  • Lab 8
    Lab 8
    Document7 pagini
    Lab 8
    Andrei Barbalat
    Încă nu există evaluări
  • L.2 Sav
    L.2 Sav
    Document4 pagini
    L.2 Sav
    Andrei Barbalat
    Încă nu există evaluări
  • MODEL PROIECT de An BAZE DE DATE
    MODEL PROIECT de An BAZE DE DATE
    Document7 pagini
    MODEL PROIECT de An BAZE DE DATE
    Andrei Barbalat
    Încă nu există evaluări
  • Laboratorul1 SAV
    Laboratorul1 SAV
    Document8 pagini
    Laboratorul1 SAV
    Gold River
    100% (1)
  • Cinematic A
    Cinematic A
    Document147 pagini
    Cinematic A
    Natalia Chirca
    Încă nu există evaluări
  • Culegere de Probleme de Mecanica Teoretica
    Culegere de Probleme de Mecanica Teoretica
    Document488 pagini
    Culegere de Probleme de Mecanica Teoretica
    sady1967
    100% (1)