Calcul Stiintific Java
Calcul Stiintific Java
JAVA IN
CALCULUL S
TIINT
IFIC
Brasov
2016
Cuprins
I
9
.
.
.
.
.
.
.
.
.
.
.
.
11
11
12
14
15
16
17
20
25
33
34
36
39
produse matematice
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
47
47
51
53
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
CUPRINS
6 Aplicatii cu interfat
a grafic
a
6.1 Rezolvarea unei ecuatii algebrice . . . . . . . . .
6.1.1 Interfata grafica bazata pe JavaFX . . .
6.2 Rezolvarea unui sistem algebric de ecuatii liniare
6.2.1 Interfata grafica bazata pe Swing . . . .
7 Generarea reprezent
arilor grafice
7.1 PtPlot . . . . . . . . . . . . . . .
7.2 jfreechart . . . . . . . . . . . . .
7.3 VisAD . . . . . . . . . . . . . . .
7.4 Vizualizarea functiilor complexe .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8 Aplicatii Web
8.1 Servlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.1.1 Codul unui servlet . . . . . . . . . . . . . . . . . . .
8.1.2 Program client al unui servlet . . . . . . . . . . . . .
8.1.3 Dezvoltarea unui servlet prin maven . . . . . . . . .
8.1.4 Servlet ca modul OSGi . . . . . . . . . . . . . . . . .
8.2 WebSocket . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.2.1 Interfata de programare HTML5 de client WebSocket
8.2.2 WebSocket n Java . . . . . . . . . . . . . . . . . . .
8.2.3 Client Java pentru WebSocket . . . . . . . . . . . . .
8.3 Google Web Toolkit (GWT) . . . . . . . . . . . . . . . . . .
8.3.1 Dezvoltarea unei aplicatii cu GWT . . . . . . . . . .
8.4 Desfasurarea n nor . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
83
83
84
86
86
.
.
.
.
.
.
.
.
91
91
95
100
108
.
.
.
.
.
.
.
.
.
.
.
.
125
. 127
. 128
. 132
. 133
. 135
. 138
. 138
. 140
. 144
. 145
. 146
. 155
.
.
.
.
9 Inc
arcarea unui fisier - upload
159
9.1 Preluarea unei matrice prin functii Javascript . . . . . . . . . . . . . . . . 159
9.2 FileUpload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
10 Servicii Web
10.1 Descrierea unui serviciu . . . . . . .
10.2 Modelul JAX-WS prin Metro . . .
10.2.1 Serviciu JAX-WS ca servlet
10.3 Modelul JAX-RS prin jersey . . . .
II
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
167
168
168
169
172
Programare paralel
a n Java
179
181
. 181
. 184
. 186
. 189
. 189
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
CUPRINS
209
CUPRINS
Prefat
a
Lucrarea de fata are ca obiectiv problematica legata de implementarea n Java a
aplicatiilor de calcul stiintific si este o versiune actualizata a lucrarii noastre, [10].
Din partea cititorului vom presupune existenta unor abilitati de programare n Java
si binenteles, cunostinte elementare de calcul numeric. Anumite parti din lucrare cer
cititorului familiarizarea cu un anumit produs informatic. Pentru fiecare produs utilizat,
Internetul ofera o multime de informatii privind instalarea, utilizarea, exemple, interfata
de programare, raspunsuri la ntrebari frecvente, etc.
Implementarea unei metode de calcul numeric bazat pe un algoritm iterativ este exemplificata prin crearea unei mini-biblioteci de programe numerice care este folosit pe
parcursul lucrari. Pentru configurarea si executarea sarcinilor se va utiliza cu precadere
apache-ant.
Vom pune n evidenta posibilitatea utilizarii n Java a resurselor oferite de produsele
matematice Mathematica, Maple si Scilab.
Utilizarea limbajului de programare Java n calculul stiintific este reprezentata prin
biblioteci de clase pentru rezolvarea unor probleme specifice domeniului. Lucrarea exemplifica doar folosirea pachetele apache commons-math si Jama.
O evidenta si observatii comparative a resurselor de calcul stiintific se gasesc pe Internet [13, 14].
Utilizarea unei functii definita printr-un sir de caractere este o problema de programare
specifica unei aplicatii de calcul numeric care se doreste utilizata prin intermediul unei
interfete grafice sau n mediu distribuit.
Interfetele grafice si aspecte privind vizualizarea unor obiecte matematice sunt de
asemenea atinse. Este dat un exemplu de interfata grafica programata n JavaFX, pachet
dezvoltat n ultimii ani, parte din distributia Java Development Kit - JDK. Se prezinta
solutii pentru vizualizarea graficului unei functii, prin intermediul unor produse specializate, integrabile n aplicatii Java.
Tipurile de aplicatii distribuite tratate n lucrare sunt aplicatiile Web bazate pe servlet
si serviciile Web dezvoltate pe modelul apelului de procedura la distanta (Remote Procedure Call) dar si serviciile REST. Exemplificarile utilizeaza pachetele metro si respectiv,
jersey. Prin utilizarea pachetului apache commons-fileupload este data o solutie pentru
ncarcarea unui fisier.
In prezent calculatoarele uzuale permit efectuarea de calcule n paralel prin unitatea
de procesare grafica (GPU). Exemplificam tehnica de programare n Java prin produsul
Aparapi, bazat pe OpenCL.
Codurile tuturor programelor din lucrare pot fi descarcate de la adresa
7
CUPRINS
https://github.com/e-scheiber/Scientific_Computing_and_Java.git.
Partea I
Programarea aplicatiilor numerice n
Java
Capitolul 1
Aplicatii numerice simple
Scopul acestui capitol este prezentarea unui mod de implementare n limbajul de programare Java a unor metode numerice. Se vor utiliza mai multe produse informatice
ajutatoare dar nu vom face apel la un mediu integrat de dezvoltare (Integrated Development Environment - IDE). Motivatia acestei optiuni este simpla: un mediu integrat de
dezvoltare acopera (ascunde, face transparenta) multe din activitatile care se ntreprind.
In plus, din punct de vedere educativ, nu dorim sa promovam un anumit mediu integrat
de dezvoltare n dauna altuia.
Pentru nceput ne propunem sa calculam:
1. Solutia negativa a ecuatiei 2x x2 = 0.
Ecuatia are 3 solutii x1 0.7666647 (1, 12 ), x2 = 2, x3 = 4;
R
2. Integrala 04 ln(1 + tan x)dx = 8 ln 2 0.2721983;
probleme pentru care se vor realiza programe simple. Apoi aceste programe vor fi dezvoltate pentru a putea trata un caz general si pentru a putea fi utilizate n mediu distribuit.
Rezolvarea numerica a unei probleme de calcul numeric conduce de multe ori la construirea unui sir (xk )kN , despre care se arata ca converge ntr-un sens catre solutia problemei. Rezultate privind evaluarea erorii, a vitezei de convergenta, a complexitatii unui
algoritm sunt factori care prezinta importanta n alegerea metodei de rezolvare numerica
a unei probleme.
Aspectele care ne intereseaza privesc implementarea metodelor de rezolvare numerica
utilizand limbajul de programare Java.
1.1
Una dintre proprietatile unui algoritm este finitudinea. Pentru aceasta este nevoie de
o regula de oprire. Spre exemplificare, n cadrul unei probleme numerice, o regula de
oprire simpla este:
Daca eroarea relativa (absoluta) a aproximatiei xk+1 = Y pentru xk = X este mai
mica decat un numar pozitiv eps, sau daca numarul de iteratii executate ni este egal cu
11
12
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
numarul maxim admis de iteratii nmi atunci programul se opreste; altfel se trece la o
noua iteratie.
Dupa oprirea calculelor, se pozitioneaza un indicator de raspuns ind pe 0, daca eroarea
relativa este mai mica decat eps, iar n caz contrar pe 1.
Numarul eps este denumit toleranta de calcul sau test de precizie.
Natura problemei poate impune si alte conditii pentru terminarea procesului de calcul
iar valoarea parametrului ind va preciza felul n care a avut loc oprirea calculului.
Pseudocodul algoritmului metodei iterative este
Algorithm 1 Pseudocodul metodei iterative
1.2
13
Derivata f 0 (x) a functiei date de membrul stang al ecuatiei, ntr-un punct, va fi calculata numeric utilizand extrapolarea Richardson, [3]. Se construieste tabloul subdiagonal
D0,0
D1,0
..
.
D1,1
..
.
Dm,0 Dm,1
..
.
. . . Dm,m
f (x +
h
)
2k
f (x
h
)
2k
h
2k
k = 0, 1 . . . , m;
4j
1
Dk,j1 j
Dk1,j1
j
4 1
4 1
j = 1, 2, . . . , m;
k = j, j + 1, . . . , m.
Calculul integralei
R
4
Pentru calculul integralei se va utiliza o schema adaptiva bazata pe metoda lui Simpson
[11]
Z
a
m1
m1
X
X
ba
f (x)dx =
[f (a) + 2
f (a2i ) + 4
f (a2i+1 ) + f (b)]
6m
i=1
i=0
(1.2)
14
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
(b a)5 (4)
f (),
2880m4
, i {0, 1, . . . , 2m}.
unde ai = a + i ba
2m
Practic, integrala se aproximeaza prin
m1
m1
X
X
ba
Jm =
[f (a) + 2
f (a2i ) + 4
f (a2i+1 ) + f (b)]
6m
i=1
i=0
ultimul termen din (1.2), denumit rest, se neglijeaza. Astfel apare o eroare de metoda care
se suprapune peste erorile de rotunjire datorate reprezentarii numerelor reale n virgula
mobila din memoria unui calculator si calculului aritmetic corespunzator.
Schema adaptiva consta din calculul unui sir (Jmk )k . Elementele sirului se calculeaza
pana la ndeplinirea unei conditii din regula de oprire. Sirul (mk )kN il vom defini prin
formula de recurenta mk+1 = 2mk .
In acest fel, daca notam prin S p , S i sumele
m
m
p
Sm
m1
X
f (a2i ) si
i=1
i
Sm
m1
X
f (a2i+1 )
i=0
p
i
i
p
.
. La fiecare noua iteratie va trebui calculata doar suma Sm+1
+ Sm
atunci Sm+1
= Sm
1.3
Probleme conexe
15
Verificarea rezultatelor obtinute. Fiind dat rezultatul, fiecare dintre problemele propuse este o problema de test. Rolul unei probleme de test este verificarea functionarii
programului de rezolvare, depistarea unor greseli. In acest sens vom utiliza produsul
junit.
Alt produs cu acelasi scop este TestNG.
Dezvoltarea aplicatiei, n sensul simplificarii operatiilor de compilare, arhivare, rularea problemelor de test, etc. Vom arata modul de folosire pentru
apache-ant. Se presupune ca toate resursele utilizate, cuprinse uzual n fisiere
cu extensia jar (j ava ar hive) sunt disponibile pe calculatorul local. Daca
calculatorul este conectat la Internet, atunci, folosind suplimentar apache-ivy,
resursele publice pot fi descarcate mpreuna cu toate dependintele si utilizate
prin apache-ant.
apache-maven 1 este un alt cadru de dezvoltare si gestiune a proiectelor (Project
management framework). Calculatorul pe care se dezvolta proiectul / aplicatia
trebuie sa fie conectat la Internet. Resursele necesare ndeplinirii diferitelor
sarcini (maven artifacts) sunt preluate din Internet si depuse ntr-un depozit
local maven (local repository). In prezent sunt ntretinute depozite publice
de resurse soft necesare dezvoltarii de aplicatii cu maven 2 iar dezvoltatorii de
instrumente soft au posibilitatea de a-si promova produsele prin depunerea
ntr-un depozit maven. Dintr-un asemenea depozit public resursele necesare
sunt descarcate n depozitul local.
1.3.1
Jurnalizare
import j a v a . u t i l . l o g g i n g . Logger ;
public c l a s s Exemplu{
s t a t i c Logger l o g g e r = Logger . g e t L o g g e r ( Exemplu . c l a s s . getName ( ) ) ;
6
7
8
9
10
11
Programul afiseaza
Jan 23, 2013 2:34:40 PM Exemplu main
SEVERE: SEVERE : Hello
Jan 23, 2013 2:34:40 PM Exemplu main
WARNING: WARNING : Hello
Jan 23, 2013 2:34:40 PM Exemplu main
INFO: INFO : Hello
1
2
16
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
Daca dorim ca rezultatele sa fie nscrise ntr-un fisier, de exemplu logging.txt atunci clasa
de mai sus se modifica n
1
2
3
4
6
7
import
import
import
import
u t i l . l o g g i n g . Logger ;
u t i l . logging . FileHandler ;
u t i l . l o g g i n g . SimpleFormatter ;
i o . IOException ;
public c l a s s Exemplu{
s t a t i c Logger l o g g e r = Logger . g e t L o g g e r ( Exemplu . c l a s s . getName ( ) ) ;
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
try {
F i l e H a n d l e r l o g g i n g F i l e = new F i l e H a n d l e r ( l o g g i n g . t x t ) ;
l o g g i n g F i l e . s e t F o r m a t t e r (new S i m p l e F o r m a t t e r ( ) ) ;
l o g g e r . addHandler ( l o g g i n g F i l e ) ;
}
catch ( IOException e ) {
System . out . p r i n t l n ( e . g e t M e s s a g e ( ) ) ;
}
l o g g e r . s e v e r e ( SEVERE : H e l l o ) ;
l o g g e r . warning ( WARNING : H e l l o ) ;
l o g g e r . i n f o ( INFO : H e l l o ) ;
}
9
10
11
12
13
14
15
16
17
18
19
20
21
22
java .
java .
java .
java .
1.3.2
17
import o r g . j u n i t . ;
import s t a t i c o r g . j u n i t . A s s e r t . ;
public c l a s s Exemplu{
public double r e z u l t a t = 1 . 0 ;
public double e p s=1e 6;
double g e t V a l u e ( ) {
return 1 . 0 0 0 0 0 0 1 ;
}
8
9
10
@Test
public void t e s t ( ) {
a s s e r t E q u a l s ( r e z u l t a t , getValue ( ) , eps ) ;
}
12
13
14
15
17
18
19
20
se obtine
JUnit version 4.5
.
Time: 0.03
OK (1 test)
1.3.3
Incepem aceasta sectiune prin a introduce cateva elemente privind sintaxa ntr-un
document xml pentru ca apache-ant face apel la un fisier xml.
XML
Extensible Markup Language (XML) reprezinta un limbaj pentru definirea marcajelor
de semantica, care mpart un document n parti identificabile n document.
Totodata XML este un meta-limbaj pentru definirea sintaxei de utilizat n alte domenii.
XML descrie structura si semantica si nu formatarea.
Structura unui document XML este
<?xml version="1.0" encoding="ISO-8859-1"?>
corpul documentului alcatuit din elemente
18
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
19
16
17
18
19
20
21
22
23
24
25
26
27
Amintim faptul ca reprezentarea obiectelor matematice prin elemente XML constituie subiectul a doua proiecte MathML si OpenMath. Obiectivul limbajului MathML este
reprezentarea unui text matematic ntr-un document HTML, n timp ce obiectivul proiectului OpenMath este reprezentarea semantica a datelor matematice pentru realizarea de
aplicatii cooperante ntre sisteme de calcul simbolic - CAS (Computer Algebra System).
apache-ant
Utilitarul apache-ant asigura executarea unui sir de comenzi de operare. Aceste
comenzi se nregistreaza ntr-un fisier de tip xml, cu denumirea build.xml. Astfel,
apache-ant se substituie unui fisier de comenzi bat n Windows sau unui script shell
din Linux/Unix. Avantajul obtinut consta n independenta fata de platforma de calcul
(Windows, Linux).
Instalarea consta n dezarhivarea fisierului descarcat din Internet.
Lansarea n executie necesita fixarea variabilei de mediu JAVA HOME, ce contine
calea la distributia Java. Lansarea se poate face prin urmatorul fisier de comenzi
set JAVA_HOME=. . .
set ANT_HOME=. . .
%ANT_HOME%\bin\ant.bat %1
Parametrul %1 acestui fisier de comenzi reprezinta obiectivul care se doreste a fi atins.
Daca se modifica denumirea sau locatia fisierului build.xml atunci fisierul de comenzi se
invoca cu optiunea -buildfile.
Un fisier build.xml corespunde unui proiect (project), alcatuit din unul sau mai multe
obiective (target). Atingerea fiecararui obiectiv consta din ndeplinirea uneia sau mai
multor sarcini (task). Apache-ant contine o familie predefinita de sarcini. Programatorul
are datoria fixarii atributelor sarcinilor. Manualul din documentatia produsului contine
descrierea atributelor cat si exemple. In general, o sarcina reprezinta o operatie executata
uzual n linia de comanda.
Atributele se dau, respectand sintaxa XML
numeAtribut = valoareAtribut
Astfel, un proiect apare sub forma
20
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
<project name="numeProiect"
default="obiectiv"
basedir="catalogDeReferinta">
<target name="numeObiectiv">
sarcini
</target>
. . . . . . .
</project>
Daca la apelarea lui Apache-ant lipseste parametrul optional atunci se va executa
obiectivul default.
Intr-un proiect se pot defini variabile prin elementul
<property name=numeVariabila value=valoareVariabila />
O variabila definita se va utiliza cu sintaxa ${numeVariabila}.
1.3.4
21
Nume sablon
Semnificatia
maven-archetype-quickstart aplicatie simpla
(sablonul implicit)
maven-archetype-webapp
aplicatie Web
Indeplinirea diferitelor obiective (generarea unui proiect, compilare, arhivare, testare,
etc) se obtin prin comenzi maven.
Comenzile maven sunt de doua tipuri:
Comanda maven
mvn -version
Semnificatia
afiseaza versiunea lui maven
(utila pentru verificarea functionarii lui maven)
mvn clean
sterge fisierele maven generate
mvn compile
compileaza sursele Java
mvn test-compile compileaza sursele Java care
realizeaza testele junit
mvn test
executa testul junit
mvn package
creaza o arhiva jar sau war
mvn install
depune arhiva jar sau war n depozitul local
22
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
Comanda maven
mvn -B archetype:generate
Semnificatia
genereaza structura de cataloage a proiectului
Optiunea -B are ca efect generarea
neinteractiva.
mvn -B archetype:generate \
-DgroupId=numelePachetuluiAplicatiei \
-DartifactId=numeleProiectului \
-DarchetypeArtifactId=numeS
ablon\
-Dversion=versiuneaProiectului
mvn
mvn
mvn
mvn
mvn
clean:clean
compiler:compile
surefire:test
jar:jar
install:install-file
mvn exec:java
mvn dependency:copy-dependencies
-Dexec.mainClass=clasaMetodeiMain
descarca n catalogul target resursele
declarate n dependencies.
Astfel comanda
mvn -B archetype:generate -DgroupId=unitbv.cs.calcul -DartifactId=hello -Dversion=1.0
genereaza arborescenta
hello
|--> src
|
|--> main
|
|
|-->
|
|
|
|
|
|
|
|
|
|
|
|
|
|--> test
|
|
|-->
|
|
|
|
|
|
|
|
|
|
|
|
|
pom.xml
java
|-->
|
|
|
unitbv
|--> cs
|
|--> calcul
|
|
| App.java
java
|-->
|
|
|
unitbv
|--> cs
|
|--> calcul
|
|
|
AppTest.java
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
23
App.java este programul Java HelloWorld iar AppTest.java este un program de verificare bazat pe junit.
Pentru testarea aplicatiei, din catalogul hello, se executa comenzile
mvn compile
mvn test
Aceasta varianta este avantajoasa n cazul n care proiectul include mai multe clase cu
metoda main.
Sarcina programatorul este acela de a nlocui aceste programe cu cele care rezolva
sarcinile proiectului. Pentru orice prelucrare toate dependintele trebuie sa se gaseasca
n depozitul local maven. Daca o dependinta (resursa jar) nu se gaseste n depozitul
local atunci resursa este cautata ntr-un depozit global si este descarcata n depozitul
global. Este sarcina programatorului sa declare toate dependintele necesare unei aplicatii.
Declararea se face ntr-un element <dependency>. Daca resursa este inaccesibila atunci
maven termina prelucrarea.
24
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
${compile_classpath}"/>
${runtime_classpath}"/>
${test_classpath}"/>
${plugin_classpath}"/>
In elementul <tasks> se definesc sarcinile ant care se doresc executate la comanda corespunzatoare prelucrarii etapei din evolutia proiectului maven - compile, package, install,
test, etc.
NUMERICA
1.4. O MINI-BIBLIOTECA
1.4
25
O mini-bibliotec
a numeric
a
Programele corespunzatoare metodelor de calcul (metoda tangentei si metoda Simpson) le vom include ntr-o mini-biblioteca. Aceasta biblioteca va fi valorificata n capitolele urmatoare, prin dezvoltarea de programe client cu interfete grafice prietenoase si
prin apelarea resurselor mini-bibliotecii de la distanta.
In timpul programarii apare problema transmiterii datelor catre campurile claselor sau
catre parametrii metodelor. Probleme apar si n cazul rezultatelor returnate de metode.
Deseori printre date se afla expresii ale unor functii matematice.
Semnalam urmatoarele posibilitati de programare a transmiterii datelor:
Datele - mai putin functiile - se transmit ca si parametri iar o functie se poate defini
ntr-o clasa care eventual implementeaza o interfata predefinita. O instanta a unei
asemenea clase se transmite de asemenea ca parametru. Aceasta solutie corespunde
modului de programare din Fortran sau C [7].
Prin clase acoperitoare a datelor si respectiv, a rezultatelor.
Varianta n care o functie este data prin expresia ei de calcul fixata printr-un sir de
caractere (string) va fi tratata n Cap. 5.
In continuare, varianta adoptata va fi cea n care datele se transmit prin clase acoperitoare. Avantajul acestei solutii este dat de flexibilitatea oferita de paradigma programarii
orientate pe obiecte, iar dezavantajul consta n cerinta ca un utilizator (client) sa aiba
cunostinte de programare orientata pe obiecte.
Pentru fiecare tip de problema, mini-biblioteca va contine:
o interfata n care se declara metodele disponibile;
o implementare a interfetei.
Astfel, se ofera posibilitatea dezvoltarii si utilizarii mai multor implementari ale aceleiasi
metode.
Clasele Java prin care se transmitit datele de intrare (DataIn) si cele de iesire (DataOut)
sunt incluse n pachetele interfetelor corespunzatoare. Aceste clase sunt componente Java
(bean).
Desfasurarea mini-bibliotecii mathlib cu programele sursa este
lib
|
log4j-*.jar
src
|--> mathlib
|
|--> client
|
|
|--> ecalg
|
|
|
|--> impl
|
|
|
|
|
MetodaTangentei.java // implementeaza interfata
|
|
|
|
IMetodaTangentei.java
// interfata
|
|
|
|
DataIn.java
|
|
|
|
DataOut.java
|
|
|--> cvadra
|
|
|
|--> impl
|
|
|
|
|
MetodaSimpson.java // implementeaza interfata
|
|
|
|
IMetodaSimpson.java
// interfata
|
|
|
|
DataIn.java
|
|
|
|
DataOut.java
26
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
Utilizarea mini-bibliotecii ca un modul Google Web Toolkit impune intercalarea catalogului client.
Codurile claselor / interfetelor sunt:
1. Clasa mathlib.client.ecalg.IMetodaTangentei
1
2
3
4
5
6
7
8
9
10
package m a t h l i b . c l i e n t . e c a l g ;
/
I n t e r f a t a metodei t a n g e n t e i .
/
p u b l i c i n t e r f a c e IMetodaTangentei {
/
Metoda t a n g e n t e i .
/
p u b l i c DataOut metodaTangentei ( DataIn d i n ) ;
}
2. Clasa mathlib.client.ecalg.DataIn
1
2
3
4
5
6
7
8
9
11
12
13
14
16
17
18
19
20
21
22
23
24
25
26
27
29
30
31
32
33
34
35
36
37
38
39
40
42
43
44
45
46
package m a t h l i b . c l i e n t . e c a l g ;
/
Clasa a c o p e r i t o a r e a d a t e l o r necesare r e z o l v a r i i
unei e c u a t i i a l g e b r i c e
/
public abstract c l a s s DataIn {
private double x ;
// a p r o x i m a t i a i n i t i a l a
private double e p s ; // t o l e r a n t a admisa
private i n t nmi ;
// numar maxim admis de i t e r a t i i
/
F u n c t i a c o r e s p u n z a t i o a r e membrului s t a n g a l e c u a t i e i f c t ( x )=0.
/
public abstract double f c t ( double x ) ;
/
Fixeaza aproximatia s o l u t i e i .
/
public void setX ( double x ) {
t h i s . x=x ;
}
/
F i x e a z a e x t r e m i t a t e a i n f e r i o a r a a i n t e r v a l u l u i de i n t e g r a r e
/
public double getX ( ) {
return x ;
}
/
Fixeaza t o l e r a n t a .
/
public void s e t E p s ( double e p s ) {
t h i s . e p s=e p s ;
}
/
Returneaza t o l e r a n t a .
/
public double getEps ( ) {
return e p s ;
}
/
F i x e a z a numarul maxim admis de i t e r a t i i .
/
public void setNmi ( i n t nmi ) {
t h i s . nmi=nmi ;
NUMERICA
1.4. O MINI-BIBLIOTECA
}
/
Returneaza numarul maxim admis de i t e r a t i i .
/
public i n t getNmi ( ) {
return nmi ;
}
47
48
49
50
51
52
53
54
3. Clasa mathlib.client.ecalg.DataOut
1
2
3
4
5
6
7
8
9
10
12
13
14
15
16
17
18
19
20
21
22
23
25
26
27
28
29
30
31
32
33
34
35
36
37
38
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package m a t h l i b . c l i e n t . e c a l g ;
/
Clasa a c o p e r i t o a r e a r e z u l t a t e l o r o b t i n u t e
l a r e z o l v a r e a unei e c u a t i i a l g e b r i c e
/
public c l a s s DataOut {
private double x ;
// a p r o x i m a t i a c a l c u l a t a a s o l u t i e i
private i n t i n d ;
// i n d i c a t o r u l de r a s p u n s a l p r o g r a m u l u i
private double f ;
// v a l o a r e a e x p r e s i e i s t a n g i a e c u a t i e i i n x
private i n t n i ;
// numarul i t e r a t i i l o r e f e c t u a t e
/
Returneaza a p r o x i m a t i a s o l u t i e i .
/
public double getX ( ) {
return x ;
}
/
Fixeaza aproximatia s o l u t i e i .
/
public void setX ( double x ) {
t h i s . x=x ;
}
/
Returneaza v a l o a r e a membrului s t a n g a l e c u a t i e i c a l c u l a t a
in aproximatia f i x a t a a s o l u t i e i e c u a t i e i .
/
public double getF ( ) {
return f ;
}
/
F i x e a z a v a l o a r e a membrului s t a n g a l e c u a t i e i c a l c u l a t a
in aproximatia c a l c u l a t a a s o l u t i e i e c u a t i e i .
/
public void s e t F ( double f ) {
t h i s . f=f ;
}
/
Returneaza i n d i c a t o r u l de r a s p u n s .
0 succes ;
1 insucces .
2 s i n g u l a r i t a t e d e p i s t a t a in timpul c a l c u l u l u i .
/
public i n t g e t I n d ( ) {
return i n d ;
}
/
F i x e a z a i n d i c a t o r u l de r a s p u n s .
/
public void s e t I n d ( i n t i n d ) {
t h i s . i n d=i n d ;
}
27
28
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
/
Returneaza numarul i t e r a t i i l o r e f e c t u a t e .
/
public i n t g e t N i ( ) {
return n i ;
}
/
F i x e a z a numarul i t e r a t i i l o r e f e c t u a t e .
/
public void s e t N i ( i n t n i ) {
t h i s . n i=n i ;
}
57
58
59
60
61
62
63
64
65
66
67
68
69
4. Clasa mathlib.client.ecalg.impl.MetodaTangentei
1
2
3
4
5
6
7
8
10
11
12
13
14
15
17
18
19
20
21
22
23
24
25
26
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package m a t h l i b . c l i e n t . e c a l g . impl ;
import j a v a . u t i l . l o g g i n g . Logger ;
import j a v a . u t i l . l o g g i n g . F i l e H a n d l e r ;
import j a v a . u t i l . l o g g i n g . S i m p l e F o r m a t t e r ;
import m a t h l i b . c l i e n t . e c a l g . DataIn ;
import m a t h l i b . c l i e n t . e c a l g . DataOut ;
import m a t h l i b . c l i e n t . e c a l g . IMetodaTangentei ;
import j a v a . i o . IOException ;
/
Implementarea m e t o d e i t a n g e n t e i .
V a r i a n t a cu i n r e g i s t r a r e a r e z u l t a t e l o r i n t e r m e d i a r e ( l o g ) .
/
public c l a s s MetodaTangentei implements IMetodaTangentei {
s t a t i c Logger l o g g e r = Logger . g e t L o g g e r ( MetodaTangentei . c l a s s . getName ( ) ) ;
public MetodaTangentei ( ) {
try {
F i l e H a n d l e r l o g g i n g F i l e = new F i l e H a n d l e r ( r e s u l t s E c a l g . l o g ) ;
l o g g i n g F i l e . s e t F o r m a t t e r (new S i m p l e F o r m a t t e r ( ) ) ;
l o g g e r . addHandler ( l o g g i n g F i l e ) ;
}
catch ( IOException e ) {
System . out . p r i n t l n ( e . g e t M e s s a g e ( ) ) ;
}
}
/
Metoda t a n g e n t e i a p l i c a t a d a t e l o r f i x a t e i n o b i e c t u l d i n .
/
public DataOut metodaTangentei ( DataIn d i n ) {
double x , y=d i n . getX ( ) , d , f , df , e p s=d i n . getEps ( ) ;
i n t nmi=d i n . getNmi ( ) ;
DataOut dout=new DataOut ( ) ;
i n t n i =0;
do{
n i ++;
x=y ;
f=d i n . f c t ( x ) ;
d f=d f c t ( x , d i n ) ;
y=xf / d f ;
i f ( ( y==Double . NaN ) | | ( Math . abs ( y)==Double . POSITIVE INFINITY ) ) {
dout . s e t I n d ( 2 ) ;
dout . setX ( y ) ;
dout . s e t F ( Double . NaN ) ;
dout . s e t N i ( n i ) ;
return dout ;
}
d=Math . abs ( ( yx ) ) ;
29
NUMERICA
1.4. O MINI-BIBLIOTECA
S t r i n g mesaj= i t e r = +n i+ s o l u t i a = +x+ e r o a r e a = +d ;
l o g g e r . i n f o ( mesaj ) ;
50
51
}
while ( ( d>=e p s ) && ( ni <nmi ) ) ;
i f ( d<e p s )
dout . s e t I n d ( 0 ) ;
else
dout . s e t I n d ( 1 ) ;
dout . setX ( x ) ;
dout . s e t F ( d i n . f c t ( x ) ) ;
dout . s e t N i ( n i ) ;
return dout ;
52
53
54
55
56
57
58
59
60
61
62
64
/
C a l c u l u l d e r i v a t e i de o r d i n u l i n t a i .
@param x P u n c t u l i n c a r e s e c a l c u l e a z a d e r i v a t a .
@param d i n O b i e c t DataIn c a r e c o n t i n e d e f i n i t i a f u n c t i e i a c a r e i d e r i v a t a
se c a l c u l e a z a .
/
private double d f c t ( double x , DataIn d i n ) {
i n t m=6;
double h=1e 10;
double pk =1; // 4 k
double [ ] [ ] d=new double [m ] [ m ] ;
f o r ( i n t i =0; i <m; i ++)
d [ i ] [ 0 ] = 0 . 5 ( d i n . f c t ( x+h) d i n . f c t ( xh ) ) / h ;
f o r ( i n t j =1; j <m; j ++){
pk=4pk ;
f o r ( i n t i=j ; i <m; i ++){
d [ i ] [ j ]=( pkd [ i ] [ j 1]d [ i 1 ] [ j 1 ] ) / ( pk 1);
}
}
return d [m 1 ] [m 1 ] ;
}
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
5. Clasa mathlib.client.cvadra.IMetodaSimpson
1
2
3
4
5
6
7
8
9
10
package m a t h l i b . c l i e n t . c v a d r a ;
/
I n t e r f a t a m e t o d e i Simpson .
/
public i n t e r f a c e IMetodaSimpson {
/
Metoda Simpson .
/
public DataOut metodaSimpson ( DataIn d i n ) ;
}
6. Clasa mathlib.client.cvadra.DataIn
1
2
3
4
5
6
package m a t h l i b . c l i e n t . c v a d r a ;
/
Clasa a c o p e r i t o a r e a d a t e l o r necesare c a l c u l u i
unei i n t e g r a l e .
/
public abstract c l a s s DataIn {
11
private
private
private
private
13
8
9
10
double a ;
double b ;
double e p s ;
i n t nmi ;
//
//
//
//
extremitatea stanga
extremitatea dreapta
t o l e r a n t a admisa
numar maxim admis de i t e r a t i i
30
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
Functia i n t e g r a t a .
/
public abstract double f c t ( double x ) ;
14
15
16
/
Returneaza e x t r e m i t a t e a i n f e r i o a r a a i n t e r v a l u l u i de i n t e g r a r e .
/
public double getA ( ) {
return a ;
}
/
F i x e a z a e x t r e m i t a t e a i n f e r i o a r a a i n t e r v a l u l u i de i n t e g r a r e .
/
public void setA ( double a ) {
t h i s . a=a ;
}
18
19
20
21
22
23
24
25
26
27
28
29
/
Returneaza e x t r e m i t a t e a s u p e r i o a r a a i n t e r v a l u l u i de i n t e g r a r e .
/
public double getB ( ) {
return b ;
}
/
F i x e a z a e x t r e m i t a t e a s u p e r i o r a a i n t e r v a l u l u i de i n t e g r a r e .
/
public void setB ( double b ) {
t h i s . b=b ;
}
31
32
33
34
35
36
37
38
39
40
41
42
/
Fixeza t o l e r a n t a .
/
public void s e t E p s ( double e p s ) {
t h i s . e p s=e p s ;
}
/
Returneaza t o l e r a n t a .
/
public double getEps ( ) {
return e p s ;
}
44
45
46
47
48
49
50
51
52
53
54
55
/
F i x e a z a numarul maxim admis de i t e r a t i i .
/
public void setNmi ( i n t nmi ) {
t h i s . nmi=nmi ;
}
/
Returneaza numarul maxim admis de i t e r a t i i .
/
public i n t getNmi ( ) {
return nmi ;
}
57
58
59
60
61
62
63
64
65
66
67
68
69
7. Clasa mathlib.client.cvadra.DataOut
1
2
3
4
5
6
7
package m a t h l i b . c l i e n t . c v a d r a ;
/
Clasa a c o p e r i t o a r e a r e z u l t a t e l o r o b t i n u t e
l a c a l c u l u l unei i n t e g r a l e .
/
public c l a s s DataOut{
private double i n t e g r a l a ; // i n t e g r a l a
31
NUMERICA
1.4. O MINI-BIBLIOTECA
private i n t i n d ;
private i n t n i ;
8
9
/
Returneaza v a l o a r e a i n t e g r a l e i .
/
public double g e t I n t e g r a l a ( ) {
return i n t e g r a l a ;
}
/
Fixeaza valoarea i n t e g r a l e i .
/
public void s e t I n t e g r a l a ( double i n t e g r a l a ) {
t h i s . i n t e g r a l a=i n t e g r a l a ;
}
11
12
13
14
15
16
17
18
19
20
21
22
/
Returneaza i n d i c a t o r u l de r a s p u n s .
0 succes ;
1 insucces .
/
public i n t g e t I n d ( ) {
return i n d ;
}
/
F i x e a z a i n d i c a t o r u l de r a s p u n s .
/
public void s e t I n d ( i n t i n d ) {
t h i s . i n d=i n d ;
}
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/
Returneaza numarul i t e r a t i i l o r e f e c t u a t e .
/
public i n t g e t N i ( ) {
return n i ;
}
/
F i x e a z a numarul i t e r a t i i l o r e f e c t u a t e .
/
public void s e t N i ( i n t n i ) {
t h i s . n i=n i ;
}
40
41
42
43
44
45
46
47
48
49
50
51
52
// i n d i c a t o r u l de r a s p u n s a l p r o g r a m u l u i
// numarul i t e r a t i i l o r e f e c t u a t e
8. Clasa mathlib.client.cvadra.impl.MetodaSimpson
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
17
18
package m a t h l i b . c l i e n t . c v a d r a . impl ;
import j a v a . u t i l . l o g g i n g . Logger ;
import j a v a . u t i l . l o g g i n g . F i l e H a n d l e r ;
import j a v a . u t i l . l o g g i n g . S i m p l e F o r m a t t e r ;
import m a t h l i b . c l i e n t . c v a d r a . DataIn ;
import m a t h l i b . c l i e n t . c v a d r a . DataOut ;
import m a t h l i b . c l i e n t . c v a d r a . IMetodaSimpson ;
import j a v a . i o . IOException ;
/
Implementarea m e t o d e i Simpson .
V a r i a n t a cu i n r e g i s t r a r e a r e z u l t a t e l o r i n t e r m e d i a r e ( l o g ) .
/
public c l a s s MetodaSimpson implements IMetodaSimpson {
private double s=Double . NaN ;
s t a t i c Logger l o g g e r = Logger . g e t L o g g e r ( MetodaSimpson . c l a s s . getName ( ) ) ;
public MetodaSimpson ( ) {
try {
32
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
F i l e H a n d l e r l o g g i n g F i l e = new F i l e H a n d l e r ( r e s u l t s I n t e g . l o g ) ;
l o g g i n g F i l e . s e t F o r m a t t e r (new S i m p l e F o r m a t t e r ( ) ) ;
l o g g e r . addHandler ( l o g g i n g F i l e ) ;
19
20
21
}
catch ( IOException e ) {
System . out . p r i n t l n ( e . g e t M e s s a g e ( ) ) ;
}
22
23
24
25
26
28
/
Formula Simpson de a p l i c a r e p r a c t i c a cu
parametru de d i s c r e t i z a r e f i x a t .
La prima a p e l a r e s=Double .NaN !
29
30
31
/
private double simpson ( i n t m, DataIn d i n ) {
double a=d i n . getA ( ) , b=d i n . getB ( ) ;
double h = 0. 5( ba ) /m;
double sp =0 , s i =0;
i f ( Double . isNaN ( s ) ) {
f o r ( i n t i =1; i <m; i ++)
sp+=d i n . f c t ( a+2 i h ) ;
}
else
sp=s ;
f o r ( i n t i =0; i <m; i ++)
s i+=d i n . f c t ( a +(2 i +1)h ) ;
s=sp+s i ;
return h ( d i n . f c t ( a)+ d i n . f c t ( b)+2 sp+4 s i ) / 3 ;
}
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/
Schema a d a p t i v a p e n t r u metoda l u i Simpson .
A l g o r i t m i t e r a t i v cu r e g u l a de o p r i r e .
/
public DataOut metodaSimpson ( DataIn d i n ) {
double i n t v , i n t n , d , e p s=d i n . getEps ( ) ;
i n t nmi=d i n . getNmi ( ) ;
i n t m=2;
// Parametrul de d i s c r e t i z a r e
i n t n=simpson (m, d i n ) ;
DataOut dout=new DataOut ( ) ;
i n t n i =0;
do{
n i ++;
i n t v=i n t n ;
m=2m;
i n t n=simpson (m, d i n ) ;
d=Math . abs ( i n t n i n t v ) ;
S t r i n g mesaj= i t e r = +n i+ i n t e g r a l a = +i n t n+ e r o a r e a = +d ;
l o g g e r . i n f o ( mesaj ) ;
}
while ( ( d>=e p s ) && ( ni <nmi ) ) ;
i f ( d<e p s )
dout . s e t I n d ( 0 ) ;
else
dout . s e t I n d ( 1 ) ;
dout . s e t I n t e g r a l a ( i n t n ) ;
dout . s e t N i ( n i ) ;
return dout ;
}
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
1
2
<property
<property
<property
<property
7
8
9
11
12
13
14
15
16
18
19
20
21
22
24
25
26
27
28
29
30
32
33
34
36
37
38
39
40
41
33
name= l i b . d i r v a l u e= l i b />
name= b u i l d . d i r v a l u e= b u i l d />
name= d i s t . d i r v a l u e= d i s t />
name= d i s t . name v a l u e= m a t h l i b />
<path i d= p a t h r e f >
< f i l e s e t d i r= ${ l i b . d i r } >
<include name= . j a r />
</ f i l e s e t>
<pathelement path= ${ b u i l d . d i r } />
</path>
<target name= I n i t >
<mkdir d i r= ${ b u i l d . d i r } />
<delete d i r= ${ d i s t . d i r } />
<mkdir d i r= ${ d i s t . d i r } />
</ target>
<target name= Compile depends= I n i t description= c o m p i l e >
<javac s r c d i r= s r c /${ package }
d e s t d i r= ${ b u i l d . d i r }
i n c l u d e a n t r u n t i m e= f a l s e >
<classpath r e f i d= p a t h r e f />
</ javac>
</ target>
<target name= ToJar depends= Compile >
<j a r d e s t f i l e = ${ d i s t . d i r }/${ d i s t . name } . j a r b a s e d i r= ${ b u i l d . d i r } />
</ target>
<target name= Docs >
<delete d i r= d o c s />
<mkdir d i r= d o c s />
<javadoc d e s t d i r= d o c s sourcepath= s r c />
</ target>
</ project>
1.5
Formatarea rezultatetor
34
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
Atunci cand afisarea are loc de un program desktop, formatarea se face cu metoda
printf a clasei PrintWriter. Formate uzuale sunt %m.nX unde
m - este numarul caracterelor;
n - este numarul zecimalelor;
X {e, f, g}; e - reprezentare stiintifica; f - reprezentare zecimala; g combinatie
ntre reprezentare stiintifica si zecimala.
Daca rezultatul apare prin intermediul unui program navigator, atunci se pot utiliza
sablonul
import java.text.DecimalFormat;
. . .
DecimalFormat df=new DecimalFormat("0.00001");
out.println(df.format(r));
. . .
1.6
Rezolvarea problemelor
Deoarece clasele de tip DataIn ale mini-bibliotecii nu contin codul functiei specifice
unei probleme concrete, ele au fost declarate clase abstract. Un client trebuie sa extinda
o asemenea clasa specificand metoda double fct(double x).
import m a t h l i b . c l i e n t . e c a l g . DataIn ;
public c l a s s SimpluEcAlgDataIn extends DataIn {
// membrul s t a n g a l e c u a t i e i
SimpluEcAlgDataIn ( ) {
setX ( 0 . 5 ) ;
// a p r o x i m a t i a i n i t i a l a
s e t E p s ( 1 e 8);
// t o l e r a n t a admisa
setNmi ( 5 0 ) ;
// numar maxim admis de i t e r a t i i
}
4
5
6
7
8
9
11
12
13
14
35
si
1
2
3
4
6
7
8
9
10
import
import
import
import
public c l a s s TestEcAlg {
// r e z u l t a t u l c u n o s c u t a l e c u a t i e i
private double r e z u l t a t = 0.7666647;
private DataIn d i n ;
private DataOut dout ;
@Before
public void i n i t i a l i z a r e ( ) {
d i n=new SimpluEcAlgDataIn ( ) ;
IMetodaTangentei o b j=new MetodaTangentei ( ) ;
dout=o b j . metodaTangentei ( d i n ) ;
}
12
13
14
15
16
17
@Test
public void t e s t ( ) {
a s s e r t E q u a l s ( r e z u l t a t , dout . getX ( ) , d i n . getEps ( ) ) ;
}
19
20
21
22
@After
public void a f i s a r e ( ) {
System . out . p r i n t l n ( \ n I n d i c a t o r u l de r a s p u n s : +dout . g e t I n d ( ) ) ;
System . out . p r i n t f ( S o l u t i a e c u a t i e i : %16.8 f \n , dout . getX ( ) ) ;
System . out . p r i n t f ( V a l o a r e a f u n c t i e i i n s o l u t i e : %16.8 e \n , dout . getF ( ) ) ;
System . out . p r i n t l n ( Numarul i t e r a t i i l o r e f e c t u a t e : +dout . g e t N i ( ) ) ;
}
24
25
26
27
28
29
30
32
33
34
35
org . j u n i t . ;
static org . j u n i t . Assert . ;
mathlib . c l i e n t . e c a l g . ;
m a t h l i b . c l i e n t . e c a l g . impl . ;
Calculul integralei
R
4
import m a t h l i b . c l i e n t . c v a d r a . DataIn ;
public c l a s s SimpluCvadraDataIn extends DataIn {
SimpluCvadraDataIn ( ) {
setA ( 0 ) ;
// e x t r e m i t a t e a s t a n g a
setB ( 0 . 2 5 Math . PI ) ;
// e x t r e m i t a t e a d r e a p t a
s e t E p s ( 1 e 12);
// t o l e r a n t a admisa
setNmi ( 5 0 ) ;
// numar maxim admis de i t e r a t i i
}
// f u n c t i a de i n t e g r a t
public double f c t ( double x ) {
36
12
13
14
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
si
1
2
3
4
6
7
8
9
10
import
import
import
import
public c l a s s T e s t I n t e g r a l a {
// r e z u l t a t u l c u n o s c u t a l i n t e g r a l e i
private double r e z u l t a t =0.125Math . PI Math . l o g ( 2 ) ;
private DataIn d i n ;
private DataOut dout ;
@Before
public void i n i t i a l i z a r e ( ) {
d i n=new SimpluCvadraDataIn ( ) ;
IMetodaSimpson o b j=new MetodaSimpson ( ) ;
dout=o b j . metodaSimpson ( d i n ) ;
}
12
13
14
15
16
17
@Test
public void t e s t ( ) {
a s s e r t E q u a l s ( r e z u l t a t , dout . g e t I n t e g r a l a ( ) , d i n . getEps ( ) ) ;
}
19
20
21
22
@After
public void a f i s a r e ( ) {
System . out . p r i n t l n ( \ n I n d i c a t o r u l de r a s p u n s : +dout . g e t I n d ( ) ) ;
System . out . p r i n t f ( I n t e g r a l a : %16.8 f \n , dout . g e t I n t e g r a l a ( ) ) ;
System . out . p r i n t l n ( Numarul i t e r a t i i l o r e f e c t u a t e : +dout . g e t N i ( ) ) ;
}
24
25
26
27
28
29
31
32
33
34
org . j u n i t . ;
static org . j u n i t . Assert . ;
mathlib . c l i e n t . cvadra . ;
m a t h l i b . c l i e n t . c v a d r a . impl . ;
1.7
37
set HOME=locatia_curenta
start mvn install:install-file
-Dfile=%HOME%\jep-2.4.1.jar
-DgroupId=jep
-DartifactId=jep
-Dversion=2.4.1
-Dpackaging=jar
start mvn install:install-file
-Dfile=%HOME%\matheclipse-parser-0.0.10.jar
-DgroupId=org.matheclipse
-DartifactId=matheclipse-parser
-Dversion=0.0.10
-Dpackaging=jar
java
|-->
|
|
|
|
|
mathlib
|--> client
|
|--> ecalg
|
|
|
DataIn.java
|
|
|
DataOut.java
|
|
|
IMetodaTangentei.java
Prelucrarile necesare sunt: mvn clean install care nglobeaza stergerea fisierelor generate anterior de maven, compilarea, arhivarea si depunerea proiectului n depozitul local
maven.
Generam proiectul pentru implementarea interfetei definita mai sus.
set GroupId=mathlib.client.ecalg.impl
set ArtifactId=ecalgimpl
set Version=1.0
set ArchetypeArtifactId=maven-archetype-quickstart
mvn -B archetype:generate
-DgroupId=%GroupId%
-DartifactId=%ArtifactId%
-Dversion=%Version%
-DarchetypeArtifactId=%ArchetypeArtifactId%
Partea de test se completeaza cu clasele utilizate n 1.5 pentru calculul solutiei negative
a ecuatiei 2x x2 = 0. In final, desfasurarea proiectului este
ecalgimpl
|--> src
|
|-->
|
|
|
|
|
|
|
|
main
|-->
|
|
|
java
|--> mathlib
|
|--> client
|
|
|--> ecalg
38
|
|
|
|
|
|
|
|
|
|
|
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
|
|
|
|
|--> test
|
|-->
|
|
|
|
|
|
|
|
|
|
|
|
pom.xml
|
|
|
|
|
|
|--> impl
|
|
MetodaTangentei.java
java
|-->
|
|
|
|
|
mathlib
|--> client
|
|--> ecalg
|
|
|--> impl
|
|
|
SimpluEcAlgDataIn.java
|
|
|
TestEcAlg.java
Fisierul pom.xml trebuie completat cu dependinta pentru iecalg. Codul fisierului pom.xml
devine
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
cu fisierul pom.xml
1
2
3
4
5
7
8
9
10
11
12
14
15
16
17
18
19
20
39
Oricare din comenzile maven va actiona asupra fiecarui modul (modulul este denumirea
data unui proiect inclus).
Compilarea si testarea se obtine cu comanda mvn clean test.
Compilarea, testarea, arhivarea si copierea n depozitul local se obtine cu comanda
mvn clean install.
1.8
OSGi - Open Sourse Gateway initiative, 1999, (semnificatia numelui fiind astazi depasita) a dezvoltat un model de cadru de lucru privind:
gestiunea ciclului de viata a unei aplicatii (application life cycle management);
registru de servicii;
mediu de executie;
module.
Pe aceasta baza au fost dezvoltate interfete de programare (API), servicii, extensii OSGi
(OSGi layers).
Cadrul de lucru contine un model specific de aplicatie sub forma de componenta sau
modul OSGi (bundle for deployment). O asemenea componenta poate pune la dispozitia
altor componente functionalitati, comportandu-se ca un serviciu (ofertant de servicii) sau
poate executa o actiune punctuala. O componenta OSGi se prezinta sub forma unei arhive
jar.
In esenta, scopul unui cadru de lucru OSGi este oferirea unui mediu pentru crearea si
integrarea uniforma de unitati (module, componente) de soft.
O componenta OSGi se poate instala, lansa n executie, opri, actualiza si dezinstala.
Cadrul de lucru contine un registru de servicii care permite unei componente OSGi
sa sesizeze existenta, aparitia sau disparitia unor servicii.
Programarea unei aplicatii (serviciu) OSGi se poate face n mod
imperativ prin existenta unei clase activator ce implementeaza interfata org.osgi.
framework.BundleActivator.
40
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
declarativ prin utilizarea unor resurse OSGi suplimentare care nlocuiesc activatorul
cu fisiere de configurare. Descriptive service, blueprint, iPOJO sunt tehnologii de
programare declarative.
Functionalitatea
Afiseaza lista modulelor OSGi instalate.
Paraseste si nchide cadrul de lucru.
Instaleaza modulul OSGi
La instalare unui modul i se atribuie n
vederea identificarii un numar natural id.
start id
Lanseaza modulul OSGi id.
start file: modulOSGi .jar
Instaleaza si lanseaza modulul OSGi
stop id
Opreste modulul OSGi id.
uninstall id
Dezinstaleaza modulul OSGi id.
Interfata de lucru, Apache Felix Gogo, implementeaza RFC (Request for Comments)
147 publicat de Internet Engineering Task Force (IETF).
41
Bundele-Description:
Bundle-Version:
1.0.0
Bundle-Activator:
BundleActivator
Ultima linie din fisierul manifest.mf este o linie vida. In liste, separatorul este
virgula.
import m a t h l i b . c l i e n t . e c a l g . ;
import m a t h l i b . c l i e n t . e c a l g . impl . ;
import o r g . o s g i . framework . ;
public c l a s s A c t i v a t o r implements B u n d l e A c t i v a t o r {
public void s t a r t ( BundleContext c o n t e x t ) {
DataIn d i n=new SimpluEcAlgDataIn ( ) ;
IMetodaTangentei o b j=new MetodaTangentei ( ) ;
DataOut dout=o b j . metodaTangentei ( d i n ) ;
System . out . p r i n t l n ( \ n I n d i c a t o r u l de r a s p u n s : +dout . g e t I n d ( ) ) ;
System . out . p r i n t l n ( S o l u t i a e c u a t i e i : +dout . getX ( ) ) ;
System . out . p r i n t l n ( V a l o a r e a f u n c t i e i i n s o l u t i e : +dout . getF ( ) ) ;
System . out . p r i n t l n ( Numarul i t e r a t i i l o r e f e c t u a t e : +dout . g e t N i ( ) ) ;
}
public void s t o p ( BundleContext c o n t e x t ) {}
16
17
lib
|
mathlib.jar
Activator.class
SimpluEcAlgDataIn.class
42
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
BundleName : TestEcAlg
BundleD e s c r i p t i o n : Test EcAlg
BundleV e r s i o n : 1 . 0 . 0
BundleA c t i v a t o r : A c t i v a t o r
BundleC l a s s p a t h : . , l i b / m a t h l i b . j a r
ImportPackage : o r g . o s g i . framework
Dupa lansarea cadrului OSGi n executie, instalam componenta OSGi astfel creata si o
lansam n lucru:
g! start file: . . .\testecalg.jar
Indicatorul de raspuns : 0
Solutia ecuatiei : -0.766664695962095
Valoarea functiei in solutie : 1.1102230246251565E-16
Numarul iteratiilor efectuate : 5
Pentru a relua executia trebuie sa aflam codul atribuit de cadrul de lucru OSGi componentei testecalg.jar
g! lb
ID|State
. . .
5|Active
|Level|Name
|
1|TestEcAlg(1.0.0)|1.0.0
1
2
3
4
5
7
8
9
10
11
12
13
14
15
16
17
18
19
import
import
import
import
import
c l i e n t . cvadra . ;
client . ecalg . ;
c l i e n t . c v a d r a . impl . ;
c l i e n t . e c a l g . impl . ;
. framework . ;
public c l a s s A c t i v a t o r implements B u n d l e A c t i v a t o r {
S e r v i c e R e g i s t r a t i o n metodaSimpsonService ;
S e r v i c e R e g i s t r a t i o n metodaTangenteiService ;
public void s t a r t ( BundleContext c o n t e x t ) {
m e t o d a S i m p s o n S e r v i c e=
c o n t e x t . r e g i s t e r S e r v i c e ( IMetodaSimpson . c l a s s . getName ( ) ,
new MetodaSimpson ( ) , n u l l ) ;
System . out . p r i n t l n ( R e g i s t e r i n g MetodaSimpson s e r v i c e . ) ;
m e t o d a T a n g e n t e i S e r v i c e=
c o n t e x t . r e g i s t e r S e r v i c e ( IMetodaTangentei . c l a s s . getName ( ) ,
new MetodaTangentei ( ) , n u l l ) ;
System . out . p r i n t l n ( R e g i s t e r i n g MetodaTangentei s e r v i c e . ) ;
}
public void s t o p ( BundleContext c o n t e x t ) {
metodaSimpsonService . u n r e g i s t e r ( ) ;
metodaTangenteiService . u n r e g i s t e r ( ) ;
}
21
22
23
24
25
mathlib .
mathlib .
mathlib .
mathlib .
org . o s g i
43
BundleName : M a t h l i b S e r v i c e
BundleD e s c r i p t i o n : Mathlib S e r v i c e
BundleV e r s i o n : 1 . 0 . 0
BundleA c t i v a t o r : A c t i v a t o r
BundleC l a s s p a t h : . , l i b / m a t h l i b . j a r , l i b / l o g 4 j 1 . 2 . 1 5 . j a r
ImportPackage : o r g . o s g i . framework
ExportPackage : m a t h l i b . c l i e n t . c v a d r a ; v e r s i o n= 1 . 0 . 0 ,
m a t h l i b . c l i e n t . e c a l g ; v e r s i o n= 1 . 0 . 0
Rezolvarea fiecarei probleme se obtine n cate un modul OSGi. Vom reutiliza clasele
SimpleEcAlgDataIn si SimpluCvadraDataIn, la care se adauga cate o clasa care implementeaza interfata BundleActivator.
Calculul solutiei negative a ecuatiei 2x x2 = 0
Un obiect care implementeaza interfata se obtine n doi pasi:
1. Se gaseste o referinta a serviciului cu metoda
ServiceReference getServiceReference(String)
a clasei BundleContext. Variabila String reprezinta numele serviciului, adica numele interfetei.
2. Se obtine o instanta a clasei ce implementeaza interfata cu metoda
Object getService(ServiceReference)
44
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
import m a t h l i b . c l i e n t . e c a l g . ;
import o r g . o s g i . framework . ;
public c l a s s A c t i v a t o r implements B u n d l e A c t i v a t o r {
ServiceReference metodaSimpsonServiceReference ;
public void s t a r t ( BundleContext c o n t e x t ) {
try {
m e t o d a S i m p s o n S e r v i c e R e f e r e n c e=
c o n t e x t . g e t S e r v i c e R e f e r e n c e ( IMetodaTangentei . c l a s s . getName ( ) ) ;
i f ( m e t o d a S i m p s o n S e r v i c e R e f e r e n c e != n u l l ) {
DataIn d i n=new SimpluEcAlgDataIn ( ) ;
IMetodaTangentei o b j=
( IMetodaTangentei ) c o n t e x t . g e t S e r v i c e ( m e t o d a S i m p s o n S e r v i c e R e f e r e n c e ) ;
DataOut dout=o b j . metodaTangentei ( d i n ) ;
System . out . p r i n t l n ( \ n I n d i c a t o r u l de r a s p u n s : +dout . g e t I n d ( ) ) ;
System . out . p r i n t l n ( S o l u t i a e c u a t i e i : +dout . getX ( ) ) ;
System . out . p r i n t l n ( V a l o a r e a f u n c t i e i i n s o l u t i e : +dout . getF ( ) ) ;
System . out . p r i n t l n ( Numarul i t e r a t i i l o r e f e c t u a t e : +dout . g e t N i ( ) ) ;
}
}
catch ( E x c e p t i o n e ) {
System . out . p r i n t l n ( App E x c e p t i o n : +e . g e t M e s s a g e ( ) ) ;
}
}
public void s t o p ( BundleContext c o n t e x t ) {
i f ( m e t o d a S i m p s o n S e r v i c e R e f e r e n c e != n u l l ) {
context . ungetService ( metodaSimpsonServiceReference ) ;
}
}
26
27
28
29
30
31
BundleName : AppEcAlg
BundleD e s c r i p t i o n : R e z o l v a r e a u n e i e c u a t i i a l g e b r i c e
BundleV e r s i o n : 1 . 0 . 0
BundleA c t i v a t o r : A c t i v a t o r
ImportPackage : o r g . o s g i . framework , m a t h l i b . c l i e n t . e c a l g
Calculul integralei
R
4
import m a t h l i b . c l i e n t . c v a d r a . ;
import o r g . o s g i . framework . ;
import o r g . o s g i . u t i l . t r a c k e r . S e r v i c e T r a c k e r ;
public c l a s s A c t i v a t o r implements B u n d l e A c t i v a t o r {
ServiceTracker metodaSimpsonServiceTracker ;
public void s t a r t ( BundleContext c o n t e x t ) {
m e t o d a S i m p s o n S e r v i c e T r a c k e r=new S e r v i c e T r a c k e r ( c o n t e x t ,
IMetodaSimpson . c l a s s . getName ( ) , n u l l ) ;
m e t o d a S i m p s o n S e r v i c e T r a c k e r . open ( ) ;
DataIn d i n=new SimpluCvadraDataIn ( ) ;
IMetodaSimpson o b j=
( IMetodaSimpson ) m e t o d a S i m p s o n S e r v i c e T r a c k e r . g e t S e r v i c e ( ) ;
DataOut dout=o b j . metodaSimpson ( d i n ) ;
System . out . p r i n t l n ( \ n I n d i c a t o r u l de r a s p u n s : +dout . g e t I n d ( ) ) ;
System . out . p r i n t l n ( I n t e g r a l a : +dout . g e t I n t e g r a l a ( ) ) ;
System . out . p r i n t l n ( Numarul i t e r a t i i l o r e f e c t u a t e : +dout . g e t N i ( ) ) ;
8
9
10
11
12
13
14
15
16
17
18
20
21
22
23
mpreuna cu manifest.mf
1
2
3
4
5
6
BundleName : A p p I n t e g r a l a
BundleD e s c r i p t i o n : C a l c u l u l u n e i i n t e g r a l e
BundleV e r s i o n : 1 . 0 . 0
BundleA c t i v a t o r : A c t i v a t o r
ImportPackage : o r g . o s g i . framework , o r g . o s g i . u t i l . t r a c k e r ,
mathlib . c l i e n t . cvadra
45
46
CAPITOLUL 1. APLICAT
II NUMERICE SIMPLE
Capitolul 2
Accesarea n Java a unor produse
matematice
Multe pachete de programe matematice ofera posibilitatea apelarii lor din clase Java.
Ne vom limita numai la produse distribuite gratuit. Vom prezenta utilizarea n Java a
produselor Mathematica, Maple, Scilab.
Ca motivatii pentru un asemenea interes este posibilitatea elaborarii unei aplicatii
Java care utilizeaza functionalitati ale softurilor amintite.
2.1
Java cu Mathematica
48
catch(MathLinkException e){
System.out.println("Fatal opening link error : "+e.getMessage());
System.exit(1);
}
Ultimul element al sirului mlArgs fixeaza locatia nucleului MathKernel.exe, fiind transmis
ca argument al programului Java.
Sablonul de prelucrare al unei expresii / comenzi Mathematica este
try{
// Evaluarea expresiei / comenzii reprezentata prin String-ul expr
String expr=". . .";
ml.evaluate(expr);
ml.waitForAnswer();
// Prelucrarea rezultatului
}
catch(MathLinkException e){
System.out.println("MathLinkException : "+e.getMessage());
}
finally{
ml.close();
}
Alternativ, metoda evaluate poate avea ca parametru o variabila de tip Expr.
Functie de tipul rezultatului, acesta se obtine cu una din metodele clasei KernerLink:
Expr getExpr(), double getDouble(), int getInteger(), boolean getBoolean().
Exemplul 2.1.1 Sa se rezolve ecuatia 2x x2 = 0.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
49
4
5
6
7
8
50
10
s t a t i c K e r n e l L i n k ml ;
12
public MathGraphics ( ) {
initComponents ( ) ;
}
13
14
16
17
18
19
20
private void i n i t C o m p o n e n t s ( ) {
j a v a . awt . G r i d B a g C o n s t r a i n t s g r i d B a g C o n s t r a i n t s ;
s e t T i t l e ( Mathematica : G r a f i c a ) ;
setSize (400 ,400);
getContentPane ( ) . s e t L a y o u t (new j a v a . awt . GridBagLayout ( ) ) ;
mathGraphicsJPanel=new MathGraphicsJPanel ( ml ) ;
mathGraphicsJPanel . s e t B a c k g r o u n d ( j a v a . awt . C o l o r . w h i t e ) ;
mathGraphicsJPanel . s e t P r e f e r r e d S i z e (new j a v a . awt . Dimension ( 2 5 0 , 2 0 0 ) ) ;
g r i d B a g C o n s t r a i n t s = new j a v a . awt . G r i d B a g C o n s t r a i n t s ( ) ;
gridBagConstraints . gridx = 1;
gridBagConstraints . gridy = 0;
getContentPane ( ) . add ( mathGraphicsJPanel , g r i d B a g C o n s t r a i n t s ) ;
22
23
24
25
26
27
28
mJLabel=new j a v a x . swing . J L a b e l ( ) ;
mJLabel . s e t P r e f e r r e d S i z e (new j a v a . awt . Dimension ( 2 0 0 , 1 8 ) ) ;
mJLabel . s e t T e x t ( E x p r e s i e \ Mathematica \ ) ;
mJLabel . s e t H o r i z o n t a l A l i g n m e n t ( j a v a x . swing . SwingConstants .CENTER) ;
g r i d B a g C o n s t r a i n t s = new j a v a . awt . G r i d B a g C o n s t r a i n t s ( ) ;
gridBagConstraints . gridx = 0;
gridBagConstraints . gridy = 0;
getContentPane ( ) . add ( mJLabel , g r i d B a g C o n s t r a i n t s ) ;
30
31
32
33
34
35
36
37
m J S c r o l l P a n e=new j a v a x . swing . J S c r o l l P a n e ( ) ;
m J S c r o l l P a n e . s e t P r e f e r r e d S i z e (new j a v a . awt . Dimension ( 2 0 0 , 6 0 ) ) ;
mJTextArea=new j a v a x . swing . JTextArea ( ) ;
m J S c r o l l P a n e . s e t V i e w p o r t V i e w ( mJTextArea ) ;
g r i d B a g C o n s t r a i n t s = new j a v a . awt . G r i d B a g C o n s t r a i n t s ( ) ;
gridBagConstraints . gridx = 0;
gridBagConstraints . gridy = 1;
getContentPane ( ) . add ( mJScrollPane , g r i d B a g C o n s t r a i n t s ) ;
39
40
41
42
43
44
45
46
48
49
50
51
52
53
54
55
56
57
58
59
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
77
78
79
80
81
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
51
Clientul interactioneaza cu programul prin interfata grafica din Fig. 2.1. In zona
TextArea se introduce o comanda Mathematica.
2.2
Java cu Maple
Maple este un produs comercial de matematica produs de Waterloo Maple Inc., aflat
n concurenta cu Mathematica.
52
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
53
cu rezultatele
u := [2., 4., -.7666646958]
3
2.
4.
-.7666646958
Solutiile obtinute
x[1] = 2.0
x[2] = 4.0
x[3] = -0.7666646958
Semnalam faptul ca pentru compilare si executie trebuie sa includem n variabila de sistem classpath fisierele jopenmaple.jar, externalcall.jar din catalogul Maple HOME\java.
In plus, pentru executie, trebuie completata variabila de sistem PATH cu calea catre
catalogul Maple HOME\bin.X86 64 WINDOWS.
2.3
Java cu Scilab
Scilab este un produs de calcul numeric produs de INRIA (Institut National de Recherche en Informatique et Automatique) Franta disponibil n mediile Windows, Linux
si Mac OS X. Produsul este distribuit gratuit. Scilab este nsotit de o documentatie
cuprinzatoare.
Din punctul de vedere al utilizari Scilab are trasaturi comune cu produsul comercial
Matlab.
54
Clasa org.scilab.modules.javasci.Scilab
Constructor:
public Scilab()
Clasa Scilab contine metodele statice:
public boolean open() throws JavasciException
public boolean close()
public boolean exec(String sarcina )
public boolean exec(String[] sarcini )
public boolean exec(File numeFisierScript)
public boolean put(String numeVar, ScilabType val )
Se defineste variabila Scilab numeVar a carei valoare este val.
ScilabType get(String numeVar )
Returneaza un obiect acoperitor Java corespunzator tipului variabilei Scilab.
Valoarea logica returnata de metodele de mai sus este true daca Scilab nu genereaza o
eroare.
Sablonul de apelare pentru executia de cod Scilab este
55
import org.scilab.modules.javasci.Scilab;
public class ApelScilab{
public static void main(String[] args){
try{
Scilab sci=new Scilab();
if(sci.open()){
. . .
sci.exec( cod Scilab );
. . .
sci.close();
}
else{
System.out.println("Could not start Scilab ");
}
}
catch(org.scilab.modules.javasci.JavasciException e) {
System.err.println("Exception: " + e.getLocalizedMessage());
}
}
}
Interfata org.scilab.modules.types.ScilabType
Interfata declara metodele:
boolean equals(Object obiect)
int getHeight()
Returneaza numarul liniilor.
int getWidth()
Returneaza numarul coloanelor.
boolean isEmpty()
String toString()
Interfata este implementata de clasele ScilabBoolean, ScilabDouble, ScilabInteger,
ScilabString, ScilabList.
Clasa org.scilab.modules.types.ScilabDouble
Constructori:
ScilabDouble()
56
ScilabDouble(double data)
ScilabDouble(double[][] data)
ScilabDouble(double realData, double imagData)
ScilabDouble(double[][] realData, double[][] imagData)
Metode:
double[][] getRealPart()
double[][] getImaginarylPart()
boolean isReal()
Schema pentru transferul unei date double x din Java n Scilab consta din
double x=. . .;
ScilabDouble sci_x=new new ScilabDouble(x);
sci.put("x",sci_x);
Invers, preluarea n Java a valorii unei variabile Scilab a, presupusa numar real, se programeaza prin
ScilabDouble sci_a=(ScilabDouble)sci.get("a");
double[][] aa=sci_a.getRealPart();
double a=aa[0][0];
Exemplul 2.3.1 Executia unui script Scilab u=1,v=u+1, disp(v).
1
2
3
5
6
7
8
9
import o r g . s c i l a b . modules . j a v a s c i . S c i l a b ;
import o r g . s c i l a b . modules . t y p e s . S c i l a b T y p e ;
import o r g . s c i l a b . modules . t y p e s . S c i l a b D o u b l e ;
public c l a s s
TstJavaSci1 {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
try {
S c i l a b s c i=new S c i l a b ( ) ;
i f ( s c i . open ( ) ) {
s c i . e x e c (new S t r i n g [ ] { u=1 , v=u+1 , d i s p ( v ) } ) ;
11
13
14
15
16
17
}
catch ( o r g . s c i l a b . modules . j a v a s c i . J a v a s c i E x c e p t i o n e ) {
System . e r r . p r i n t l n ( An e x c e p t i o n o c c u r e d : + e . g e t L o c a l i z e d M e s s a g e ( ) ) ;
}
18
19
20
21
22
23
Se obtine
57
2.
import o r g . s c i l a b . modules . j a v a s c i . S c i l a b ;
import o r g . s c i l a b . modules . t y p e s . S c i l a b T y p e ;
import o r g . s c i l a b . modules . t y p e s . S c i l a b D o u b l e ;
public c l a s s
TstJavaSci2 {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
try {
S c i l a b s c i=new S c i l a b ( ) ;
i f ( s c i . open ( ) ) {
S t r i n g [ ] s={ d e f f ( \ y=f c t ( x ) \ , \ y =2.xx . x \ ) , [ x , y , i n f o ]= f s o l v e ( 0 . 5 , f c t ) } ;
s c i . exec ( s ) ;
S c i l a b D o u b l e s c i x =( S c i l a b D o u b l e ) s c i . g e t ( x ) ;
double [ ] [ ] x=s c i x . g e t R e a l P a r t ( ) ;
System . out . p r i n t l n ( S o l u t i a : +x [ 0 ] [ 0 ] ) ;
S c i l a b D o u b l e s c i y =( S c i l a b D o u b l e ) s c i . g e t ( y ) ;
double [ ] [ ] y=s c i y . g e t R e a l P a r t ( ) ;
System . out . p r i n t l n ( V a l o a r e a f u n c t i e i i n s o l u t i e : +y [ 0 ] [ 0 ] ) ;
16
17
18
S c i l a b D o u b l e s c i i n f o =( S c i l a b D o u b l e ) s c i . g e t ( i n f o ) ;
double [ ] [ ] i n f o= s c i i n f o . g e t R e a l P a r t ( ) ;
System . out . p r i n t l n ( I n d i c a t o r u l de r a s p u n s : +i n f o [ 0 ] [ 0 ] ) ;
sci . close ();
20
21
22
23
}
else {
System . out . p r i n t l n ( Could not s t a r t S c i l a b ) ;
}
24
25
26
27
}
catch ( o r g . s c i l a b . modules . j a v a s c i . J a v a s c i E x c e p t i o n e ) {
System . e r r . p r i n t l n ( An e x c e p t i o n o c c u r e d : + e . g e t L o c a l i z e d M e s s a g e ( ) ) ;
}
28
29
30
31
32
33
R
4
import o r g . s c i l a b . modules . j a v a s c i . S c i l a b ;
import o r g . s c i l a b . modules . t y p e s . S c i l a b T y p e ;
import o r g . s c i l a b . modules . t y p e s . S c i l a b D o u b l e ;
public c l a s s
TstJavaSci3 {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
try {
S c i l a b s c i=new S c i l a b ( ) ;
i f ( s c i . open ( ) ) {
S t r i n g f c t= \ l o g (1+ tan ( x ) ) \ ;
S t r i n g v a r= \ x \ ;
S t r i n g lowerBound= 0 ;
S t r i n g upperBound=%p i /4 ;
S t r i n g scicomm=u=i n t e g r a t e ( +f c t+ , +v a r+ , +lowerBound+ , +upperBound+ ) ;
boolean e r r o r=s c i . e x e c ( scicomm ) ;
System . out . p r i n t l n ( O p e r a t i a sa t e r m i n a t cu s u c c e s ( t r u e / f a l s e ) : +e r r o r ) ;
S c i l a b D o u b l e s c i u =( S c i l a b D o u b l e ) s c i . g e t ( u ) ;
58
double [ ] [ ] u=s c i u . g e t R e a l P a r t ( ) ;
System . out . p r i n t l n ( I n t e g r a l a : +u [ 0 ] [ 0 ] ) ;
sci . close ();
18
19
20
}
else {
System . out . p r i n t l n ( Could not s t a r t S c i l a b ) ;
}
21
22
23
24
}
catch ( o r g . s c i l a b . modules . j a v a s c i . J a v a s c i E x c e p t i o n e ) {
System . e r r . p r i n t l n ( An e x c e p t i o n o c c u r e d : + e . g e t L o c a l i z e d M e s s a g e ( ) ) ;
}
25
26
27
28
29
30
Rezultatele sunt:
Operatia s-a terminat cu succes (true/false) : true
Integrala : 0.27219826128795027
import o r g . s c i l a b . modules . j a v a s c i . S c i l a b ;
import o r g . s c i l a b . modules . t y p e s . S c i l a b T y p e ;
import o r g . s c i l a b . modules . t y p e s . S c i l a b D o u b l e ;
public c l a s s
TstJavaSci4 {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
try {
S c i l a b s c i=new S c i l a b ( ) ;
i f ( s c i . open ( ) ) {
double [ ] [ ] r e = { { 1 } , { 1 } } ;
double [ ] [ ] im ={{2 ,} ,{ 1}};
S c i l a b D o u b l e s c i z=new S c i l a b D o u b l e ( re , im ) ;
s c i . put ( z , s c i z ) ;
s c i . e x e c ( w=z ( 1 ) z ( 2 ) ) ;
S c i l a b D o u b l e s c i w =( S c i l a b D o u b l e ) s c i . g e t ( w ) ;
double [ ] [ ] w r e=s c i w . g e t R e a l P a r t ( ) ;
double [ ] [ ] w im=s c i w . g e t I m a g i n a r y P a r t ( ) ;
System . out . p r i n t l n ( w r e [ 0 ] [ 0 ] + I +w im [ 0 ] [ 0 ] ) ;
sci . close ();
}
else {
System . out . p r i n t l n ( Could not s t a r t S c i l a b ) ;
}
20
21
22
23
24
}
catch ( o r g . s c i l a b . modules . j a v a s c i . J a v a s c i E x c e p t i o n e ) {
System . e r r . p r i n t l n ( An e x c e p t i o n o c c u r e d : + e . g e t L o c a l i z e d M e s s a g e ( ) ) ;
}
25
26
27
28
29
30
x1 + x 2 + x3 + x4
2x1 x2 + 2x3 x4
x1 + 2x2 x3 + 2x4
2x
x2 + 4x3 + x4
1 +
liniare
=
2
=
1
= 1
=
7
= 5
59
x1
1
x2 1
x3 = 2 +
x4
0
1
c =
0
1
0
1
1
1
+ 2
0
2
1
0
2
0
c .
(2.1)
unde c R.
In Scilab, rezolvarea unui sistem algebric de ecuatii liniare Ax+b = 0, A Mm,n (R), b
n
R , se obtine cu functia [x,k]=linsolve(A,b). x este o solutie particulara a sistemului n timp ce k este o matrice avand drept coloane o baza ortonormata a nucleului
Ker(A) = {x Rn : Ax = 0}. Daca sistemul este incompatibil atunci rezultatele sunt
x = [ ], k = [ ].
1
2
3
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import o r g . s c i l a b . modules . j a v a s c i . S c i l a b ;
import o r g . s c i l a b . modules . t y p e s . S c i l a b T y p e ;
import o r g . s c i l a b . modules . t y p e s . S c i l a b D o u b l e ;
public c l a s s
TstJavaSci5 {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
try {
S c i l a b s c i=new S c i l a b ( ) ;
i f ( s c i . open ( ) ) {
double [ ] [ ] a = { { 1 , 1 , 1 , 1 } , { 2 , 1 , 2 , 1 } , { 1 , 2 , 1 , 2 } , { 2 , 1 , 4 , 1 } , { 3 , 2 , 2 , 2 } } ;
S c i l a b D o u b l e s c i a=new S c i l a b D o u b l e ( a ) ;
s c i . put ( a , s c i a ) ;
double [ ] [ ] b ={{2} ,{1} ,{ 1} ,{7} ,{ 5}};
S c i l a b D o u b l e s c i b=new S c i l a b D o u b l e ( b ) ;
s c i . put ( b , s c i b ) ;
// b o o l e a n e r r o r=s c i . e x e c ( [ x , k ]= l i n s o l v e (+a+,+b + )) ;
boolean e r r o r=s c i . e x e c ( [ x , k]= l i n s o l v e ( a ,b ) ) ;
System . out . p r i n t l n ( O p e r a t i a sa t e r m i n a t cu s u c c e s ( t r u e / f a l s e ) : +e r r o r ) ;
S c i l a b D o u b l e s c i x =( S c i l a b D o u b l e ) s c i . g e t ( x ) ;
i f ( ! s c i x . isEmpty ( ) ) {
double [ ] [ ] x=s c i x . g e t R e a l P a r t ( ) ;
System . out . p r i n t l n ( x : ) ;
f o r ( i n t i =0; i <x . l e n g t h ; i ++){
f o r ( i n t j =0; j <x [ 0 ] . l e n g t h ; j ++)
System . out . p r i n t ( x [ i ] [ j ]+ ) ;
System . out . p r i n t l n ( ) ;
}
}
S c i l a b D o u b l e s c i k =( S c i l a b D o u b l e ) s c i . g e t ( k ) ;
i f ( ! s c i k . isEmpty ( ) ) {
double [ ] [ ] k=s c i k . g e t R e a l P a r t ( ) ;
System . out . p r i n t l n ( k : ) ;
f o r ( i n t i =0; i <k . l e n g t h ; i ++){
f o r ( i n t j =0; j <k [ 0 ] . l e n g t h ; j ++)
System . out . p r i n t ( k [ i ] [ j ]+ ) ;
System . out . p r i n t l n ( ) ;
}
}
sci . close ();
}
else {
System . out . p r i n t l n ( Could not s t a r t S c i l a b ) ;
}
}
catch ( o r g . s c i l a b . modules . j a v a s c i . J a v a s c i E x c e p t i o n e ) {
System . e r r . p r i n t l n ( An e x c e p t i o n o c c u r e d : + e . g e t L o c a l i z e d M e s s a g e ( ) ) ;
}
}
60
49
Rezultatele sunt:
Operatia s-a terminat cu succes (true/false) : true
x:
- 1.0000000000000002
0.5000000000000001
2.0000000000000013
0.4999999999999983
k:
8.326672684688674E-17
- 0.7071067811865475
- 3.0531133177191805E-16
0.7071067811865474
1 T
) . Notand cu u si v cele doua solutii particulare
k aproximeaza versorul (0, 12 , 0,
2
puse n evidenta la scrierea solutiei n (2.1) si respectiv cea data de functia linsolve,
u = (1, 1, 2, 0)T , v = (1, 0.5, 2, 0.5)T , vom avea
1
u v = (0, 0.5, 0, 0.5)T = k KerA.
2
Pentru rezolvarea unui sistem algebric de ecuatii liniare de forma Ax = b, extindem
mini-biblioteca mathlib cu o implementare bazata pe functia Scilab linsolve.
Extinderea este ilustrata n schema de mai jos
src
|-->
|
|
|
|
|
|
|
|
|
mathlib
|--> client
|
|
. . .
|
|--> linear
|
|
|--> impl
|
|
|
|
RezolvitorScilab.java // implementeaza interfata
|
|
|
IRezolvitorScilab.java
// interfata
|
|
|
DataIn.java
|
|
|
DataOut.java
|
|
. . .
package m a t h l i b . c l i e n t . l i n e a r ;
/
I n t e r f a t a r e z o l v a r i i unui s i s t e m a l g e b r i c de e c u a t i i l i n i a r e
via Scilab .
/
public i n t e r f a c e I R e z o l v i t o r S c i l a b {
/
R e z o l v a r e a unui s i s t e m a l g e b r i c de e c u a t i i l i n i a r e
via Scilab .
/
public DataOut r e z o l v i t o r S c i l a b ( DataIn d i n ) ;
}
2. Clasa mathlib.client.linear.DataIn.java
1
2
3
4
5
6
7
8
9
package m a t h l i b . c l i e n t . l i n e a r ;
import j a v a . u t i l . V e c t o r ;
import j a v a . i o . B u f f e r e d R e a d e r ;
/
Clasa a c o p e r i t o a r e a d a t e l o r necesare r e z o l v a r i i
unui s i s t e m a l g e b r i c de e c u a t i i l i n i a r e
/
public c l a s s DataIn {
private double [ ] [ ] m a t r i x=n u l l ;
// m a t r i c e a e x t i n s a a s i s t e m u l u i
/
Fixeaza matricea e x t i n s a a s i s t e m u l u i a l g e b r i c .
@param m a t r i x m a t r i c e a e x t i n s a a s i s t e m u l u i .
/
public void s e t M a t r i x ( double [ ] [ ] m a t r i x ) {
t h i s . m a t r i x=m a t r i x ;
}
/
Fixeaza matricea e x t i n s a a s i s t e m u l u i a l g e b r i c .
@param b r f l u x c a r e f u r n i z e a z a m a t r i c e a e x t i n s a a s i s t e m u l u i ;
d a t e l e s u n t t r a n s m i s e pe l i n i i .
/
public void s e t M a t r i x ( B u f f e r e d R e a d e r br ) throws E x c e p t i o n {
Vector<Double> v=new Vector<Double > ( 1 0 ) ;
try {
String line ;
i n t m=0 ,n , mn ;
do{
l i n e=br . r e a d L i n e ( ) ;
i f ( l i n e != n u l l ) {
m++;
S t r i n g [ ] r e s u l t=l i n e . s p l i t ( ) ;
n=r e s u l t . l e n g t h ;
for ( S t r i n g s : r e s u l t )
v . addElement (new Double ( s ) ) ;
}
}
while ( l i n e != n u l l ) ;
i f ( v . s i z e () >0){
mn=v . s i z e ( ) ;
n=mn/m;
m a t r i x=new double [m ] [ n ] ;
f o r ( i n t i =0; i <m; i ++){
f o r ( i n t j =0; j <n ; j ++){
m a t r i x [ i ] [ j ] = ( ( Double ) v . elementAt ( i n+j ) ) . d o u b l e V a l u e ( ) ;
System . out . p r i n t ( m a t r i x [ i ] [ j ]+ ) ;
}
System . out . p r i n t l n ( ) ;
}
}
}
catch ( E x c e p t i o n e ) {
throw new E x c e p t i o n ( e . g e t M e s s a g e ( ) ) ;
}
}
/
Returneaza m a t r i c e a s i s t e m u l u i .
/
public double [ ] [ ] g e t M a t r i x ( ) {
return m a t r i x ;
}
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
61
62
package m a t h l i b . c l i e n t . l i n e a r ;
/
Clasa a c o p e r i t o a r e a r e z u l t a t e l o r o b t i n u t e
l a r e z o l v a r e a unui s i s t e m a l g e b r i c de e c u a t i i l i n i a r e
/
public c l a s s DataOut {
private double [ ] x=n u l l ;
// s o l u t i e p a r t i c u l a r a
private double [ ] [ ] k=n u l l ; // b a z a a s p a t i u l u i l i n i a r a l
// s o l u t i i l o r s i s t e m u l u i omogen
private boolean c o m p a t i b i l ;
// n a t u r a s i s t e m u l u i
/
Returneaza o s o l u t i e p a r t i c u l a r a a s i s t e m u l u i .
/
public double [ ] getX ( ) {
return x ;
}
/
Fixeaza o s o l u t i e p a r t i c u l a r a a s i s t e m u l u i .
/
public void setX ( double [ ] x ) {
t h i s . x=x ;
}
12
13
14
15
16
17
18
19
20
21
22
23
/
Returneaza o b a z a n o r m a l i z a t a a s o l u t i i l o r
s i s t e m u l u i omogen .
/
public double [ ] [ ] getK ( ) {
return k ;
}
/
Fixeaza o baza normalizata a s o l u t i i l o r
s i s t e m u l u i omogen .
/
public void setK ( double [ ] [ ] k ) {
t h i s . k=k ;
}
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/
Returneaza n a t u r a s i s t e m u l u i .
/
public boolean i s C o m p a t i b i l ( ) {
return c o m p a t i b i l ;
}
/
Fixeaza natura s i s t e m u l u i .
/
public void s e t C o m p a t i b i l ( boolean c o m p a t i b i l ) {
t h i s . c o m p a t i b i l=c o m p a t i b i l ;
}
40
41
42
43
44
45
46
47
48
49
50
51
52
4. Clasa mathlib.client.linear.impl.RezolvitorScilab.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package m a t h l i b . c l i e n t . l i n e a r . impl ;
import o r g . s c i l a b . modules . j a v a s c i . S c i l a b ;
import o r g . s c i l a b . modules . t y p e s . S c i l a b T y p e ;
import o r g . s c i l a b . modules . t y p e s . S c i l a b D o u b l e ;
import m a t h l i b . c l i e n t . l i n e a r . ;
/
Implementarea r e z o l v a r i i unui s i s t e m a l g e b r i c de e c u a t i i
l i n i a r e prin apelarea f u n c t i e i l i n s o l v e din S c i l a b
/
public c l a s s R e z o l v i t o r S c i l a b implements I R e z o l v i t o r S c i l a b {
/
Metoda de r e z o l v a r e a s i s t e m u l u i a l g e b r i c de e c u a t i i l i n i a r e .
/
public DataOut r e z o l v i t o r S c i l a b ( DataIn d i n ) {
DataOut dout=new DataOut ( ) ;
double [ ] [ ] m a t r i x=d i n . g e t M a t r i x ( ) ;
i n t l=m a t r i x . l e n g t h ;
i n t c=m a t r i x [ 0 ] . l e n g t h ;
double [ ] [ ] a=new double [ l ] [ c 1 ] ;
double [ ] [ ] b=new double [ l ] [ 1 ] ;
f o r ( i n t i =0; i <l ; i ++){
f o r ( i n t j =0; j <c 1; j ++)
a [ i ] [ j ]= m a t r i x [ i ] [ j ] ;
b [ i ] [ 0 ] = matrix [ i ] [ c 1];
}
try {
S c i l a b s c i=new S c i l a b ( ) ;
i f ( s c i . open ( ) ) {
S c i l a b D o u b l e s c i a=new S c i l a b D o u b l e ( a ) ;
s c i . put ( a , s c i a ) ;
S c i l a b D o u b l e s c i b=new S c i l a b D o u b l e ( b ) ;
s c i . put ( b , s c i b ) ;
boolean e r r o r=s c i . e x e c ( [ x , k]= l i n s o l v e ( a ,b ) ) ;
System . out . p r i n t l n ( S u c c e s s f l a g ( t r u e / f a l s e ) : +e r r o r ) ;
S c i l a b D o u b l e s c i x =( S c i l a b D o u b l e ) s c i . g e t ( x ) ;
i f ( ! s c i x . isEmpty ( ) ) {
double [ ] [ ] x=s c i x . g e t R e a l P a r t ( ) ;
double [ ] x1=new double [ x . l e n g t h ] ;
f o r ( i n t i =0; i <x . l e n g t h ; i ++)
x1 [ i ]=x [ i ] [ 0 ] ;
dout . setX ( x1 ) ;
}
S c i l a b D o u b l e s c i k =( S c i l a b D o u b l e ) s c i . g e t ( k ) ;
i f ( ! s c i k . isEmpty ( ) ) {
double [ ] [ ] k=s c i k . g e t R e a l P a r t ( ) ;
dout . setK ( k ) ;
}
i f ( s c i x . g e t R e a l P a r t ( ) . l e n g t h ==0)
dout . s e t C o m p a t i b i l ( f a l s e ) ;
else
dout . s e t C o m p a t i b i l ( true ) ;
sci . close ();
}
else {
System . out . p r i n t l n ( Could not s t a r t S c i l a b ) ;
}
}
catch ( o r g . s c i l a b . modules . j a v a s c i . J a v a s c i E x c e p t i o n e ) {
System . e r r . p r i n t l n ( An e x c e p t i o n o c c u r e d : + e . g e t L o c a l i z e d M e s s a g e ( ) ) ;
}
return dout ;
}
}
63
64
Capitolul 3
Pachete Java de calcul numeric
In prezent sunt disponibile mai multe pachete de clase Java cu facilitati de calcul
numeric. Dintre cele accesibile gratuit din internet, vom prezenta doar doua produse prin
exemple simple.
Pentru utilizare este nevoie doar de arhiva jar, care se gaseste n catalogul care se
obtine n urma dezarhivarii fisierului descarcat din internet.
De cele mai multe ori, semnificatia parametrilor formali ai metodelor este imediata,
n plus, prezentarea lor se poate citi din descrierea claselor (apidocs).
3.1
apache commons-math
65
66
9
10
11
12
13
14
. s o l v e r s . NewtonRaphsonSolver ;
. UnivariateFunction ;
. differentiation .
. differentiation .
c l a s s F u n c t i a implements U n i v a r i a t e D i f f e r e n t i a b l e F u n c t i o n {
public D e r i v a t i v e S t r u c t u r e v a l u e ( D e r i v a t i v e S t r u c t u r e x ) {
D e r i v a t i v e S t r u c t u r e t 1=x . m u l t i p l y ( Math . l o g ( 2 ) ) . exp ( ) ;
D e r i v a t i v e S t r u c t u r e t 2=x . pow ( 2 ) ;
return new D e r i v a t i v e S t r u c t u r e ( 1 , t1 , 1 , t 2 ) ;
}
public double v a l u e ( double x ) {
return Math . exp ( xMath . l o g (2)) xx ;
}
16
17
18
19
21
public c l a s s MetodaTangentei {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
U n i v a r i a t e D i f f e r e n t i a b l e F u n c t i o n f u n c t i o n = new F u n c t i a ( ) ;
double a b s o l u t e A c c u r a c y =1.0 e 5;
NewtonRaphsonSolver s o l v e r=
new NewtonRaphsonSolver ( a b s o l u t e A c c u r a c y ) ;
i n t maxEval =1000;
double min = 0.8;
double max= 0.5;
try {
double c = s o l v e r . s o l v e ( maxEval , f u n c t i o n , min , max ) ;
System . out . p r i n t l n ( S o l u t i a : +c ) ;
}
catch ( E x c e p t i o n e ) {
System . out . p r i n t l n ( E x c e p t i o n : +e . g e t M e s s a g e ( ) ) ;
}
}
}
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
10
11
12
i n t grad=r e a l C o e f f . l e n g t h ;
Complex [ ] c o m p l e x C o e f f=new Complex [ grad ] ;
f o r ( i n t i =0; i <grad ; i ++)
c o m p l e x C o e f f [ i ]=new Complex ( r e a l C o e f f [ i ] , i m a g C o e f f [ i ] ) ;
try {
Complex [ ] r o o t s = s o l v e r . s o l v e A l l ( c o m p l e x C o e f f , i n i t i a l ) ;
System . out . p r i n t l n ( R a d a c i n i l e : ) ;
f o r ( i n t i =0; i <grad ; i ++)
System . out . p r i n t l n ( r o o t s [ i ] . g e t R e a l ()+ +I +
roots [ i ] . getImaginary ( ) ) ;
}
catch ( E x c e p t i o n e ) { }
14
15
16
17
18
19
20
21
22
23
24
25
26
27
67
import
o r g . apache . commons . math . a n a l y s i s . i n t e r p o l a t i o n . S p l i n e I n t e r p o l a t o r ;
import
o r g . apache . commons . math . a n a l y s i s . i n t e r p o l a t i o n . U n i v a r i a t e R e a l I n t e r p o l a t o r ;
import o r g . apache . commons . math . a n a l y s i s . U n i v a r i a t e R e a l F u n c t i o n ;
public c l a s s I n t e r p o l a r e S p l i n e {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
double x [ ] = { 2 , 1 , 0 , 1 , 2 } ;
double y [ ] = { 2 , 1 , 0 , 1 , 2 } ;
try {
U n i v a r i a t e R e a l I n t e r p o l a t o r i n t e r p o l a t o r=new S p l i n e I n t e r p o l a t o r ( ) ;
U n i v a r i a t e R e a l F u n c t i o n f u n c t i o n=i n t e r p o l a t o r . i n t e r p o l a t e ( x , y ) ;
double t = 0 . 5 ;
double z=f u n c t i o n . v a l u e ( t ) ;
System . out . p r i n t l n ( V a l o a r e a i n t e r p o l a t a i n +t+ e s t e +z ) ;
}
catch ( E x c e p t i o n e ) {
System . out . p r i n t l n ( E x c e p t i o n : +e . g e t M e s s a g e ( ) ) ;
}
}
}
68
Integrare numerica. Se poate utiliza metoda trapezelor, metoda Simpson sau metoda
Romberg (extrapolare tip Richardson pornind de la metoda trapezelor).
Exemplul 3.1.4 Sa se calculeze
R
4
ln 2 0.2721983.
x = (xk )0kn1
n1
X
xj wkj ,
y = (yk )0kn1
0 k n 1,
(3.1)
j=0
unde w = e
i 2
n
a0 X
f (x) =
+
(ak cos kx + bk sin kx)
2
k=1
(3.2)
69
avand coeficientii
Z
1 2
f (x)dx
a0 =
0
1
ak =
1
bk =
n1
1 X 2 ik( 2 j)
1 X 2
n
f ( j)e
f ( j)wjk .
ck
=
n j=0
n
n j=0
n
(3.3)
Astfel, sirul c = (ck )0kn1 este aproximat de n1 Fn (y), unde y = (yj )0jn1 , yj =
f ( 2
j).
n
1
2
3
4
6
7
8
9
10
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import
import
import
import
c l a s s F u n c t i a implements U n i v a r i a t e R e a l F u n c t i o n {
public double v a l u e ( double x ) {
return Math . s i n ( x)+Math . c o s ( 3 x ) ;
}
}
public c l a s s C o e f i c i e n t i F o u r i e r {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
i n t n=16;
double e p s=1e 15;
U n i v a r i a t e R e a l F u n c t i o n f u n c t i o n = new F u n c t i a ( ) ;
double [ ] f V a l=new double [ n ] ;
double [ ] a=new double [ n ] ;
double [ ] b=new double [ n ] ;
Complex [ ] f f t =new Complex [ n ] ;
DecimalFormat f=new DecimalFormat ( 0 . 0 0 0 0 E0 ) ;
try {
f o r ( i n t i =0; i <n ; i ++)
f V a l [ i ]= f u n c t i o n . v a l u e ( 2 i Math . PI /n ) ;
F a s t F o u r i e r T r a n s f o r m e r t r a n s f o r m e r=new F a s t F o u r i e r T r a n s f o r m e r ( ) ;
f f t =t r a n s f o r m e r . t r a n s f o r m ( f V a l ) ;
f o r ( i n t i =0; i <n ; i ++){
a [ i ]=2 f f t [ i ] . g e t R e a l ( ) / n ;
i f ( Math . abs ( a [ i ]) < e p s ) a [ i ] = 0 ;
b [ i ]=2 f f t [ i ] . g e t I m a g i n a r y ( ) / n ;
i f ( Math . abs ( b [ i ]) < e p s ) b [ i ] = 0 ;
}
System . out . p r i n t l n ( C o e f i c i e n t i i F o u r i e r : ) ;
f o r ( i n t i =0; i <n / 2 ; i ++)
System . out . p r i n t l n ( a [ +i+ ] = +f . f o r m a t ( a [ i ])+
b [ +i+ ] = +f . f o r m a t ( b [ i ] ) ) ;
}
catch ( E x c e p t i o n e ) {
System . out . p r i n t l n ( E x c e p t i o n : +e . g e t M e s s a g e ( ) ) ;
}
}
}
70
=
=
=
=
=
=
=
=
0.0000E0
1.0000E0
0.0000E0
0.0000E0
0.0000E0
0.0000E0
0.0000E0
0.0000E0
Rezolvarea problemelor cu conditii initiale pentru ecuatii si sisteme de ecuatii diferentiale ordinare.
1
2
3
4
5
6
8
9
10
11
import
import
import
import
import
import
c l a s s Problema implements F i r s t O r d e r D i f f e r e n t i a l E q u a t i o n s {
public void c o m p u t e D e r i v a t i v e s ( double t , double [ ] y , double [ ] yDot ) {
yDot [ 0 ] = y [ 0 ] ;
}
public i n t g e t D i m e n s i o n ( ) {
return 1 ;
}
13
14
15
16
18
public c l a s s MetodaRungeKutta {
s t a t i c i n t k=1;
s t a t i c double [ ] [ ] z=new double [ 1 0 1 ] [ 2 ] ;
19
20
22
23
24
25
26
27
28
29
30
31
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
71
3.2. JAMA
52
53
3.2
Jama
Jama - Java matrix contine clase pentru rezolvarea unor probleme de algebra liniara
(matrice; factorizarea LU, QR, Cholesky; valori proprii, descompunerea valorii singulare).
Exemplul 3.2.1 Sa se rezolve sistemul algebric
x1 + 2x2 + 3x3
4x1 + x2 + 2x3
de ecuatii liniare
+ 4x4
+ x4
+ 2x4
+ 3x4
=
=
=
=
11
12
13
14
Pentru rezolvarea unui sistem Ax = b, metoda solve a clasei Matrix se poate folosi doar
n cazul matricei A nesingulare. Codul rezolvarii este extrem de simplu:
1
2
3
5
6
7
8
9
import Jama . ;
import j a v a . i o . ;
import j a v a . t e x t . ;
public c l a s s S i s t e m L i n i a r {
public s t a t i c void main ( S t r i n g a r g s [ ] ) {
double [ ] [ ] a = { { 1 , 2 , 3 , 4 } , { 2 , 3 , 4 , 1 } , { 3 , 4 , 1 , 2 } , { 4 , 1 , 2 , 3 } } ;
double [ ] b = { 1 1 , 1 2 , 1 3 , 1 4 } ;
i n t n=a . l e n g t h ;
Matrix A=new Matrix ( a ) ;
Matrix B=new Matrix ( b , n ) ;
Matrix X=A. s o l v e (B ) ;
System . out . p r i n t l n ( S o l u t i a ) ;
X. p r i n t ( NumberFormat . g e t N u m b e r I n s t a n c e ( ) , 1 0 ) ;
11
12
13
14
15
16
17
1
2 1 3
2
2
4 2 5
1
A = 1 2 1 3 4
.
3
6
2 10 7
1
2
4
0
4
Din nou codul este explicit:
1
2
3
5
6
7
8
import Jama . ;
import j a v a . i o . ;
import j a v a . t e x t . ;
public c l a s s LUfact {
public s t a t i c void main ( S t r i n g a r g s [ ] ) {
double [ ] [ ] a ={{1 ,2 , 1 ,3 ,2} ,{2 ,4 , 2 ,5 ,1} ,{ 1 , 2 ,1 , 3 , 4} ,
{3 ,6 ,2 ,10 ,7} ,{1 ,2 ,4 ,0 ,4}};
72
i n t n=a . l e n g t h ;
Matrix l , u , p , v ;
int [ ] piv ;
Matrix m=new Matrix ( a ) ;
LUDecomposition l u=m. l u ( ) ;
l=l u . getL ( ) ;
u=l u . getU ( ) ;
p i v=l u . g e t P i v o t ( ) ;
System . out . p r i n t l n ( M a t r i c e a L ) ;
l . p r i n t ( NumberFormat . g e t N u m b e r I n s t a n c e ( ) , 1 0 ) ;
System . out . p r i n t l n ( M a t r i c e a U ) ;
u . p r i n t ( NumberFormat . g e t N u m b e r I n s t a n c e ( ) , 1 0 ) ;
System . out . p r i n t l n ( M a t r i c e a P ) ;
p=new Matrix ( n , n ) ;
f o r ( i n t i =0; i <n ; i ++)
p . s e t ( i , piv [ i ] , 1 ) ;
p . p r i n t ( NumberFormat . g e t N u m b e r I n s t a n c e ( ) , 1 0 ) ;
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
System . out . p r i n t l n ( V e r i f i c a r e : P A L U = 0 ( ? ) ) ;
v=new Matrix ( n , n ) ;
v=p . t i m e s (m) . minus ( l . t i m e s ( u ) ) ;
v . p r i n t ( NumberFormat . g e t N u m b e r I n s t a n c e ( ) , 1 0 ) ;
28
29
30
31
32
33
cu rezultatele
Matricea L
1
0.667
0.333
0.333
-0.333
0
1
0
0
0
0
0
1
-0.5
0.5
0
0
0
1
-1
0
0
0
0
1
6
0
0
0
0
2
-3.333
3.333
0
0
10
-1.667
-3.333
-2
0
7
-3.667
1.667
0.5
-2
0
1
0
0
0
0
0
0
0
1
1
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
Matricea U
3
0
0
0
0
Matricea P
0
0
0
1
0
Verificare : P A - L U = 0 (?)
0
0
0
0
0
0
0
0
0
0
0
-0
0
-0
0
Capitolul 4
Calcul simbolic n Java
Cel mai simplu mod de efectuare a unor calcule simbolice ntr-un program Java este
prin intermediul produselor Mathematica, Maple.
Symja - Java Computer Algebra Library este o biblioteca de pachete Java pentru calcul
simbolic (https://bitbucket.org/axelclk/symja_android_library/wiki/Home) dar
si numeric.
4.1
Structura unui program Java care apeleaza o functie Mathematica de calcul simbolic
este cea prezentata n 2.1.
Apelarea si generarea rezultatului sub forma uzuala din consola Mathematica se obtine
cu functia clasei com.wolfram.jlink.KernelLink
evaluateToOutputForm(String apelMathematica, 0)
Pentru descompunerea n factori a expresiei algebrice (x+y)7 x7 y 7 codul de apelare
a functiei Factor este
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
73
74
finally {
ml . c l o s e ( ) ;
}
22
23
24
25
26
Rezultatul va fi
Factor[(x + y)7 x7 y7 ]
7xy(x + y)(x2 + xy + y 2 )2
Analog
R
integrala 04 ln (1 + tan x)dx se calculeaza cu functia Integrate[Log[1+Tan[x]],x,
.
0,Pi/4] din Mathematica. Se obtine: Pi Log[2]
8
problema cu valoare initiala y+y
4.2
Sablonul de programare coincide cu cel prezentat n sectiunea 2.2. Pentru descompunerea n factori a expresiei algebrice (x + y)7 x7 y 7 codul este
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Rezultatul este
7*x*y*(x+y)*(x^2+x*y+y^2)^2
y(x)=cos(x)*tan(x)+cos(x)
. Pentru expresia
simplify(dsolve(diff(y(x),x)+y(x)*tan(x)-1/cos(x)=0,y(0)=1,y(x)));
se va obtine
y(x)=sin(x)+cos(x)
4.3
75
sunt echivalente.
Trebuie subliniat ca posibilitatile de calcul simbolic nu coincid cu cele din Mathematica.
Sablonul de programare este
ExprEvaluator util = new ExprEvaluator();
IExpr result=util.evaluate("Expresia de calcul");
System.out.println(result.toString());
d sin 2x cos x
;
dx
3.
d2 arctan x
;
dx2
4.
5.
1
dx;
1+x4
0
1
dx;
1+x2
cu codul Java
1
2
4
5
6
7
8
9
11
12
14
15
17
18
20
21
import o r g . m a t h e c l i p s e . c o r e . e v a l . E x p r E v a l u a t o r ;
import o r g . m a t h e c l i p s e . c o r e . i n t e r f a c e s . IExpr ;
public c l a s s ESymja{
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
try {
E x p r E v a l u a t o r u t i l = new E x p r E v a l u a t o r ( ) ;
IExpr r e s u l t=u t i l . e v a l u a t e ( F a c t o r [ ( x+y)7x7y 7 ] ) ;
System . out . p r i n t l n ( r e s u l t . t o S t r i n g ( ) ) ;
r e s u l t = u t i l . e v a l u a t e ( D[ S i n [ 2 x ] Cos [ x ] , x ] ) ;
System . out . p r i n t l n ( r e s u l t . t o S t r i n g ( ) ) ;
r e s u l t = u t i l . e v a l u a t e ( D[ ArcTan [ x ] , { x , 2 } ] ) ;
System . out . p r i n t l n ( r e s u l t . t o S t r i n g ( ) ) ;
r e s u l t = u t i l . e v a l u a t e ( I n t e g r a t e [1 /( 1+ x 4 ) , x ] ) ;
System . out . p r i n t l n ( r e s u l t . t o S t r i n g ( ) ) ;
r e s u l t = u t i l . e v a l u a t e ( I n t e g r a t e [1 /( 1+ x 2 ) , { x , 0 , I n f i n i t y } ] ) ;
System . out . p r i n t l n ( r e s u l t . t o S t r i n g ( ) ) ;
76
}
catch ( E x c e p t i o n e ) {
e . printStackTrace ( ) ;
}
22
23
24
25
26
27
Capitolul 5
Expresie de calcul dat
a ca String
Executia unui program de calcul stiintific poate solicita furnizarea de catre client a
unor expresii de calcul. Acestea pot reprezenta membrul stang al unei ecuatii algebrice
f (x) = 0 sau membrul drept al unei ecuatii diferentiele ordinare x = f (x), etc. Expresia
de calcul, notata prin f (x), poate contine simboluri matematice uzuale, chiar nume de
functii.
String-ul introdus de client trebuie interpretat de programul de calcul ca o expresie de
evaluat, chiar permitand evaluarea ei pentru tot felul de valori date parametrilor.
Scopul acestui capitol este prezentarea de solutii pentru aceste probleme.
Vom utiliza produsele informatice:
Java Expression Parser - JEP;
MathEclipse Parser.
In afara acestora semnalam existenta urmatoarelor softuri exp4j, javaluator cat si posibilitatea utilizarii motorului Javascript din Java.
5.1
JEP este probabil produsul cel mai reprezentativ pentru problema enuntata. Pana la
versiunea 2.4.1, JEP a fost un produs gratuit, versiunile urmatoare fiind produse comerciale. Astfel, ne vom limita doar la versiunea gratuita 2.4.1.
Variabila de sistem classpath trebuie sa contina referinta catre jep-2.4.1.jar.
Utilizarea produsului. Evaluarea unei expresii n care intervin variabile se obtine
prin
1. Generarea unui convertor JEP
JEP parser=new JEP();
2. Definirea variabilelor. Daca variabila var are valoarea val definirea ei se face prin
parser.addVariable(var,val);
77
78
CA STRING
CAPITOLUL 5. EXPRESIE DE CALCUL DATA
+ scadere
* mpartire
import o r g . nfunk . j e p . ;
c l a s s TestJep1 {
public s t a t i c void main ( S t r i n g a r g s [ ] ) {
double x=3 ,y =4;
S t r i n g s e x p=x2+y 2 ;
JEP p a r s e r=new JEP ( ) ;
p a r s e r . a d d V a r i a b l e ( x , x ) ;
p a r s e r . a d d V a r i a b l e ( y , y ) ;
parser . parseExpression ( s exp ) ;
double r e z u l t a t=p a r s e r . g e t V a l u e ( ) ;
System . out . p r i n t l n ( R e z u l t a t : +r e z u l t a t ) ;
}
}
4
5
6
7
8
9
10
11
12
13
14
e e pi i = 1 i
Recunoasterea acestor functii si constante presupune declararea lor:
parser.addStandardFunctions();
parser.addStandardConstants();
79
import
import
import
import
c l a s s J e p E r f extends PostfixMathCommand {
public J e p E r f ( ) {
numberOfParameters = 1 ;
}
public void run ( S t a c k i n S t a c k ) throws P a r s e E x c e p t i o n {
checkStack ( inStack ) ;
O b j e c t param = i n S t a c k . pop ( ) ;
i f ( param instanceof Double ) {
try {
double r =0 ,x =(( Double ) param ) . d o u b l e V a l u e ( ) ;
i f ( Math . abs ( x ) <26)
r = Erf . e r f ( x ) ;
else {
i f ( x>0)
r =1;
else
r =1;
}
i n S t a c k . push (new Double ( r ) ) ;
}
catch ( E x c e p t i o n e ) {
throw new P a r s e E x c e p t i o n ( e . g e t M e s s a g e ( ) ) ;
}
}
else {
throw new P a r s e E x c e p t i o n ( I n v a l i d p a r a m e t e r t y p e ) ;
}
}
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
java . u t i l . ;
o r g . nfunk . j e p . ;
o r g . nfunk . j e p . f u n c t i o n . ;
o r g . apache . commons . math3 . s p e c i a l . ;
80
CA STRING
CAPITOLUL 5. EXPRESIE DE CALCUL DATA
double x=10;
String s_exp="erf(x)";
JEP parser=new JEP();
parser.addStandardFunctions();
parser.addStandardConstants();
parser.addFunction("erf", new JepErf());
parser.addVariable("x",x);
parser.parseExpression(s_exp);
double rezultat=parser.getValue();
5.2
MathEclipse-Parser
5.2. MATHECLIPSE-PARSER
81
Pi
import o r g . m a t h e c l i p s e . p a r s e r . c l i e n t . e v a l . ;
import o r g . m a t h e c l i p s e . p a r s e r . c l i e n t . math . ;
public c l a s s E x p r e s i i C o m p l e x e {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
try {
Complex z=new Complex ( 1 , 3 ) ;
System . out . p r i n t ( z= ) ;
System . out . p r i n t l n ( ComplexEvaluator . t o S t r i n g ( z ) ) ;
System . out . p r i n t l n ( C o n j u g a t u l ) ;
Complex w=z . c o n j u g a t e ( ) ;
System . out . p r i n t l n ( ComplexEvaluator . t o S t r i n g (w ) ) ;
System . out . p r i n t l n ( Suma ) ;
System . out . p r i n t l n ( ComplexEvaluator . t o S t r i n g ( z . add (w ) ) ) ;
System . out . p r i n t l n ( P r o d u s u l ) ;
System . out . p r i n t l n ( ComplexEvaluator . t o S t r i n g ( z . m u l t i p l y (w ) ) ) ;
System . out . p r i n t l n ( Catul ) ;
System . out . p r i n t l n ( ComplexEvaluator . t o S t r i n g ( z . d i v i d e (w ) ) ) ;
System . out . p r i n t l n ( Modulul ) ;
System . out . p r i n t l n ( z . abs ( ) ) ;
System . out . p r i n t l n ( \ n F u n c t i i complexe ) ;
System . out . p r i n t l n ( s i n ( z ) ) ;
System . out . p r i n t l n ( ComplexEvaluator . t o S t r i n g ( z . s i n ( ) ) ) ;
System . out . p r i n t l n ( c o s ( z ) ) ;
System . out . p r i n t l n ( ComplexEvaluator . t o S t r i n g ( z . c o s ( ) ) ) ;
35
37
System . out . p r i n t l n ( s i n h ( z ) ) ;
34
82
Complex u=z . s i n h ( ) ;
System . out . p r i n t l n ( ComplexEvaluator . t o S t r i n g ( u ) ) ;
38
39
System . out . p r i n t l n ( c o s h ( z ) ) ;
Complex v=z . c o s h ( ) ;
System . out . p r i n t l n ( ComplexEvaluator . t o S t r i n g ( v ) ) ;
41
42
43
45
46
48
49
50
51
52
53
54
55
56
57
}
catch ( E x c e p t i o n e ) {
System . out . p r i n t l n ( e . g e t M e s s a g e ( ) ) ;
}
58
59
60
61
62
63
CA STRING
CAPITOLUL 5. EXPRESIE DE CALCUL DATA
Capitolul 6
Aplicatii cu interfat
a grafic
a
Atasam o interfata grafica unor aplicatii dezvoltate n capitolele anterioare. Prin intermediul interfetei grafice, un client (utilizator) introduce datele si primeste afisat rezultatul
problemei.
Programarea interfetei grafice se poate baza pe resursele oferite de pachetele javax.swing
si javafx din distributia Java.
Utilizarea mediului integrat de programare (Integrated Development Environment IDE) Netbeans, www.netbeans.org, usureaza mult munca de programare.
6.1
Expresia functiei este introdusa de client sub forma unui string. Aplicand rezultatele
anterioare, extindem mini-biblioteca prezentata n primul capitol cu clase de tip DataIn
care implementeaza corespunzator metoda public double fct(double x).
Componenta Java care retine datele problemei, bazat pe JEP (clasa mathlib.client.
ecalg.JepDataIn), are codul
1
2
3
4
5
6
7
8
9
10
12
13
14
15
16
17
18
19
20
21
22
23
24
package m a t h l i b . c l i e n t . e c a l g ;
import o r g . nfunk . j e p . ;
/
E x t i n d e r e a c l a s e i DataIn cu p r e l u a r e a unor d a t e
ca S t r i n g u r i c a r e s u n t c o n v e r t i t e i n v a l o r i numerice
p r i n p a c h e t u l JEP ( Java E x p r e s s i o n P a r s e r )
/
public c l a s s JepDataIn extends DataIn {
private JEP p a r s e r=n u l l ;
private S t r i n g v a r ;
/
Constructorul c l a s e i care i n s t a n t i a z a s i c a l i b r e a z a
o b i e c t u l JEP u t i l i z a t l a p e n t r u e v a l u a r e a f u n c t i e i .
@param v a r S i m b o l u l v a r i a b i l e i .
@param e x p r E x t r e s i a f u n c t i e i .
/
public JepDataIn ( S t r i n g var , S t r i n g e x p r ) {
t h i s . v a r=v a r ;
p a r s e r=new JEP ( ) ;
p a r s e r . addStandardFunctions ( ) ;
p a r s e r . addStandardConstants ( ) ;
p a r s e r . a d d V a r i a b l e ( var , 0 ) ;
p a r s e r . p ar s eE xp re ss i on ( expr ) ;
83
84
GRAFICA
CAPITOLUL 6. APLICAT
II CU INTERFAT
A
25
27
/
F u n c t i a c o r e s p u n z a t o a r e membrului s t a n g a l e c u a t i e i f c t ( x )=0.
/
public double f c t ( double x ) {
p a r s e r . a d d V a r i a b l e ( var , x ) ;
return p a r s e r . g e t V a l u e ( ) ;
}
28
29
30
31
32
33
34
6.1.1
Interfata grafic
a bazat
a pe JavaFX
package e c u a t i e f x ;
import
import
import
import
javafx
javafx
javafx
javafx
18
import
import
import
import
import
import
import
import
import
import
import
20
public c l a s s E c u a t i e f x extends A p p l i c a t i o n {
4
5
6
8
9
10
11
12
13
14
15
16
17
22
23
24
26
27
28
29
30
. application . Application ;
. e v e n t . ActionEvent ;
. s c e n e . Group ;
. s c e n e . Scene ;
32
34
L a b e l l a b e l V a r=new L a b e l ( V a r i a b i l a ) ;
GridPane . s e t C o n s t r a i n t s ( l a b e l V a r , 1 , 1 ) ;
L a b e l l a b e l A p r o x=new L a b e l ( Aproximatia i n i t i a l a ) ;
GridPane . s e t C o n s t r a i n t s ( l a b e l A p r o x , 1 , 2 ) ;
L a b e l l a b e l E x p r=new L a b e l ( E x p r e s i a membrului s t a n g ) ;
GridPane . s e t C o n s t r a i n t s ( l a b e l E x p r , 1 , 3 ) ;
L a b e l l a b e l T o l=new L a b e l ( T o l e r a n t a ) ;
GridPane . s e t C o n s t r a i n t s ( l a b e l T o l , 1 , 4 ) ;
L a b e l l a b e l N m i=new L a b e l ( Numar maxim de i t e r a t i i ) ;
GridPane . s e t C o n s t r a i n t s ( labelNmi , 1 , 5 ) ;
35
36
37
38
39
40
41
42
43
45
46
47
48
f i n a l T e x t F i e l d T e x t F i e l d V a r=new T e x t F i e l d ( ) ;
GridPane . s e t C o n s t r a i n t s ( TextFieldVar , 2 , 1 ) ;
f i n a l T e x t F i e l d TextFieldAprox=new T e x t F i e l d ( ) ;
GridPane . s e t C o n s t r a i n t s ( TextFieldAprox , 2 , 2 ) ;
49
50
51
52
53
54
56
57
58
59
60
61
62
63
65
66
67
68
69
70
71
72
73
74
75
76
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
104
105
106
107
108
109
110
111
112
113
114
115
f i n a l T e x t F i e l d T e x t F i e l d E x p r=new T e x t F i e l d ( ) ;
GridPane . s e t C o n s t r a i n t s ( TextFieldExpr , 2 , 3 ) ;
f i n a l T e x t F i e l d T e x t F i e l d T o l=new T e x t F i e l d ( 1 . 0 e8 ) ;
GridPane . s e t C o n s t r a i n t s ( T e x t F i e l d T o l , 2 , 4 ) ;
f i n a l T e x t F i e l d TextFieldNmi=new T e x t F i e l d ( 50 ) ;
GridPane . s e t C o n s t r a i n t s ( TextFieldNmi , 2 , 5 ) ;
L a b e l l a b e l I n d=new L a b e l ( I n d i c a t o r u l de r a s p u n s ) ;
GridPane . s e t C o n s t r a i n t s ( l a b e l I n d , 3 , 1 ) ;
L a b e l l a b e l S o l=new L a b e l ( S o l u t i a ) ;
GridPane . s e t C o n s t r a i n t s ( l a b e l S o l , 3 , 2 ) ;
L a b e l l a b e l V a l=new L a b e l ( V a l o a r e a i n s o l u t i e ) ;
GridPane . s e t C o n s t r a i n t s ( l a b e l V a l , 3 , 3 ) ;
L a b e l l a b e l I t e r=new L a b e l ( Numar de i t e r a t i i ) ;
GridPane . s e t C o n s t r a i n t s ( l a b e l I t e r , 3 , 4 ) ;
f i n a l T e x t F i e l d T e x t F i e l d I n d=new T e x t F i e l d ( ) ;
TextFieldInd . s e t V i s i b l e ( false ) ;
GridPane . s e t C o n s t r a i n t s ( T e x t F i e l d I n d , 4 , 1 ) ;
f i n a l T e x t F i e l d T e x t F i e l d S o l=new T e x t F i e l d ( ) ;
TextFieldSol . s e t V i s i b l e ( false ) ;
GridPane . s e t C o n s t r a i n t s ( T e x t F i e l d S o l , 4 , 2 ) ;
f i n a l T e x t F i e l d T e x t F i e l d V a l=new T e x t F i e l d ( ) ;
TextFieldVal . s e t V i s i b l e ( false ) ;
GridPane . s e t C o n s t r a i n t s ( T e x t F i e l d V a l , 4 , 3 ) ;
f i n a l T e x t F i e l d T e x t F i e l d I t e r=new T e x t F i e l d ( ) ;
TextFieldIter . setVisible ( false ) ;
GridPane . s e t C o n s t r a i n t s ( T e x t F i e l d I t e r , 4 , 4 ) ;
Button btn=new Button ( C a l c u l e a z a ) ;
GridPane . s e t C o n s t r a i n t s ( btn , 2 , 6 ) ;
btn . se tO nA ct io n ( (new EventHandler<ActionEvent >() {
public void h a n d l e ( ActionEvent me) {
S t r i n g v a r=T e x t F i e l d V a r . g e t T e x t ( ) ;
S t r i n g e x p r=T e x t F i e l d E x p r . g e t T e x t ( ) ;
DataIn d i n=new JepDataIn ( var , e x p r ) ;
d i n . setX ( (new Double ( TextFieldAprox . g e t T e x t ( ) ) ) . d o u b l e V a l u e ( ) ) ;
d i n . s e t E p s ( (new Double ( T e x t F i e l d T o l . g e t T e x t ( ) ) ) . d o u b l e V a l u e ( ) ) ;
d i n . setNmi ( (new I n t e g e r ( TextFieldNmi . g e t T e x t ( ) ) ) . i n t V a l u e ( ) ) ;
IMetodaTangentei o b j=new MetodaTangenteiWeb ( ) ;
DataOut dout=o b j . metodaTangentei ( d i n ) ;
DecimalFormat f=new DecimalFormat ( 0 . 0 0 0 0 0 E0 ) ;
S t r i n g s o l=f . f o r m a t ( dout . getX ( ) ) ;
S t r i n g v a l=f . f o r m a t ( dout . getF ( ) ) ;
T e x t F i e l d I n d . s e t T e x t ( (new I n t e g e r ( dout . g e t I n d ( ) ) ) . t o S t r i n g ( ) ) ;
T e x t F i e l d I t e r . s e t T e x t ( (new I n t e g e r ( dout . g e t N i ( ) ) ) . t o S t r i n g ( ) ) ;
TextFieldSol . setText ( s o l ) ;
TextFieldVal . setText ( val ) ;
T e x t F i e l d I n d . s e t V i s i b l e ( true ) ;
T e x t F i e l d S o l . s e t V i s i b l e ( true ) ;
T e x t F i e l d V a l . s e t V i s i b l e ( true ) ;
T e x t F i e l d I t e r . s e t V i s i b l e ( true ) ;
}
}));
g r i d p a n e . setVgap ( 8 ) ;
g r i d p a n e . setHgap ( 8 ) ;
gridpane . getChildren ( ) .
addAll ( labelVar , labelAprox , labelExpr , labelTol , labelNmi ) ;
gridpane . getChildren ( ) .
a d d A l l ( TextFieldVar , TextFieldAprox , TextFieldExpr , T e x t F i e l d T o l , TextFieldNmi ) ;
gridpane . getChildren ( ) .
addAll ( l a b e l I n d , l a b e l S o l , labelVal , l a b e l I t e r ) ;
gridpane . getChildren ( ) .
addAll ( TextFieldInd , TextFieldSol , TextFieldVal , T e x t F i e l d I t e r ) ;
g r i d p a n e . g e t C h i l d r e n ( ) . a d d A l l ( btn ) ;
r o o t . g e t C h i l d r e n ( ) . add ( g r i d p a n e ) ;
85
86
GRAFICA
CAPITOLUL 6. APLICAT
II CU INTERFAT
A
116
117
118
119
6.2
6.2.1
Interfata grafic
a bazat
a pe Swing
Clientul editeaza un fisier text cu coeficientii sistemului. Fiecare linie a acestui fisier
va contine coeficientii unei linii a sistemului iar ultimul element va fi termenul liber.
Separatorul este caracterul spatiu (blanc).
Dupa un clic pe butonul Incarca fisierul sistemului va apare fereastra pentru selectarea
fisierului cu datele sistemului (Fig. 6.3).
87
package l i n e a r ;
import j a v a x . swing . J F i l e C h o o s e r ;
import j a v a . i o . ;
88
GRAFICA
CAPITOLUL 6. APLICAT
II CU INTERFAT
A
import m a t h l i b . c l i e n t . l i n e a r . ;
import m a t h l i b . c l i e n t . l i n e a r . impl . R e z o l v i t o r S c i l a b ;
import j a v a . t e x t . DecimalFormat ;
4
5
10
11
12
14
15
16
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public S i s t e m L i n i a r ( ) {
initComponents ( ) ;
}
private void i n i t C o m p o n e n t s ( ) {
// cod g e n e r a t de Netbeans
}
private void jButtonUploadMouseClicked ( j a v a . awt . e v e n t . MouseEvent e v t ) {
jTextFieldStatus . setText ( ) ;
J F i l e C h o o s e r f c=new J F i l e C h o o s e r ( ) ;
fc . setDialogTitle ( Alegeti f i s i e r u l sistemului );
f c . s e t F i l e S e l e c t i o n M o d e ( J F i l e C h o o s e r . FILES ONLY ) ;
DecimalFormat f=new DecimalFormat ( 0 . 0 0 0 0 E0 ) ;
jTextAreaSol . setText ( ) ;
try {
i f ( e v t . g e t S o u r c e ( ) == jButtonUpload ) {
i n t r e t u r n V a l = f c . showOpenDialog ( t h i s ) ;
i f ( r e t u r n V a l == J F i l e C h o o s e r .APPROVE OPTION) {
File f i l e = fc . getSelectedFile ();
F i l e I n p u t S t r e a m f i s =new F i l e I n p u t S t r e a m ( f i l e ) ;
InputStreamReader i s r =new InputStreamReader ( f i s ) ;
B u f f e r e d R e a d e r br=new B u f f e r e d R e a d e r ( i s r ) ;
DataIn d i n=new DataIn ( ) ;
d i n . s e t M a t r i x ( br ) ;
br . c l o s e ( ) ;
isr . close ();
f i s . close ();
I R e z o l v i t o r S c i l a b o b j=new R e z o l v i t o r S c i l a b ( ) ;
DataOut dout=o b j . r e z o l v i t o r S c i l a b ( d i n ) ;
S t r i n g r e z= ;
i f ( dout . i s C o m p a t i b i l ( ) ) {
double [ ] x=dout . getX ( ) ;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
}
else {
r e z= S i s t e m i n c o m p a t i b i l ! ;
}
jTextAreaSol . setText ( rez ) ;
64
65
66
67
68
}
else {
throw new E x c e p t i o n ( A c t i u n e a n u l a t a de c l i e n t . ) ;
}
69
70
71
72
}
}
catch ( E x c e p t i o n ex ) {
j T e x t F i e l d S t a t u s . s e t T e x t ( ex . g e t M e s s a g e ( ) ) ;
}
73
74
75
76
77
78
89
90
80
81
82
83
84
85
86
private
private
private
private
private
private
88
89
90
91
92
93
94
GRAFICA
CAPITOLUL 6. APLICAT
II CU INTERFAT
A
Capitolul 7
Generarea reprezent
arilor grafice
Afirmatia o imagine grafica spune mai multe decat o mie de cuvinte este adevarata n
numeroase cazuri - si cu siguranta cand rezultatele corespund valorilor unei functii.
Exista multe produse informatice care ofera functii pentru obtinerea de reprezentari
grafice.
7.1
PtPlot
O solutie simpla este data de produsul PtPlot, dezvoltat la Universitatea din California.
In cele ce urmeaza vom utiliza interfata de programare oferita (API) pentru generarea
graficului unei functii reale de variabila reala. Este nevoie de arhiva plotapplication.jar
aflata n catalogul ptolemy\plot din distributie.
Problema pe care dorim sa o rezolva este reprezentarea grafica a unei functii reale de
variabila reala.
Datele problemei sunt simbolul variabilei, expresia functiei si intervalul n care se
reprezinta functia. Acest interval poate sa nu fie inclus n domeniul de definitie al functiei.
Ideea reprezentarii este simpla: n intervalul dat, se considera o retea de puncte n care se
calculeaza valorile functiei. Generarea graficului este transparenta programatorului, fiind
efectuata de PtPlot. Rezultatul va fi un obiect java.awt.image.BufferedImage a carei
vizualizare cade n sarcina programatorului.
O problema consta n depistarea punctelor sau intervalelor n care functia nu este
definita.
Utilizarea resursele pachetului PtPlot se declara prin
import ptolemy.plot.*;
91
92
if((Double.isInfinite(y))||(Double.isNaN(y))){
dataset++;
}
else{
plotObj.addPoint(dataset,x,y,true);
}
}
package p l o t 2 d ;
import j a v a . awt . ;
import j a v a x . swing . JFrame ;
public c l a s s ShowImage{
MyCanvas mc=n u l l ;
i n t xDim=0;
i n t yDim=0;
ShowImage ( Image image , i n t xDim , i n t yDim ) {
t h i s . xDim=xDim ;
t h i s . yDim=yDim ;
mc=new MyCanvas ( image ) ;
}
public void show ( ) {
JFrame j f r a m e = new JFrame ( G r a f i c u l f u n c t i e i ) ;
jframe . addNotify ( ) ;
j f r a m e . getContentPane ( ) . s e t L a y o u t (new BorderLayout ( ) ) ;
j f r a m e . getContentPane ( ) . add (mc , BorderLayout .CENTER) ;
j f r a m e . s e t S i z e ( xDim , yDim ) ;
j f r a m e . s e t V i s i b l e ( true ) ;
}
10
11
12
13
14
15
16
17
18
19
20
21
22
23
93
7.1. PTPLOT
package p l o t 2 d ;
import j a v a . awt . ;
public c l a s s MyCanvas extends Canvas {
Image image=n u l l ;
MyCanvas ( Image image ) {
t h i s . image=image ;
}
@Override
public void p a i n t ( G r a p h i c s g ) {
g . drawImage ( image , 0 , 0 , t h i s ) ;
}
7
8
9
10
11
12
13
14
Codul programului cu interfata grafica Swing si care utilizeaza JEP pentru evaluarea
valorilor functiei data ca parametru de tip String este
1
2
3
4
5
7
8
9
package p l o t 2 d ;
import ptolemy . p l o t . ;
import o r g . nfunk . j e p . ;
import j a v a . awt . R e c t a n g l e ;
import j a v a . awt . image . B u f f e r e d I m a g e ;
public c l a s s G r a f i c extends j a v a x . swing . JFrame {
i n t xDim=500;
i n t yDim=300;
94
11
12
13
15
16
17
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
60
61
62
63
64
65
66
68
69
70
71
72
73
74
75
76
public G r a f i c ( ) {
initComponents ( ) ;
}
private void i n i t C o m p o n e n t s ( ) {
// cod g e n e r a t de Netbeans
}
private void j B u t t o n P l o t M o u s e C l i c k e d ( j a v a . awt . e v e n t . MouseEvent e v t ) {
JEP p a r s e r=new JEP ( ) ;
p a r s e r . addStandardFunctions ( ) ;
p a r s e r . addStandardConstants ( ) ;
S t r i n g v a r=j T e x t F i e l d V a r . g e t T e x t ( ) ;
S t r i n g f c t=j T e x t F i e l d F c t . g e t T e x t ( ) ;
S t r i n g l e f t =j T e x t F i e l d I n f . g e t T e x t ( ) ;
parser . parseExpression ( l e f t ) ;
double a=p a r s e r . g e t V a l u e ( ) ;
S t r i n g r i g h t=j T e x t F i e l d S u p . g e t T e x t ( ) ;
parser . parseExpression ( right ) ;
double b=p a r s e r . g e t V a l u e ( ) ;
p a r s e r . a d d V a r i a b l e ( var , 0 ) ;
parser . parseExpression ( f c t ) ;
P l o t p l o t O b j=new P l o t ( ) ;
i n t n=xDim 8 ;
double h , x , y ;
i f ( b<a ) {
h=a ;
a=b ;
b=h ;
}
h=(ba ) / n ;
i n t d a t a s e t =0;
f o r ( i n t i =0; i <=n ; i ++){
x=a+i h ;
p a r s e r . a d d V a r i a b l e ( var , x ) ;
y=p a r s e r . g e t V a l u e ( ) ;
i f ( ( Double . i s I n f i n i t e ( y ) ) | | ( Double . isNaN ( y ) ) ) {
d a t a s e t ++;
}
else {
p l o t O b j . addPoint ( d a t a s e t , x , y , true ) ;
}
}
R e c t a n g l e r e c t a n g l e=new R e c t a n g l e ( xDim , yDim ) ;
B u f f e r e d I m a g e image=p l o t O b j . e x p o r t I m a g e ( r e c t a n g l e ) ;
ShowImage s i=new ShowImage ( image , xDim , yDim ) ;
s i . show ( ) ;
}
public s t a t i c void main ( S t r i n g a r g s [ ] ) {
j a v a . awt . EventQueue . i n v o k e L a t e r (new Runnable ( ) {
public void run ( ) {
new G r a f i c ( ) . s e t V i s i b l e ( true ) ;
}
});
}
private
private
private
private
private
private
private
private
private
j a v a x . swing . JButton j B u t t o n P l o t ;
j a v a x . swing . J L a b e l j L a b e l F c t ;
j a v a x . swing . J L a b e l j L a b e l I n f ;
j a v a x . swing . J L a b e l j L a b e l S u p ;
j a v a x . swing . J L a b e l j L a b e l V a r ;
j a v a x . swing . J T e x t F i e l d j T e x t F i e l d F c t ;
j a v a x . swing . J T e x t F i e l d j T e x t F i e l d I n f ;
j a v a x . swing . J T e x t F i e l d j T e x t F i e l d S t a t u s ;
j a v a x . swing . J T e x t F i e l d j T e x t F i e l d S u p ;
95
7.2. JFREECHART
private j a v a x . swing . J T e x t F i e l d j T e x t F i e l d V a r ;
77
78
7.2
jfreechart
96
7.2. JFREECHART
97
public JFreeChart c r e a t e X Y D i s c o n t i n u o u s C h a r t ( S t r i n g t i t l e ,
S t r i n g xAx isLa bel ,
S t r i n g yAx isLa bel ,
XYDataset d a t a s e t ,
PlotOrientation orientation ,
boolean l e g e n d ,
boolean t o o l t i p s ,
boolean u r l s ) {
NumberAxis xAxis = new NumberAxis ( x A x i s L a b e l ) ;
xAxis . s e t A u t o R a n g e I n c l u d e s Z e r o ( f a l s e ) ;
NumberAxis yAxis = new NumberAxis ( y A x i s L a b e l ) ;
XYItemRenderer r e n d e r e r =
new StandardXYItemRenderer ( StandardXYItemRenderer . DISCONTINUOUS LINES ) ;
XYPlot p l o t = new XYPlot ( d a t a s e t , xAxis , yAxis , r e n d e r e r ) ;
plot . setOrientation ( orientation ) ;
i f ( t o o l t i p s ){
r e n d e r e r . s e t B a s e T o o l T i p G e n e r a t o r (new StandardXYToolTipGenerator ( ) ) ;
}
i f ( u r l s ){
r e n d e r e r . setURLGenerator (new StandardXYURLGenerator ( ) ) ;
}
JFreeChart c h a r t=
new JFreeChart ( t i t l e , new Font ( S a n s S e r i f , Font .BOLD, 1 8 ) , p l o t , l e g e n d ) ;
return c h a r t ;
}
Aceasta reprezentare se utilizeaza doar daca numarul componentelor este cel putin 2.
Pentru exemplul dat, va rezulta imaginea din Fig. 7.3
package p l o t 2 d ;
import o r g . j f r e e . c h a r t . ;
import o r g . j f r e e . data . xy . ;
98
import
import
import
import
import
import
import
import
o r g . j f r e e . c h a r t . r e n d e r e r . xy . ;
org . j f r e e . chart . p l o t . ;
org . j f r e e . chart . a x i s . ;
org . j f r e e . chart . l a b e l s . ;
org . j f r e e . chart . u r l s . ;
j a v a . awt . ;
j a v a . awt . image . ;
o r g . nfunk . j e p . ;
99
7.2. JFREECHART
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
88
public JFreeChart c r e a t e X Y D i s c o n t i n u o u s C h a r t ( . .
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
.){.
. .}
100
return true ;
108
109
111
112
113
114
115
116
117
private
private
private
private
private
private
private
private
private
private
119
120
121
122
123
124
125
126
127
128
129
j a v a x . swing . JButton j B u t t o n P l o t ;
j a v a x . swing . J L a b e l j L a b e l F c t ;
j a v a x . swing . J L a b e l j L a b e l I n f ;
j a v a x . swing . J L a b e l j L a b e l S u p ;
j a v a x . swing . J L a b e l j L a b e l V a r ;
j a v a x . swing . J T e x t F i e l d j T e x t F i e l d F c t ;
j a v a x . swing . J T e x t F i e l d j T e x t F i e l d I n f ;
j a v a x . swing . J T e x t F i e l d j T e x t F i e l d S t a t u s ;
j a v a x . swing . J T e x t F i e l d j T e x t F i e l d S u p ;
j a v a x . swing . J T e x t F i e l d j T e x t F i e l d V a r ;
7.3
VisAD
VisAD Visualization for Algorithmic Development este un pachet Java, care permite obtinerea de reprezentari grafice n doua (2D) si trei dimensiuni (3D), de animatii,
ftp://ftp.ssec.wisc.edu/pub/visad-2.0/visad.jar. La dezvoltarea pachetului au
contribuit mai multe universitati si institutii, ncepand din 1992. VisAD se bazeaza
pe un model de reprezentare prin obiecte a diverselor entitati ce apar n construirea unei
reprezentari grafice. Fixarea datelor de reprezentat grafic, care apar uzual ntr-o formulare
matematica, n obiectele modelului este relativ simpla si cade n sarcina programatorului,
la fel si fixarea unor parametri privind modul de afisare. Toate operatiile care conduc la
imaginea grafica sunt complet transparente programatorului.
Utilizarea produsului necesita n plus softul java3d de la Oracle.
Ierarhia de clase Java care fixeaza structurile de date utilizabile n VisAD este
MathType
|
----------------------------------------------------|
|
|
|
ScalarType
TupleType
SetType
FunctionType
|
|
---------RealTupleType
|
|
RealType TextType
Dintre aceste clase precizam:
RealType serveste la declararea unei variabile numerice.
Instantierea unui obiect se programeaza prin metoda statica
7.3. VISAD
101
Reprezentarea grafic
a a unei functii de o variabil
a
Construirea reprezentarii grafice a unei functii f ct : [a, b]D R se obtine parcurgand
pasii:
1. Definirea structurilor de date
RealType xType = RealType.getRealType("x");
RealType yType = RealType.getRealType("y");
FunctionType fctType = new FunctionType(xType, yType);
2. Precizarea datelor: n intervalul [a, b] se defineste o retea echidistanta de n N
puncte
Linear1DSet xSet = new Linear1DSet(xType, a, b, n);
Tabloul absciselor este generat prin
float[][] xValues=xSet.getSamples(true);
iar multimea valorilor functiei se calculeaza prin
double[][] yValues = new double[1][n];
for(int i=0;i<n;i++){
yValues[0][i]=fct(xValues[0][i]);
}
3. Fixarea conexiunii dintre structurile de date si tablourile de valori
FlatField ff = new FlatField( fctType, xSet);
ff.setSamples( yValues );
4. Fixarea elementelor care definesc reprezentarea grafica
102
Structurile de date:
ScalarMap xMap = new ScalarMap( xType, Display.XAxis );
ScalarMap yMap = new ScalarMap( yType, Display.YAxis );
Conexiunea dintre structurile de date si tablourile de valori
DataReferenceImpl dri=new DataReferenceImpl("data_ref");
dri.setData(ff);
5. Definirea unui container grafic caruia i se adauga elementele reprezentarii grafice
DisplayImpl display = new DisplayImplJ2D("2d");
display.addMap( xMap );
display.addMap( yMap );
display.addReference(dri);
6. Optional, reprezintarea axelor se programeaza prin
GraphicsModeControl
gmc=(GraphicsModeControl)display.getGraphicsModeControl();
gmc.setScaleEnable(true);
7. Containerul grafic se integreaza ntr-un cadru swing
JFrame jframe = new JFrame();
jframe.getContentPane().add(display.getComponent(),
BorderLayout.CENTER);
package g r a f i c 2 d ;
public c l a s s DataIn {
private double a=5;
private double b=5;
private i n t n =100;
public double f c t ( double x ) {
return xMath . s q r t ( xx 1);
}
7
8
9
11
12
13
15
16
17
public i n t getN ( ) {
return n ;
}
19
20
21
22
7.3. VISAD
package g r a f i c 2 d ;
import v i s a d . ;
import v i s a d . j a v a 2 d . DisplayImplJ2D ;
import j a v a . rmi . RemoteException ;
import j a v a . awt . ;
import j a v a x . swing . ;
public c l a s s R e p r e z e n t a r e F u n c t i e 2 D {
private DataIn d i n ;
public R e p r e z e n t a r e F u n c t i e 2 D ( DataIn d i n ) {
t h i s . d i n=d i n ;
}
public void p l o t ( ) {
i n t n=d i n . getN ( ) ;
D i s p l a y I m p l d i s p l a y=n u l l ;
try {
// D e f i n i r e a s t r u c t u r i l o r de d a t e
RealType xType = RealType . getRealType ( x ) ;
RealType yType = RealType . getRealType ( y ) ;
FunctionType f c t T y p e = new FunctionType ( xType , yType ) ;
// P r e c i z a r e a d a t e l o r
L i n e a r 1 D S e t x S e t = new L i n e a r 1 D S e t ( xType , d i n . getA ( ) , d i n . getB ( ) , n ) ;
f l o a t [ ] [ ] x V al u e s=x S e t . g e t S a m p l e s ( true ) ;
double [ ] [ ] y V al u e s = new double [ 1 ] [ n ] ;
f o r ( i n t i =0; i <n ; i ++){
y Va l u es [ 0 ] [ i ]= d i n . f c t ( x V a lu e s [ 0 ] [ i ] ) ;
}
// F i x a r e a c o n e x i u n i i d i n t r e s t r u c t u r i l e de d a t e
// s i t a b l o u r i l e de v a l o r i
F l a t F i e l d f f = new F l a t F i e l d ( fctType , x S e t ) ;
f f . s e t S a m p l e s ( y Va l u es ) ;
// F i x a r e a e l e m e n t e l o r c a r e d e f i n e s c r e p r e z e n t a r e g r a f i c a
ScalarMap xMap = new ScalarMap ( xType , D i s p l a y . XAxis ) ;
ScalarMap yMap = new ScalarMap ( yType , D i s p l a y . YAxis ) ;
D a t a R e f e r e n c e I m p l d r i=new D a t a R e f e r e n c e I m p l ( d a t a r e f ) ;
d r i . setData ( f f ) ;
// D e f i n i r e a c o n t a i n e r u l u i g r a f i c e c a r u i a i
// s e adauga e l e m e n t e l e r e p r e z e n t a r i i g r a f i c e
d i s p l a y = new DisplayImplJ2D ( 2d ) ;
d i s p l a y . addMap ( xMap ) ;
d i s p l a y . addMap ( yMap ) ;
d i s p l a y . addReference ( d r i ) ;
// Desenarea a x e l o r de c o o r d o n a t e
GraphicsModeControl gmc=
( GraphicsModeControl ) d i s p l a y . g e t G r a p h i c s M o d e C o n t r o l ( ) ;
gmc . s e t S c a l e E n a b l e ( true ) ;
}
catch ( VisADException e ) {
System . out . p r i n t l n ( V i s a d E x c e p t i o n : +e . g e t M e s s a g e ( ) ) ;
System . e x i t ( 1 ) ;
}
catch ( RemoteException e ) {
System . out . p r i n t l n ( RMIRemoteException : +e . g e t M e s s a g e ( ) ) ;
System . e x i t ( 1 ) ;
}
// I n t e g r a r e a i n t r un c a d r u l s w i n g
JFrame j f r a m e = new JFrame ( G r a f i c u l f u n c t i e i ) ;
j f r a m e . getContentPane ( ) . s e t L a y o u t (new BorderLayout ( ) ) ;
j f r a m e . getContentPane ( ) . add ( d i s p l a y . getComponent ( ) , BorderLayout .CENTER) ;
j f r a m e . s e t D e f a u l t C l o s e O p e r a t i o n ( j f r a m e . EXIT ON CLOSE ) ;
jframe . s e t S i z e (400 , 400);
103
104
j f r a m e . s e t V i s i b l e ( true ) ;
66
67
69
70
71
72
73
74
Reprezentarea grafic
a a unei functii de dou
a variabile
Procedam asemanator pentru construirea reprezentarii grafice a unei functii f ct :
([xM in , xM ax ] [yM in , yM ax ]) D R:
1. Definirea structurilor de date
RealType yType = RealType.getRealType("y");
105
7.3. VISAD
Ultimul rand are ca efect afisarea n culori a suprafetei, punctele cu valori mici
ale lui z se reprezinta n albastru iar cele cu valori mari n rosu.
Conexiunea dintre structurile de date si tablourile de valori
DataReferenceImpl dri=new DataReferenceImpl("data_ref");
dri.setData(ff);
5. Definirea unui container grafic caruia i se adauga elementele reprezentarii grafice
106
package g r a f i c 3 d ;
public c l a s s DataIn {
private double xMin=5;
private double xMax=5;
private double yMin=5;
private double yMax=5;
private i n t nx =30;
private i n t ny =30;
public double f c t ( double x , double y ) {
return xxyy ;
}
public double getXMin ( ) {
return xMin ;
}
public double getXMax ( ) {
return xMax ;
}
public double getYMin ( ) {
return yMin ;
}
public double getYMax ( ) {
return yMax ;
}
public i n t getNx ( ) {
return nx ;
7.3. VISAD
32
34
public i n t getNy ( ) {
return ny ;
}
35
36
37
package g r a f i c 3 d ;
import v i s a d . ;
import v i s a d . j a v a 3 d . DisplayImplJ3D ;
import j a v a . rmi . RemoteException ;
import j a v a . awt . ;
import j a v a x . swing . ;
public c l a s s R e p r e z e n t a r e F u n c t i e 3 D {
private DataIn d i n ;
public R e p r e z e n t a r e F u n c t i e 3 D ( DataIn d i n ) {
t h i s . d i n=d i n ;
}
public void plot3D ( ) {
i n t nx=d i n . getNx ( ) ;
i n t ny=d i n . getNy ( ) ;
D i s p l a y I m p l d i s p l a y=n u l l ;
try {
// D e f i n i r e a s t r u c t u r i i de d a t e
RealType xType = RealType . getRealType ( x ) ;
RealType yType = RealType . getRealType ( y ) ;
RealType zType = RealType . getRealType ( z ) ;
RealTupleType xyType = new RealTupleType ( xType , yType ) ;
FunctionType f c t T y p e = new FunctionType ( xyType , zType ) ;
// P r e c i z a r e a d a t e l o r
L i n e a r 2 D S e t xySet=new L i n e a r 2 D S e t ( xyType , d i n . getXMin ( ) , d i n . getXMax ( ) ,
nx , d i n . getYMin ( ) , d i n . getYMax ( ) , ny ) ;
f l o a t [ ] [ ] xyValues=xySet . g e t S a m p l e s ( true ) ;
double [ ] [ ] z V a l u e s = new double [ 1 ] [ nxny ] ;
f o r ( i n t i =0; i <nxny ; i ++){
z V a l u e s [ 0 ] [ i ]= d i n . f c t ( xyValues [ 0 ] [ i ] , xyValues [ 1 ] [ i ] ) ;
}
// F i x a r e a c o n e x i u n i i d i n t r e s t r u c t u r i l e de d a t e
// s i t a b l o u r i l e de v a l o r i
F l a t F i e l d f f = new F l a t F i e l d ( fctType , xySet ) ;
f f . setSamples ( zValues ) ;
// F i x a r e a e l e m e n t e l o r c a r e d e f i n e s c r e p r e z e n t a r e g r a f i c a
ScalarMap xMap = new ScalarMap ( xType , D i s p l a y . XAxis ) ;
ScalarMap yMap = new ScalarMap ( yType , D i s p l a y . YAxis ) ;
ScalarMap zMap = new ScalarMap ( zType , D i s p l a y . ZAxis ) ;
ScalarMap zColMap = new ScalarMap ( zType , D i s p l a y .RGB) ;
D a t a R e f e r e n c e I m p l d r i=new D a t a R e f e r e n c e I m p l ( d a t a r e f ) ;
d r i . setData ( f f ) ;
// D e f i n i r e a c o n t a i n e r u l u i g r a f i c e c a r u i a i
// s e adauga e l e m e n t e l e r e p r e z e n t a r i i g r a f i c e
d i s p l a y = new DisplayImplJ3D ( 3d ) ;
d i s p l a y . addMap ( xMap ) ;
d i s p l a y . addMap ( yMap ) ;
d i s p l a y . addMap ( zMap ) ;
d i s p l a y . addMap ( zColMap ) ;
d i s p l a y . addReference ( d r i ) ;
107
108
// Elemente s u p l i m e n t a r e de c o n t r o l
GraphicsModeControl gmc=
( GraphicsModeControl ) d i s p l a y . g e t G r a p h i c s M o d e C o n t r o l ( ) ;
gmc . s e t S c a l e E n a b l e ( true ) ;
gmc . s e t T e x t u r e E n a b l e ( f a l s e ) ;
59
60
61
62
63
}
catch ( VisADException e ) {
System . out . p r i n t l n ( V i s a d E x c e p t i o n : +e . g e t M e s s a g e ( ) ) ;
System . e x i t ( 1 ) ;
}
catch ( RemoteException e ) {
System . out . p r i n t l n ( RMIRemoteException : +e . g e t M e s s a g e ( ) ) ;
System . e x i t ( 1 ) ;
}
64
65
66
67
68
69
70
71
72
// I n t e g r a r e a i n t r un cadru s w i n g
JFrame j f r a m e=new JFrame ( G r a f i c u l 3D a l u n e i f u n c t i i i n 2 v a r i a b i l e ) ;
j f r a m e . getContentPane ( ) . s e t L a y o u t (new BorderLayout ( ) ) ;
j f r a m e . getContentPane ( ) . add ( d i s p l a y . getComponent ( ) , BorderLayout .CENTER) ;
j f r a m e . s e t D e f a u l t C l o s e O p e r a t i o n ( j f r a m e . EXIT ON CLOSE ) ;
jframe . s e t S i z e (600 , 600);
j f r a m e . s e t V i s i b l e ( true ) ;
74
75
76
77
78
79
80
}
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
DataIn d i n=new DataIn ( ) ;
R e p r e z e n t a r e F u n c t i e 3 D o b j=new R e p r e z e n t a r e F u n c t i e 3 D ( d i n ) ;
o b j . plot3D ( ) ;
}
81
82
83
84
85
86
87
Imaginea reprodusa este dupa rotirea cu ajutorul mouse-ului a imaginii generata initial.
7.4
P, Q N.
109
110
'
z
6
D XXX
yM
XXX
X
X
a
XX
XXX
XX
XXX
D
Xz
X
ym
?
&
xm
xM
Cubul culorilor
O culoare se formeaza dintr-un triplet (r, g, b) [0, 1]3 . Interpretam multimea [0, 1]3
ca un cub ale carui varfuri definesc culorile potrivit Fig. 7.7.
In Java, atribuirea unei culori (r, g, b) unui pixel (p, q) se programeaza prin
graphics.setColor(new Color(r,g,b));
graphics.fillRect(p,q,1,1);
Proiectia stereografic
a
Proiectia stereografica realizeaza o bijectie ntre planul complex completat cu elementul si suprafata S a sferei cu centrul n origine si de raza 1
S:
X 2 + Y 2 + Z 2 = 1.
x2
2x
,
+ y2 + 1
YN =
x2
2y
,
+ y2 + 1
ZN = 1
x2
2
.
+ y2 + 1
111
6
b
albastru
cyan
magenta
alb
gverde
negru
rosu
r
galben
(r, g, b)
(0,0,0)
(1,0,0)
(0,1,0)
(0,0,1)
(1,1,0)
(1,0,1)
(0,1,1)
(1,1,1)
Culoarea
negru
rosu
verde
albastru
galben
magenta
cyan
alb
de pe semisfera superioara, respectiv, conul cu aceasi baza dar cu varful V 0 (0, 0, 3) n cazul punctului de pe semisfera inferioara.
O dreapta care trece prin V
X = (Z 3)
(7.1)
Y = (Z 3)
112
Proiectia stereografica
Constructia
pentru modificarea lui Z.
Fig. 7.8:
este generatoare a conului daca intersecteaza cercul bazei. Rezulta conditia de compatibilitate
3(2 + 2 ) = 1.
(7.2)
Eliminand parametrii si ntre relatiile (7.1) si (7.2) se obtine ecuatia conului superior
Z=
3(1
X 2 + Y 2 ).
3( X 2 + Y 2 1).
Prin urmare
Z=
!
p
2 + y2
x
3 sgn(x2 + y 2 1) 1 2 2
.
x + y2 + 1
2 +y 2
x
ZN 0 =
3 sgn(x2 + y 2 1) 1 2 x2 +y2 +1
Efectuam cele trei operatii descrise anterior care duc corpul format de cele doua conuri
(7.8) n cubul culorilor [0, 1]3 .
113
x
x2 +y 2 +1
y
x2 +y 2 +1
=
3 sgn(x2 + y 2 1)
1
2
x2 +y 2
x2 +y 2 +1
~ J,
~ K
~ versorii axelor de coordonate n sistemul XY Z si cu
2. Rotatia. Notand prin I,
~, ~, ~k versorii axelor n spatiul cubului culorilor rgb, avem (Fig. 7.9)
~ = 1 (~ + ~ + ~k).
Z
3
b
6
~
~k 6 Z
~
g
-
c 23c2
.
2
1
2
de unde b =
a 23a2
.
2
2
2
~k,
I~ = a~ + a223a ~ a 23a
2
2
2
c
23c
c
23c
~k.
J~ = c~ +
~
2
2
~ J~ I~ J~ = 0 implica
Conditia de ortogonalitate I
= 0. (7.3)
2
2
2
2
114
Daca pentru alegem simultan acelasi semn atunci relatia anterioara devine 3ac +
p
(2 3a2 )(2 3c2 ) = 0, relatie care nu poate avea loc.
Prin urmare semnele n I~ si J~ trebuie sa fie contrare, de unde
2
2
~k,
I~ = a~ + a+223a ~ a+ 23a
2
2
2
c
c
23c
23c
~k.
J~ = c~ +
~
2
2
p
Conditia de ortogonalitate (7.3) devine 3ac (2 3a2 )(2 3c2 ) = 0, de unde se
obtine
r
2 3a2
.
c=
3
Valoarea lui a se determina astfel ncat axa OX sa fie cat mai apropiata de axa Or
din spatiul culorilor. In acest fel, valorile reale se vor reprezenta n rosu.
Exprimam conditia de apropiere prin cerinta ca expresia
|I~ ~|
(7.4)
sa fie minima.
Prin calcul direct |I~ ~|2 = 2 2a. Conditiile 2 3a2 0, a 0 implica a [0, 26 ].
Minimul expresiei (7.4) se obtine pentru a = 2 . In consecinta
6
I~ = 26~ 16 ~
J~ = 12~ 12 ~,
sau
2 ~
k,
6
~ 2
16 16
I
6
1
J~ =
12
0
2
1
1
1
~
K
3
~
~ .
~k
1
0
xN2
xN 1
6
3
1
1
1
yN2 =
6 2 3 yN1 .
zN2
zN1
16 12 13
3. In urma translatiei din spatiul cubului culorilor, formulele de calcul ale componentelor culorii devin
x2 +y 2
1
1
2
x
1
2
2
x2 +y 2
y
1
1
1
1
1
x
2
2
(7.5)
g = 2 + yN2 = 2 6 x2 +y2 +1 + 2 x2 +y2 +1 + sgn(x + y 1)( 2 x2 +y2 +1 )
2
2
x +y
b = 21 + zN2 = 12 16 x2 +yx2 +1 12 x2 +yy 2 +1 + sgn(x2 + y2 1)( 12 x2 +y2 +1 )
115
Aplicatia de vizualizare
Formulele (7.5) le vom folosi ntr-o aplicatie de vizualizarea unei functii complexe.
Pentru orice functie f , se vor afisa doua panouri, unul corespunzand vizualizarii functiei
z 7 z, cu rol de calibrare a perceptiei vizuale, iar celalalt panou destinat vizualizarii
functiei f, z D. Cele doua reprezentari sunt programate n metodele refPlot si fctPlot
ale clasei ComplexPlot.
In plus, daca xm = 2, xM = 2, ym = 2, yM = 2 atunci sunt reprezentate dreptele
=z = 0, <z = 0, arg(z) = 4 si cercurile |z| = 12 , |z| = 1, |z| = 32 , respectiv imaginile lor
prin f.
Clasele Java ale aplicatiei au codurile
1
2
3
4
5
7
8
9
10
12
13
14
15
16
18
19
20
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package c o m p l e x p l o t ;
import j a v a . awt . image . B u f f e r e d I m a g e ;
import j a v a . awt . G r a p h i c s ;
import j a v a . awt . C o l o r ;
import o r g . nfunk . j e p . t y p e . Complex ;
public c l a s s ComplexPlot {
DataIn d i n=n u l l ;
int P;
i n t Q;
ComplexPlot ( DataIn d i n ) {
t h i s . d i n=d i n ;
P=d i n . getXDim ( ) ;
Q=d i n . getYDim ( ) ;
}
double sgn ( double x ) {
return x>0 ? 1 : ( x<0 ? 1 : 0 ) ;
}
BufferedImage r e f P l o t (){
double xm=d i n . getXm ( ) ;
double ym=d i n . getYm ( ) ;
double xM=d i n . getXM ( ) ;
double yM=d i n . getYM ( ) ;
double mx=(xMxm) /P ;
double my=(yMym) /Q;
B u f f e r e d I m a g e b i=new B u f f e r e d I m a g e (P , Q, B u f f e r e d I m a g e . TYPE 3BYTE BGR ) ;
G r a p h i c s gh=b i . g e t G r a p h i c s ( ) ;
Complex w ;
double u , v , s , R, R2 , xx , yy ;
float b , g , r ;
f o r ( i n t p=0;p<P ; p++){
f o r ( i n t q =0;q<Q; q++){
u=xm+mxp ;
v=yMmyq ;
R=Math . s q r t ( uu+vv ) ;
R2=RR+1;
s=sgn (R1)(0.5 R/R2 ) ;
xx=u/R2/Math . s q r t ( 6 ) ;
yy=v/R2/Math . s q r t ( 2 ) ;
r =( f l o a t ) ( 0 . 5 + s +2xx ) ;
g=( f l o a t ) ( 0 . 5 + sxx+yy ) ;
b=( f l o a t ) ( 0 . 5 + sxxyy ) ;
gh . s e t C o l o r (new C o l o r ( r , g , b ) ) ;
gh . f i l l R e c t ( p , q , 1 , 1 ) ;
}
}
gh . s e t C o l o r ( C o l o r .BLACK) ;
gh . drawLine ( 0 ,Q/ 2 ,P ,Q/ 2 ) ;
116
52
53
54
55
56
57
58
59
60
62
BufferedImage f c t P l o t (){
double xm=d i n . getXm ( ) ;
double ym=d i n . getYm ( ) ;
double xM=d i n . getXM ( ) ;
double yM=d i n . getYM ( ) ;
double mx=(xMxm) /P ;
double my=(yMym) /Q;
B u f f e r e d I m a g e b i=new B u f f e r e d I m a g e (P , Q, B u f f e r e d I m a g e . TYPE 3BYTE BGR ) ;
G r a p h i c s gh=b i . g e t G r a p h i c s ( ) ;
Complex w ;
double x=0 ,y=0 ,u , v , s , R, R2 , xx , yy ;
float b , g , r ;
f o r ( i n t p=0;p<P ; p++){
f o r ( i n t q =0;q<Q; q++){
x=xm+mxp ;
y=yMmyq ;
w=d i n . f c t ( x , y ) ;
u=w . r e ( ) ;
v=w . im ( ) ;
R=Math . s q r t ( uu+vv ) ;
R2=RR+1;
s=sgn (R1)(0.5 R/R2 ) ;
xx=u/R2/Math . s q r t ( 6 ) ;
yy=v/R2/Math . s q r t ( 2 ) ;
r =( f l o a t ) ( 0 . 5 + s +2xx ) ;
g=( f l o a t ) ( 0 . 5 + sxx+yy ) ;
b=( f l o a t ) ( 0 . 5 + sxxyy ) ;
gh . s e t C o l o r (new C o l o r ( r , g , b ) ) ;
gh . f i l l R e c t ( p , q , 1 , 1 ) ;
}
}
i n t vx , vy ;
i n t [ ] d={P , P , ( i n t ) ( PMath . s q r t ( 2 ) ) , ( i n t ) ( PMath . s q r t ( 2 ) ) , 1 0 0 0 , 1 0 0 0 , 1 0 0 0 } ;
f o r ( i n t k =0;k<d . l e n g t h ; k++){
f o r ( i n t p=0;p<d [ k ] ; p++){
switch ( k ) {
case 0 : x=xm+mxp ;
y=yMmyQ/ 2 ;
break ;
case 1 : x=xm+mxP/ 2 ;
y=yMmyp ;
break ;
case 2 : x=xm+mxp ;
y=yMmy (Pp ) ;
break ;
case 3 : x=xm+mxp ;
y=yMmyp ;
break ;
case 4 : u=P/2+P/4Math . c o s ( 2 Math . PI p/d [ 4 ] ) ;
v=Q/2+P/4Math . s i n ( 2 Math . PI p/d [ 4 ] ) ;
x=xm+mxu ;
y=yMmyv ;
break ;
case 5 : u=P/2+P/8Math . c o s ( 2 Math . PI p/d [ 4 ] ) ;
v=Q/2+P/8Math . s i n ( 2 Math . PI p/d [ 4 ] ) ;
x=xm+mxu ;
y=yMmyv ;
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
break ;
case 6 : u=P/2+3P/8Math . c o s ( 2 Math . PI p/d [ 4 ] ) ;
v=Q/2+3P/8Math . s i n ( 2 Math . PI p/d [ 4 ] ) ;
x=xm+mxu ;
y=yMmyv ;
break ;
119
120
121
122
123
124
}
i f ( k<4)
gh . s e t C o l o r ( C o l o r .BLACK) ;
else
gh . s e t C o l o r ( C o l o r .GREEN) ;
w=d i n . f c t ( x , y ) ;
i f ( ! w . isNaN ( ) ) {
u=w . r e ( ) ;
v=w . im ( ) ;
vx=( i n t ) ( ( uxm) /mx ) ;
vy=( i n t ) ( ( yMv ) /my ) ;
i f ((0<=vx)&&(vx<=P)&&(0<=vy)&&(vy<=Q) ) {
gh . f i l l R e c t ( vx , vy , 1 , 1 ) ;
}
}
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
}
}
return b i ;
140
141
142
143
144
117
package c o m p l e x p l o t ;
import o r g . nfunk . j e p . t y p e . Complex ;
import o r g . nfunk . j e p . ;
public c l a s s DataIn {
private double xm, ym, xM,yM;
private S t r i n g v a r ;
private S t r i n g e x p r ;
private i n t P=500;
private i n t Q=500;
12
JEP p a r s e r=n u l l ;
14
15
16
17
18
19
20
21
22
23
24
25
27
28
29
30
31
32
33
34
35
36
37
public double
return xm ;
}
public double
return ym ;
}
public double
return xM;
}
public double
return yM;
getXm ( ) {
getYm ( ) {
getXM ( ) {
getYM ( ) {
xm) {
ym) {
xM) {
yM) {
118
38
40
public S t r i n g getVar ( ) {
return v a r ;
}
public S t r i n g getExpr ( ) {
return e x p r ;
}
41
42
43
44
45
public void s e t P ( i n t P) {
t h i s . P=P ;
}
public i n t getP ( ) {
return P ;
}
public void setQ ( i n t Q) {
t h i s .Q=Q;
}
public i n t getQ ( ) {
return Q;
}
47
48
49
50
51
52
53
54
55
56
57
58
DataIn ( S t r i n g var , S t r i n g e x p r ) {
t h i s . v a r=v a r ;
t h i s . e x p r=e x p r ;
p a r s e r=new JEP ( ) ;
p a r s e r . addStandardFunctions ( ) ;
p a r s e r . addStandardConstants ( ) ;
p a r s e r . addComplex ( ) ;
p a r s e r . a d d V a r i a b l e ( var , 0 , 0 ) ;
p a r s e r . p ar s eE xp re ss i on ( expr ) ;
}
60
61
62
63
64
65
66
67
68
69
71
72
73
74
75
package c o m p l e x p l o t ;
import j a v a . awt . ;
import j a v a . t e x t . DecimalFormat ;
1
2
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private void i n i t C o m p o n e n t s ( ) {
// cod g e n e r a t de Netbeans
}
27
28
29
private
private
private
private
private
private
31
32
33
34
35
36
37
j a v a x . swing . J L a b e l
j a v a x . swing . J L a b e l
j a v a x . swing . J L a b e l
j a v a x . swing . J L a b e l
j a v a x . swing . J L a b e l
j a v a x . swing . JPanel
jLabelName ;
jLabelXM ;
jLabelXm ;
jLabelYM ;
jLabelYm ;
jPanelCanvas ;
11
12
13
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
48
49
50
51
52
package c o m p l e x p l o t ;
import j a v a . awt . image . B u f f e r e d I m a g e ;
import j a v a . awt . ;
public c l a s s Main extends j a v a x . swing . JFrame {
public Main ( ) {
initComponents ( ) ;
}
private void i n i t C o m p o n e n t s ( ) {
// cod g e n e r a t de Netbeans
}
private void jButtonComputeMouseClicked ( j a v a . awt . e v e n t . MouseEvent e v t )
S t r i n g v a r=j T e x t F i e l d V a r . g e t T e x t ( ) ;
S t r i n g e x p r=j T e x t F i e l d E x p r . g e t T e x t ( ) ;
DataIn d i n=new DataIn ( var , e x p r ) ;
i n t P=400;
i n t Q=400;
double v a l =(new Double ( jTextFieldXm . g e t T e x t ( ) ) ) . d o u b l e V a l u e ( ) ;
d i n . setXm ( v a l ) ;
v a l =(new Double ( jTextFieldYm . g e t T e x t ( ) ) ) . d o u b l e V a l u e ( ) ;
d i n . setYm ( v a l ) ;
v a l =(new Double ( jTextFieldXM . g e t T e x t ( ) ) ) . d o u b l e V a l u e ( ) ;
d i n . setXM ( v a l ) ;
v a l =(new Double ( jTextFieldYM . g e t T e x t ( ) ) ) . d o u b l e V a l u e ( ) ;
d i n . setYM ( v a l ) ;
d i n . s e t P (P ) ;
d i n . setQ (Q) ;
ComplexPlot cp=new ComplexPlot ( d i n ) ;
B u f f e r e d I m a g e b f 0=cp . r e f P l o t ( ) ;
P l o t P a n e l p0=new P l o t P a n e l ( din , ( Image ) bf0 , d i n . getVar ()+ > +
d i n . getVar ( ) ) ;
B u f f e r e d I m a g e b f=cp . f c t P l o t ( ) ;
P l o t P a n e l p f=new P l o t P a n e l ( din , ( Image ) bf , d i n . getVar ()+ > +
d i n . getExpr ( ) ) ;
S t r i n g t i t l e = R e p r e z e n t a r e a f u n c t i e i c o m p l e z e ;
j a v a x . swing . JFrame j f r a m e = new j a v a x . swing . JFrame ( t i t l e ) ;
jframe . addNotify ( ) ;
j f r a m e . getContentPane ( ) . s e t L a y o u t (new GridLayout ( 1 , 2 ) ) ;
j f r a m e . getContentPane ( ) . add ( p0 ) ;
j f r a m e . getContentPane ( ) . add ( p f ) ;
j f r a m e . s e t S i z e ( 2 P+120 ,Q+ 10 0) ;
j f r a m e . s e t V i s i b l e ( true ) ;
}
public s t a t i c void main ( S t r i n g a r g s [ ] ) {
j a v a . awt . EventQueue . i n v o k e L a t e r (new Runnable ( ) {
public void run ( ) {
new Main ( ) . s e t V i s i b l e ( true ) ;
}
119
120
});
53
54
56
private
private
private
private
private
private
private
private
private
private
private
private
private
57
58
59
60
61
62
63
64
65
66
67
68
69
121
122
z 2 1
.
z 2 +1
123
124
Capitolul 8
Aplicatii Web
Retelele locale, internetul, raspandirea pe o arie geografica a resurselor si a locatiilor
n care se petrec actiuni ce tin de o activitate bine definita sau sunt urmarite, gestionate
din alte locuri au drept consecinta existenta aplicatiilor distribuite. Termenul distribuit
se refera tocmai la faptul ca componente ale aplicatiei se afla pe calculatoare diferite, dar
ntre care au loc schimburi de date. Daca partile unei aplicatii sau resursele utilizate se
gasesc pe calculatoare distincte atunci aplicatia se numeste distribuita.
Intre partile sau resursele unei aplicatii distribuite au loc schimburi de date la realizarea
carora concura sistemul de calcul, sistemul de operare si limbajul de programare.
Astfel, se vorbeste de programare distribuita ca mijloc de realizare a aplicatiilor distribuite.
Schimburile de date se pot realiza prin mai multe metode. Punem n evidenta doua
modele de aplicatii distribuite:
client-server: Programul server executa cererile clientilor.
Printre aplicatiile distribuite de tip client-server, n care comunicatiile se bazeaza
pe protocolul http, se disting
Aplicatii Web (site): cererea adresata serverului este lansata de o persoana
prin intermediul unui site, utilizand un program navigator (browser Web).
Servicii Web: cererea catre server se face de un program.
dispecer-lucr
ator: Programul dispecer distribuie sarcinile de executat lucratorilor
si le coordoneaza activitatea.
Limitandu-ne la aplicatii distribuite de tip client-server si la platforma Java, n acest
capitol se vor utiliza urmatoarele tehnologii de programare:
servlet-ul, care reprezinta tehnologia de baza pentru realizarea aplicatiilor Web n
Java;
websocket bazat pe protocolul omonim, introdus de HTML5.
Google Web Toolkit (GWT) cadru de lucru pentru dezvoltarea aplicatiilor Web.
125
126
CAPITOLUL 8. APLICAT
II WEB
8.1. SERVLET
8.1
127
Servlet
Interfata de programare (API) pentru servlet nu face parte din JDK, fiind implementat
de fiecare producator de server Web container de servlet.
Legatura dintre serverul Web cu clasa servlet-ului se poate realiza
programat prin adnotari1 n codul servlet-ului;
descriptiv n catalogul WEB-INF se editeaza fisierul web.xml.
In versiunile anterioare versiunii 3.0 ale interfetei de programare servlet aceasta a
fost unica optiune.
Trebuie demarcata diferenta dintre apelarea / lansarea n executie a clasei servlet de
apelarea aplicatiei Web.
Modul programat se bazeaza pe adnotarea javax.servlet.annotation.WebServlet
cu elementele:
String
name
String[ ]
urlPatterns
@InitParams[ ] initParam
boolean
asyncSupported
long
asyncTimeout
Modul descriptiv In fisierul web.xml apar elementele
1. <servlet> leaga numele servlet-ului definit n elementul <servlet-name> de
clasa servlet-ului dat n elementul <servlet-class> .
2. <servlet-mapping> defineste numele sub care servlet-ul identificat prin
<servlet-name> nume servlet< /servlet> se invoca din programul navigator.
Acest identificator - numeApel - se fixeaza n elementul <url-pattern> . Identificatorul are ca prefix caracterul / (slash).
Structura unui fisier web.xml este
1
2
3
4
5
6
7
8
9
10
11
12
13
14
In Java o adnotare (annotation) este o metadata a unui element de cod (identificator al unei entit
ati
din codul Java).
O adnotare poate s
a-si fac
a efectul asupra codului surss, naintea compilarii, asupra codului obiect,
dup
a compilare, dar naintea execut
arii sau n timpul executiei codului.
128
15
16
17
18
19
20
21
22
CAPITOLUL 8. APLICAT
II WEB
cu precizarea fisierelor html sau jsp care apeleaza aplicatia Web. Declaratia fisierului
index.html este implicita.
Compilarea clasei servlet necesita completarea variabilei de mediu classpath cu
fisierul TOMCAT HOME\lib\servlet-api.jar.
Odata completata structura de cataloage si fisiere ale aplicatiei servlet aceasta structura trebuie copiata n catalogul TOMCAT HOME\webapps. Aceasta operatie se numeste
desf
asurarea (deployment) sau instalarea servlet-ului. Copierea se poate executa si cu
serverul Web pornit.
Pentru instalarea unui servlet exista mai multe alternative:
Din catalogul catalogAppServlet se realizeaza arhiva catalogAppServlet.war
jar cfv catAppServlet.war WEB-INF\ index.html
care se copiaza n catalogul TOMCAT HOME\webapps.
Serverul Web tomcat va dezarhiveaza arhiva. Astfel servlet-ul este instalat.
Aceasta instalare se numeste instalare dinamica - hot deployment.
Daca fisierul war este creat, atunci n locul copierii, instalarea se poate face prin
componenta manager a lui tomcat.
O alta posibilitate de instalare a unui servlet n serverul web tomcat este prin intermediul produsului apache-tomcat-deployer. apache-tomcat-deployer permite instalarea unui servlet de la distanta cat si instalarea comandata dintr-un program.
8.1.1
Un servlet implementeaza interfata Servlet sau extinde una din clasele GenericServlet
sau HttpServlet. GenericServlet implementeaza interfata Servlet, iar HttpServlet
extinde clasa GenericServlet. Extinzand clasa GenericServlet nu este nevoie de rescrierea tuturor metodelor abstracte ale intrefetei Servlet.
8.1. SERVLET
129
Uzual clasa unui servlet va fi o clasa care extinde clasa HttpServlet, programatorul
va suprascrie metodele doGet(...) sau doPost(...), n functie de metoda utilizata de
client la lansarea cererii.
Practic, un servlet consta din scrierea metodelor
void init(ServletConfig config)
Aceasta metoda este optionala.
public void init(ServletConfig config) throws ServletException{
super.init(config);
// cod de initializare
}
Obiectul config are o metoda String getInitParameter(String numeParam) cu
ajutorul careia se pot recupera parametri de initializare asociati servlet-ului si care
se dau fie prin adnotarea @initParams, fie n fisierul web.xml prin elementele
<init-param>
<param-name> NumeleParametrului </param-name>
<param-value> Valoare </param-value>
</init-param>
cuprinse n elementul <servlet>.
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws
IOException, ServletException
Trateaza o cerere trimisa cu metoda GET (vezi marcajul <form>).
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws
IOException, ServletException
Trateaza o cerere trimisa cu metoda POST (vezi marcajul <form>).
Activitatile de ntreprins ntr-o metoda doGet() sau doPost() sunt
1. Stabilirea naturii raspunsului:
res.setContentType(String tip)
unde tip specifica tipul MIME - Multipurpose Internet Mail Extensions al raspunsului:
"text/html" - pagina html;
"text/xml" - document xml;
"text/plain" - text;
"image/jpg" - imagine gif;
"image/gif" - imagine jpg.
130
CAPITOLUL 8. APLICAT
II WEB
2. Se obtine o referinta catre un obiect care realizeaza transmisia datelor catre navigatorul clientului:
ServletOutputStream out = res.getOutputStream();
sau
PrintWriter out=res.getWriter();
3. Se preiau datele cererii cu una din metodele:
String getParameter(String numeParapetru)
java.util.Enumeration getParameterNames()
4. Rezolva cererea clientului;
5. Formeaza si scrie raspunsul;
6. Inchide conexiunea obiectului prin care s-a realizat transmisia datelor catre navigatorul clientului prin out.close().
Un utilizator lanseaza o cerere catre servlet. De obicei acest lucru se realizeaza prin
clientul Web. Programul navigator trimite cererea serverului Web prin intermediul caruia
este lansat clasa servlet-ului n actiune.
Versiunea 3.0 a interfetei de programare pentru servlet ofera posibilitatea programarii
asincrone a actiunii servletului prin includerea acestuia ntr-un fir de executie.
Mai mult n versiunea 3.1, actiunea firului de executie este nlocuita prin programarea
unor interfete de tip listener.
Ciclul de viat
a al unui servlet. Cand un servlet este apelat prima data de catre
serverul Web se executa metoda init. Dupa aceasta, fiecarei cereri lansate de un utilizator
i se asociaza un fir de executie n care se apeleaza metoda service. Metoda service
apeleaza apoi metodele doGet(), doPost().
Exemplul 8.1.1 Servlet pentru calculul unei integrale.
Transformam aplicatia dezvoltata n (1.2) ntr-un servlet.
Codul servlet-ului va fi
10
package i n t e g r a l a ;
import j a v a . i o . IOException ;
import j a v a . i o . P r i n t W r i t e r ;
import j a v a x . s e r v l e t . S e r v l e t E x c e p t i o n ;
import j a v a x . s e r v l e t . h t t p . H t t p S e r v l e t ;
import j a v a x . s e r v l e t . h t t p . H t t p S e r v l e t R e q u e s t ;
import j a v a x . s e r v l e t . h t t p . H t t p S e r v l e t R e s p o n s e ;
import j a v a x . s e r v l e t . a n n o t a t i o n . WebServlet ;
import m a t h l i b . c l i e n t . c v a d r a . ;
import m a t h l i b . c l i e n t . c v a d r a . impl . ;
12
@WebServlet ( u r l P a t t e r n s = / i n t e g )
14
public c l a s s M e t o d a S i m p s o n S e r v l e t extends H t t p S e r v l e t {
1
2
3
4
5
6
7
8
9
16
17
18
19
8.1. SERVLET
S t r i n g v a r=r e q . g e t P a r a m e t e r ( s v a r ) ;
S t r i n g e x p r=r e q . g e t P a r a m e t e r ( e x p r ) ;
S t r i n g e p s=r e q . g e t P a r a m e t e r ( e p s ) ;
S t r i n g nmi=r e q . g e t P a r a m e t e r ( nmi ) ;
S t r i n g t i p=r e q . g e t P a r a m e t e r ( t i p ) ;
System . out . p r i n t l n ( v a r+ +e x p r+ +a+ +b+ +e p s+ +nmi+ +t i p ) ;
JepDataIn d i n=new JepDataIn ( var , e x p r ) ;
d i n . setA ( a ) ;
d i n . setB ( b ) ;
d i n . s e t E p s ( Double . p a r s e D o u b l e ( e p s ) ) ;
d i n . setNmi ( I n t e g e r . p a r s e I n t ( nmi ) ) ;
IMetodaSimpson o b j=new MetodaSimpsonWeb ( ) ;
DataOut dout=o b j . metodaSimpson ( d i n ) ;
r e s . setContentType ( t i p ) ;
P r i n t W r i t e r out=r e s . g e t W r i t e r ( ) ;
i f ( t i p . e q u a l s ( t e x t / html ) ) {
out . p r i n t l n ( <html> ) ;
out . p r i n t l n ( <head><t i t l e > </ t i t l e ></head> ) ;
out . p r i n t l n ( <body b g c o l o r=\#bbccbb\> ) ;
out . p r i n t l n ( <c e n t e r > ) ;
out . p r i n t l n ( <h1>C a l c u l u l i n t e g r a l e i p r i n metoda Simpson </h1> ) ;
out . p r i n t l n ( <p> ) ;
out . p r i n t l n ( I n d i c a t o r u l de r a s p u n s : + dout . g e t I n d ( ) ) ;
out . p r i n t l n ( </p> ) ;
out . p r i n t l n ( <p> ) ;
out . f o r m a t ( I n t e g r a l a : %1$12 . 6 f , dout . g e t I n t e g r a l a ( ) ) ;
out . p r i n t l n ( </p> ) ;
out . p r i n t l n ( <p> ) ;
out . p r i n t l n ( Numarul i t e r a t i i l o r e f e c t u a t e : + dout . g e t N i ( ) ) ;
out . p r i n t l n ( </p> ) ;
out . p r i n t l n ( <br/> ) ;
out . p r i n t l n ( </ c e n t e r > ) ;
out . p r i n t l n ( </body> ) ;
out . p r i n t l n ( </html> ) ;
}
else {
out . p r i n t l n ( I n d i c a t o r u l de r a s p u n s : +dout . g e t I n d ( ) ) ;
out . p r i n t l n ( I n t e g r a l a : +dout . g e t I n t e g r a l a ( ) ) ;
out . p r i n t l n ( Numarul i t e r a t i i l o r e f e c t u a t e : +dout . g e t N i ( ) ) ;
}
out . c l o s e ( ) ;
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
63
64
65
66
67
131
Pentru fixarea naturii raspunsului text/html sau text/plain s-a introdus variabila
tip, care n fisierul de invocare index.html primeste pe ascuns valoarea text/html. In
cazul n care vom apela servlet-ul dintr-un program, va fi mai avantajos sa primim
raspunsul ca text/plain.
Desfasurarea servlet-ului este
appinteg
|--> WEB-INF
|
|--> classes
|
|
|--> integrala
|
|
|
|
MetodaSimpsonServlet.class
|
|
|--> lib
|
|
|
|
mathlib.jar
|
|
|
|
jep-2.4.1.jar
|
index.html
132
CAPITOLUL 8. APLICAT
II WEB
8.1.2
Apelarea unui servlet dintr-un program Java adica lansarea unei cereri si receptionarea
raspunsului furnizat de servlet se poate obtine cu produsul httpcomponents-client dezvoltat de apache.
Intr-un asemenea caz, din punctul de vedere al clientului este mai avantajos ca raspunsul
servlet-ului fie text/plain, n loc de text/html.
Exista mai multe modalitati de programare dintre care vom utiliza varianta de programare fluenta.
Exemplul 8.1.2 Program client pentru servlet-ul MetodaSimpson (8.1.1):
8.1. SERVLET
1
2
3
4
6
7
package i n t e g r a l a ;
import j a v a . u t i l . S c a n n e r ;
import o r g . apache . h t t p . c l i e n t . f l u e n t . Form ;
import o r g . apache . h t t p . c l i e n t . f l u e n t . Request ;
public c l a s s C l i e n t {
static S t r i n g u r l = http :// l o c a l h o s t :8080/ appinteg / i n t e g ;
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
S c a n n e r s c a n n e r=new S c a n n e r ( System . i n ) ;
System . out . p r i n t l n ( I n t r o d u c e t i : ) ;
System . out . p r i n t l n ( V a r i a b i l a ) ;
S t r i n g s v a r=s c a n n e r . n e x t ( ) ;
System . out . p r i n t l n ( E x p r e s i a de i n t e g r a t ) ;
S t r i n g e x p r=s c a n n e r . n e x t ( ) ;
System . out . p r i n t l n ( L i m i t a i n f e r i o a r a ) ;
double a=s c a n n e r . nextDouble ( ) ;
System . out . p r i n t l n ( L i m i t a s u p e r i o a r a ) ;
double b=s c a n n e r . nextDouble ( ) ;
System . out . p r i n t l n ( T o l e r a n t a ) ;
double e p s=s c a n n e r . nextDouble ( ) ;
System . out . p r i n t l n ( Numar maxim admis de i t e r a t i i ) ;
i n t nmi=s c a n n e r . n e x t I n t ( ) ;
try {
S t r i n g r e s u l t=Request . Post ( u r l )
. bodyForm ( Form . form ( )
. add ( s v a r , s v a r )
. add ( e x p r , e x p r )
. add ( a ,new Double ( a ) . t o S t r i n g ( ) )
. add ( b ,new Double ( b ) . t o S t r i n g ( ) )
. add ( e p s ,new Double ( e p s ) . t o S t r i n g ( ) )
. add ( nmi ,new I n t e g e r ( nmi ) . t o S t r i n g ( ) )
. add ( t i p , t e x t / p l a i n )
. build ())
. execute ( ) . returnContent ( ) . asString ( ) ;
System . out . p r i n t l n ( r e s u l t ) ;
}
catch ( E x c e p t i o n e ) {
e . printStackTrace ( ) ;
}
}
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
8.1.3
133
134
CAPITOLUL 8. APLICAT
II WEB
appinteg
|-- src
|
|-- main
|
|
|-- java
|
|
|
|-- integrala
|
|
|
|
|
MetodaSimpsonServlet.java
|
|
|-- resources
|
|
|-- webapp
|
|
|
|-- WEB-INF
|
|
|
|
|-- lib
|
|
|
|
|
|
mathlib.jar
|
|
|
|
|
|
jep-2.4.1.jar
|
|
|
|
|
web.xml
|
|
|
|
index.html
|
pom.xml
? xml v e r s i o n= 1 . 0 e n c o d i n g=UTF8?>
<webapp version= 3 . 0 xmlns= h t t p : // j a v a . sun . com/xml/ ns / j a v a e e
x m l n s : x s i= h t t p : //www. w3 . o r g /2001/XMLSchemai n s t a n c e >
</webapp>
8.1. SERVLET
135
8.1.4
Integrarea unei aplicatii Web ntr-o platforma OSGi necesita o abordare specifica.
Integrata ntr-o platforma OSGi, aplicatia Web nu mai este desfasurata nemijlocit n
serverul Web, dar apelurile se vor adresa n continuare serverului Web.
Integrarea unei aplicatii servlet ntr-o componenta OSGi se va baza pe interfata
org.osgi.service.http.HttpService, pentru care vom folosi implemantarea org.apache.felix.
http.bundle-*.jar. Cu foarte putine diferente, n varianta de programare pe care o
prezenta, componenta OSGi se va putea utiliza pe platformele OSGi apache-karaf si
glassfish.
Interfata HttpService declara metodele
void registerResources(String alias, String name, HttpContext context)
throws NamespaceException
void registerServlet(String alias, Servlet servlet, Dictionary initparams,
HttpContext context)ServletException, NamespaceException
void unregister(String alias)
Structura componentei OSGi corespunzatoare unui servlet este
|-->
|
|
|
|
META-INF
|
MANIFEST.MF
ClasaServlet.class
Activator.class
fisier.html
136
CAPITOLUL 8. APLICAT
II WEB
import
import
import
import
public c l a s s A c t i v a t o r implements B u n d l e A c t i v a t o r {
1
2
3
osgi
osgi
osgi
osgi
. framework . B u n d l e A c t i v a t o r ;
. framework . BundleContext ;
. framework . S e r v i c e R e f e r e n c e ;
. s e r v i c e . http . HttpService ;
8
9
10
11
12
13
14
15
17
18
org .
org .
org .
org .
M a n i f e s t V e r s i o n : 1 . 0
BundleM a n i f e s t V e r s i o n : 2
BundleName: M e t o d a S i m p s o n S e r v l e t
BundleSymbolicName: a p p i n t e g
BundleV e r s i o n : 1 . 0 . 0
BundleA c t i v a t o r : A c t i v a t o r
BundleL o c a l i z a t i o n : p l u g i n
ImportP a c k a g e : j a v a x . s e r v l e t , j a v a x . s e r v l e t . http , o r g . o s g i . framework ; v e r s i o n= 1 . 3 . 0 ,
o r g . o s g i . s e r v i c e . h t t p ; v e r s i o n= 1 . 2 . 0
BundleC l a s s p a t h : . , l i b / m a t h l i b . j a r , l i b / j e p 2 . 4 . 1 . j a r
137
8.1. SERVLET
Comenzi OSGi uzuale sunt: start n, stop n, install file:..., uninstall n, list,
help.
Mediul OSGi apache-karaf utilizeaza serverul Web incorporat Jetty pe portul 8181.
Pentru a schimba portul se creaza n prealabil fisierul etc\org.ops4j.pax.web.cfg cu
continutul
org.osgi.service.http.port=8080
Trebuie instalat suportul pentru protocolul http prin
feature:install http
Apelarea unei aplicatii servlet va fi http://host:port/fisier.html
138
CAPITOLUL 8. APLICAT
II WEB
8.2
WebSocket
Daca ntre cei doi parteneri se stabileste acordul (handshake) atunci restul comunicatiilor
au loc prin intermediul unui soclu TCP pe portul 80.
Astfel ciclul de viata al procesului de comunicatie este:
1. Un client solicita printr-un mesaj http acordul pentru trecerea la protocolul WebSocket.
2. Serverul raspunde acceptand acordul.
3. Odata stabilita conexiunea, acesta devine bidirectionala (simetrica), clientul si serverul
transmit si receptioneaza mesaje.
4. Una din parti nchide conexiunea.
8.2.1
139
8.2. WEBSOCKET
Semnificatia
Nu s-a stabilit conexiunea
Conexiune pregatita pentru comunicatii
Conexiune n pragul confirmarii (handshake)
Conexiune nchisa si nu mai poate fi redeschisa
bufferedAmount
Numarul octetilor trimisi de functia send. Datele sunt codificate UTF-8.
Un sablon de utilizare poate fi
<script language="javascript" type="text/javascript">
var wsUri = "ws://host:8080/context/numeApel";
var websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { . . . };
websocket.onmessage = function(evt) { . . . };
websocket.onerror = function(evt) { . . . };
websocket.onclose = function(evt) { . . . };
. . .
</script>
Expedierea datelor.
Consideram formularul HTML
<form name="myform">
<input type="text" name="xyz" . . ./>
. . .
<input type="button" onclick="send"/>
</form>
Receptia unui rezultat furnizat de server. Functia onmessage permite recuperarea rezultatului din evt.data.
140
CAPITOLUL 8. APLICAT
II WEB
8.2.2
WebSocket n Java
Interfata de programare Java pentru WebSocket declara clase atat pentru server cat
si pentru client.
Programarea serverului se poate realiza prin adnotari (Annotation driven) potrivit
ablonului
@ServerEndpoint(value="/urlPattern")
public class EndpointWebSocketServer {
private static Set<Session> sessions =
Collections.synchronizedSet(new HashSet<Session>());
@OnMessage
public void myTask(String msg, Session session)
throws IOException,EncodeException{
. . .
}
@OnOpen
public void onOpen(Session session){
sessions.add(session);
}
@OnClose
public void onClose(Session session){
sessions.remove(session);
}
}
8.2. WEBSOCKET
Interfata javax.websocket.RemoteEndpoint.Basic
Metode
void sendObject(Object data) throws IOException,EncodeException
void sendText(String data) throws IOException
void sendBinary(ByteBuffer data) throws IOException
OutputStream getSendStream() throws IOException
Exemplul 8.2.1 Aplicatie WebSocket pentru calculul unei integrale.
Aplicatia server are codul
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
20
21
22
23
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package w e b s o c k e t . c v a d r a ;
import j a v a x . w e b s o c k e t . OnMessage ;
import j a v a x . w e b s o c k e t . s e r v e r . S e r v e r E n d p o i n t ;
import j a v a x . w e b s o c k e t . S e s s i o n ;
import j a v a x . w e b s o c k e t . OnOpen ;
import j a v a x . w e b s o c k e t . OnClose ;
import j a v a x . w e b s o c k e t . OnError ;
import j a v a x . w e b s o c k e t . RemoteEndpoint ;
import j a v a x . w e b s o c k e t . EncodeException ;
import j a v a . i o . IOException ;
import j a v a . u t i l . S e t ;
import j a v a . u t i l . C o l l e c t i o n s ;
import j a v a . u t i l . HashSet ;
import m a t h l i b . c l i e n t . c v a d r a . JepDataIn ;
import m a t h l i b . c l i e n t . c v a d r a . DataOut ;
import m a t h l i b . c l i e n t . c v a d r a . IMetodaSimpson ;
import m a t h l i b . c l i e n t . c v a d r a . impl . MetodaSimpsonWeb ;
import j a v a . t e x t . DecimalFormat ;
@ServerEndpoint ( v a l u e= / c v a d r a )
public c l a s s I n t e g r a l a W e b S o c k e t S e r v e r A d {
private s t a t i c Set<S e s s i o n > s e s s i o n s =
C o l l e c t i o n s . s y n c h r o n i z e d S e t (new HashSet<S e s s i o n > ( ) ) ;
@OnMessage
public void onMessage ( S t r i n g message , S e s s i o n s e s s i o n ) {
S t r i n g [ ] elem=message . s p l i t ( : ) ;
S t r i n g v a r=elem [ 0 ] ;
S t r i n g e x p r=elem [ 1 ] ;
JepDataIn d i n=new JepDataIn ( var , e x p r ) ;
d i n . setA ( elem [ 2 ] ) ;
d i n . setB ( elem [ 3 ] ) ;
d i n . s e t E p s ( Double . p a r s e D o u b l e ( elem [ 4 ] ) ) ;
d i n . setNmi ( I n t e g e r . p a r s e I n t ( elem [ 5 ] ) ) ;
S t r i n g t i p=elem [ 6 ] ;
IMetodaSimpson o b j=new MetodaSimpsonWeb ( ) ;
DataOut dout=o b j . metodaSimpson ( d i n ) ;
DecimalFormat d f=new DecimalFormat ( 0 . 0 0 0 0 0 0 1 ) ;
S t r i n g B u f f e r r e z=new S t r i n g B u f f e r ( ) ;
i f ( t i p . e q u a l s ( html ) ) {
r e z . append ( <t a b l e ><t r ><td> ) ;
r e z . append ( I n d i c a t o r u l de r a s p u n s : +dout . g e t I n d ( ) ) ;
r e z . append ( </td></t r ><t r ><td> ) ;
r e z . append ( I n t e g r a l a : +d f . f o r m a t ( dout . g e t I n t e g r a l a ( ) ) ) ;
r e z . append ( </td></t r ><t r ><td> ) ;
r e z . append ( Numarul i t e r a t i i l o r e f e c t u a l e : +dout . g e t N i ( ) ) ;
r e z . append ( </td></t r ></t a b l e > ) ;
141
142
CAPITOLUL 8. APLICAT
II WEB
}
else {
r e z . append ( I n d i c a t o r u l de r a s p u n s : +dout . g e t I n d ( ) ) ;
r e z . append ( \n ) ;
r e z . append ( I n t e g r a l a : +dout . g e t I n t e g r a l a ( ) ) ;
r e z . append ( \n ) ;
r e z . append ( Numarul i t e r a t i i l o r e f e c t u a l e : +dout . g e t N i ( ) ) ;
}
s e s s i o n s . stream ( )
. f i l t e r ( s>s . e q u a l s ( s e s s i o n ) )
. f o r E a c h ( s>{
RemoteEndpoint . B a s i c e n d p o i n t=s . getBasicRemote ( ) ;
try {
e n d p o i n t . sendText ( r e z . t o S t r i n g ( ) ) ;
}
catch ( IOException e ) { } ;
});
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
67
@OnOpen
public void onOpen ( S e s s i o n s e s s i o n )
throws IOException , EncodeException {
s e s s i o n s . add ( s e s s i o n ) ;
}
68
69
70
71
@OnClose
public void o n C l o s e ( S e s s i o n s e s s i o n ) {
s e s s i o n s . remove ( s e s s i o n ) ;
}
73
74
75
76
77
8.2. WEBSOCKET
35
36
37
39
40
41
43
44
45
47
48
49
51
52
53
54
55
56
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
f u n c t i o n onMessage ( e v t ) {
w r i t e T o S c r e e n ( RECEIVED : + e v t . data ) ;
}
f u n c t i o n onError ( evt ) {
w r i t e T o S c r e e n ( <span s t y l e= c o l o r : r e d ; >ERROR:</span> + e v t . data ) ;
}
f u n c t i o n onClose ( evt ) {
w r i t e T o S c r e e n ( CLOSED ) ;
}
f u n c t i o n myclose ( ) {
websocket . c l o s e ( ) ;
}
f u n c t i o n w r i t e T o S c r e e n ( message ) {
v a r p r e = document . c r e a t e E l e m e n t ( p ) ;
p r e . s t y l e . wordWrap = breakword ;
p r e . innerHTML = message ;
ou tp ut . appendChild ( p r e ) ;
}
window . a d d E v e n t L i s t e n e r ( l o a d , i n i t , f a l s e ) ;
</ s c r i p t>
</head>
<body bgcolor=#bbccbb >
<center>
<h1> Pagina de a p e l a r e a a p l i c a ţ i e i w e b s o c k e t MetodaSimpson</h1>
<h3> C a l c u l u l u n e i i n t e g r a l e </h3>
<p/>I n t r o d u c e ţ i :
< !<div s t y l e= t e x t a l i g n : c e n t e r ; >>
<form name= c v a d r a >
<table border= 2 >
<tr>
<td> V a r i a b i l a i n d e p e n d e n t a : </td>
<td> <input type= t e x t name= s v a r s i z e =30 r e q u i r e d> </td>
</ tr>
<tr>
<td> E x p r e s i a de i n t e g r a t : </td>
<td> <input type= t e x t name= e x p r s i z e =30 r e q u i r e d> </td>
</ tr>
<tr>
<td> L i m i t a i n f e r i o a r a a i n t e r v a l u l u i : </td>
<td> <input type= t e x t name= a s i z e =30 r e q u i r e d> </td>
</ tr>
<tr>
<td> L i m i t a s u p e r i o a r a a i n t e r v a l u l u i : </td>
<td> <input type= t e x t name=b s i z e =30 r e q u i r e d> </td>
</ tr>
<tr>
<td> T o l e r a n t a : </td>
<td> <input type= t e x t name= e p s value= 1 . 0 e8 s i z e =30 r e q u i r e d> </td>
</ tr>
<tr>
<td> Numar maxim admis de i t e r a t i i : </td>
<td> <input type= t e x t name=nmi value= 50 s i z e =30 r e q u i r e d> </td>
</ tr>
<tr>
<td>
<input type= b ut to n value= C a l c u l e a z a onclick= send ( ) />
</td>
<td></td>
</ tr>
<tr>
<td>
<input type= b ut to n value= I n c h i d e c o n e x i u n e a onclick= m y c l o s e ( ) />
143
144
102
103
104
105
106
107
108
109
110
111
CAPITOLUL 8. APLICAT
II WEB
</td>
<td></td>
</ tr>
</ table>
</form>
</ div>
<div id= r e s u l t ></ div>
</ center>
</body>
</html>
8.2.3
import
import
import
import
import
import
import
j a v a . i o . IOException ;
j a v a . n e t . URI ;
javax . websocket . ContainerProvider ;
j a v a x . w e b s o c k e t . DeploymentException ;
j a v a x . w e b s o c k e t . WebSocketContainer ;
javax . websocket . S e s s i o n ;
java . u t i l . Scanner ;
11
import j a v a x . w e b s o c k e t . Endpoint ;
import j a v a x . w e b s o c k e t . E n d p o i n t C o n f i g ;
import j a v a x . w e b s o c k e t . MessageHandler ;
13
9
10
private s t a t i c boolean s f a r s i t =f a l s e ;
private s t a t i c S t r i n g s e r v e r = ws : / / l o c a l h o s t : 8 0 8 0 / IntegralaWebSocketAd / c v a d r a ;
14
15
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
46
47
48
49
50
51
52
53
54
55
145
8.3
GWT utilizeaza protocolul Asynchronous JavaScript And Xml (AJAX). La baza protocolului AJAX se afla o interfata de programare (API) care printr-un obiect XMLHttpRequest (XHR), poate fi utilizata de un limbaj de scripting, n particular Javascript, pentru
transfer de date catre un server Web prin protocolul HTTP;
manipularea datelor XML sau JSON (JavaScript Object Notation).
Caracterul asincron consta n faptul ca raspunsul furnizat de un program server reface
doar o parte din pagina html si nu ntrega pagina, asa cum este cazul utilizarii obisnuite
a unui servlet.
Din punct de vedere al structurii aplicatiei GWT, aceasta poate fi:
146
CAPITOLUL 8. APLICAT
II WEB
Simpla, fara apel de procedura la distanta. In acest caz, rezolvarea cererii este
programata n clase aflate n catalogul client.
Programatorul dezvolta aplicatia n Java si HTML iar GWT transforma partea de
client n JavaScript. Astfel se evita programarea n JavaScript.
Cu apel de procedura la distanta. Partea de server este bazata pe tehnologia servlet.
GWT este distribuit gratuit de firma Google.
Instalarea produsului consta din dezarhivarea fisierului descarcat din Internet.
8.3.1
O aplicatie GWT o vom dezvolta cu apache-ant. Alternativ se poate utiliza apachemaven sau eclipse.
O aplicatie GWT se initiaza prin generarea unei structuri de cataloage si fisiere. Daca
se doreste realizarea unei aplicatii cu punctul de intrare dat de clasa context.MyApp si
care sa se afle ntr-un catalog catapp, atunci generarea se obtine prin comanda
webAppCreator -out catapp context.MyApp
lansata ntr-o fereasta DOS. Contextul poate reprezenta un sir de cataloage.
Rezultatul este reprezentat n Fig. 8.1 si corespunde unei aplicatii de ntampinare.
catapp
|-->
|
|
|
|
|
|
|
|
|
|
|-->
|
|-->
|
|
|
|
|
|
|
|
|
|
src
|--> context
|
|--> client
|
|
|
MyApp.java
|
|
|
GreetingService.java
|
|
|
GreetingServiceAsync.java
|
|--> server
|
|
|
GreetingServiceImpl.java
|
|--> shared
|
|
|
FieldVerifier.java
|
|
MyApp.gwt.xml
test
|
|
. . .
war
|--> WEB-INF
|
|
web.xml
|
MyApp.css
|
MyApp.html
|
favicon.ico
.classpath
.project
MyApp.launch
README.txt
build.xml
147
pentru construirea oricarei alte aplicatii, a carei dezvoltare consta n modificarea, rescrierea fisierelor create si completarea cu altele noi. Pentru o aplicatie GWT se mai
foloseste si termenul de modul GWT.
Fisierul MyApp.gwt.xml este un fisier de configurare n care trebuie declarate modulele
externe utilizate.
O aplicatie GWT poate fi executata n
modul de dezvoltare. Rularea n acest mod se lanseaza prin ant devmode.
Verificarea aplicatiei se face prin intermediul navigatorului implicit.
modul Web, de productie - caz n care se genereaza arhiva war a aplicatiei. Se va
executa ant war.
Cu notatiile utilizate mai sus, va rezulta fisierul MyApp.war. Dupa desfasurarea
aplicatiei ntr-un server Web, container de servlet, se va apela http://host:port/My
App/MyApp.html.
148
CAPITOLUL 8. APLICAT
II WEB
Label()
Label(String text)
Metode:
public void setText(String text)
TextBox
Constructori:
TextBox()
Metode:
public String getText()
public void setText(String text)
public void setVisibleLength(int lungime)
Button
Constructori:
Button(String text)
Metode:
public HandlerRegistration addClickHandler(ClickHandler click
Handler )
Metoda clickHandler contine prelucrarea atasata butonului.
Containere de widget
VerticalPanel
VerticalSplitPanel
HorizontalPanel HorizontalSplitPanel
FlowPanel
DockPanel
Un widget se include ntr-un container cu metoda
void add(Widget widget)
3. Generarea evenimentelor. Activitatile / actiunile care constituie obiectivul aplicatiei
GWT se lanseaza printr-un clic pe un buton. Fiecarui buton i se atribuie un obiect
care implementeaza interfata ClickHandler. Activitatile amintite mai sus sunt
definite n codul metodei public void onClick(ClickEvent event).
4. Programarea activitatilor corespunzatoare evenimentelor atasate butoanelor, adica
implementarea metodelor onClick.
5. Fixarea elementelor de stil ale elementelor grafice n fisierul MyApp.css. Atasarea la
un widget a unui element de stil se obtine cu metoda public void addStyleName(
String style).
Urmarim acesti pasi n
Exemplul 8.3.1 Calculul unei integrale. Transformam aplicatia 1.2 ntr-o aplicatie GWT.
149
Intr-o aplicatie GWT codurile Java din catalogul client sunt transformate n cod
JavaScript. Drept consecinta, nu se pot utiliza arhive jar. In locul lor, se vor folosi
module GWT, care n cazul aplicatiei de fata sunt:
mini-biblioteca mathlib, pentru calculul propriu-zis al integralei. Mini-biblioteca
mathlib a fost organizata de la nceput ca modul GWT;
MathEclipse-Parser, pentru evaluarea expresiilor de calcul date ca String.
Clasa mathlib.client.cvadra.MEParserDataIn, parte a mini-bibliotecii mathlib, extinde
clasa abstracta mathlib.client.cvadra.DataIn:
1
2
4
5
6
7
package m a t h l i b . c l i e n t . c v a d r a ;
import o r g . m a t h e c l i p s e . p a r s e r . c l i e n t . e v a l . ;
public c l a s s MEParserDataIn extends DataIn {
private D o u b l e E v a l u a t o r p a r s e r=n u l l ;
private ID ou bl eVa lu e v=n u l l ;
private S t r i n g e x p r ;
public void setA ( S t r i n g e x p r ) {
D o u b l e E v a l u a t o r a P a r s e r=new D o u b l e E v a l u a t o r ( ) ;
super . setA ( a P a r s e r . e v a l u a t e ( e x p r ) ) ;
}
public void setB ( S t r i n g e x p r ) {
D o u b l e E v a l u a t o r b P a r s e r=new D o u b l e E v a l u a t o r ( ) ;
super . setB ( b P a r s e r . e v a l u a t e ( e x p r ) ) ;
}
9
10
11
12
13
14
15
16
18
19
20
21
22
23
// f u n c t i a de i n t e g r a t
public double f c t ( double x ) {
v . setValue (x ) ;
return p a r s e r . e v a l u a t e ( e x p r ) ;
}
25
26
27
28
29
30
Concret se vor copia unele cataloage din sursa mini-bibliotecii si din fisierele sursa
obtinute din dezarhivarea fisierului matheclipse-parser-*.jar.
Se genereaza proiectului GWT cu punctul de intrare dat de clasa numerjava.gwt.
AppIntegrala. Structura generata de cataloage si fisiere se completeaza cu resursele
indicate n Fig. 8.2.
Proiectarea interfetei grafice. Consideram interfeta grafica
Calculul unei integrale Label titleLabel
HorizontalPanel hp
Panou container pentru dataPanel si resultsPanel
VerticalPanel dataPanel
Panoul stang pentru datele furnizate de client
VerticalPanel resultsPanel
Panou drept pentru rezultatele aplicatiei
Integreaza
Button button
150
CAPITOLUL 8. APLICAT
II WEB
integrala
|--> src
|
|--> numerjava
|
|
|--> gwt
|
|
|
|--> client
|
|
|
|
|
AppIntegrala.java
|
|
|
|
|
. . .
|
|
|
|
AppIntegrala.gwt.xml
|
|--> mathlib
|
|
|--> client
|
|
|
|--> cvadra
|
|
|
|
|--> impl
|
|
|
|
|
|
MetodaSimpsonWeb.java
|
|
|
|
|
IMetodaSimpson.java
|
|
|
|
|
DataIn.java
|
|
|
|
|
DataOut.java
|
|
|
|
|
MEParserDataIn.java
|
|
|
Mathlib.gwt.xml
|
|--> org
|
|
|--> matheclipse
|
|
|
|--> parser
|
|
|
|
|
. . .
|
|
. . .
|
|--> war
|
|
|--> WEB-INF
|
|
|
|
. . .
|
|
|
MyApp.css
|
|
|
MyApp.html
|
. . .
si respectiv
151
Indicatorul de raspuns
Label indLabel
Integrala
Label integLabel
Numarul de iteratii efectuat Label niLabel
Widgetele titleLabel, hp, button vor fi redate n fantele declarate respectiv prin
<body class="bd">
<center>
<div id="titleLabel"> </div>
<p><div id="mainPanel"></div></p>
<p><div id="button"></div></p>
</center>
</body>
152
CAPITOLUL 8. APLICAT
II WEB
Generarea evenimentelor. Butonului i se asociaza o instanta a clasei MyClickHandler, care contine actiunile executate dupa clic pe buton.
MyClickHandler handler=new MyClickHandler(varTextBox,
exprTextBox,infTextBox,supTextBox,epsTextBox,nmiTextBox,
indLabel,integLabel,niLabel);
button.addClickHandler(handler);
Programarea activitatilor corespunzatoare evenimentelor. Acest pas corespunde realizarii clasei MyClickHandler. Actiunile care se executa constau din verificarea completarii fiecarui camp al formularului, urmata de calculul integralei.
Codul clasei MyClickHandler este
1
2
3
4
5
6
7
8
9
10
12
13
14
15
16
17
18
19
20
21
22
23
24
25
27
28
29
30
31
32
33
34
35
36
37
39
40
41
42
43
c l a s s MyClickHandler implements C l i c k H a n d l e r {
TextBox varTextBox ;
TextBox exprTextBox ;
TextBox i n f T e x t B o x ;
TextBox supTextBox ;
TextBox epsTextBox ;
TextBox nmiTextBox ;
Label indLabel ;
Label i n t e g L a b e l ;
Label niLabel ;
MyClickHandler ( TextBox varTextBox , TextBox exprTextBox ,
TextBox infTextBox , TextBox supTextBox ,
TextBox epsTextBox , TextBox nmiTextBox ,
Label indLabel , Label integLabel , Label niLabel ){
t h i s . varTextBox=varTextBox ;
t h i s . exprTextBox=exprTextBox ;
t h i s . i n f T e x t B o x=i n f T e x t B o x ;
t h i s . supTextBox=supTextBox ;
t h i s . epsTextBox=epsTextBox ;
t h i s . nmiTextBox=nmiTextBox ;
t h i s . i n d L a b e l=i n d L a b e l ;
t h i s . i n t e g L a b e l=i n t e g L a b e l ;
t h i s . n i L a b e l=n i L a b e l ;
}
public boolean i s C o m p l e t e d ( TextBox tb , S t r i n g name ) {
S t r i n g t x t=tb . g e t T e x t ( ) ;
i f ( txt . equals ( ) ) {
Window . a l e r t ( Camp n e c o m p l e t a t : +name ) ;
indLabel . setText ( ? ) ;
integLabel . setText ( ? ) ;
niLabel . setText ( ? ) ;
return f a l s e ;
}
return true ;
}
public void o n C l i c k ( C l i c k E v e n t e v e n t ) {
i f ( ! i s C o m p l e t e d ( varTextBox , S i m b o l u l v a r i a b i l e i ) ) return ;
i f ( ! i s C o m p l e t e d ( exprTextBox , F u n c t i a ) ) return ;
i f ( ! i s C o m p l e t e d ( infTextBox , L i m i t a i n f e r i o a r a ) ) return ;
i f ( ! i s C o m p l e t e d ( supTextBox , L i m i t a s u p e r i o a r a ) ) return ;
i f ( ! i s C o m p l e t e d ( epsTextBox , T o l e r a n t a ) ) return ;
i f ( ! i s C o m p l e t e d ( nmiTextBox , Numar maxim admin de i t e r a t i i ) ) return ;
MEParserDataIn d i n=
new MEParserDataIn ( varTextBox . g e t T e x t ( ) , exprTextBox . g e t T e x t ( ) ) ;
d i n . setA ( i n f T e x t B o x . g e t T e x t ( ) ) ;
d i n . setB ( supTextBox . g e t T e x t ( ) ) ;
S t r i n g e p s=epsTextBox . g e t T e x t ( ) ;
S t r i n g nmi=nmiTextBox . g e t T e x t ( ) ;
d i n . s e t E p s ( Double . p a r s e D o u b l e ( e p s ) ) ;
d i n . setNmi ( I n t e g e r . p a r s e I n t ( nmi ) ) ;
IMetodaSimpson o b j=new MetodaSimpsonWeb ( ) ;
DataOut dout=o b j . metodaSimpson ( d i n ) ;
i n d L a b e l . s e t T e x t ( I n d i c a t o r u l de r a s p u n s : +dout . g e t I n d ( ) ) ;
i n t e g L a b e l . s e t T e x t ( I n t e g r a l a : +
NumberFormat . getFormat ( ###0.000000 ) . f o r m a t ( dout . g e t I n t e g r a l a ( ) ) ) ;
n i L a b e l . s e t T e x t ( Numarul i t e r a t i i l o r e f e c t u a t e : +dout . g e t N i ( ) ) ;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
10
import
import
import
import
import
import
import
import
12
public c l a s s A p p I n t e g r a l a implements E n t r y P o i n t {
4
5
6
7
8
9
14
15
16
17
18
19
20
21
22
23
24
25
26
com . g o o g l e . gwt . c o r e . c l i e n t . E n t r y P o i n t ;
com . g o o g l e . gwt . u s e r . c l i e n t . u i . ;
com . g o o g l e . gwt . u s e r . c l i e n t . Window ;
com . g o o g l e . gwt . i 1 8 n . c l i e n t . NumberFormat ;
com . g o o g l e . gwt . e v e n t . dom . c l i e n t . C l i c k E v e n t ;
com . g o o g l e . gwt . e v e n t . dom . c l i e n t . C l i c k H a n d l e r ;
mathlib . c l i e n t . cvadra . ;
m a t h l i b . c l i e n t . c v a d r a . impl . MetodaSimpsonWeb ;
153
154
CAPITOLUL 8. APLICAT
II WEB
27
28
29
30
31
32
33
34
35
36
V e r t i c a l P a n e l d a t a P a n e l=new V e r t i c a l P a n e l ( ) ;
d a t a P a n e l . add ( v a r L a b e l ) ;
d a t a P a n e l . add ( varTextBox ) ;
d a t a P a n e l . add ( e x p r L a b e l ) ;
d a t a P a n e l . add ( exprTextBox ) ;
d a t a P a n e l . add ( i n f L a b e l ) ;
d a t a P a n e l . add ( i n f T e x t B o x ) ;
d a t a P a n e l . add ( s u p L a b e l ) ;
d a t a P a n e l . add ( supTextBox ) ;
d a t a P a n e l . add ( e p s L a b e l ) ;
d a t a P a n e l . add ( epsTextBox ) ;
d a t a P a n e l . add ( nmiLabel ) ;
d a t a P a n e l . add ( nmiTextBox ) ;
d a t a P a n e l . setBorderWidth ( 2 ) ;
38
39
40
41
42
43
44
45
L a b e l i n d L a b e l=new L a b e l ( I n d i c a t o r u l de r a s p u n s ) ;
L a b e l i n t e g L a b e l=new L a b e l ( I n t e g r a l a ) ;
L a b e l n i L a b e l=new L a b e l ( Numarul de i t e r a t i i e f e c t u a t ) ;
47
48
49
V e r t i c a l P a n e l r e s u l t s P a n e l=new V e r t i c a l P a n e l ( ) ;
r e s u l t s P a n e l . add ( i n d L a b e l ) ;
r e s u l t s P a n e l . add ( i n t e g L a b e l ) ;
r e s u l t s P a n e l . add ( n i L a b e l ) ;
r e s u l t s P a n e l . setBorderWidth ( 2 ) ;
51
52
53
54
55
H o r i z o n t a l P a n e l hp=new H o r i z o n t a l P a n e l ( ) ;
hp . s e t S p a c i n g ( 1 0 ) ;
hp . add ( d a t a P a n e l ) ;
hp . add ( r e s u l t s P a n e l ) ;
57
58
59
60
62
63
64
65
66
67
RootPanel . g e t ( t i t l e L a b e l ) . add ( t i t l e L a b e l ) ;
RootPanel . g e t ( mainPanel ) . add ( hp ) ;
RootPanel . g e t ( b ut to n ) . add ( but t on ) ;
69
70
71
72
73
75
c l a s s MyClickHandler implements C l i c k H a n d l e r {
TextBox varTextBox ;
TextBox exprTextBox ;
TextBox i n f T e x t B o x ;
TextBox supTextBox ;
TextBox epsTextBox ;
TextBox nmiTextBox ;
Label indLabel ;
Label i n t e g L a b e l ;
Label niLabel ;
76
77
78
79
80
81
82
83
84
86
87
88
89
90
91
92
93
URAREA IN NOR
8.4. DESFAS
t h i s . nmiTextBox=nmiTextBox ;
t h i s . i n d L a b e l=i n d L a b e l ;
t h i s . i n t e g L a b e l=i n t e g L a b e l ;
t h i s . n i L a b e l=n i L a b e l ;
94
95
96
97
98
100
101
102
103
104
105
106
107
108
109
110
public void o n C l i c k ( C l i c k E v e n t e v e n t ) {
i f ( ! i s C o m p l e t e d ( varTextBox , S i m b o l u l v a r i a b i l e i ) ) return ;
i f ( ! i s C o m p l e t e d ( exprTextBox , F u n c t i a ) ) return ;
i f ( ! i s C o m p l e t e d ( infTextBox , L i m i t a i n f e r i o a r a ) ) return ;
i f ( ! i s C o m p l e t e d ( supTextBox , L i m i t a s u p e r i o a r a ) ) return ;
i f ( ! i s C o m p l e t e d ( epsTextBox , T o l e r a n t a ) ) return ;
i f ( ! i s C o m p l e t e d ( nmiTextBox , Numar maxim admin de i t e r a t i i ) ) return ;
MEParserDataIn d i n=new MEParserDataIn ( varTextBox . g e t T e x t ( ) , exprTextBox . g e t T e x t ( ) ) ;
d i n . setA ( i n f T e x t B o x . g e t T e x t ( ) ) ;
d i n . setB ( supTextBox . g e t T e x t ( ) ) ;
S t r i n g e p s=epsTextBox . g e t T e x t ( ) ;
S t r i n g nmi=nmiTextBox . g e t T e x t ( ) ;
d i n . s e t E p s ( Double . p a r s e D o u b l e ( e p s ) ) ;
d i n . setNmi ( I n t e g e r . p a r s e I n t ( nmi ) ) ;
IMetodaSimpson o b j=new MetodaSimpsonWeb ( ) ;
DataOut dout=o b j . metodaSimpson ( d i n ) ;
i n d L a b e l . s e t T e x t ( I n d i c a t o r u l de r a s p u n s : +dout . g e t I n d ( ) ) ;
i n t e g L a b e l . s e t T e x t ( I n t e g r a l a : +
NumberFormat . getFormat ( ###0.000000 ) . f o r m a t ( dout . g e t I n t e g r a l a ( ) ) ) ;
n i L a b e l . s e t T e x t ( Numarul i t e r a t i i l o r e f e c t u a t e : +dout . g e t N i ( ) ) ;
}
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
155
8.4
Desf
asurarea n nor
156
CAPITOLUL 8. APLICAT
II WEB
URAREA IN NOR
8.4. DESFAS
157
lansate ntr-o fereasta DOS, n catalogul care contine catalogul war. Aplicatia se apeleaza
prin http://localhost:8080. Daca n loc de index.html se utilizeaza alt nume, atunci
apelarea aplicatiei este
http://localhost:8080/fi
sier.html.
Exemplul 8.4.1 Integrarea servlet-ului MetodaSimpsonServet, dezvoltata ntr-o sectiune
anterioara, n platforma Google App Engine.
158
CAPITOLUL 8. APLICAT
II WEB
Sablonul aplicatiei se copiaza ntr-o zona de lucru sub numele appintegrala si se completeaza cu fisierele servlet-ului (MetodaSimpsonServlet.java, index.html ) si catalogul lib.
Rezultatul va fi
appintegrala
|--> src
|
|--> integrala
|
|
|
MetodaSimpsonServlet.java
|
|--> META-INF
|
|
|
. . .
|
|
log4j.properties
|
|
logging.properties
|
|--> WEB-INF
|
|
|--> lib
|
|
|
|
jep-2.4.1.jar
|
|
|
|
mathlib.jar
|
|
|
appengine-web.xml
|
|
|
web.xml
|
|
index.html
|
build.xml
Singurul fisier specific GAE este appengine-web.xml, dar adaptarea acestuia se face
doar pentru ncarcarea n nor.
Capitolul 9
Inc
arcarea unui fisier - upload
Problema pe care o tratam consta n transferul unui volum mare de date ale clientului
catre aplicatia server. In particular, consideram cazul n care datele corespund unei
matrice.
La nceput vom distinge cazul n care matricea are dimensiuni rezonabile, putand fi
introdusa ntr-o pagina html. In acest scop se vor utiliza functii Javascript.
In cazul n care volumul datelor de preluat de catre aplicatia Web este mare, calea de
urmat consta din:
1. Scrierea / depozitarea datelor ntr-un fisier;
2. Incarcarea fisierului n aplicatia Web.
Expedierea datelor dintr-un fisier si receptionarea lor defineste problema ncarcarii unui
fisier (file upload ). Un produs care ne ajuta sa ndeplinim acest obiectiv este pachetul
commons-fileupload - dezvoltat de apache.
9.1
Preluarea elementelor unei matrice sau vector de dimensiune redusa, necesare unei
aplicatii Web, se poate programa n mod elegant utilizand functii Javascript. Exemplificam prin
Exemplul 9.1.1 Preluarea si transmiterea unei matrice la un servlet.
Pentru nceput se preiau ntr-un formular html numarul liniilor si ale coloanelor.
1
2
3
4
5
6
7
8
9
10
11
159
160
CAPITOLUL 9. INCARCAREA
UNUI FIS
IER - UPLOAD
12
14
f u n c t i o n compute ( ) {
var mField=document . g e t E l e m e n t B y I d ( rows ) ;
var n F i e l d=document . g e t E l e m e n t B y I d ( c o l s ) ;
var u r l = / j s m a t r i x / m a t r i x ?m= +
e s c a p e ( mField . value)+&n=+e s c a p e ( n F i e l d . value)+&mat=+e s c a p e ( a r r a y 2 S t r i n g ( ) ) ;
var r e q = i n i t R e q u e s t ( ) ;
req . onreadystatechange = function () {
i f ( r e q . r e a d y S t a t e == 4) {
i f ( r e q . s t a t u s == 200) {
p a r s e M e s s a g e s ( r e q . responseXML ) ;
} else {
a l e r t ( r e q . s t a t u s+ : +r e q . s t a t u s T e x t ) ;
}
}
};
r e q . open ( g e t , u r l , t r u e ) ;
r e q . send ( n u l l ) ;
}
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
67
68
69
70
71
72
73
74
75
76
77
78
f u n c t i o n p a r s e M e s s a g e s ( responseXML ) {
var r = responseXML . getElementsByTagName ( r e z u l t a t ) [ 0 ] ;
document . g e t E l e m e n t B y I d ( r e z u l t a t ) . innerHTML= ;
f o r ( i =0; i<r . c h i l d N o d e s . l e n g t h ; i ++){
document . getElementById ( r e z u l t a t ) . innerHTML=
document . getElementById ( r e z u l t a t ) . innerHTML+<br/> ;
var row=r . c h i l d N o d e s [ i ] ;
f o r ( j =0; j <row . c h i l d N o d e s . l e n g t h ; j ++){
var c o l=row . getElementsByTagName ( c o l ) [ j ] ;
var t=c o l . c h i l d N o d e s [ 0 ] . nodeValue ;
document . getElementById ( r e z u l t a t ) . innerHTML=
document . getElementById ( r e z u l t a t ) . innerHTML+t+ ;
}
}
}
function templateMatrix (){
var rows=document . myForm . rows . value ;
var c o l s=document . myForm . c o l s . value ;
var myInput= ;
document . getElementById ( m a t r i x ) . innerHTML= ;
f o r ( var i =0; i <rows ; i ++){
myInput=<br/> ;
document . getElementById ( m a t r i x ) . innerHTML=
document . getElementById ( m a t r i x ) . innerHTML+myInput ;
f o r ( var j =0; j <c o l s ; j ++){
myInput=<i n p u t t y p e =number s t e p =any name= mat +i+
+j+ s i z e = 5 i d = mat +i+ +j+ /> ;
document . getElementById ( m a t r i x ) . innerHTML=
document . getElementById ( m a t r i x ) . innerHTML+myInput ;
}
}
}
function array2String (){
var rows=document . myForm . rows . value ;
var c o l s=document . myForm . c o l s . value ;
var x=new Array ( rows ) ;
f o r ( var i =0; i <rows ; i ++){
x [ i ]=new Array ( c o l s )
f o r ( var j =0; j <c o l s ; j ++){
x [ i ] [ j ]= p a r s e F l o a t ( document . getElementById ( mat +i+ +j ) . value ) ;
}
}
return x . toString ( ) ;
}
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
161
//>
</ s c r i p t>
</head>
<body>
<h1> Matrix Enter Form </h1>
<br/>
<form name=myForm>
<table>
<tr>
<td> Rows </td>
<td>
<input type=number id= rows name= rows s i z e= 10 r e q u i r e d min= 1 />
</td>
</ tr>
<tr>
<td> Columns </td>
<td>
<input type=number id= c o l s name= c o l s s i z e= 10 r e q u i r e d min= 1 />
</td>
</ tr>
<tr>
<td></td>
<td>
<input type= b ut to n onClick= t e m p l a t e M a t r i x ( )
name= m a t r i x value= G e n e r a t e a r r a y />
</td>
</ tr>
</ table>
<div id= m a t r i x > </ div>
<p/>
<input type= b ut to n value= C a l c u l e a z a onClick= compute ( ) >
</form>
<div id= r e z u l t a t ></ id>
</body>
</html>
package m a t r i x ;
import j a v a . i o . ;
import j a v a x . s e r v l e t . ;
import j a v a x . s e r v l e t . h t t p . ;
import j a v a x . s e r v l e t . a n n o t a t i o n . WebServlet ;
@WebServlet ( u r l P a t t e r n s = / m a t r i x )
public f i n a l c l a s s R e a d M a t r i x S e r v l e t extends H t t p S e r v l e t {
public void doGet ( H t t p S e r v l e t R e q u e s t req , H t t p S e r v l e t R e s p o n s e r e s )
throws S e r v l e t E x c e p t i o n , IOException {
P r i n t W r i t e r out=r e s . g e t W r i t e r ( ) ;
S t r i n g rows=r e q . g e t P a r a m e t e r ( m ) ;
i n t m=I n t e g e r . p a r s e I n t ( rows ) ;
162
CAPITOLUL 9. INCARCAREA
UNUI FIS
IER - UPLOAD
S t r i n g c o l s=r e q . g e t P a r a m e t e r ( n ) ;
i n t n=I n t e g e r . p a r s e I n t ( c o l s ) ;
S t r i n g mat=r e q . g e t P a r a m e t e r ( mat ) ;
double [ ] [ ] t=new double [m ] [ n ] ;
S t r i n g [ ] s=mat . s p l i t ( , ) ;
f o r ( i n t i =0; i <m; i ++)
f o r ( i n t j =0; j <n ; j ++)
t [ i ] [ j ]= Double . p a r s e D o u b l e ( s [ i n+j ] ) ;
r e s . setContentType ( t e x t /xml ) ;
r e s . s e t H e a d e r ( CacheC o n t r o l , noc a c h e ) ;
out . p r i n t ( <?xml v e r s i o n =\1.0\ ?> ) ;
out . p r i n t ( <r e z u l t a t > ) ;
f o r ( i n t i =0; i <m; i ++){
out . p r i n t ( <row> ) ;
f o r ( i n t j =0; j <n ; j ++){
out . p r i n t ( <c o l > ) ;
out . p r i n t (new Double ( t [ i ] [ j ] ) . t o S t r i n g ( ) ) ;
out . p r i n t ( </ c o l > ) ;
}
out . p r i n t ( </row> ) ;
}
out . p r i n t ( </ r e z u l t a t > ) ;
out . c l o s e ( ) ;
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
40
41
42
43
44
9.2
FileUpload
Transferarea unui fisier, din partea clientului nu ridica nicio problema. In fisierul html
de apelare (client Web) se defineste un formular
<form
action=. . .
enctype="multipart/form-data"
method="post">
iar un fisier de ncarcat se fixeaza prin intermediul marcajului
<input type="file" name=. . . size=. . .>
Programul navigator afiseaza o fereastra de cautare, prin care clientul selecteaza fisierul
pe care doreste sa-l ncarce.
1
2
3
4
5
6
7
8
9
10
163
9.2. FILEUPLOAD
11
12
13
14
15
16
17
18
19
20
21
22
<tr>
<td> <input type= f i l e name= m y f i l e s i z e =30 r e q u i r e d> </td>
</ tr>
<tr>
<td> <input type= submit value= Expediaza > </td>
</ tr>
</ table>
<input type= h id de n name= t i p value= t e x t / html >
</form>
</ center>
</body>
</html>
Daca partea de client este un program, atunci se utilizeaza commons-httpclient, prezentat n 8.1.2.
Pe partea serverului utilizam produsul apache Commons-FileUpload care simplifica
transferul unui fisier de la un client la un servlet.
Din distributia produsului fisierele commons-fileupload-*.jar, commons-io-*.jar se depun
n catalogul WEB-INF\lib al servlet-ului.
Programarea ncarcarii revine la:
1. Declararea pachetelor din commons-fileupload utilizate
import org.apache.commons.fileupload.disk.*;
import org.apache.commons.fileupload.servlet.*;
import org.apache.commons.fileupload.*;
2. Crearea unei fabrici pentru manipularea fisierelor pe disc
FileItemFactory factory = new DiskFileItemFactory();
3. Crearea unei unelte de ncarcare
ServletFileUpload
164
CAPITOLUL 9. INCARCAREA
UNUI FIS
IER - UPLOAD
sau direct
DiskFileItemFactory factory = new DiskFileItemFactory(
maxMemorySize, tempDirectory);
dimensiunea maxima a unui fisier
upload.setSizeMax(maxRequestSize);
5. Prelucrarea elementelor ncarcate
Iterator iter=fileItems.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {
// Prelucrarea elementului item care corespunde unei
// date din formularul html care nu este de tip fisier
}
else{
// Prelucrarea elementului item de tip fisier
}
}
6. In cazul unui element care nu este de tip fisier putem obtine numele si valoarea
atributului furnizat de client
String name = item.getFieldName();
String value = item.getString();
7. In cazul unui fisier putem afla numele campului input cu type="file", numele
fisierului, dimensiunea fisierului
String fieldName = item.getFieldName();
String fileName = item.getName();
long sizeInBytes = item.getSize();
8. Daca dorim sa salvam fisierul pe calculatorul server atunci prelucrarea este
File uploadedFile = new File(...);
item.write(uploadedFile);
9. Daca datele fisierului se ncarca n memoria calculatorului atunci prelucrarea este
InputStream in = item.getInputStream();
//preluarea datelor din fluxul in
. . .
in.close();
9.2. FILEUPLOAD
165
package l i n e a r ;
import j a v a . i o . ;
import j a v a x . s e r v l e t . ;
import j a v a x . s e r v l e t . h t t p . ;
import j a v a . u t i l . ;
import o r g . apache . commons . f i l e u p l o a d . d i s k . ;
import o r g . apache . commons . f i l e u p l o a d . s e r v l e t . ;
import o r g . apache . commons . f i l e u p l o a d . ;
import m a t h l i b . c l i e n t . l i n e a r . ;
import m a t h l i b . c l i e n t . l i n e a r . impl . R e z o l v i t o r S c i l a b ;
import j a v a . t e x t . DecimalFormat ;
public c l a s s S i s t e m L i n i a r S e r v l e t extends H t t p S e r v l e t {
public void doPost ( H t t p S e r v l e t R e q u e s t req , H t t p S e r v l e t R e s p o n s e r e s )
throws S e r v l e t E x c e p t i o n , IOException {
S t r i n g t i p= ;
S e r v l e t O u t p u t S t r e a m out=n u l l ;
DecimalFormat f=new DecimalFormat ( 0 . 0 0 0 0 E0 ) ;
try {
F i l e I t e m F a c t o r y f a c t o r y = new D i s k F i l e I t e m F a c t o r y ( ) ;
ServletFileUpload
up lo ad = new S e r v l e t F i l e U p l o a d ( f a c t o r y ) ;
L i s t i t e m s = u pl oa d . p a r s e R e q u e s t ( r e q ) ;
up lo ad . s e t S i z e M a x ( 1 0 0 0 0 0 0 ) ;
I t e r a t o r i t e r=i t e m s . i t e r a t o r ( ) ;
DataIn d i n=new DataIn ( ) ;
while ( i t e r . hasNext ( ) ) {
F i l e I t e m item = ( F i l e I t e m ) i t e r . n e x t ( ) ;
i f ( ! item . i s F o r m F i e l d ( ) ) {
InputStream i n=item . g e t I n p u t S t r e a m ( ) ;
InputStreamReader i s r =new InputStreamReader ( i n ) ;
B u f f e r e d R e a d e r br=new B u f f e r e d R e a d e r ( i s r ) ;
d i n . s e t M a t r i x ( br ) ;
br . c l o s e ( ) ;
isr . close ();
in . close ( ) ;
}
else {
S t r i n g name = item . getFieldName ( ) ;
i f ( name . e q u a l s ( t i p ) )
t i p=item . g e t S t r i n g ( ) ;
}
}
r e s . setContentType ( t i p ) ;
out = r e s . getOutputStream ( ) ;
I R e z o l v i t o r S c i l a b o b j=new R e z o l v i t o r S c i l a b ( ) ;
DataOut dout=o b j . r e z o l v i t o r S c i l a b ( d i n ) ;
double [ ] x=n u l l ;
double [ ] [ ] k=n u l l ;
i n t l =0 , c =0;
166
i f ( dout . g e t E C o m p a t i b i l ( ) ) {
x=dout . getX ( ) ;
k=dout . getK ( ) ;
l=x . l e n g t h ;
i f ( k!= n u l l ) c=k [ 0 ] . l e n g t h ;
}
i f ( t i p . e q u a l s ( t e x t / html ) ) {
out . p r i n t l n ( <html><body b g c o l o r=\#bbccbb \ > ) ;
out . p r i n t l n ( <c e n t e r > ) ;
out . p r i n t l n ( <h1> S o l u ţ i a s i s t e m u l u i a l g e b r i c +
de ecua ţ i i l i n i a r e </h1> ) ;
i f ( dout . g e t E C o m p a t i b i l ( ) ) {
out . p r i n t l n ( <t a b l e b o r d e r=1 c e l l s p a c i n g =5> ) ;
out . p r i n t l n ( <t r > ) ;
out . p r i n t l n ( <th> X= </th> ) ;
out . p r i n t l n ( <th a l i g n =\ c e n t e r \ c o l s p a n=+(c 1)+> Ker= </th> ) ;
out . p r i n t l n ( </t r > ) ;
f o r ( i n t i =0; i <l ; i ++){
out . p r i n t l n ( <t r > ) ;
out . p r i n t l n ( <td> ) ;
out . p r i n t l n ( f . f o r m a t ( x [ i ] ) ) ;
out . p r i n t l n ( </td> ) ;
i f ( c >0){
f o r ( i n t j =0; j <c ; j ++){
out . p r i n t l n ( <td> ) ;
out . p r i n t l n ( f . f o r m a t ( k [ i ] [ j ] ) ) ;
out . p r i n t l n ( </td> ) ;
}
}
out . p r i n t l n ( </t r > ) ;
}
out . p r i n t l n ( </ t a b l e > ) ;
}
else {
out . p r i n t l n ( S i s t e m i n c o m p a t i b i l ! ) ;
}
out . p r i n t l n ( </ c e n t e r > ) ;
out . p r i n t l n ( </html></body> ) ;
}
else {
S t r i n g r e z= ;
i f ( dout . g e t E C o m p a t i b i l ( ) ) {
f o r ( i n t i =0; i <l ; i ++){
r e z+=x [ i ] ;
r e z+= ;
i f ( c >0){
f o r ( i n t j =0; j <c ; j ++){
r e z+=k [ i ] [ j ] ;
r e z+= ;
}
}
r e z+= \n ;
}
}
System . out . p r i n t l n ( r e z ) ;
out . p r i n t l n ( r e z . t r i m ( ) ) ;
}
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
}
catch ( E x c e p t i o n e ) {
System . out . p r i n t l n ( E x c e p t i o n : +e . g e t M e s s a g e ( ) ) ;
}
out . c l o s e ( ) ;
107
108
109
110
111
112
113
CAPITOLUL 9. INCARCAREA
UNUI FIS
IER - UPLOAD
Capitolul 10
Servicii Web
Un serviciu Web este o aplicatie client-server cu serverul gazduit de un server Web,
apelabil prin aplicatia client si realizat potrivit unei interfete de programare specifice.
Protocolul de comunicatie este http.
Sunt cunoscute urmatoarele tipuri de servicii Web:
Servicii bazate pe modelul Remote Precedure Call (RPC) - Apel de Procedura de
la Distanta.
Protocolul de reprezentare a cererii si a raspunsului (de serializare / deserializare)
variaza. Din acest punct de vedere sunt cunoscute:
Servicii xml-rpc (www.xmlrpc.org). Cererea si raspunsul sunt transmise prin
cod xml cuprins n corpul mesajului http.
Servicii json-rpc (www.json-rpc.org) bazat pe reprezentarea JSON.
Servicii hessian. Se utilizeaza un protocol pentru serializare / deserealizare
bazat pe reprezentarea binara a datelor. Protocolul a fost dezvoltat de firma
Caucho Technologies (2007).
Servicii bazate pe interfata de programare Java API for XML Web Services
- JAX-WS. Interfata de programare JAX-WS este varianta cea mai recenta
pentru serviciile cunoscute sub numele de servicii soap-rpc.
Pentru fiecare caz semnalat mai sus sunt realizate implementari n mai multe limbaje
/ platforme de programare.
Servicii REST.
REpresentational State Transfer (REST) este un model de arhitectura de aplicatie
distribuita1 .
REST specifica modul cum o resursa - entitate care contine informatie specifica este definita si cum poate fi adresata.
1
REST a fost introdus de Roy Fielding, n teza sa de doctorat din 2000. Roy Fielding este autorul
principal al specificatiilor protocolului http.
167
168
10.1
10.2
JSR (Java Specification Request) 109 defineste o interfata de programare (API) pentru
realizarea serviciilor Web bazate pe RPC : Java API for XML Web Services (JAX-WS).
Un asemenea serviciu Web se poate implementa prin:
169
servlet:
Serviciul este implementat ca o clasa Java care ruleaza ntr-un container Web, fiind
integrat ntr-un servlet. Integrarea este complet transparenta programatorului.
sesiune EJB (Enterprise Java Bean) fara stare (stateless session):
Serviciul ruleaza ntr-un container EJB.
10.2.1
Cadrul de lucru pe care l vom utiliza este Metro, dezvoltat de Oracle. Un scop al
cadrului de lucru Metro este asigurarea interoperabilitatii ntre server si client atunci cand
acestea sunt realizate pe platformele soft Java si .NET, dar faciliteaza si dezvoltarea n
mediul omogen Java. Metro implementeaza modelul JAX-WS.
Alternativ, s-ar fi putut folosi implementarea de referinta jaxws-ri, dezvoltat tot de
Oracle sau apache-CXF.
Metro ofera suport pentru dezvoltarea serviciului Web pe serverele:
apache-tomcat; 2
glassfish.
Instalarea n apache-tomcat se face
prin ant cu fisierul metro-on-tomcat.xml aflat n distributia lui Metro.
fisierele jar aflate n catalogul metro\lib se copiaza n apache-tomcat-*\lib sau n
catalogul WEB-INF\lib al serviciului.
Dezvoltarea aplicatiei server
Clasa serverului este o clasa POJO cu adnotari specifice. Definirea serviciului, a
operatiilor pe care le ofera serviciul si a parametrilor de intrare pentru fiecare operatie se
face utilizand adnotarile @WebService, respectiv @WebMethod si @WebParam.
Vom dezvolta serviciul Web pentru calculul unei integrale. In clasa server se va
crea cate o instanta a claselor mathlib.client.cvadra.JepDataIn si mathlib.client.cvadra.
impl.MetodaSimpsonWeb a mini-bibliotecii mathlib iar rezultatele se obtin apeland metoda
de integrare numerica metodaSimson. In final, sursa devine:
1
package i n t e g r a l a . s e r v e r ;
import
import
import
import
import
4
5
6
7
9
10
j a v a x . j w s . WebMethod ;
j a v a x . j w s . WebParam ;
j a v a x . j w s . WebService ;
mathlib . c l i e n t . cvadra . ;
m a t h l i b . c l i e n t . c v a d r a . impl . MetodaSimpsonWeb ;
@WebService ( )
public c l a s s MetodaSimpsonWS {
Functioneaz
a si n serverul Web jetty.
170
@WebMethod( operationName = i n t e g r e a z a )
public DataOut i n t e g r e a z a (@WebParam( name = a ) S t r i n g a ,
@WebParam( name = b ) S t r i n g b ,
@WebParam( name = s v a r ) S t r i n g s v a r ,
@WebParam( name = e x p r ) S t r i n g expr ,
@WebParam( name = e p s )
S t r i n g eps ,
@WebParam( name = nmi )
S t r i n g nmi ) {
12
13
14
15
16
17
18
20
21
22
23
24
25
26
27
28
29
171
sun-jaxws.xml
1
2
3
4
5
6
7
web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
172
<arg
<arg
<arg
<arg
</exec>
</target>
value="-keep"/>
value="-p"/>
value="${app.name}.client"/>
value="${wsdl.uri}"/>
Optiunea -d specifica locatia unde se depun fisierele generate, optiunea -p indica pachetul
din care fac parte clasele generate.
Dintre aceste clase, n codul clientului propriu-zis se foloseste clasa MetodaSimpsonWSService. Numele clasei s-a obtinut adaugand sufixul Service la numele clasei server.
Aceasta clasa contine metoda getMetodaSimpsonWSPort() ce returneaza un reprezentant
al serviciului pe calculatorul clientului.
Astfel referinta la serviciu se obtine prin
MetodaSimpsonWSService service=new MetodaSimpsonWSService();
MetodaSimpsonWS port=service.getMetodaSimpsonWSPort();
Prin variabila port putem apela orice operatie a serviciului.
Codul clientului este
1
2
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package i n t e g r a l a . c l i e n t ;
import j a v a . u t i l . S c a n n e r ;
public c l a s s C l i e n t I n t e g r a l a {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
MetodaSimpsonWSService s e r v i c e=new MetodaSimpsonWSService ( ) ;
MetodaSimpsonWS p o r t=s e r v i c e . getMetodaSimpsonWSPort ( ) ;
S c a n n e r s c a n n e r=new S c a n n e r ( System . i n ) ;
System . out . p r i n t l n ( E x t r e m i t a t e a s t a n g a ) ;
S t r i n g a=s c a n n e r . n e x t ( ) ;
System . out . p r i n t l n ( E x t r e m i t a t e a d r e a p t a ) ;
S t r i n g b=s c a n n e r . n e x t ( ) ;
System . out . p r i n t l n ( S i m b o l u l v a r i a b i l e i ) ;
S t r i n g s v a r=s c a n n e r . n e x t ( ) ;
System . out . p r i n t l n ( E x p r e s i a de i n t e g r a t ) ;
S t r i n g e x p r=s c a n n e r . n e x t ( ) ;
System . out . p r i n t l n ( T o l e r a n t a ) ;
S t r i n g e p s=s c a n n e r . n e x t ( ) ;
System . out . p r i n t l n ( Numar maxim admis de i t e r a t i i ) ;
S t r i n g nmi=s c a n n e r . n e x t ( ) ;
DataOut dout=p o r t . i n t e g r e a z a ( a , b , s v a r , expr , eps , nmi ) ;
System . out . p r i n t l n ( I n d i c a t o r u l de r a s p u n s : +dout . g e t I n d ( ) ) ;
System . out . p r i n t l n ( I n t e g r a l a : +dout . g e t I n t e g r a l a ( ) ) ;
System . out . p r i n t l n ( Numar de i t e r a t i i e f e c t u a t e : +dout . g e t N i ( ) ) ;
}
}
10.3
173
Clasa resursa - Resource class. Resursa Web este reprezinta de o clasa Java cu
adnotari JAX-RS. Clasa resursa radacina - Root resource class. Clasa cu adnotarea
@Path. Resursele adiacente se definesc relativ la aceasta clasa (resursa).
Metoda de identificare a cererii - Request method designator. Adnotarea @GET /
@POST /@PUT / @DELETE este folosita pentru identificarea cererii HTTP n vederea
desemnarii metodei de generare / prelucrare a resursei.
Metoda de generare / prelucrare a resusei - Resource method.
Localizator a resurselor adiacente - Sub-resource locator. Metoda pentru localizarea
a resurselor adiacente, adica a resurselor care se specifica relativ la resursa radacina.
Metoda de generare / prelucrare a unei resurse adiacente - Sub-resource method.
Provider o implementare a interfetei JAX-RS.
O implementare de referinta (Reference Implementation - RI) este oferita de pachetul
jersey-*.*.* realizat de Oracle.
Serverul Web care se va utiliza va fi apache-tomcat. In vederea desfasurarii, serviciul se
arhiveaza, avand extensia war. Numele arhivei va desemna numele serviciului. Structura
care se arhiveaza va fi
catalogul_serviciului_RESTful
|--> WEB-INF
|
|--> classes
|
|
|--> resources
|
|
|
|
*.class
|
|--> lib
|
|
|
*.jar
|
index.html sau index.jsp
Printre fisierele *.class se gasesc resursele serviciului. Fisierele *.jar sunt cele din catalogul
lib al distributiei jersey si eventual cele cerute de aplicatie. index.html sau index.jsp ofera
oportunitatea apelarii serviciului si de obicei reprezinta un client Web.
Serviciul RESTful este oferit prin intermediul unui servlet
org.glassfish.jersey.servlet.ServletContainer,
complet transparent programatorului, specificat doar n fisierul web.xml :
1
2
3
4
5
6
7
8
9
10
11
174
12
13
14
15
16
17
18
19
20
21
22
<i n i t param>
<paramname> j e r s e y . c o n f i g . s e r v e r . p r o v i d e r . p a c k a g e s</paramname>
<paramv a l u e>r e s o u r c e s</paramv a l u e>
</ i n i t param>
<l o a d ons t a r t u p>1</ l o a d ons t a r t u p>
</ s e r v l e t>
<s e r v l e t mapping>
<s e r v l e t name>J e r s e y Web A p p l i c a t i o n</ s e r v l e t name>
<u r l p a t t e r n>/ r e s o u r c e s /</ u r l p a t t e r n>
</ s e r v l e t mapping>
</webapp>
1
2
3
4
5
6
7
8
9
package r e s o u r c e s ;
im po rt j a v a x . ws . r s . QueryParam ;
im po rt j a v a x . ws . r s . c o r e . Response ;
im po rt j a v a x . ws . r s . Path ;
im po rt j a v a x . ws . r s .GET;
im po rt m a t h l i b . c l i e n t . c v a d r a . JepDataIn ;
im po rt m a t h l i b . c l i e n t . c v a d r a . DataOut ;
im po rt m a t h l i b . c l i e n t . c v a d r a . IMetodaSimpson ;
im po rt m a t h l i b . c l i e n t . c v a d r a . impl . MetodaSimpsonWeb ;
14
@Path ( i n t e g )
public c l a s s IntegResource {
p r i v a t e DataOut dout ;
p r i v a t e d o u b l e s=Double . NaN ;
16
p u b l i c I n t e g R e s o u r c e ( ) {}
11
12
13
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@GET
p u b l i c Response doGet (
@QueryParam ( s v a r ) S t r i n g s v a r ,
@QueryParam ( e x p r ) S t r i n g expr ,
@QueryParam ( a ) S t r i n g a ,
@QueryParam ( b ) S t r i n g b ,
@QueryParam ( nmi ) S t r i n g nmi ,
@QueryParam ( e p s ) S t r i n g eps ,
@QueryParam ( t i p ) S t r i n g t i p ) {
JepDataIn d i n=new JepDataIn ( s v a r , e x p r ) ;
d i n . setA ( a ) ;
d i n . setB ( b ) ;
d i n . s e t E p s ( Double . p a r s e D o u b l e ( e p s ) ) ;
d i n . setNmi ( I n t e g e r . p a r s e I n t ( nmi ) ) ;
IMetodaSimpson o b j=new MetodaSimpsonWeb ( ) ;
dout=o b j . metodaSimpson ( d i n ) ;
i n t n t i p =0;
i f ( t i p . e q u a l s ( t e x t / html ) ) n t i p =1;
Response r=n u l l ;
switch ( ntip ){
case 0 :
r=Response . ok ( g e t P l a i n R e p ( ) , t e x t / p l a i n ) . b u i l d ( ) ;
break ;
case 1 :
r=Response . ok ( getHtmlRep ( ) , t e x t / html ) . b u i l d ( ) ;
break ;
}
return r ;
35
36
37
38
39
40
41
42
43
44
45
46
47
49
p ub l ic S tr in g getPlainRep ( ) {
S t r i n g r e z u l t a t= ;
r e z u l t a t=r e z u l t a t+
I n d i c a t o r u l de r a s p u n s : + ( new I n t e g e r ( dout . g e t I n d ( ) ) ) . t o S t r i n g ()+ \n ;
r e z u l t a t=r e z u l t a t+
I n t e g r a l a : + ( new Double ( dout . g e t I n t e g r a l a ( ) ) ) . t o S t r i n g ()+ \n ;
r e z u l t a t=r e z u l t a t+
Numar de i t e r a t i i e f e c t u a t e : + ( new I n t e g e r ( dout . g e t N i ( ) ) ) . t o S t r i n g ( ) ;
return rezultat ;
}
50
51
52
53
54
55
56
57
58
60
61
62
63
64
65
66
p u b l i c S t r i n g getHtmlRep ( ) {
S t r i n g r e z u l t a t=<html><head></head><body b g c o l o r=
\ #bbeebb \ ><c e n t e r ><h1>R e z u l t a t u l f u r n i z a t de s e r v i c i u l RESTfull ;
r e z u l t a t=r e z u l t a t+<t a b l e b o r d e r=\ 1\ > ;
r e z u l t a t=r e z u l t a t+<t r > ;
r e z u l t a t=r e z u l t a t+<td> I n d i c a t o r u l de r a s p u n s </td> ;
r e z u l t a t=r e z u l t a t+<td>+(new I n t e g e r ( dout . g e t I n d ( ) ) ) . t o S t r i n g ()+ </td> ;
175
176
67
68
69
70
71
72
73
74
75
76
77
78
79
<html>
<body bgcolor=#bbeebb >
<center>
<h1> C a l c u l u l u n e i i n t e g r a l e p r i n t r un s e r v i c i u RESTful </h1>
<form method= g e t
action= / i n t e g r a l a / r e s o u r c e s / i n t e g >
<p>I n t r o d u c e ţ i</p>
<table border= 1 >
<tr>
<td> S i m b o l u l v a r i a b i l e i </td>
<td> <input type= t e x t name= s v a r s i z e= 10 />
</ tr>
<tr>
<td> E x p r e s i a f u n c ţ i e i de i n t e g r a t </td>
<td> <input type= t e x t name= e x p r s i z e= 10 />
</ tr>
<tr>
<td> E x t r e m i t a t e a s t âgă </td>
<td> <input type= t e x t name= a s i z e= 10 />
</ tr>
<tr>
<td> E x t r e m i t a t e a d r e a p t ă </td>
<td> <input type= t e x t name=b s i z e= 10 />
</ tr>
<tr>
<td> Numă r u l maxim admis de i t e r a ţ i i </td>
<td> <input type= t e x t name=nmi s i z e= 10 value= 50 />
</ tr>
<tr>
<td> T o l e r a n ţa </td>
<td> <input type= t e x t name= e p s s i z e= 10 value= 1 e6 />
</ tr>
<tr>
<td> S e l e c t a ţ i t i p u l r ă s p u n s u l u i </td>
<td>
<s e l e c t name= t i p >
<option value= t e x t / p l a i n > Text / P l a i n </ option>
<option value= t e x t / html > Text /Html </ option>
</ s e l e c t>
</td>
</ tr>
<tr a l i g n= c e n t e r >
<td> <input type= submit value= C a l c u l e a z a /> </td>
</ tr>
</ table>
</form>
</ center>
</body>
</html>
177
package i n t e g ;
import j a v a x . ws .
import j a v a x . ws .
import j a v a x . ws .
import j a v a . u t i l
rs . c l i en t . Client ;
rs . client . ClientBuilder ;
r s . c l i e n t . WebTarget ;
. Scanner ;
public c l a s s J e r s e y C l i e n t {
public s t a t i c void main ( S t r i n g a r g s [ ] ) {
C l i e n t c l i e n t = C l i e n t B u i l d e r . newClient ( ) ;
S t r i n g rootURL= h t t p : / / l o c a l h o s t : 8 0 8 0 / i n t e g r a l a / r e s o u r c e s / i n t e g ;
WebTarget webTarget = c l i e n t . t a r g e t ( rootURL ) ;
S c a n n e r s c a n n e r=new S c a n n e r ( System . i n ) ;
System . out . p r i n t l n ( E x t r e m i t a t e a s t a n g a ) ;
S t r i n g a=s c a n n e r . n e x t ( ) ;
System . out . p r i n t l n ( E x t r e m i t a t e a d r e a p t a ) ;
S t r i n g b=s c a n n e r . n e x t ( ) ;
System . out . p r i n t l n ( S i m b o l u l v a r i a b i l e i ) ;
S t r i n g s v a r=s c a n n e r . n e x t ( ) ;
System . out . p r i n t l n ( E x p r e s i a de i n t e g r a t ) ;
S t r i n g e x p r=s c a n n e r . n e x t ( ) ;
System . out . p r i n t l n ( T o l e r a n t a ) ;
S t r i n g e p s=s c a n n e r . n e x t ( ) ;
System . out . p r i n t l n ( Numar maxim admis de i t e r a t i i ) ;
S t r i n g nmi=s c a n n e r . n e x t ( ) ;
S t r i n g r e s p o n s e=webTarget .
queryParam ( s v a r , s v a r ) .
queryParam ( e x p r , e x p r ) .
queryParam ( a , a ) .
queryParam ( b , b ) .
queryParam ( nmi , nmi ) .
queryParam ( e p s , e p s ) .
queryParam ( t i p , t e x t / p l a i n ) .
request ( ) . get ( String . class ) ;
System . out . p r i n t l n ( r e s p o n s e ) ;
}
}
178
Partea II
Programare paralel
a n Java
179
Capitolul 11
Introducere n programarea
concurent
a / paralel
a
11.1
Procese paralele
Evenimentele se petrec n spatiu si timp. Exista urmatoarele posibilitati: doua evenimente se petrec n acelasi loc la alte momente de timp (succesiv, secvential) sau cele
doua evenimente se petrec n acelasi timp, dar n locuri diferite (concomitent, concurent,
paralel). Astfel paralelismul este o trasatura a acestui univers.
Apare astfel naturala cerinta ca un calculator sa poata simula sau exe- cuta operatii,
activitati paralele.
In cele ce urmeaza printr-un proces se va ntelege un sir de actiuni executate cate una
singura la un moment dat, iar un procesor va indica un dispozitiv care executa instructiuni
n mod secvential.
A
O.C., POPESCU
Mai precis un proces este caracterizat de urmatoarele atribute (BASC
I., 1989):
indivizibilitatea: Procesul este o unitate atomica care nu mai este divizat n alte
unitati carora sistemul de calcul sa le aloce resurse n mod autonom.
secventialitatea: Operatiile unui proces se executa cate una singura la un moment
dat.
asincronismul: Un proces se desfasoara independent de celelalte procese, cu exceptia
momentelor de interactiune cu alte procese.
temporalitatea: Un proces exista, se manifesta si este recunoscut numai n intervalul
de timp dintre lansarea sa n executie si terminarea sa.
Intr-un program, un proces are o existenta formata din mai multe stari:
Trecerea de la starea inexistent la starea creat se face prin declararea procesului.
Din starea creat un proces ajunge n starea executabil prin lansarea n executie sau
printr-o forma de activare. Starea executabil are doua substari:
181
182
1. starea gata de executare: procesul este pregatit pentru executare, dar nu i s-a
alocat nca un procesor logic/fizic;
2. starea n curs de executare: procesului i s-a alocat un procesor logic/fizic care
i executa instructiunile.
La terminarea executarii unui proces, acesta trece n starea terminat.
In final procesele sunt distruse - automat sau prin instructiuni - trecandu-se n starea
inexistent.
Un proces se poate bloca, mai precis poate fi
amanat : ntreruperea pentru un anumit timp a executiei procesului.
suspendat : ntreruperea executiei pe baza unei relatii cu alte procese. Procesul
poate reveni ulterior n starea de executabil, reluand executarea instructiunilor din
momentul suspendarii. Trecerea n starea executabil se realizeaza fie aleator, fie cu
disciplina unei cozi.
Un calculator cu procesare paralela poate fi definit, ntr-o prima aproximatie, ca o
masina capabila sa execute diferite operatii utilizand simultan cel putin doua procesoare.
Merita de semnalat aici clasificarea lui Flynn: Din punctul de vedere al secventei
de instructiuni executate de catre un sistem de calcul si al secventei de date asupra careia
actioneaza instructiunile la un moment dat, se pun n evidenta urmatoarele modele de
calculatoare:
SISD : Single Instruction, Single Data stream;
SIMD : Single Instruction, Multiple Data stream;
MIMD : Multiple Instruction, Multiple Data stream.
Modelul SISD corespunde sistemelor de calcul obisnuite, iar modelele SIMD si MIMD
caracterizeaza sistemele de calcul ce ofera facilitati de calcul paralel. In modelul SIMD
toate procesoarele efectueaza aceleasi operatii dar pe multimi de date diferite, n timp
ce n modelul MIMD procesoarele efectueaza secvente distincte de operatii asupra unor
multimi de date.
Daca executia proceselor se efectueaza concomitent pe procesoare diferite atunci executia
se numeste paralela.
Daca executia proceselor se efectueaza cu un singur procesor atunci executia se numeste
concurenta.
Pretul de achizitie, ntretinere si exploatare al unui calculator paralel fiind mare, pentru orice institutie problema achizitionarii unui asemenea calculator se pune n termenii
raportului eficienta/cost. Necesitatea de a dispune de o putere de calcul cat mai mare
la preturi cat mai mici a condus la solutii care permit programare paralela ntr-o retea
obisnuita de calculatoare.
In cazul n care procesele se executa pe calculatoare distincte, legate ntr-o retea,
atunci executia se numeste distribuita, paralel - distribuita.
183
184
11.2
Pentru a ntelege problemele care se ridica la realizarea unui program n care exista
procese ce se executa n paralel consideram doua exemple deosebit de importante.
1. Se considera un sistem de rezervare de bilete n care de la doua terminale se poate
cere ocuparea unor locuri. Actiunile necesare rezervarii sunt executate de procesele
P1 si P2 care se desfasoara n paralel; permitand solicitarea de bilete n orice moment,
de la oricare terminal. Fiecare operatiune de rezervare impune, printre altele, si
incrementarea unei variabile v, care indica numarul total de locuri ocupate.
2. Fie un sistem format din doua procese P1 si P2 , primul producand niste date care
apoi vor fi preluate de cel de al doilea. Comunicarea ntre cele doua procese se realizeaza prin intermediul unei zone de memorie tampon, de o anumita dimensiune,
n care procesul P1 introduce informatii (sub forma unor nregistrari), pe care apoi
P2 le extrage.
Procesul P2 nu este nevoit sa astepte pentru fiecare nregistrare n parte, iar P1
nu astepta pana ce P2 este gata sa receptioneze nregistrarea produsa. Procesele
evolueaza independent unul de cela- lalt, P1 introducand n tampon nregistrarea
produsa, de unde P2 o va extrage la nevoie.
Se impun urmatoarele restrictii:
Procesul P1 ncearca sa introduca o nregistrare n tampon si constata ca acesta
s-a umplut. In acest caz, el va trebui sa astepte pana ce se iveste un loc n
tampon (ceea ce se va ntampla ca urmare a extrageri unei nregistrari de catre
P2 ).
Procesul P2 ncearca sa extraga o nregistrare si constata ca tamponul este gol.
In acest caz el va trebui sa astepte pana ce apare o nregistrare ca urmare a
introduceri unei nregistrari n tampon de catre P1 .
Din aceste exemple se deduce ca ntre procese exista interactiuni de forma:
comunic
ari: transmitere de informatii ntre procese;
sincroniz
ari: restrictii asupra evolutiei n timp a unui proces.
Problemele de sincronizare sunt:
1. Excluderea reciproc
a ( mutual
a ) : Forma de sincronizare prin care se evita
utilizarea simultana de catre mai multe procese a unei resurse critice. O resursa
este critica daca, la un moment dat, poate fi utilizata doar ntr-un proces.
Variabila v din Exemplul 1 este o resursa critica. Procesele P1 si P2 nu pot accesa
simultan aceasta variabila, altfel spus, cele doua procese trebuie sa se sincronizeze
prin excludere reciproca.
185
2. Sincronizarea pe conditie : Forma de sincronizare prin care se amana executarea sau continuarea executarii unui proces pana cand o anumita conditie devine
adevarata.
Procesele P1 si P2 ale Exemplului 2 trebuie sa se sincronizeze n cazul n care tamponul este plin, respectiv gol.
Un caz particular al sincronizarii pe conditie este sincronizarea barier
a. Mai multe
procese executa aceasi prelucrare, ntre care exista un marcaj - care reprezinta bariera.
Un proces ce ajunge la marcaj se blocheaza pana n momentul n care toate procesele
ating marcajul, dupa care se deblocheaza si si continua executia.
Sistemul de programare paralela / concurenta reprezinta o interfata (software si/sau
hardware) ntre program si sistemul de calcul, el furnizand printre altele, primitive pentru comunicare ntre procese si pentru sincronizarea lor. Primitivele de sincronizare sunt
operatiile pe care sistemul de programare paralela / concurenta le pune la dispozitia programatorului n vederea rezolvarii problemelor de sincronizare. Practic, aceste primitive
se prezinta programatorului sub forma unor instructiuni oarecare, pe care programatorul
le poate folosi fara a cunoaste modul lor de implementare.
Rezultatele unui program executat de un sistem de calcul n care exista procese paralele
trebuie sa fie independent de vitezele relative de executie ale proceselor si de ordinea n
care acestea sunt executate, atunci cand nu sunt supuse unor restrictii de precedenta.
Modelul de aplicatie utilizat n cele mai multe cazuri este cel de dispecer - lucrator
(master - slave). O componenta a aplicatiei - dispecerul - coordoneaza si distribuie o
serie de activitati de calcul lucratorilor. Dupa efectuarea calculelor, lucratorii transmit
rezultatele dispecerului, care le utilizeaza pentru finalizarea rezolvarii problemei.
Acest model de aplicatie este opusul modelului client - server, n care clientii solicita
serverului efectuarea unor prelucrari. De data asta, aplicatia server este cel care efectueaza
operatiile de prelucrare.
S-au pus n evidenta o serie de modele (tipuri) de programe / aplicatii specifice calculului paralel:
Program SPMD (Single Program, Multiple Data) un program actioneaza simultan,
prin acelasi cod, asupra datelor n procese distincte.
Modelul nodal o instanta a aceluiasi program este executat de fiecare proces.
In vederea executarii unei aplicatii paralel - distribuita ntr-o retea de statii de lucru
trebuie efectuate operatiile:
definirea retelei de statii de lucru prin instalarea si lansarea n executie a suportului
soft utilizat;
desfasurarea aplicatiei (deployment), adica instalarea aplicatiei mpre- una cu resurselor
necesare pe fiecare calculator al retelei;
lansarea n executie a aplicatiei - a lucratorilor si a dispecerului.
186
11.3
n
X
ai
i=1
n tn secunde.
Pentru calculul lui Sn sunt necesare n 1 adunari, astfel indicele de performanta este
n1
.
tn
In analiza indicelui de performanta, prezinta interes determinarea valorii lui nc de la
care tn 1 si n plus tn variaza proportional cu n.
In Java masurarea timpului face apel la metoda clasei System
static long currentTimeMillis()
11.3. EFICIENT
A PROGRAMELOR PARALELE
187
Sp
p
188
S-au formulat diverse evaluari ale vitezei algoritmice care neaga (Amdahl G.M., 1967)
si respectiv valideaza (Gustafson J.L., 1988) oportunitatea construirii calculatoarelor paralele cu numar mare de procesoare.
Urmand prezentarea lui Shi Y. (Reevaluating Amdahls Law and Gustafsons Law,
http://cgvr.cs.uni-bremen.de/teaching/mpar_literatur/), fie
tS durata executiei partii secventiale (executata de un singur procesor);
tP (p) durata executarii partii paralele utilizand p procesoare.
Durata executarii programului cu un sigur procesor este T1 = tS + tP (1), iar cu p procesoare, durata este Tp = tS + tP (p).
Raportat la durata totala de executie a programului cu un singur procesor, fractiunea
partii secventiale este
tS
,
A =
tS + tP (1)
si raportat la durata totala de executie a programului cu p procesoare, fractiunea partii
secventiale este
tS
G =
.
tS + tP (p)
In functie de cele doua exprimari, fractiunea partii paralele este
tP (1)
tS + tP (1)
1 A =
Apreciind ca tP (p) =
tP (1)
,
p
si respectiv 1 G =
tP (p)
.
tS + tP (p)
1
A +
1A
p
1
A
1
,
A
este marginita relativ la numarul de procesoare. Drept consecinta, scopul paralelizarii este
rezolvarea unor probleme de dimensiune din ce n ce mai mari si nu rezolvarea ntr-un
timp cat mai scurt a unei probleme de dimensiune fixata.
Pe de alta parte, deoarece orice program paralel are o parte secventiala, potrivit legii
lui Gustafson, viteza algoritmica este functie crescatoare relativ la p si Sp < p, adica
programul paralel are viteza algoritmica subliniara, neputandu-se obtine programe cu
viteza algoritmica liniara (Sp = p) si supraliniara (Sp > p).
Stabilirea acestor rezultate presupune faptul ca atat n varianta secventiala (p = 1)
cat si n varianta paralela (p > 1), programul executa aceleasi operatii.
189
IN JAVA
11.4. PROGRAMARE PARALELA
11.4
Programare paralel
a n Java
Limbajul de programare Java permite executia simultana a mai multor activitati prin
intermediul firelor de executie (thread).
Spre deosebire de un proces, un fir de executie nu presupune executia sa de catre un
procesor dedicat si toate firele de executie mpart acelasi spatiu de adrese. Fiecare fir de
executie are o stiva proprie pentru gestionarea metodelor apelate si a variabilelor locale.
Avand acelasi spatiu de adrese, firele de executie comunica prin variabile comune.
Utilizarea firelor de executie nu conduce la reducerea timpului de executie - mai ales
daca exista o singura unitate centrala. Intr-un program Java, rolul utilizarii firelor de
executie este separarea preocuparilor, adica simplificarea programarii. Este mai usor de
scris o secventa de cod pentru fiecare activitate a algoritmului, executarea lor trecand n
sarcina Masinii Virtuale Java si a sistemului de operare care simuleaza executia simultan
a.
Singura problema care ramane n sarcina programatorului este rezolvarea problemelor
de sincronizare ntre firele de executie.
Chiar n cazul unui calculator cu un procesor avand mai multe nuclee de calcul (multicore) gestionarea acestor nuclee nu cade n sarcina programatorului si nu exista nici o
certitudine ca executia este paralela.
Astfel utilizarea firelor de executie conduce doar la executie concurenta.
Pe un calculator obisnuit executie paralela se va obtine prin utilizarea procesorului
grafic. Daca metoda de calcul este iterativa atunci programarea va fi mai simpla prin
utilizarea unui algoritm paralel si iterativ asincron.
11.5
Scopul acestei sectiuni este prezentarea unor metode numerice care se pot paraleliza
prin descompunerea domeniului de calcul.
Rezolvarea unei probleme consta din executarea a N sarcini de calcul identice. Multimea
acestor sarcini, {0, 1, . . . , N 1}, reprezinta domeniul de calcul. Pentru efectuarea calculelor se vor utiliza p procese.
Fiecare proces i {0, 1, . . . , p 1} va efectua cel mult d Np e sarcini, unde
N
p
=
daca
N
p
N,
h i
N + 1 daca
p
N
p
/ N,
N
p
190
Calc(i)
pentru s = 0 : d Np e 1 executa
|
j sp+i
|
daca j N 1 atunci
|
|
executa sarcina j
|
stop
n bloc: sarcina j va fi executata de procesul j div d Np e, sau procesul i executa
sarcinile d Np e i + s, s = 0, 1, . . . , d Np e 1.
Pseudocodul procesului i este:
Calc(i)
pentru s = 0 : d Np e 1 executa
|
j d Np e i + s
|
daca j N 1 atunci
|
|
executa sarcina j
|
stop
Exemplul 11.5.1
Pentru N = 10 si p = 4 distribuirea sarcinilor este
sarcina 0 1 2 3 4 5 6 7
Cazul ciclic
procesul 0 1 2 3 0 1 2 3
8 9
0 1
sarcina 0 1 2 3 4 5 6 7 8 9
procesul 0 0 0 1 1 1 2 2 2 3
Un algoritm caruia i se poate aplica paralelizarea prin descompunerea domeniului de
calcul se numeste trivial paralel.
Metodele numerice de care ne ocupam constau n generarea unui sir de aproximatii pe
baza unei formule de recurenta
Cazul n blocuri
x(k+1) = F (x(k) ),
(k)
kN
iar x(k) = (xi )1iN . Paralelizarea se refera doar la calculul unei aproximatii pe baza
formulei de recurenta: cele N componente se calculeaza n N procese.
Global un algoritm va genera un sir finit de aproximatii potrivit unei reguli de oprire,
iar schema de trecere la o noua iteratie se poate face sincron sau asincron. In modul
sincron are loc o sincronizare bariera la sfarsitul calculului unei componente iar n modul
asincron aceasta sincronizare nu mai are loc.
191
n
X
1
ai,j ukj
i {1, . . . , n},
(11.1)
uk+1
=
bi
i
ai,i
j=1
j6=i
sau este simetrica si pozitiv definita, atunci convergenta procedeului (11.1) este asigurata.
Determinarea simultan
a a r
ad
acinilor unui polinom
Fie polinomul P C[X], P (z) = z n + a1 z n1 + . . . + an1 z + an . Notam prin
= (1 , 2 , . . . , n )T vectorul format de radacinile polinomului P, pe care le consideram
distincte doua cate doua, deci simple.
O clasa de metode pentru determinarea simultana a radacinilor polinomului P este
data de formula de recurenta
z (k+1) = T (z (k) ),
kN
P (zi )
,
j=1,n (zi zj )
i {1, . . . , n}.
j6=i
(k+1)
zi
(k)
zi
Qn
P (zi )
j=1
j6=i
(k)
(zi
(k)
zj )
i {1, . . . , n},
k N.
Daca aproximatia initiala z (0) este aleasa ntr-o vecinatate convenabila a lui atunci sirul
de aproximatii (z (k) )kN converge catre .
192
Capitolul 12
Algoritm paralel si iterativ
Punem n evidenta doua clase de algoritmi paraleli si iterativi. Prezentare se refera la
calculul unui punct fix al unei functii.
Fie T : D Rn Rn o functie care admite un punct fix x D, T (x ) = x .
Calculul punctului fix va utiliza metoda aproximatiilor succesive
xk+1 = T (xk ),
(12.1)
pornind de la un element x0 D.
Fie r = kx0 x k. Daca
1.
2.
B(x , r) D;
kT (x) T (x )k kx x k,
x D,
atunci xk D, k N.
Varianta paralela va utiliza L n procese (fire de executie). Procesul i {1, . . . , L}
actioneaza asupra variabilelor (xj1 , . . . , xjni ) = xi si calculeaza termenii (Tk1 , . . . , Tkni ) =
Ti .
Notam Ji = {j1 , . . . , jni }, Ki = {k1 , . . . , kni }. Presupunem
ni=1 Ji = ni=1 Ki = {1, . . . , n},
si
i 6= j
Ji Jj =
.
Ki K j =
194
12.1
Fiecare proces i poate contoriza ntr-un contor ki iteratiile pe care le executa. Odata
calculata componenta xki i +1 ea este trimisa celorlalte procese. Pentru calculul acestei
componente procesul i utilizeaza pentru xj , j 6= i valori care pot sa nu coincida cu
ultimele valori calculate, respectiv de procesele j 6= i.
Notam cu sij (ki ) indicele lui xj furnizat de procesul j procesului i, valoare utilizata
pentru calculul lui xki i +1 ,
si (ki )
xki i +1 = Ti (x11
si
i1
, . . . , xi1
(ki )
si
i+1
, xki i , xi+1
(ki )
si (ki )
, . . . , xLL
).
si (ki )
xj j
Semnificatia acestei restrictii este aceea ca n lipsa regulii de oprire, toate procesele conlucreaza, adica trimit si receptioneaza valori, niciun proces nu este lasat deoparte.
195
Algorithm 2 Procesul i
1: procedure Proces(i, x0 )
2:
ki 0
3:
do
si (ki )
4:
receive xj j , j 6= i
5:
Compute xki i +1
6:
send xki i +1
7:
ki ki + 1
8:
while convergence()
9: end procedure
Q
Q
Consideram T : D Rn = Lj=1 Rnj Lj=1 Rnj , si notam norma din Rnj prin k kj
iar norma din Rn va fi kxk = max1jL kxj kj .
Presupunem ca exista [0, 1) astfel ncat
kT (x) T (x )k kx x k,
x D.
(12.3)
xi l+1 se obtine dupa ce toate componenetele necesare calculului au fost rennoite. Semnificatia
inegalitatii sij (ki ) > mil consta n aceea ca procesul i a receptionat cel putin o valoare noua
i
pentru xj , dupa aceea utilizata pentru calcului lui xml .
i
si (k )
si
(ki )
mi
si
i1
i+1
Notam xml+1 = (x11 i , . . . , xi1
, xi l+1 , xi+1
Are loc urmatorul rezultat de convergenta:
(ki )
si (ki ) T
, . . . , xLL
) cu ki = mil+1 1.
= kT (x0 ) T (x )k kx0 x k,
i
196
mil+1
xi ki =
Apoi kxi
si (ki )
= kTi ((x11
si (ki )
kT ((x11
(ki )
si
(ki )
i1
, . . . , xi1
si (ki )
k(x11
si
i1
, . . . , xi1
si
i1
, . . . , xi1
si
(ki )
si
(ki )
i+1
, xki i , xi+1
i+1
, xki i , xi+1
(ki )
si
i+1
, xki i , xi+1
si (ki ) T
) ) Ti (x )ki
, . . . , xLL
si (ki ) T
, . . . , xLL
(ki )
) ) T (x )k
si (ki ) T
, . . . , xLL
) x k
l+1 kx0 x k.
Astfel
i
mil+1
kxml+1 x k = max{kxi
si (ki )
xi ki , max kxj j
j6=i
xj kj } l+1 kx0 x k.
Capitolul 13
OpenCL prin Aparapi
Procesoarele grafice (Graphical Processing Unit - GPU ), unitatile de procesare (multicore Central Processing Unit) sunt utilizate n calculul paralel.
In acest sens au fost dezvoltate instrumente de programare:
CUDA - Compute Unified Device Arhitecture este o platforma si model de programare pentru procesoarele grafice Nvidia. CUDA este dezvoltat de Nvidia.
OpenCL - Open Computing Language este un standard de programare mentinut de
organizatia non-profit Khronos Group si vizeaza utilizarea unitatilor de procesare
(CPU) si a procesoarelor grafice (GPU). Dezvoltat initial de Apple n prezent este
adoptat de AMD, Intel, Nvidia, ARM Holdings.
Modelul de programare paralela este SIMD.
Fiecare instrument este reprezentat de biblioteci de functii iar limbajul de dezvoltare
este C.
Intel dezvolta arhitectura Many-Integrated-Core (MIC), destinat de asemenea calculului paralel.
13.1
Aparapi
Aparapi -(A PARallel API )1 este un cadru de lucru care permite programarea n Java
pentru platforma OpenCL - https://github.com/aparapi/aparapi/releases. Ideea
cadrului de lucru este convertirea codului Java n cod OpenCL n timpul executiei.
In functie de resursele existente pe calculatorul de lucru executia aplicatiei se va face
utilizand GPU sau ntr-un bazin de fire de executie JTP Java Thread Pool.
Pe un calculator cu placa grafica AMD este posibil ca pentru utilizarea GPU sa fie
necesara instalarea produsului AMD-APP-SDK-*.
Aparapi se distribuie sub forma unei arhive care trebuie dezarhivata. Arhiva contine
fisiere dll prin care se interactioneaza cu platforma OpenCL.
Compilarea unui program
1
197
198
set APARAPI_DIR=. . .
javac -g -cp %APARAPI_DIR%\aparapi.jar *.java
Modul de procesare este redat n Fig. 13.1 (imagine preluata din QuickReference.pdf ).
13.2
Programare n aparapi
199
kernel.dispose();
. . .
}
}
Actiunea din metoda run a obiectului Kernel contine prelucrarea executata de o unitate
de procesare sau fir de executie, functie de modul de lucru.
Datele cu care se fac calcule trebuie sa fie de tip int sau float iar tablourile unidimensionale. Transformarea unei matrice mat Mr,c (T ) ntr-un vector v T rc prin
juxtapunerea liniilor se face prin formula
vic+j = mati,j ,
unde T {int,float}.
Clasa com.amd.aparapi.Kernel
Constructori
Kernel()
Metode
public abstract void run()
public Kernel.EXECUTION MODE getExecutionMode()
Evidentiaza modul lucru care poate fi GPU, JTP, CPU.
public Kernel execute(Range range)
public Kernel execute(Range range, int n)
range indica structura unitatilor de procesare, iar n indica numarul de cate ori se
executa mtoda run dintr-o unitate de procesare.
Clasa Kernel contine o familie de functii matematica de argument si valoare de tip
float, dar care nu pot fi utilizate decat n instantierea clasei. Functiile nlocuiesc pe cele
din clasa java.lang.Math care nu pot fi folosite.
Clasa com.amd.aparapi.Range
Specifica modul de organizare / gestiune a unitatilor de procesare. Metode
public static Range create(int globalWidth)
public static Range create2D(int globalWidth, int globalHeight)
public static Range create3D(int globalWidth, int globalHeight,
int globalDepth,)
200
13.3
Exemple
Produsul a dou
a matrice
Date fiind A Mm,n (Z), B Mn,p (Z) se calculeaza C = AB. Componentele matricei
C se calculeaza n paralel, fiecare componenta este calculata de o unitate de procesare
GPU,
n1
X
Ci,j =
Ai,k Bk,j , (i, j) {0, . . . , m 1} {0, . . . , p 1}.
k=0
13
14
15
16
17
18
19
20
21
22
long i n c e p u t=System . c u r r e n t T i m e M i l l i s ( ) ;
k e r n e l . e x e c u t e ( Range . c r e a t e 2 D (m, p ) ) ;
long s f a r s i t =System . c u r r e n t T i m e M i l l i s ( ) ;
24
25
26
28
29
30
32
33
34
35
36
37
38
40
41
42
43
44
45
46
47
Transformarea u n e i m a t r i c e i n v e c t o r
prin juxtapunerea l i n i i l o r
/
private s t a t i c i n t [ ] i M a t 2 v e c t ( i n t [ ] [ ] mat ) {
i n t rows=mat . l e n g t h ;
i n t c o l s=mat [ 0 ] . l e n g t h ;
i n t [ ] v=new i n t [ rows c o l s ] ;
13.3. EXEMPLE
48
49
50
51
52
53
54
56
57
74
I n i t i a l i z a r e a primei matrice A
/
private s t a t i c i n t [ ] i n i t A ( i n t m, i n t n ) {
i n t [ ] [ ] mat=new i n t [m ] [ n ] ;
i n t f a c t =1;
f o r ( i n t i =0; i <m; i ++){
f o r ( i n t j =0; j <n ; j ++){
mat [ i ] [ j ]= f a c t ( j +1);
}
f a c t =10;
}
System . out . p r i n t l n ( M a t r i c e a A : ) ;
f o r ( i n t i =0; i <m; i ++){
f o r ( i n t j =0; j <n ; j ++) System . out . p r i n t ( mat [ i ] [ j ]+ ) ;
System . out . p r i n t l n ( ) ;
}
return i M a t 2 v e c t ( mat ) ;
}
76
77
I n i t i a l i z a r e a c e l e i de a doua m a t r i c e B
/
private s t a t i c i n t [ ] i n i t B ( i n t m, i n t n ) {
i n t [ ] [ ] mat=new i n t [m ] [ n ] ;
i n t f a c t =1;
f o r ( i n t i =0; i <m; i ++){
f o r ( i n t j =0; j <n ; j ++){
mat [ i ] [ j ]=( i +1)( j +1);
}
}
System . out . p r i n t l n ( M a t r i c e a B : ) ;
f o r ( i n t i =0; i <m; i ++){
f o r ( i n t j =0; j <n ; j ++) System . out . p r i n t ( mat [ i ] [ j ]+ ) ;
System . out . p r i n t l n ( ) ;
}
return i M a t 2 v e c t ( mat ) ;
}
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
201
In cod initializarea este facuta n mod convenabil pentru verificarea facila a rezultatelor.
Codul fisierului de comenzi al executiei este
1
2
3
4
5
s e t ProgName=ProdMat
d e l %ProgName%. c l a s s
s e t APARAPI DIR=. . .
j a v a c g cp %APARAPI DIR%\a p a r a p i . j a r %ProgName%. j a v a
j a v a Djava . l i b r a r y . path=%APARAPI DIR% cp %APARAPI DIR%\a p a r a p i . j a r ; . %ProgName%
202
m1
X
ba
[f (a) + 2
f (a + ih) + f (b)].
f (x)dx Im (f, a, b) =
2m
i=1
f (x)dx =
a
size1
X Z i+1
i=0
f (x)dx
size1
X
partiali .
i=0
18
Formula t r a p e z e l o r a p l i c a t a f u n c t i e i f c t
i n i n t e r v a l u l [ a , b ] cu p a r a m e t r u l de d i s c r e t i z a r e m
19
20
/
f l o a t t r a p e z e ( f l o a t a , f l o a t b , i n t m) {
f l o a t s =0 ,h=(ba ) /m;
f o r ( i n t i =1; i <m; i ++) s+=f c t ( a+i h ) ;
return 0 . 5 f h ( f c t ( a )+2 s+f c t ( b ) ) ;
}
21
22
23
24
25
26
@Override
public void run ( ) {
int gid = getGlobalId ( ) ;
f l o a t h=( data [ 1 ] data [ 0 ] ) / s i z e ;
f l o a t a=data [ 0 ] + h g i d ;
f l o a t b=a+h ;
p a r t i a l [ g i d ]= t r a p e z e ( a , b , 5 0 0 ) ;
}
28
29
30
31
32
33
34
35
36
};
203
13.3. EXEMPLE
40
k e r n e l . e x e c u t e ( Range . c r e a t e ( s i z e ) ) ;
System . out . p r i n t l n ( E x e c u t i o n mode= + k e r n e l . getExecutionMode ( ) ) ;
kernel . dispose ( ) ;
42
43
Insumarea r e z u l t a t e l o r p a r t i a l e
/
f l o a t i n t e g =0;
f o r ( i n t i = 0 ; i < s i z e ; i ++) {
i n t e g+=p a r t i a l [ i ] ;
}
38
39
44
45
46
47
48
50
51
52
n
X
1
(k)
(bi
ai,j uj ),
=
ai,i
j=1,j6=i
i {1, . . . , n}, k N.
9 1 3 1 3
2 8 0 1 3
2 2
7
1
1
x
=
4 1 1 9 2
1 3 0 2 6
5
15
16
20
1
f l o a t [ ] x=new f l o a t [ n ] ;
f l o a t [ ] y=new f l o a t [ n ] ;
f l o a t [ ] e r r o r s=new f l o a t [ n ] ;
t o l =1e5f , nrm=0.0 f ;
204
19
i n t nmi =50;
21
K e r n e l k e r n e l = new K e r n e l ( ) {
@Override public void run ( ) {
int gid = getGlobalId ( ) ;
f o r ( i n t i =0; i <n ; i ++)x [ i ]=y [ i ] ;
f l o a t s =0;
f o r ( i n t i =0; i <n ; i ++){
i f ( i != g i d ) s+=a [ g i d n+i ] x [ i ] ;
}
y [ g i d ]=( b [ g i d ] s ) / a [ g i d n+g i d ] ;
e r r o r s [ g i d ]=Math . abs ( y [ g i d ]x [ g i d ] ) ;
}
};
22
23
24
25
26
27
28
29
30
31
32
// Aproximatia i n i t i a l a
f o r ( i n t i =0; i <n ; i ++) y [ i ] = 0 . 0 f ;
long i n c e p u t=System . c u r r e n t T i m e M i l l i s ( ) ;
k e r n e l . e x e c u t e ( Range . c r e a t e ( n ) , nmi ) ;
long s f a r s i t =System . c u r r e n t T i m e M i l l i s ( ) ;
System . out . p r i n t l n ( E x e c u t i o n mode= + k e r n e l . getExecutionMode ( ) ) ;
kernel . dispose ( ) ;
System . out . p r i n t l n ( Durata : +( s f a r s i t i n c e p u t ) ) ;
34
35
36
37
38
39
40
41
System . out . p r i n t l n ( S o l u t i a : ) ;
f o r ( i n t i = 0 ; i < n ; i ++) {
System . out . p r i n t f ( %10.4 f \n , y [ i ] ) ;
}
f o r ( i n t i =0; i <n ; i ++)nrm=Math . max( nrm , e r r o r s [ i ] ) ;
i n t i n d =0;
i f ( nrm>=t o l ) i n d =1;
System . out . p r i n t l n ( I n d i c a t o r u l de r a s p u n s : +i n d ) ;
43
44
45
46
47
48
49
50
51
53
/
Transformarea u n e i m a t r i c e i n v e c t o r
prin juxtapunerea l i n i i l o r
54
55
/
private s t a t i c f l o a t [ ] f M a t 2 v e c t ( f l o a t [ ] [ ] mat ) { . . . }
56
57
59
66
I n i t i a l i z a r e a matricei A
/
private s t a t i c f l o a t [ ] i n i t A ( ) {
f l o a t [ ] [ ] mat = { { 9 , 1 , 3 , 1 , 3 } , { 2 , 8 , 0 , 1 , 3 } , { 2 , 2 , 7 , 1 , 1 } , { 4 , 1 , 1 , 9 , 2 } , { 1 , 3 , 0 , 2 , 6 } } ;
i n t n=mat . l e n g t h ;
return f M a t 2 v e c t ( mat ) ;
}
68
69
Initializarea vectorului b
/
private s t a t i c f l o a t [ ] i n i t B ( ) {
f l o a t [ ] mat ={ 5 , 15 ,16 ,20 ,1};
return mat ;
}
60
61
62
63
64
65
70
71
72
73
74
75
args ) {
13.3. EXEMPLE
f i n a l i n t n=b . l e n g t h ;
// A f i s a r e a d a t e l o r s i s t e m u l u i
f o r ( i n t i =0; i <n ; i ++){
f o r ( i n t j =0; j <n ; j ++) System . out . p r i n t ( a [ i n+j ]+ ) ;
System . out . p r i n t l n ( <> +b [ i ] ) ;
}
8
9
10
11
12
13
f i n a l f l o a t [ ] x=new f l o a t [ n ] ;
f i n a l f l o a t [ ] y=new f l o a t [ n ] ;
f i n a l f l o a t [ ] e r r o r s=new f l o a t [ n ] ;
f l o a t t o l =1e5f , nrm=0.0 f ;
i n t nmi =50;
15
16
17
18
19
K e r n e l k e r n e l = new K e r n e l ( ) {
@Override public void run ( ) {
int gid = getGlobalId ( ) ;
f o r ( i n t i =0; i <n ; i ++)x [ i ]=y [ i ] ;
f l o a t s =0;
f o r ( i n t i =0; i <n ; i ++){
i f ( i != g i d ) s+=a [ g i d n+i ] x [ i ] ;
}
y [ g i d ]=( b [ g i d ] s ) / a [ g i d n+g i d ] ;
e r r o r s [ g i d ]=Math . abs ( y [ g i d ]x [ g i d ] ) ;
}
};
21
22
23
24
25
26
27
28
29
30
31
32
// Aproximatia i n i t i a l a
f o r ( i n t i =0; i <n ; i ++) y [ i ] = 0 . 0 f ;
long i n c e p u t=System . c u r r e n t T i m e M i l l i s ( ) ;
34
35
36
i n t i t e r =0;
do{
i t e r ++;
k e r n e l . e x e c u t e ( Range . c r e a t e ( n ) ) ;
nrm=0.0 f ;
f o r ( i n t i =0; i <n ; i ++) nrm=Math . max( nrm , e r r o r s [ i ] ) ;
// System . o u t . p r i n t l n ( I t e r : + i t e r + Norma e r o r i i : +nrm ) ;
}
while ( ( t o l <=nrm)&&( i t e r <nmi ) ) ;
long s f a r s i t =System . c u r r e n t T i m e M i l l i s ( ) ;
System . out . p r i n t l n ( Durata : +( s f a r s i t i n c e p u t ) ) ;
System . out . p r i n t l n ( E x e c u t i o n mode= + k e r n e l . getExecutionMode ( ) ) ;
kernel . dispose ( ) ;
38
39
40
41
42
43
44
45
46
47
48
49
50
System . out . p r i n t l n ( S o l u t i a : ) ;
f o r ( i n t i = 0 ; i < n ; i ++) {
System . out . p r i n t f ( %10.4 f \n , y [ i ] ) ;
}
i n t i n d =0;
i f ( nrm>=t o l ) i n d =1;
System . out . p r i n t l n ( I n d i c a t o r u l de r a s p u n s : +i n d ) ;
52
53
54
55
56
57
58
59
61
/
Transformarea u n e i m a t r i c e i n v e c t o r
prin juxtapunerea l i n i i l o r
62
63
65
/
private s t a t i c f l o a t [ ] f M a t 2 v e c t ( f l o a t [ ] [ ] mat ) { . . . }
67
68
70
I n i t i a l i z a r e a matricei A
/
private s t a t i c f l o a t [ ] i n i t A ( ) { . . . }
72
64
69
Initializarea vectorului b
73
74
205
206
private s t a t i c f l o a t [ ]
75
76
initB (){. . .}
Se constata ca durata de executie a variantei sincrone este putin mai mare decat a
variantei asincrone.
No.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
207
208
No.
27
Produsul informatic
visad
Resursa/versiunea
visad.jar
Bibliografie
[1] ANISIU V., 2006, Calcul simbolic cu Maple. Ed. Presa Universitara Clujeana, ClujNapoca.
[2] BOIAN F.M., BOIAN R. F., 2004, Tehnologii fundamentale Java pentru aplicatii
Web. Ed. Albastra, Cluj-Napoca.
[3] KINCAID D., CHENEY W., 1991, Numerical Analysis. Mathematics of scientific
computing. Brooks/Cole, Pacific Grove, California.
[4] LANDAU H. R., 2005, A First Course in Scientific Computing. Symbolic, Graphic,
and Numeric Modeling Using Maple, Java, Mathematica, and Fortran90. Princeton
Univ. Press, Princeton.
[5] MARUS
TER St., 1981, Metode numerice n rezolvarea ecuatiilor neliniare. Ed.
tehnica, Bucuresti.
[6] PETCU D., 2000, Matematica asistata de calculator. Ed. Eubeea, Timisoara.
[7] PRESS W. H., TEUKOLSKI S. A., VETTERING W. T., FLANNERY B. P., 2007,
Numerical Recipies 3rd Edition: The Art of Scientific Computation. Cambridge
University Press, Cambridge.
[8] RICHARSON L. J., 2003, Visualizing Complex Functions. http://web.archive.
org/web/20030802162645/physics.hallym.ac.kr/education/TIPTOP/VLAB/
QmSct/complex.html.
[9] SCHEIBER E., 2007, Programare concurenta si paralel-distribuita n Java. Ed. Albastra, Cluj-Napoca.
[10] SCHEIBER E., 2010, Java n calculul stiintific. Ed. Universitii Transilvania Brasov.
[11] STANCU D. D., COMAN G., (Ed), 2001, Analiza numerica si teoria aproximarii.
Vol. I, II, III, Ed. Presa Universitara Clujeana, Cluj-Napoca.
[12] TOCCI C., ADAMS S., 1996, Applied Maple for Engineers and Scientist. Artech
House, Boston, London.
[13] ***, http://en.wikipedia.org/wiki/List_of_numerical_analysis_software.
209
210
BIBLIOGRAFIE
[14] ***,
http://en.wikipedia.org/wiki/Comparison_of_numerical_analysis_
software.
Majoritatea produselor utilizate contin documentatie de utilizare, prezentarea tehnica
a interfetelor de programare (API), etc. La acestea se adauga multe alte referinte n
Internet.