Sunteți pe pagina 1din 20

5. Matrice rare Matricele rare i gsesc aplicabilitatea n modelarea unor procese de natur industrial, economic, tehnic, social etc.

Materialul de fa i propune s trateze modalitile de reprezentare n structuri de date a matricelor rare, precum i principalele operaii matriceale implementate ntr-un limbaj orientat pe obiecte. n final este prezentat o aplicaie concret estimarea parametrilor unei regresii statistice. 1. Introducere n rezolvarea multor probleme de natur economic, tehnic, social, a diverselor probleme de optimizare, precum i n modelarea unor procese industriale i tehnologice este necesar s se determine modelul matematic care descrie funcionarea procesului respectiv. Descrierea acestor sisteme fizice conduce la obinerea unor modele matematice care fie n mod direct, prin modelare, fie prin metoda de rezolvare implic sisteme de ecuaii algebrice liniare sau probleme de programare liniar a cror matrice a coeficienilor este rar ( sparse ), n sensul c ponderea elementelor nenule n totalul elementelor matricei este mic. Din punct de vedere practic trebuie remarcat faptul c analiza sistemelor mai sus amintite conduce la obinerea unor modele matematice de mari dimensiuni care implic sisteme de ecuaii algebrice liniare de mii de ecuaii, pentru a cror rezolvare sunt necesare resurse mari de memorie i timp de calcul. n multe cazuri practice, cum ar fi sistemele n timp real, timpul de calcul este o resurs critic, creia nu-I este permis s depeasc o valoare limit. Modelele matematice ale proceselor reale implic un numr foarte mare de variabile i restricii care prezint fenomenul de raritate ( sparsity ), adic de slab interconectare a elementelor sale. Luarea n consideraie a fenomenului de raritate furnizeaz un nou mod de abordare foarte eficient, ce implic n dezvoltarea aplicaiilor informatice folosirea unor structuri de date speciale, care s conduc la reducerea resurselor de memorie i a timpului de calcul. elemente nenule , adic << n . Cantitativ, matricele rare sunt caracterizate de ponderea numrului de elemente nenule n totalul de elemente, pondere ce definete gradul de umplere al matricei. n aplicaiile curente se ntlnesc matrice rare cu grade de umplere ntre 0,15% i 3%.
2

n general, o matrice (n, n) - dimensional este rar dac conine un numr mic de

2. Memorarea matricelor rare. Se consider matricea:

1 0 0 0 0 2 A= 0 0 0 0 1 0
de 20.

0 0 0 0

0 4 0 0

Matricea A este un exemplu de matrice rar, ea coninnd 16 elemente nule din totalul Se definete gradul de umplere (densitatea) unei matrice prin raportul dintre numrul elementelor nenule i numrul total al elementelor sale:

G=
unde:

p 100 (%) nm (1)

p numrul de elemente nenule; n numrul de linii; m numrul de coloane. Se accept, n general, c o matrice este rar dac densitatea sa este de cel mult 3%. Densitatea

% matricei A este G( A) = 20 , ea fiind prezentat aici n scopul ilustrrii conceptului de matrice rar. Structura de date clasic folosit pentru manipularea matricelor obinuite tablou de dimensiune ( n, m ) alocat la compilare se dovedete a fi ineficient n cazul n care ,matricea este rar. Un prim avantaj este legat de folosirea neeconomic a spaiului de memorie prin alocarea de zone mari pentru memorarea elementelor nule, care nu sunt purttoare de informaie. Ocuparea unor zone de memorie cu elemente nule nu se justific deoarece acestea

nu contribuie la formarea rezultatului operaiilor cu matrice (adunare, nmulire, etc) ducnd totodat i la mrirea duratei de realizare a acestor operaii prin ocuparea procesorului cu adunri i nmuliri scalare cu zero. Acest inconvenient se manifest cu att mai pregnant cu ct dimensiunea matricei este mai mare. Prin urmare, pentru probleme de dimensiuni mari, s-a cutat gsirea unor modaliti de reprezentare compact a matricelor rare, n care s se renune la memorarea elementelor nule. n acest caz este necesar ca tehnicile de memorare s ncorporeze e lng elementele nenule i mijloacele de identificare a poziiilor acestor elemente n matrice. Sunt prezentate n continuare cteva posibiliti de memorare compact a MR. Se face de asemeni o analiz a oportunitii folosirii fiecrei tehnici n parte, n funcie de densitatea matricei. Memorarea prin identificare binar se bazeaz pe natura binar a sistemului de calcul, constnd n memorarea numai a elementelor nenule ale matricei ntr-o zon primar ZP avnd tipul de baz corespunztor tipului elementelor matricei i dimensiunea egal cu numrul elementelor nenule. Structura matricei este indicat printr-o secven binar memorat ntr-o zon secundar ZS. Matricea A prezentat anterior se memoreaz astfel: Zona primar Locaie 1 2 3 4 Valoare 1 -2 4 -1 Zona secundar Locaie 1 Valoare 1 0 Locaie 11 Valoare 0 0 5 0 0 0 15 0 0 0 6 0 16 0 10 0 1 1 0 20 1

Matricea A a fost memorat n ordinea liniilor, dar se poate imagina o alt posibilitate de memorare, n ordinea coloanelor. Zona secundar prezentat mai sus poate fi memorat chiar la nivel de bit. Dac matricea B ( m, n ) dimensional are densitatea G i dac tipul de baz al matricei (tipul fiecruia dintre elemente nenule ale matricei) este reprezentat printr-un cuvnt de b octei, atunci zona primar va necesita mnG cuvinte de b octei iar zona secundar mn/8b cuvinte. Numrul total de cuvinte necesare memorrii matricei B prin intermediul celor dou zone este mnG + mn/8b. ntruct pentru memorarea matricei n forma clasic sunt necesare mn cuvinte, raportul dintre cerinele de memorie ale structurii de mai sus i a celei standard este: (2) n relaia (2) s-a considerat c memorarea zonei secundare se face la nivel de bit. Considernd c elementele matricei A sunt reale i se reprezint pe 4 octei, rezult:

c1 = G + 1 / 8b

c1A = 0,2 + 1/ 32= 0,23

