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
/**
* @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);
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
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];
// 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
}
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]);
}
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
x x1
y y1 y 2 y1
x 2 x1
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)
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
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.
10
package interpolare;
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;
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];
}
Desenarea graficului functiei
package interpolare;
12
import java.awt.*;
import javax.swing.*;
/**
*
*/
private static final long serialVersionUID = 1235237784941049108L;
int Xmax = 800;
int Ymax = 600;
int XScale = 50;
int YScale = 50;
public GraficSpline(){
this.setSize(Xmax, Ymax);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
GraficSpline grSp = new GraficSpline();
grSp.setVisible(true);
}
13
Integrarea numerică
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 )
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
/**
* @param args
*/
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));
}}
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;
/**
* @param args
*/
int n=100;
static double[] xArray = new double[100];
static double[] yArray = new double[100];
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;
}
System.out.println(Double.toString(RungeKutta.xArray[i])
+"\t"+Double.toString(RungeKutta.yArray[i]));
}
}
import java.awt.*;
import javax.swing.*;
/**
* @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);
}
20
Rezolvarea sistemelor de ecuaţii diferenţiale prin metoda Runge-Kutta
dyi
f i ( t , y1 , y 2 ,.., yn ), i 1.. n
dt
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:
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;
/**
* @param args
*/
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;
}
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.*;
/**
* @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);
}
24
25