adic memorarea matricei A conform acestei structuri ocup de circa 4 ori mai puin memorie dect cea standard. Folosind relaia (2) n care se egaleaz 1 se determin limita superioar a densitii unei matrice pentru care aceast structur necesit mai puin memorie dect cea standard:

c =1

Glim = 1 1 / 8b

(3)

Pentru matricea A:

Glim = 1 1/ 32= 0,96= 96 %

Aceast structur de memorare difer de altele prin aceea c n zona secundar este alocat memorie i pentru elementele nule ale matricei (un singur bit). Structura este mai puin eficient pentru matricele de mari dimensiuni foarte rare. Principala dificultate const n complexitatea programelor de implementare a operaiilor matriciale. O alt modalitate de memorare prin identificare binar se obine prin modificarea informaiilor din zona secundar. Aceast zon va conine pe jumti de cuvnt indicii de coloan ai elementelor nenule din matrice, precum i anumite informaii de control pentru identificarea rapid a poziiei elementelor nenule n matrice. Structura ZS pe cuvinte este urmtoarea: Numrul cuvntului Jumtatea stng Jumtatea dreapt

1 2 3 4 k k+1 k+2 j

Numrul de linii Numrul de coloane Numrul de elemente nenule Numrul de elemente nenule n Numrul de elemente nenule n linia1 linia 2 Numrul de elemente nenule n etc linia 3 Numrul de elemente nenule n ultima linie Indicele de coloan al primului Indicele de coloan al celui de-al element memorat doilea element memorat Indicele de coloan al celui de-al etc. treilea element memorat Indicele de coloan al ultimului element memorat 5 1 3 5 6 2

Pentru matricea A, ZS are urmtoarea structur: Locaie 1 2 3 4 Valoare 4 5 4 1 2 0 1

n reprezentarea de mai sus s-a considerat c elementele nenule sunt reprezentate pe 4 octei astfel c o jumtate de cuvnt n zona secundar se reprezint pe 2 octei. Prin structura de memorare prezentat mai sus se pot memora matrice a cror dimensiune maxim este de 9999 de linii sau coloane cu numrul de elemente nenule memorate de 10 8 1. Se face observaia c n cazul matricelor ptrate n primul cuvnt din ZS se va memora dimensiunea matricei.

) Numrul total de cuvinte necesare zonei secundare va fi (5 + m+ mnG / 2 rotunjit la cel mai mare ntreg. Numrul total de cuvinte necesar memorrii unei matrice prin ) intermediul celor dou zone ZP i ZS este (5 + m+ 3mnG / 2. Raportul dintre cerinele de memorie ale acestei structuri de identificare binar i a celei standard este:
(4) Pentru o matrice ptrat (m = n), egalnd c2 = 1 n (4) i trecnd la limit pentru m rezult valoarea maxim a densitii unei matrice rare pentru care structura prezentat este eficient:

c2 =

3G 5 + m + 2 2mn

Glimm

2 5+ m 1 = 0,666 = 66,6% 3 2m 2 (5)

n relaia (5) se ajunge la acelai rezultat n cazul unei matrice neptratice pentru care se trece la limit pentru n i m . Pentru o matrice rar (100,100) dimensional cu o medie de 66 elemente nenule pe linie, structura de mai sus necesit un total de 6600 + ( 5 + 100 + 6600 )/2 = 9952 cuvinte, cu ceva mai puin (0,6%) de 10.000 cuvinte necesare pentru memorarea standard. ntruct densitatea elementelor nenule ale unei matrice rare este de obicei ntre 1% i 3%. Structura se dovedete a fi deosebit de eficient. Memorarea compact aleatoare const n utilizarea unei zone primare ZP, coninnd numai elementele nenule ale matricei i a dou zone secundare coninnd indicii de linie i de coloan corespunztoare elementelor nenule. Deoarece fiecare element nenul al matricei este identificat individual, este posibil ca matricea s fie memorat n ordine aleatoare. Matricea A se memoreaz astfel: Locaia Valoare Indice linie Indice coloan 1 1 1 1 2 -2 2 3 3 4 2 5 4 -1 4 2

Avantajele memorrii compacte aleatoare constau n faptul c noi elemente nenule ale matricei pot fi adugate la sfritul zonelor de memorare fr a perturba celelalte elemente, precum i o manevrabilitate rapid a datelor. n cazul matricelor simetrice aceast structur de memorare se poate simplifica prin memorarea numai a elementelor nenule de deasupra diagonalei principale, precum i a elementelor nenule situate pe aceast diagonal. Numrul total de cuvinte necesare memorrii unei matrice ( m,n ) dimensionale este n acest caz 3mn. Raportul dintre cerinele de memorie ale acestei structuri i a celei standard este:

c3 = 3G (6)

Egalnd relaia (6) cu unitatea se determin valoarea limit a densitii matricei pentru rare aceast structur este eficient: lim . n structura de mai sus pentru identificarea elementelor nenule ale matricei rare au fost folosite dou zone secundare corespunztoare indicelui de linie i de coloan. Se prezint n continuare o alt posibilitate de memorare n care se va utiliza o singur zon secundar de dimensiune egal cu numrul de elemente nenule ale matricei, coninnd simultan informaii asupra indicilor de linie i de coloan. Astfel, fiecrui element din zona primar i se ataeaz n zona secundar un numr ntreg din care se pot determina indicii de linie i de coloan. Dac elementul ij este memorat n locaia k a zonei primare atunci n zona secundar se va memora numrul

= 333% ,

a 0

i + ( j 1 n, unde n este numrul de coloane a matricei. Acest numr, singur, este suficient )

pentru identificarea elementului n matrice. Utiliznd acest artificiu, matricea A se memoreaz astfel: Locaia Valoare Indice agregat 1 1 1 2 -2 12 3 4 22 4 -1 9

Pentru a regsi indicele de linie i de coloan al oricrui element memorat n locaia k se utilizeaz urmtoarea tehnic de calcul: - coloana j este obinut ca: j este mai mic ntreg Indice agregat (k)/n, - linia i este determinat astfel: i = Indice agregat (k) ( j 1 ) n. Avantajul acestei structuri de memorare const n faptul c necesit mai puin memorie dect cea precedent, fiind n schimb mai puin rapid n ce privete manevrarea datelor. Numrul total de cuvinte necesar memorrii matricei este 2mnG. Raportul dintre cerinele de memorie ale acestei structuri i a celei standard este (7) Valoarea limit a densitii matricei pentru care aceast structur este eficient este: G = 50%. Memorarea compact sistematic presupune c elementele nenule ale unei matrice rare sunt memorate ntr-o anumit ordine (pe linii sau pe coloane). n acest caz nu este necesar s se memoreze n zonele secundare indicii de linie, respectiv de coloan. Pentru o memorare n ordinea liniilor, ne putwem dispersa de indicii de linie, ns se cere specificarea nceputului fiecrei linii. i n acest caz se pot imagina mai multe structuri de memorare. Cea prezentat n continuare este caracterizat prin faptul c utilizeaz o singur zon secundar ZS, care conine indicii de coloan ale elementelor nenule din matricea considerat, precum i elemente false care indic nceputul fiecrei linii i sfritul memorrii ntregii matrice. De exemplu, un element zero n ZS marcheaz prezena unui element fals i acesta specific n ZP numrul liniei elementelor de la dreapta locaiei. Sfritul matricei este marcat prin prezena n ZP a unui element fals cu valoarea zero. Pentru matricea A, memorarea n acest form este urmtoarea: Locaia 1 2 3 4 5 6 7 8 ZP 1 1 2 -2 4 4 -1 0 ZS 0 1 0 3 5 0 2 0

c4 = 2G

) memora o matrice rar ( m, n ) dimensional este 2(mnr+ m+ 1 . Raportul de memorare este:

Pentru aceast structur de memorare numrul maxim de cuvinte necesar pentru a

c5 = 2G + 2( m + 1) / ( mm ) (8)

Se constat c structura este eficient pentru memorarea matricelor rare cu o densitate a elementelor nenule de maximum 50%. Memorarea cu ajutorul listelor reprezint o extensie a memorrii compacte aleatoare. n timpul operaiilor de inversare a matricelor rare noi elemente nenule sunt continuu generate iar altele sunt anulate i deci structurile de memorare trebuie s fie capabile s execute aceste modificri ntr-un mod eficient. De aceea structurile de memorare bazate pe aceast tehnic sunt folosite pentru memorarea i manipularea matricelor rare de mari dimensiuni. Structura propus utilizeaz o zon principal ZP pentru memorarea elementelor nenule i trei zone secundare, astfel: ZSL pentru memorarea indicilor de linie ai elementelor nenule, ZSC pentru indicii de coloan i ZSU pentru memorarea adresei urmtorului element al matricei. Matricea A se memoreaz dup cum urmeaz: Locaia ZP ZSL ZSC ZSU 1 1 1 1 &2 2 -2 2 3 &3 3 4 2 5 &4 4 -1 4 2 NULL

unde prin &2 se nelege adresa celei de-a doua locaii. Raportul dintre cerinele de memorare ale acestei structuri i a celei standard este:

c6 = 4G (9)

Prin urmare aceast structur de memorare este eficient pentru memorarea matricelor cu o densitate a elementelor nenule de maximum 25%.

3. Software orientat spre lucrul cu matrice rare Metodele de calcul cu matrice rar pentru a fi eficiente trebuie s beneficieze de proporia mare de elemente nule din aceste matrice, ceea ce creeaz necesitatea considerrii unor tehnici speciale de memorare, programare i analiz numeric. O cerin esenial n programarea matricelor rare const n memorarea i executarea operaiilor numerice numai cu elementele nenule ale matricei, de a salva memorie i timp de calcul. n acest caz memorarea standard, devenind ineficient, este abandonat i nlocuit cu metode de memorare adecvate, cteva dintre acestea fiind prezentate n paragraful anterior. Un program de calcul cu matrice rare este cu att mai eficient cu ct timpul de calcul i cerinele de memorie necesare sunt mai reduse fa de acelea ale unui program readiional. De aceea tehnica de programare trebuie s realizeze o proporie convenabil ntre timpul de calcul i memoria utilizat, cerine care de cele mai multe ori sunt contradictorii. n general, este recunoscut necesitatea unei anumite de structuri de memorare a datelor i o anumit tehnic de manipulare a acestora n cadrul unui algoritm n care sunt implicate matricele rare. Principiul fundamental de programare cu matrice rare const n memorarea i manipularea numai a elementelor nenule, de sortare i ordonare n structuri speciale n vederea meninerii structurii de matrice rar i a stabilitii numerice, de evitare a buclelor complete. n scopul ilustrrii principalelor operaii efectuate asupra matricelor rare s-a fcut implementarea acestora n limbajul VisualC++. Pentru reprezentarea matricelor s-a ales memorarea compact aleatoare, datorit flexibilitii n manevrarea datelor. Este prezentat n continuare o parte a clasei MR, coninnd constructorii, destructorul, cteva dintre funciile i operatorii implementai i seciunea privat.

classMr { public ...

void One (float); void Zero (float); void Generate(int, float); () float Tras * tip Full(int &); ( long Find ); ( void Change ); ( void Delete ); ( voidInsert ); * void FileWrite (const char ); ( void Write ); void Read(const char *); &I MR (int); & !( MR operator ); + & & MR operator (MR x); & & MR operator (MR x); & * & MR operator (MR x); & * MR operator (float); MR (int, int, int); ( MR ); ~ ( virtual MR ); : private int label; long dim; int n; * int c; * int l; * tip e; };
n cadrul seciunii private, label reprezint o etichet ce servete pentru identificarea matricei, n este dimensiunea matricei, dim servete pentru memorarea numrului de elemente nenule, l i c sunt pointeri la masive de ntregi reprezentnd linia, respectiv coloana elementelor nenule, iar e este pointer la un masiv avnd tipul de baz tip (tipul de baz al elementelor matricei). Softul realizat vizeaz principalele operaii necesare manipulrii matricelor rare: construirea acestora (prin introducerea datelor de la tastatur), vizualizarea lor, scrierea i citirea din fiiere, principalele operaii matriceale: adunarea, scderea, transpunerea, nmulirea i inversarea. Pe parcursul dezvoltrii clasei MR s-a dovedit necesar implementarea unei funcii ( void Zero (float) ) care s elimine dintr-o matrice acele elemente care sunt foarte mici (cu cteva ordine de mrime mai mici dect restul elementelor). Aceste elemente cu valoare nesemnificativ sunt rezultatul erorilor sistematice introduse prin rotunjiri, datorate numrului finit de octei n care se face reprezentarea diverselor tipuri de date n calculator. S-a realizat de asemeni o funcie (Generate(float)) care s construiasc o matrice rar cu elemente aleatoare, avnd impus n schimb valoarea gradului de umplere. n continuare se face o prezentare detaliat a operatorilor care implementeaz principalele operaii matriceale: adunarea, scderea, transpunerea, nmulirea i inversarea.

4. Adunarea, scderea i transpunerea Adunarea matricelor rare presupune parcurgerea ctorva pai: determinarea numrului de elemente nenule ale matricei sum; alocarea memoriei corespunztoare acestui numr; determinarea acelor elemente din prima matrice care nu au corespondent n cea de-a doua i adugarea lor la matricea sum; determinarea elementelor din cea de-a doua matrice care nu au corespondent n prima i adugarea lor la matricea sum; determinarea elementelor comune celor dou matrice, nsumarea lor i adugarea la matricea sum. Prin elemente comune au fost desemnate acele elemente caracterizate prin indicii de linie i de coloan care sunt nenule n ambele matrice. Pentru implementare s-a folosit suprascrierea operatorilor, pentru a conferi o mai mare putere de sugestie operaiilor matriceale implementate. Este prezentat n continuare operatorul care implementeaz operaia de adunare, structurat conform pailor prezentai mai sus. Funcia Found ( ) este definit n afara clasei MR i servete pentru gsirea elementelor comune celor dou matrice. MR & MR :: operator + (MR & x ) { int i, D, k; MR * p; AfxMessage Box ("\nAdunar e : %d + %d" , this- > label, x.label); if (this- > n! = x.n) return * this; D = x.dim; for (i = 0; i < x.dim; i + + ) if (Found ( x.1[i], x.c[i], this- > 1, this > c)) D - -; D + = this- > dim; p = new MR (this ->n, D, tis ->label+x.label); for (i = 0; i <this-> dim; i ++) { p-> 1[i]=this->1[i]; p-> c[i]=this->c[i]; p-> e[i]=this->e[i]; } k=this->dim; for(i=0; i<x.dim; i++) { D=Found(x.1[i], x.c[i],this->dim,thois->1, this->c); if(D) p->e[D-1]+=x.e[i]; else { p->1[k]=x.1[i]; p->c[k]=x.c[i]; p->e[k]=x.e[i]; k++; } } Sortare(p->1,p->c,p->e,p->dim); x.FileWrite(x.txt); this->FileWrite(this.txt); p->FileWrite(p.txt); return *p; {

Implementarea operatorului de scderea este absolut similar celui de adunare, singura diferen fiind accea c n cazul elementelor comune se face scaderea lor, n locul adunrii. Transpunerea matricelor rare este similar celei efectuate pe structr tablou, constnd n inversarea indicilor de linie i coloan ntre ei. n cazul de fa se inverseaz pointeriii la masivele de ntregi reprezentnd liniile, respectiv coloanele elementelor nenule: MR&MR::operator ++() { int*p; AfxessageBox(\nTraspunere. . .); p=this->1;this->1=this->c;this->c=p; return *this; } 5. Implementarea i inversarea matricelor rare Pentru nmulirea matricei rare A, (m, 1) dimensional, cu matricea rar B, (l, n) dimensional, se utilizeaz o modificare a procedurii standard, considernd influena liniilor matricei A asupra matricei produs C, (m,n) dimensional, prin coloanele matricei B. Procedura standard de nmulire se modific astfel nct n bucla intern s se execute toate operaiile corespunztoare unui element al matricei A. ntruct elementul aik al matricei A poate conntribui la formarea tuturor elementelor liniei i a matricei C, se determin mai nti aceast contribuie dup care se continu cu urmtorul element al liniei i a matricei A, pn la determinarea complet a liniei i a matricei C. Acest principiu este utilizat n implementarea operatorului de nmulire a matricelor rare din cadrul clasei MR prezentate n paragraful anterior. Se prezint n continuare acest operator. MR& operator * (MR &x) int i, j, k, D; tip S, R; long T; Mr *p, * q; printf (\nnmulire : &d * *d, this->label, x.label); if (this ->n!=x.n) return *this; // Pas 1 : Cte elemente va avea matricea final? D=0; for(i=0; i<this->dim; i++) for(j=0; j<x.dim; j++) if(this->c[i] ==x.1[j]) D++; // Sunt cel mult D. p=new MR(this->n, D this->label * x. label); // pas 2 : Calcul efectiv. // Se ia fiecare element din A i se nmulete cu tot ce // se poate din B // Elem. p -> e[i] trebuie s fie (i sunt) nule dup iniializare R=0; for (i =0; i<this->dim; i++) for (j=0;j<x.dim; j++) if(this->c[i]==x.1[j] { T=Found(this->1[i], x.c[j],D, p->1, p->c); if(T) if(p->e[T-1]) // deja iniializat p->[T-1]+=this->e[i]*x.e[j] else // se face iniializarea { p->1 [R]=this->1[i]; p->c[R]=x.c[j]; p->e[R]=this->e[i] *x.e[j]; R++; } else

{ p->1[R]=this->1[i]; p->c[R]x.c[j]; p->e[R]=this->e[i] *x.e[j]; R++; } } else if(this->c[i] <x.1[j])) // x e totusi sortat j=x.dim; // Se scot zerourile i se sorteaz D=p->dim; for(i=0; i<p->dim; i++) if (!p->e[i]) D- -; q=new MR(this->n,D, this->label-x.label); for(i=0; i<p->dim; i++) if(p->e[i]) { D- - ; q->1[D]=p->1[i]; q->c[D]=p->c[i]; q->e[D]=p->e[i]; } delete p; Sortare (q->1, q->c, q->e, q->dim; return *q; { Prin analiza acestui operator se constat c matricea rezultat pstreaz structura de matrice rar (zerourile aprute au fost eliminate). Pentru implementarea operatorului de inversare s-a folosit algoritmul lui Krlov. Acesta const n parcurgerea unui numr de pai egal cu dimensiunile matricei:

1 p1 = tr(A 1 ) B1 = I p1 * A 1 1 1: A1 = A 1 p 2 = tr ( A2 ) 2 2: A2 = A*B1 B2 = I p2 * A2
... n-1 An-1 = A*Bn-2

p n 1 = pn =

1 tr(A n 1 ) B n 1 = I p n 1 * A n 1 n 1 Bn = I p n * A n

n: An = A* Bn-1

1 tr(A) n

Prin tr (A) se nelege urma matricei A (suma elementelor diagonale) iar I reprezint matricea unitate de aceeai dimensiune cu matricea A. Krlov a demonstrat c dup parcurgerea celor n pai, Bn este o matrice idenitic nul. de aici rezult inversa matricei A: A-1 = pn * Bn-1 (10) Se prezint n continuare operatorul de inversare a matricelor rare care implementeaz algoritmul prezent. MR & MR::operator ! () { MR A(n, dim, label), *B,E(n,n,1), T(n,dim, label); float P; AfxMessageBox(Inversare); B=new MR(n,dim,label); E=this->I(n);

T<=*this; P=T.Tras(); B=T-E*P; T.FileWrite(A.txt); (*B). FileWrite(B.txt); for(int k=2; k<n;k++) { A=T*(*B); P=((float) 1/ float)K)*A.Tras(); B=A-EP; A.FileWrite (A.txt); (*).FileWrite(B.txt); } A=T*(*B); A.FileWrite(A.txt); P=((float)1/(float)n*Atras(); B=(B*)((float) 1/(float)P; A.FileWrite(A.txt); (*B).FileWrite(B.txt); return *B; } Avantajele acestui algoritm constau n simplitatea implementrii i precizia rezultatelor, datorat folosirii unui numr redus de operaii de mprire. 6. Estimarea parametrilor unei regresii statistice folosind clasa MR Se consider datele din tabelul 1 ce caracterizeaz cinci ntreprinderi din punctul de vedere al productivitii (y), al numrului de utilaje de mare performan deinute (x1) i al veniturilor suplimentare acordate salariailor (x2). Se dorete determinarea unei funcii care s caracterizeze dependena dintre productivitate i celelalte dou variabile considerate independente (numr de utilaje i venituri suplimentare). Tabelul 1 y productivitatea muncii (creteri procentuale) 1 2 5 6 7 x1 utilaje de mare randament (buci) 2 4 4 4 5 x2 venituri suplimentare (mil. lei) 1 1 3 5 5 Pentru a specifica forma funciei, se analizeaz pe cale grafic dependena variabilei efect (y) n raport cu fiecare dintre variabilele cauzale.

y x x1 Figura 1 Dependena y=f(x1), y=f(x2) x x2

ntruct norul de puncte din fiecare reprezentare grafic sugereaz o linie dreapt, specificm modelul astfel: yi = a0 + a1x1i + a2x2i + ui (11) unde ui reprezint o variabil rezidual ce caracterizeaz influena altori factori asupra variabilei efect y, factori care din diverse motive nu pot fi luai n considerare. Dac simbolizm specificm modelul astfel:

y valorile ajustate, rezultate n urma aplicrii modelului liniar, y i = a 0 + a1x 1i + a 2 x 2i (12)

Relaia (12) se scrie pentru fiecare set de valori prezentate n tabelul 1, rezultnd:

y1 1 x11 y 2 1 x12 = y 1 x1 n n
Aadar, iar

x 21 a0 u1 x 2 2 a1 u2 + x 2 n a n un (13)
(14) (15)

Y = XA + U

Y = XA

Determinarea dependenei dintre variabila efect i variabilele cauz nsemn determinarea valorilor numerice ale parametrilor

metoda celor mai mici ptrate. [3] Aceast metod presupune minimizarea expresiei adic, matriceal, U U. Dar (16) unde prin U' s-a notat transpusa matricei U. n [3] se demonstreaz c prin minimizarea relaiei (16) se ajunge la expresia:

a 0 , a1 i a 2 . n acest scop se utilizeaz u 2t


t

U U = ( Y XA ) ( Y XA )
A = ( X X ) X Y
1

(17) O determinare ct mai precis a matricei parametrilor unei regresii presupune existena unui numr foarte mare de date (numr mare de linii n matricea X). n multe cazuri practice valorile acestor date sunt nule, fapt ce justific implementarea relaiei (17) pe o structur de matrice rare. Avnd deja definiii operatorii de transpunere, nmulire i inversare, implementarea relaiei (17) presupune scrierea unei singure linii de cod:

A = (! ( ( + + X ) * X ) ) * ( + + X ) * Y

(18)

Aadar, pentru aflarea matricei A sunt necesare dou operaii de transpunere, trei nmuliri i o inversare. Matricele X i Y asupra crora se opereaz au n multe dintre cazurile practice o densitate foarte mic, astfel c este pe deplin justificat folosirea unor structuri de memorare specifice matricelor rare. 7. Concluzii Asistm n prezent la un fenomen care tinde s ating tot mai multe domenii de activitate: necesitatea de a cunoate ct mai precis anumii factori sau parametri ce caracterizeaz domeniul respectiv, care pn nu de mult erau fie considerai aleatori, fie nu se punea problema determinrii lor, considerat a fi imposibil. Cunoaterea acestor factori ofer o descriere mai detaliat a sistemului n care se lucreaz, permind n acest fel o mai bun activitate de control i comand a acestuia. n cele mai multe dintre cazuri baza de calcul a acestor factori o constituie statistic matematic i teoria probabilitilor, ceea ce conduce la necesitatea rezolvrii unor probleme liniare de foarte mari dimensiuni. Caracterul de raritate al structurilor implicate n rezolvarea problemelor, datorat caracteristicilor reale ale sistemelor, la care se adaug necesitatea unei rezolvri rapide, n concordan cu dinamica crescnd a sistemelor actuale, justific pe deplin introducerea n aplicaiile informatice asociate a unor structuri de date adaptate acestor particulariti. Softul orientat spre lucrul cu matrice rare exploateaz caracterul de raritate al structurilor manipulate, oferind un dublu avantaj: memorie i timp. n ultimii ani memoria nu mai constituie o problem, ns timpul necesar calculelor, odat cu apariia sistemelor n timp real, se dovedete a fi tot mai mult o resurs critic. Referitor la lucrul cu matrice n general, n cadrul unui sistem n care timpul reprezint o resurs critic, se poate imagina un soft care s fac o evaluare anterioar calculelor asupra densitii matricei, i, n funcie de aceasta, s decid asupra structurilor de date ce vor fi folosite pentru memorare i efectuarea calculelor, astfel nct timpul afectat calculelor s fie minim.

Suma si diferena matricelor rare Tendinta de a micsora spatiul ocupat de anumite date in memoria unui calculator a dus la proiectarea si dezvoltarea a multor algoritmi de compresie . O matrice rara este o matrice ce contine mai mult de doua treimi valori nule. O astfel de matrice se poate comprima foarte simplu prin inlocuirea sa in memorie cu trei vectori cu dimensiuni egale cu numarul de elemente nenule din matrice . Pe fiecare pozitie din cei trei vectori se vor gasi rangul liniei, in primul vector, rangul coloanei, in al doilea vector si elementul nenul din matrice in cel de-al treilea vector. Al treilea vector va fi ordonat dupa primul vector si dupa cel de-al doilea vector. Programul contine urmatoarele proceduri : O procedura de alocare si initiere de la tastatura a unei matrice: void incarcare(float **&a,int m,int n) care primeste ca parametri un pointer catre o matrice de numere reale prin referinta pentru a permite modificarea sa si dimensiunile matricei; O procedura care verifica daca o matrice este rara: int ifrar(float **a,int m,int n) care primeste ca parametri un pointer la matrice si dimensiunile matricei si returneaza numarul de elemente nenule din matrice daca aceasta este rara sau 0 daca nu; O procedura care transforma o matrice rara in cei trei vectori despre care am vorbit mai sus: void matrara(float **a,int m,int n,int k,int *&v1,int *&v2,float *&v3) care primeste ca parametri un pointer la matrice, dimensiunile matricei, numarul de elemente nenule din matrice si cate un pointer la fiecare din cei trei vectori care rezulta, primiti prin referinta ; O procedura care dezaloca o matrice alocata dinamic: void distruge(float **&a,int m,int n) care primeste ca parametri un pointer la matrice transmis prin referinta si dimensiunile ei; O procedura care aduna doua matrice rare ce au fost in prealabil comprimate : int adunare(float *vel1,int *vc1,int *vl1,int n1,float *vel2,int *vc2,int *vl2,int n2,float *&velr,int *&vcr,int *&vlr) care primeste ca parametri trei pointeri catre cei trei vectori corespunzatori primei matrice si dimensiunea lor, trei pointeri catre cei trei vectori corespunzatori celei de-a doua matrice si dimensiunea lor si trei pointeri catre trei vectori corespunzatori matricei rezultate si returneaza dimensiunea vectorilor rezultati; O procedura care calculeaza diferenta dintre doua matrice rare comprimate in prealabil: int scadere(float *vel1,int *vc1,int *vl1,int n1,float *vel2,int *vc2,int *vl2,int n2,float *&velr,int *&vcr,int *&vlr) avand aceiasi parametri de intrare si returnand tot dimensiunea vectorilor rezultati. Programul urmeaza urmatorul algoritm: P1-Introducerea de la tastatura a dimensiunilor matricelor( matricele trebuie sa aiba aceleasi dimensiuni pentru a le putea aduna sau scadea) ; P2-Alocarea si initializarea primei matrice prin procedura incarcare; P3-Verificarea primei matrice daca este rara prin procedura ifrar si daca nu este se afiseaza ca nu este rara si se incheie rularea programului, iar daca este se trece la pasul urmator; P4-Compresia primei matrice prin procedura matrar ; P5-Dezalocarea primei matrice prin procedura distruge; P6-Alocarea si initializarea celei de-a doua matrice prin procedura incarcare; P7-Verificarea celei de-a doua matrice daca este rara prin procedura ifrar si daca nu este se afiseaza ca nu este rara si se incheie rularea programului, iar daca este se trece la pasul usmator; P8-Compresia celei de-a doua matrice prin procedura matrar ; P9-Dezalocarea celei de-a doua matrice prin procedura distruge; P10-Suma celor doua matrice prin procedura adunare; P11-Diferenta celor doua matrice prin procedura scadere. Procedura adunare are urmatorii pasi: P1-Alocarea celor trei vectori corespunzatori rezultatului; P2- Parcurgerea vectorilor primei matrice, iar pentru fiecare iteratie se parcurg pasii P3-P5; P3- Parcurgerea vectorilor celei de-a doua matrice pana la egalarea rangului liniei si coloanei elementului curent din prima matrice si copierea lor in vectorii rezultanti;

P4-Daca rangul liniei si coloanei sunt aceleasi la elementele curente din cele doua matrice se aduna elementele si se introduce rezultatul in vectorii rezultanti si se sare la P6, altfel se trece prin pasul P5; P5-daca nu exista in cea de-a doua matrice element nenul pe linia si coloana corespunzatoare elementului curent din prima matrice se copiaza acest element si pozitia sa in matrice in vectorii rezultanti; P6-Dupa ce se termina de parcurs vectorii primei matrice, se verifica daca in cea de-a doua matrice sunt elemente de rang al liniei sau coloanei mai mare decat al ultimului element din vectorii primei matrice si daca exista astfel de elemente se vor memora aceste elemente in continuare in vectorii matricei rezultate; P7-Se returneaza lungimea vectorilor rezultati; Procedura scadere urmeaza pasii: P1-Alocarea si initializarea unui vector auxiliar cu valorile vectorului de elemente corespunzator celei de-a doua matrice, luate cu semn schimbat; P2-Efectuarea diferentei prin adunarea primei matrice cu matricea a doua inmultita cu -1; P3-Returnarea lungimii vectorilor rezultati. #include<iostream.h> //procedura de compresie a unei matrice rare(normalizarea sa) void matrara(float a[10][10],int m,int n,int v1[34],int v2[34],float v3[34]) { int k=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(a[i][j]) { v1[k]=i; //initiere v2[k]=j; //vectorilor v3[k]=a[i][j]; //cu elementele nenule ale matricei k++; } } //procedura dealocare si incarcare de la tastatura a unei matrice void incarcare(float a[10][10],int m,int n) { for(int i=0;i<n;i++) for(int j=0;j<m;j++) { cout<<"Introduceti elementul:"<<i+1<<","<<j+1<<" : "; //introducerea datelor de la tastatura cin>>a[i][j]; } } //procedura de verificare a unei matrice daca este rara int ifrar(float a[10][10],int m,int n) { int k=0; for(int i=0;i<n;i++) //contorizarea for(int j=0;j<m;j++) //elementelor if(!a[i][j]) k++; //nule if(k>m*n*2/3) return m*n-k; //returneaza numarul de elemente nenule else return 0; }

//procedura de adunare a doua matrici rare memorate in vectori int adunare(float *vel1,int *vc1,int *vl1,int n1,float *vel2,int *vc2,int *vl2,int n2,float velr[67],int vcr[67],int vlr[67]) { int l=0,k=0; float a; for(int i=0;i<n1;i++) // parcurgerea vectorilor primei matrice { for(int j=k;(vl1[i]>vl2[j])||((vl1[i]==vl2[j])&&(vc1[i]>vc2[j]));j++,l+ +,k++) //parcurgerea vectorilor { // celei de-a doua matrice //pana la egalarea rangului velr[l]=vel2[j]; //liniei si coloanei elementului vlr[l]=vl2[j]; //primei matrice vcr[l]=vc2[j]; } if((vl1[i]==vl2[j])&&(vc1[i]==vc2[j])) //daca rangul liniei si coloanei sunt { // aceleasi se aduna elementele a=vel1[i]+vel2[j]; if(a) { velr[l]=a; vlr[l]=vl2[j]; vcr[l]=vc2[j]; l++; } k++; } else { velr[l]=vel1[i]; matrice element nenul vlr[l]=vl1[i]; corespunzatoare elementului din vcr[l]=vc1[i]; matrice l++; } } if(k!=n2) de-a doua matrice sunt elemente de for(i=k;i<n2;i++) coloanei mai mare decat al { //ultimului element din vectorii primei matrice velr[l]=vel2[i]; in continuare in vlr[l]=vl2[i]; rezultate vcr[l]=vc2[i]; l++; } return l; //returneaza lungimea vectorilor rezultati } //procedura de scadere a doua matrice rare memorate fiecare in cate trei vectori //daca in cea //rang al liniei sau // vectorii primei //pe linia si coloana //daca nu exista in cea de-a doua

//se vor memora aceste elemente //vectorii matricei

int scadere(float *vel1,int *vc1,int *vl1,int n1,float *vel2,int *vc2,int *vl2,int n2,float velr[67],int vcr[67],int vlr[67]) { float *vaux=new float[n2]; //se foloseste un vector auxiliar in care se introduc //valor ile nenule cu semn schimbat din prima matrice for(int i=0;i<n2;i++) vaux[i]=-vel2[i]; int k=adunare(vel1,vc1,vl1,n1,vaux,vc2,vl2,n2,velr,vcr,vlr);//se face scaderea prin //adunare: a-b=a+(-b) delete [n2]vaux;//se dezaloca vectorul auxiliar return k;//se returneaza dimensiunea vectorilor rezultati } //************************************************************** void main () { float x[10][10],y[10][10],vel1[34],vel2[34],vela[67],vels[67];//se declara pointerii la cele doua matrice initiale //si la vectorii de elemente int n,m,vl1[34],vl2[34],vc1[34],vc2[34],vca[67],vla[67],vcs[67],vls[67];//se declara dimansiunile matricelor //si pointerii la vetorii de ranguri ale liniilor si cocloanelor cout<<"Introduceti numarul de linii(<=10) :"; introduc de la tastatura cin>>n; //numarul de linii si cout<<"Introduceti numarul de coloane(<=10) :"; cin>>m; //se

// de coloane

incarcare(x,m,n);// se aloca si se initializeaza de la tastatura prima matrice int l1=ifrar(x,m,n);//se verifica daca prima matrice este rara if(l1) { matrara(x,m,n,vl1,vc1,vel1);//se transforma prima matrice in trei vectori for(int i=0;i<l1;i++) vectori corespunzatori cout<<"\n"<<vl1[i]<<" "<<vel1[i]; a doua matrice int l2=ifrar(y,m,n);//se verifica daca a doua matrice este rara if(l2) { matrara(y,m,n,vl2,vc2,vel2);//se transforma a doua matrice //in trei vectori //primei matrice incarcare(y,m,n);// se aloca si se initializeaza de la tastatura "<<vc1[i]<<" //se afiseaza cei trei

for(int i=0;i<l2;i++)//se afiseaza cei trei vectori corespunzatori celei cout<<"\n"<<vl2[i]<<" "<<vel2[i];//de-a doua matrice int la=adunare(vel1,vc1,vl1,l1,vel2,vc2,vl2,l2,vela,vca,vla);//se aduna //cele doua matrice rezultand tot trei vectori in care va //fi memorata if(!(la<m*n/3))cout<<"Matricea suma nu este rara ";//se verifica daca //matricea rezultata este rara cout<<"\n"; for( i=0;i<la;i++) //se afiseaza vectorii rezultati cout<<"\n"<<vla[i]<<" "<<vca[i]<<" "<<vela[i]; int ls=scadere(vel1,vc1,vl1,l1,vel2,vc2,vl2,l2,vels,vcs,vls);//se scad //cele doua matrice rezultand tot trei vectori in care va //fi memorata if(!(ls<m*n/3))cout<<"Matricea diferenta nu este rara ";//se verifica daca //matricea rezultata este rara cout<<"\n"; for( i=0;i<ls;i++) //se afiseaza vectorii rezultati cout<<"\n"<<vls[i]<<" "<<vcs[i]<<" "<<vels[i]; } else cout<<"Nu este matrice rara!!!"; } else cout<<"Nu este matrice rara!!!"; } "<<vc2[i]<<"

#include<iostream.h> //procedura de compresie a unei matrice rare(normalizarea sa) void matrara(float **a,int m,int n,int k,int *&v1,int *&v2,float *&v3) { int l=m*n-k; k=0; v1=new int[l];//alocare v2=new int[l];// vectori v3=new float[l];// rezultati for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(a[i][j]) { v1[k]=i; //initiere

v2[k]=j; //vectorilor v3[k]=a[i][j];//cu elementele nenule ale matricei k++; } } //procedura dealocare si incarcare de la tastatura a unei matrice void incarcare(float **&a,int m,int n) { int k=0; a=new float*[n]; //alocarea for(int i=0;i<n;i++) //matricei a[i]=new float[m]; for(i=0;i<n;i++) for(int j=0;j<m;j++) { cout<<"Introduceti elementul:"<<i+1<<","<<j+1<<" : ";//introducerea cin>>a[i][j]; //datelor de la tastatura } } //procedura de verificare a unei matrice daca este rara int ifrar(float **a,int m,int n) { int k=0; for(int i=0;i<n;i++) //contorizarea for(int j=0;j<m;j++) //elementelor if(!a[i][j]) k++; //nule if(k>m*n*2/3) return m*n-k; //returneaza numarul de elemente nenule else return 0; } //procedura de dezalocare a unei matrice void distruge(float **&a,int m,int n) { for(int i=0;i<n;i++) delete [m]a[i]; delete [n]a; } //procedura de adunare a doua matrici rare memorate in vectori int adunare(float *vel1,int *vc1,int *vl1,int n1,float *vel2,int *vc2,int *vl2,int n2,float *&velr,int *&vcr,int *&vlr) { int l=0,k=0; float a; vlr=new int[n1+n2]; vcr=new int[n1+n2]; velr=new float[n1+n2]; for(int i=0;i<n1;i++)// parcurgerea vectorilor primei matrice { for(int j=k;(vl1[i]>vl2[j])||((vl1[i]==vl2[j])&&(vc1[i]>vc2[j]));j++,l+ +,k++)//parcurgerea vectorilor { // celei de-a doua matrice //pana la egalarea rangului

velr[l]=vel2[j]; //liniei si coloanei elementului vlr[l]=vl2[j]; //primei matrice vcr[l]=vc2[j]; } if((vl1[i]==vl2[j])&&(vc1[i]==vc2[j])) liniei si coloanei sunt { // aceleasi se aduna elementele a=vel1[i]+vel2[j]; if(a) { velr[l]=a; vlr[l]=vl2[j]; vcr[l]=vc2[j]; l++; } k++; } else { velr[l]=vel1[i]; matrice element nenul vlr[l]=vl1[i]; corespunzatoare elementului din vcr[l]=vc1[i]; matrice l++; } } if(k!=n2) de-a doua matrice sunt elemente de for(i=k;i<n2;i++) coloanei mai mare decat al { //ultimului element din vectorii primei matrice velr[l]=vel2[i]; in continuare in vlr[l]=vl2[i]; rezultate vcr[l]=vc2[i]; l++; } k=n1+n2-l; /*delete [k](vlr+l); delete [k](vcr+l); delete [k](velr+l);*/ return l; //returneaza lungimea vectorilor rezultati }

//daca rangul

//daca nu exista in cea de-a doua //pe linia si coloana // vectorii primei

//daca in cea //rang al liniei sau

//se vor memora aceste elemente //vectorii matricei

//procedura de scadere a doua matrice rare memorate fiecare in cate trei vectori int scadere(float *vel1,int *vc1,int *vl1,int n1,float *vel2,int *vc2,int *vl2,int n2,float *&velr,int *&vcr,int *&vlr) { float *vaux=new float[n2]; //se foloseste un vector auxiliar in care se introduc //valor ile nenule cu semn schimbat din prima matrice for(int i=0;i<n2;i++) vaux[i]=-vel2[i];

int k=adunare(vel1,vc1,vl1,n1,vaux,vc2,vl2,n2,velr,vcr,vlr);//se face scaderea prin //adunare: a-b=a+(-b) delete [n2]vaux;//se dezaloca vectorul auxiliar return k;//se returneaza dimensiunea vectorilor rezultati } //*************************************************************************** ****************** void main () { float **x,**y,*vel1,*vel2,*vela,*vels;//se declara pointerii la cele doua matrice initiale //si la vectorii de elemente int n,m,*vl1,*vl2,*vc1,*vc2,*vca,*vla,*vcs,*vls;//se declara dimansiunile matricelor //si pointerii la vetorii de ranguri ale liniilor si cocloanelor cout<<"Introduceti numarul de linii:"; la tastatura cin>>n; //numarul de linii si cout<<"Introduceti numarul de coloane:"; cin>>m; // de coloane //se introduc de

incarcare(x,m,n);// se aloca si se initializeaza de la tastatura prima matrice int l1=ifrar(x,m,n);//se verifica daca prima matrice este rara if(l1) { matrara(x,m,n,l1,vl1,vc1,vel1);//se transforma prima matrice in trei vectori distruge(x,m,n); //se dezaloca prima matrice for(int i=0;i<l1;i++) vectori corespunzatori cout<<"\n"<<vl1[i]<<" "<<vel1[i]; a doua matrice int l2=ifrar(y,m,n);//se verifica daca a doua matrice este rara if(l2) { matrara(y,m,n,l2,vl2,vc2,vel2);//se transforma a doua matrice //in trei vectori distruge(y,m,n);//se dezaloca a doua matrice for(int i=0;i<l2;i++)//se afiseaza cei trei vectori corespunzatori celei cout<<"\n"<<vl2[i]<<" "<<vel2[i];//de-a doua matrice "<<vc2[i]<<" //primei matrice incarcare(y,m,n);// se aloca si se initializeaza de la tastatura "<<vc1[i]<<" //se afiseaza cei trei

int la=adunare(vel1,vc1,vl1,l1,vel2,vc2,vl2,l2,vela,vca,vla);//se aduna //cele doua matrice rezultand tot trei vectori in care va //fi memorata if(!(la<m*n/3))cout<<"Matricea suma nu este rara ";//se verifica daca //matricea rezultata este rara cout<<"\n"; for( i=0;i<la;i++) //se afiseaza vectorii rezultati cout<<"\n"<<vla[i]<<" "<<vca[i]<<" "<<vela[i]; int ls=scadere(vel1,vc1,vl1,l1,vel2,vc2,vl2,l2,vels,vcs,vls);//se scad //cele doua matrice rezultand tot trei vectori in care va //fi memorata if(!(ls<m*n/3))cout<<"Matricea diferenta nu este rara ";//se verifica daca //matricea rezultata este rara cout<<"\n"; for( i=0;i<ls;i++) //se afiseaza vectorii rezultati cout<<"\n"<<vls[i]<<" "<<vcs[i]<<" "<<vels[i]; } else cout<<"Nu este matrice rara!!!"; } else cout<<"Nu este matrice rara!!!"; }