P. 1
04. Matrice Rare

04. Matrice Rare

|Views: 392|Likes:
Published by tazzzuu

More info:

Published by: tazzzuu on May 29, 2012
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as DOC, PDF, TXT or read online from Scribd
See more
See less

04/22/2015

pdf

text

original

5.

Matrice rare Matricele rare îşi găsesc aplicabilitatea în modelarea unor procese de natură industrială, economică, tehnică, socială etc. Materialul de faţă îşi propune să trateze modalităţile de reprezentare în structuri de date a matricelor rare, precum şi principalele operaţii matriceale implementate într-un limbaj orientat pe obiecte. În final este prezentată o aplicaţie 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 funcţionarea procesului respectiv. Descrierea acestor sisteme fizice conduce la obţinerea unor modele matematice care fie în mod direct, prin modelare, fie prin metoda de rezolvare implică sisteme de ecuaţii algebrice liniare sau probleme de programare liniară a căror matrice a coeficienţilor 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 obţinerea unor modele matematice de mari dimensiuni care implică sisteme de ecuaţii algebrice liniare de mii de ecuaţii, pentru a căror 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ă, căreia nu-I este permis să depăşească o valoare limită. Modelele matematice ale proceselor reale implică un număr foarte mare de variabile şi restricţii care prezintă fenomenul de raritate ( sparsity ), adică de slabă interconectare a elementelor sale. Luarea în consideraţie a fenomenului de raritate furnizează un nou mod de abordare foarte eficient, ce implică în dezvoltarea aplicaţiilor 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 numărului de elemente nenule în totalul de elemente, pondere ce defineşte gradul de umplere al matricei. În aplicaţiile curente se întâlnesc matrice rare cu grade de umplere între 0,15% şi 3%.
2

În general, o matrice (n, n) - dimensională este rară dacă conţine un număr 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 conţinând 16 elemente nule din totalul Se defineşte gradul de umplere (densitatea) unei matrice prin raportul dintre numărul elementelor nenule şi numărul total al elementelor sale:

G=
unde:

p × 100 (%) n×m (1)

p – numărul de elemente nenule; n – numărul de linii; m – numărul 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 ilustrării conceptului de matrice rară. Structura de date “clasică” folosită pentru manipularea matricelor obişnuite – tablou de dimensiune ( n, m ) alocat la compilare – se dovedeşte a fi ineficientă în cazul în care ,matricea este rară. Un prim avantaj este legat de folosirea neeconomică a spaţiului de memorie prin alocarea de zone mari pentru memorarea elementelor nule, care nu sunt purtătoare de informaţie. Ocuparea unor zone de memorie cu elemente nule nu se justifică deoarece acestea

nu contribuie la formarea rezultatului operaţiilor cu matrice (adunare, înmulţire, etc) ducând totodată şi la mărirea duratei de realizare a acestor operaţii prin ocuparea procesorului cu adunări şi înmulţiri scalare cu zero. Acest inconvenient se manifestă cu atât mai pregnant cu cât dimensiunea matricei este mai mare. Prin urmare, pentru probleme de dimensiuni mari, s-a căutat găsirea unor modalităţi de reprezentare compactă a matricelor rare, în care să se renunţe la memorarea elementelor nule. În acest caz este necesar ca tehnicile de memorare să încorporeze îe lângă elementele nenule şi mijloacele de identificare a poziţiilor acestor elemente în matrice. Sunt prezentate în continuare câteva posibilităţi de memorare compactă a MR. Se face de asemeni o analiză a oportunităţii folosirii fiecărei tehnici în parte, în funcţie de densitatea matricei. Memorarea prin identificare binară se bazează pe natura binară a sistemului de calcul, constând în memorarea numai a elementelor nenule ale matricei într-o zonă primară ZP având tipul de bază corespunzător tipului elementelor matricei şi dimensiunea egală cu numărul 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ă Locaţie 1 2 3 4 Valoare 1 -2 4 -1 Zona secundară Locaţie 1 Valoare 1 0 Locaţie 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 fiecăruia dintre elemente nenule ale matricei) este reprezentat printr-un cuvânt de b octeţi, atunci zona primară va necesita mnG cuvinte de b octeţi iar zona secundară mn/8b cuvinte. Numărul total de cuvinte necesare memorării matricei B prin intermediul celor două zone este mnG + mn/8b. Întrucât pentru memorarea matricei în forma clasică sunt necesare mn cuvinte, raportul dintre cerinţele de memorie ale structurii de mai sus şi a celei standard este: (2) În relaţia (2) s-a considerat că memorarea zonei secundare se face la nivel de bit. Considerând că elementele matricei A sunt reale şi se reprezintă pe 4 octeţi, 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 puţină memorie decât cea standard. Folosind relaţia (2) în care se egalează 1 se determină limita superioară a densităţii unei matrice pentru care această structură necesită mai puţină memorie decât 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 puţin eficientă pentru matricele de mari dimensiuni foarte rare. Principala dificultate constă în complexitatea programelor de implementare a operaţiilor matriciale. O altă modalitate de memorare prin identificare binară se obţine prin modificarea informaţiilor din zona secundară. Această zonă va conţine pe jumătăţi de cuvânt indicii de coloană ai elementelor nenule din matrice, precum şi anumite informaţii de control pentru identificarea rapidă a poziţiei elementelor nenule în matrice. Structura ZS pe cuvinte este următoarea: Numărul cuvântului Jumătatea stângă Jumătatea dreaptă

1 2 3 4 … k k+1 k+2 … j Numărul de linii Numărul de coloane Numărul de elemente nenule Numărul de elemente nenule în Numărul de elemente nenule în linia1 linia 2 Numărul de elemente nenule în etc linia 3 … … Numărul 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. Memorarea compactă aleatoare constă în utilizarea unei zone primare ZP. conţinând numai elementele nenule ale matricei şi a două zone secundare conţinând indicii de linie şi de coloană corespunzătoare elementelor nenule. Structura se dovedeşte a fi deosebit de eficientă. ZS are următoarea structură: Locaţie 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 octeţi astfel că o jumătate de cuvânt în zona secundară se reprezintă pe 2 octeţi.6% 3 2m 2  (5) În relaţia (5) se ajunge la acelaşi rezultat în cazul unei matrice nepătratice pentru care se trece la limită pentru n → ∞ şi m→ ∞ . este posibil ca matricea să fie memorată în ordine aleatoare. treilea element memorat … … Indicele de coloană al ultimului element memorat 5 1 3 5 6 2 Pentru matricea A. Numărul total de cuvinte necesar memorării unei matrice prin ) intermediul celor două zone ZP şi ZS este (5 + m+ 3mnG / 2.666 = 66. Matricea A se memorează astfel: Locaţia Valoare Indice linie Indice coloană 1 1 1 1 2 -2 2 3 3 4 2 5 4 -1 4 2 . Deoarece fiecare element nenul al matricei este identificat individual.100) – dimensională cu o medie de 66 elemente nenule pe linie. ) Numărul total de cuvinte necesare zonei secundare va fi (5 + m+ mnG / 2 rotunjit la cel mai mare întreg.6%) de 10.000 cuvinte necesare pentru memorarea standard. Raportul dintre cerinţele de memorie ale acestei structuri de identificare binară şi a celei standard este: (4) Pentru o matrice pătrată (m = n). Întrucât densitatea elementelor nenule ale unei matrice rare este de obicei între 1% şi 3%. cu ceva mai puţin (0. Pentru o matrice rară (100. egalând c2 = 1 în (4) şi trecând la limită pentru m→ ∞ rezultă valoarea maximă a densităţii unei matrice rare pentru care structura prezentată este eficientă: c2 = 3G 5 + m + 2 2mn Glimm →∞ 2 5+ m 1 −  = 0. Se face observaţia că în cazul matricelor pătrate în primul cuvânt din ZS se va memora dimensiunea matricei. structura de mai sus necesită un total de 6600 + ( 5 + 100 + 6600 )/2 = 9952 cuvinte. Prin structura de memorare prezentată mai sus se pot memora matrice a căror dimensiune maximă este de 9999 de linii sau coloane cu numărul de elemente nenule memorate de 10 8 – 1.

Cea prezentată în continuare este caracterizată prin faptul că utilizează o singură zonă secundară ZS. precum şi elemente false care indică începutul fiecărei linii şi sfârşitul memorării întregii matrice. Memorarea compactă sistematică presupune că elementele nenule ale unei matrice rare sunt memorate într-o anumită ordine (pe linii sau pe coloane). ne putwem dispersa de indicii de linie. fiind în schimb mai puţin rapidă în ce priveşte manevrarea datelor. În acest caz nu este necesar să se memoreze în zonele secundare indicii de linie. memorarea în acestă formă este următoarea: Locaţia 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 . În cazul matricelor simetrice această structură de memorare se poate simplifica prin memorarea numai a elementelor nenule de deasupra diagonalei principale. unde n este numărul de coloane a matricei. Numărul total de cuvinte necesar memorării matricei este 2mnG. Numărul total de cuvinte necesare memorării unei matrice ( m. În structura de mai sus pentru identificarea elementelor nenule ale matricei rare au fost folosite două zone secundare corespunzătoare indicelui de linie şi de coloană. Pentru o memorare în ordinea liniilor. un element zero în ZS marchează prezenţa unui element fals şi acesta specifică în ZP numărul liniei elementelor de la dreapta locaţiei. fiecărui element din zona primară i se ataşează în zona secundară un număr întreg din care se pot determina indicii de linie şi de coloană. însă se cere specificarea începutului fiecărei linii. Astfel. Pentru matricea A. De exemplu. . este suficient ) pentru identificarea elementului în matrice. Avantajul acestei structuri de memorare constă în faptul că necesită mai puţină memorie decât cea precedentă.n ) – dimensionale este în acest caz 3mn. Raportul dintre cerinţele de memorie ale acestei structuri şi a celei standard este (7) Valoarea limită a densităţii matricei pentru care această structură este eficientă este: G = 50%. respectiv de coloană. Sfârşitul matricei este marcat prin prezenţa în ZP a unui element fals cu valoarea zero. care conţine indicii de coloană ale elementelor nenule din matricea considerată.Avantajele memorării compacte aleatoare constau în faptul că noi elemente nenule ale matricei pot fi adăugate la sfârşitul zonelor de memorare fără a perturba celelalte elemente. Raportul dintre cerinţele de memorie ale acestei structuri şi a celei standard este: c3 = 3G (6) Egalând relaţia (6) cu unitatea se determină valoarea limită a densităţii matricei pentru rare această structură este eficientă: lim . Dacă elementul ij este memorat în locaţia k a zonei primare atunci în zona secundară se va memora numărul G = 333% . Se prezintă în continuare o altă posibilitate de memorare în care se va utiliza o singură zonă secundară de dimensiune egală cu numărul de elemente nenuşle ale matricei.coloana j este obţinută ca: j este mai mic întreg ≥ Indice agregat (k)/n. a ≠0 i + ( j − 1 n. singur. matricea A se memorează astfel: Locaţia Valoare Indice agregat 1 1 1 2 -2 12 3 4 22 4 -1 9 Pentru a regăsi indicele de linie şi de coloană al oricărui element memorat în locaţia k se utilizează următoarea tehnică de calcul: . Utilizând acest artificiu. Acest număr. conţinând simultan informaţii asupra indicilor de linie şi de coloană. Şi în acest caz se pot imagina mai multe structuri de memorare. precum şi a elementelor nenule situate pe această diagonală.linia i este determinată astfel: i = Indice agregat (k) – ( j – 1 ) n. precum şi o manevrabilitate rapidă a datelor.

devenind ineficientă. 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. . În scopul ilustrării principalelor operaţii efectuate asupra matricelor rare s-a făcut implementarea acestora în limbajul VisualC++. destructorul. câteva dintre acestea fiind prezentate în paragraful anterior. ceea ce creează necesitatea considerării unor tehnici speciale de memorare. n ) – dimensională este 2(mnr+ m+ 1 . O cerinţă esenţială în programarea matricelor rare constă în memorarea şi executarea operaţiilor numerice numai cu elementele nenule ale matricei. este abandonată şi înlocuită cu metode de memorare adecvate. astfel: ZSL pentru memorarea indicilor de linie ai elementelor nenule. de a salva memorie şi timp de calcul. Software orientat spre lucrul cu matrice rare Metodele de calcul cu matrice rară pentru a fi eficiente trebuie să beneficieze de proporţia mare de elemente nule din aceste matrice. câteva dintre funcţiile şi operatorii implementaţi şi secţiunea privată. datorită flexibilităţii în manevrarea datelor. În general. În acest caz memorarea standard. programare şi analiză numerică. Raportul de memorare este: Pentru această structură de memorare numărul 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%. Raportul dintre cerinţele 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%. cerinţe care de cele mai multe ori sunt contradictorii. ZSC – pentru indicii de coloană şi ZSU pentru memorarea adresei următorului element al matricei. Un program de calcul cu matrice rare este cu atât mai eficient cu cât timpul de calcul şi cerinţele de memorie necesare sunt mai reduse faţă de acelea ale unui program readiţional. conţinând constructorii. Matricea A se memorează după cum urmează: Locaţia 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 înţelege adresa celei de-a doua locaţii.) memora o matrice rară ( m. Memorarea cu ajutorul listelor reprezintă o extensie a memorării compacte aleatoare. Pentru reprezentarea matricelor s-a ales memorarea compactă aleatoare. În timpul operaţiilor 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 modificări într-un mod eficient. De aceea tehnica de programare trebuie să realizeze o proporţie convenabilă între timpul de calcul şi memoria utilizată. de sortare şi ordonare în structuri speciale în vederea menţinerii structurii de matrice rară şi a stabilităţii numerice. 3. Principiul fundamental de programare cu matrice rare constă în memorarea şi manipularea numai a elementelor nenule. Este prezentată în continuare o parte a clasei MR. 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. de evitare a buclelor complete.

long dim. iar e este pointer la un masiv având tipul de bază tip (tipul de bază al elementelor matricei). void One (float). void Generate(int. & * & MR operator (MR x). void Zero (float). * tip e. datorate numărului finit de octeţi în care se face reprezentarea diverselor tipuri de date în calculator. + & & MR operator (MR x). ( long Find ). scăderea. S-a realizat de asemeni o funcţie (Generate(float)) care să construiască o matrice rară cu elemente aleatoare. În continuare se face o prezentare detaliată a operatorilor care implementează principalele operaţii matriceale: adunarea. int). înmulţirea şi inversarea.classMr { public . ~ ( virtual MR ). ( void Write ). }. * void FileWrite (const char ). ( void Change ). scăderea. transpunerea. . transpunerea.. n este dimensiunea matricei. void Read(const char *). respectiv coloana elementelor nenule. având impusă în schimb valoarea gradului de umplere. & * MR operator (float). Pe parcursul dezvoltării clasei MR s-a dovedit necesară implementarea unei funcţii ( void Zero (float) ) care să elimine dintr-o matrice acele elemente care sunt foarte mici (cu câteva ordine de mărime mai mici decât restul elementelor). * int l. &I MR (int). ( void Delete ). Aceste elemente cu valoare nesemnificativă sunt rezultatul erorilor sistematice introduse prin rotunjiri. int. ( MR ). () float Tras * tip Full(int &). : private int label. int n. MR (int. Softul realizat vizează principalele operaţii necesare manipulării matricelor rare: construirea acestora (prin introducerea datelor de la tastatură). & & MR operator (MR x).. dim serveşte pentru memorarea numărului de elemente nenule. * int c. În cadrul secţiunii private. & !( MR operator ). scrierea şi citirea din fişiere. l şi c sunt pointeri la masive de întregi reprezentând linia. label reprezintă o etichetă ce serveşte pentru identificarea matricei. float). principalele operaţii matriceale: adunarea. vizualizarea lor. ( voidInsert ). înmulţirea şi inversarea.

• determinarea acelor elemente din prima matrice care nu au corespondent în cea de-a doua şi adăugarea lor la matricea sumă. tis ->label+x. if (this. Pentru implementare s-a folosit suprascrierea operatorilor.> n! = x.-. Prin “elemente comune” au fost desemnate acele elemente caracterizate prin indicii de linie şi de coloană care sunt nenule în ambele matrice.> dim. Este prezentat în continuare operatorul care implementează operaţia de adunare. this->FileWrite(“this.4. p->e[k]=x. p->c[k]=x. i ++) { p-> 1[i]=this->1[i]. • determinarea elementelor comune celor două matrice. Adunarea.p->e. i<x. p-> e[i]=this->e[i]. i + + ) if (Found ( x.n) return * this.thois->1. • alocarea memoriei corespunzătoare acestui număr. i < x. } } Sortare(p->1.dim. • determinarea elementelor din cea de-a doua matrice care nu au corespondent în prima şi adăugarea lor la matricea sumă. i++) { D=Found(x.label). MR & MR :: operator + (MR & x ) { int i. x. însumarea lor şi adăugarea la matricea sumă.p->c. i <this-> dim. if(D) p->e[D-1]+=x. else { p->1[k]=x. for (i = 0. scăderea şi transpunerea Adunarea matricelor rare presupune parcurgerea câtorva paşi: • determinarea numărului de elemente nenule ale matricei sumă.> label.c[i]. pentru a conferi o mai mare putere de sugestie operaţiilor matriceale implementate. this->c). D = x. k++. Funcţia Found ( ) este definită în afara clasei MR şi serveşte pentru găsirea elementelor comune celor două matrice.c[i]. for(i=0. p-> c[i]=this->c[i].1[i].this->dim. for (i = 0. p = new MR (this ->n.txt”).dim.1[i].c[i]. MR * p.1[i].e[i]. x.p->dim). structurată conform paşilor prezentaţi mai sus. this − > c)) D . x.e[i].dim.txt”).> 1. this. p->FileWrite(“p.label). } k=this->dim. { .txt”).FileWrite(“x. x. return *p. this. k. D. AfxMessage Box ("\nAdunar e : %d + %d" . D + = this. D.

(m. x. i<this->dim. label).dim.”). for(i=0. j<x. . Acest principiu este utilizat în implementarea operatorului de înmulţire a matricelor rare din cadrul clasei MR prezentate în paragraful anterior. în locul adunării. long T.Implementarea operatorului de scăderea este absolut similară celui de adunare. considerând influenţa liniilor matricei A asupra matricei produs C. tip S. MR& operator * (MR &x) int i. for (i =0. Transpunerea matricelor rare este similară celei efectuate pe structră tablou. se determină mai întâi această contribuţie după care se continuă cu următorul element al liniei i a matricei A. D this->label * x.label). (m. AfxessageBox(“\nTraspunere.c[j].e[j]’ else // se face iniţializarea { p->1 [R]=this->1[i]. respectiv coloanele elementelor nenule: MR&MR::operator ++() { int*p. Mr *p. Implementarea şi inversarea matricelor rare Pentru înmulţirea matricei rare A.j<x.1[j] { T=Found(this->1[i]. Întrucât elementul aik al matricei A poate conntribui la formarea tuturor elementelor liniei i a matricei C. // Sunt cel mult D. i++) for(j=0. 1) – dimensională. k. } else . i<this->dim. } 5. printf (“\nÎnmulţire : &d * *d”. În cazul de faţă se inversează pointeriii la masivele de întregi reprezentând liniile. p->c[R]=x. constând în inversarea indicilor de linie şi coloană între ei. n) – dimensională. p->e[R]=this->e[i] *x. (l.n) return *this. Procedura standard de înmulţire se modifică astfel încât în bucla internă să se execute toate operaţiile corespunzătoare unui element al matricei A. // Pas 1 : Câte elemente va avea matricea finală? D=0. cu matricea rară B. if (this ->n!=x. if(T) if(p->e[T-1]) // deja iniţializat p->[T-1]+=this->e[i]*x.this->1=this->c.dim. this->label. return *this. j++) if(this->c[i] ==x. prin coloanele matricei B. j++) if(this->c[i]==x.e[j]. . p->1. R. x. // Se ia fiecare element din A şi se înmulţeşte cu tot ce // se poate din B // Elem. p=this->1. j. se utilizează o modificare a procedurii standard. până la determinarea completă a liniei i a matricei C.1[j]) D++. R++.c[j]. p=new MR(this->n. p->c). p -> e[i] trebuie să fie (şi sunt) nule după iniţializare R=0. // pas 2 : Calcul efectiv. i++) for (j=0.n) – dimensională.this->c=p. * q. D. Se prezintă în continuare acest operator.D. singura diferenţă fiind accea că în cazul elementelor comune se face scaderea lor.

AfxMessageBox(“Inversare”). { Prin analiza acestui operator se constată că matricea rezultată păstrează structura de matrice rară (zerourile apărute au fost eliminate). p->c[R]x. i++) if (!p->e[i]) D. B=new MR(n.e[j]. label)..D. float P..E(n. q=new MR(this->n. q->c[D]=p->c[i]. for(i=0. R++. E=this->I(n).-.dim.1[j])) // x e totusi sortat j=x.1). Pentru implementarea operatorului de inversare s-a folosit algoritmul lui Krîlov. i<p->dim. Acesta constă în parcurgerea unui număr de paşi 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 . Sortare (q->1. q->e. 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. } delete p. return *q.n. q->e[D]=p->e[i]. T(n. } } else if(this->c[i] <x.dim. Bn este o matrice idenitic nulă. p->e[R]=this->e[i] *x. MR & MR::operator ! () { MR A(n. 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 înţelege urma matricei A (suma elementelor diagonale) iar I reprezintă matricea unitate de aceeaşi dimensiune cu matricea A. for(i=0.. *B.label). . q->1[D]=p->1[i]. i++) if(p->e[i]) { D. dim. // Se scot zerourile şi se sortează D=p->dim.dim.c[j]. i<p->dim. label).label). q->dim. Krîlov a demonstrat că după parcurgerea celor n paşi.{ p->1[R]=this->1[i]. this->label-x. q->c..

Dacă simbolizăm “ specificăm modelul astfel: y ” valorile “ajustate”.txt”).k++) { A=T*(*B). A. P=((float) 1/ float)K)*A. Tabelul 1 y – productivitatea muncii (creşteri procentuale) 1 2 5 6 7 x1 – utilaje de mare randament (bucăţi) 2 4 4 4 5 x2 – venituri suplimentare (mil. specificăm modelul astfel: yi = a0 + a1x1i + a2x2i + ui (11) unde ui reprezintă o variabilă “reziduală” ce caracterizează influenţa altori factori asupra variabilei efect y. y i = a 0 + a1x 1i + a 2 x 2i (12) Relaţia (12) se scrie pentru fiecare set de valori prezentate în tabelul 1.FileWrite(“A. factori care din diverse motive nu pot fi luaţi în considerare. return *B. FileWrite(“B.txt”). (*). B=T-E*P. y=f(x2) • x x2 • Întrucât norul de puncte din fiecare reprezentare grafică sugerează o linie dreaptă.txt”). 6.FileWrite(“B. A. k<n. lei) 1 1 3 5 5 Pentru a specifica forma funcţiei.T<=*this. P=((float)1/(float)n*Atras().FileWrite(“A. y • • • • • y • • • x x1 Figura 1 – Dependenţa y=f(x1). (*B).FileWrite (“A. Se doreşte determinarea unei funcţii care să caracterizeze dependenţa dintre productivitate şi celelalte două variabile considerate independente (număr de utilaje şi venituri suplimentare). al numărului de utilaje de mare performanţă deţinute (x1) şi al veniturilor suplimentare acordate salariaţilor (x2). P=T.txt”). B=A-EP.Tras(). se analizează pe cale grafică dependenţa variabilei – efect (y) în raport cu fiecare dintre variabilele cauzale.txt”). (*B). datorată folosirii unui număr redus de operaţii de împărţire. B=(B*)((float) 1/(float)P.Tras(). } A=T*(*B). rezultând: .txt”). T.FileWrite(A”.txt”).FileWrite(“B. } Avantajele acestui algoritm constau în simplitatea implementării şi precizia rezultatelor. rezultate în urma aplicării modelului liniar. for(int k=2. Estimarea parametrilor unei regresii statistice folosind clasa MR Se consideră datele din tabelul 1 ce caracterizează cinci întreprinderi din punctul de vedere al productivităţii (y). A.

datorat caracteristicilor reale ale sistemelor. la care se adaugă necesitatea unei rezolvări rapide. astfel că este pe deplin justificată folosirea unor structuri de memorare specifice matricelor rare. însă timpul necesar calculelor. fapt ce justifică implementarea relaţiei (17) pe o structură de matrice rare. se dovedeşte a fi tot mai mult o resursă critică. înmulţire şi inversare. care până nu de mult erau fie consideraţi aleatori. [3] Această metodă presupune minimizarea expresiei adică. 7. oferind un dublu avantaj: memorie şi timp. în cadrul unui sistem în care timpul reprezintă o resursă critică. Concluzii Asistăm în prezent la un fenomen care tinde să atingă tot mai multe domenii de activitate: necesitatea de a cunoaşte cît mai precis anumiţi factori sau parametri ce caracterizează domeniul respectiv. y1   1 x11     y 2   1 x12    =       y   1 x1 n  n  Aşadar. în funcţie de aceasta. Softul orientat spre lucrul cu matrice rare exploatează caracterul de raritate al structurilor manipulate. trei înmulţiri şi o inversare. ′ U ′U = ( Y − XA ) ( Y − XA ) A = ( X ′X ) X ′Y −1 (17) O determinare cât mai precisă a matricei parametrilor unei regresii presupune existenţa unui număr foarte mare de date (număr mare de linii în matricea X). în concordanţă cu dinamica crescândă a sistemelor actuale. Cunoaşterea acestor factori oferă o descriere mai detaliată a sistemului în care se lucrează. Caracterul de raritate al structurilor implicate în rezolvarea problemelor. se poate imagina un soft care să facă o evaluare anterioară calculelor asupra densităţii matricei. permiţând în acest fel o mai bună activitate de control şi comandă a acestuia. În multe cazuri practice valorile acestor date sunt nule. şi. odată cu apariţia sistemelor în timp real. În cele mai multe dintre cazuri baza de calcul a acestor factori o constituie statistică matematică şi teoria probabilităţilor. În acest scop se utilizează ∑ u 2t t . să decidă asupra structurilor de date ce vor fi folosite pentru memorare şi efectuarea calculelor. Matricele X şi Y asupra cărora se operează au în multe dintre cazurile practice o densitate foarte mică. U U. astfel încât timpul afectat calculelor să fie minim. ceea ce conduce la necesitatea rezolvării unor probleme liniare de foarte mari dimensiuni. Dar (16) unde prin U' s-a notat transpusa matricei U. 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 dependenţei dintre variabila efect şi variabilele cauză însemnă determinarea valorilor numerice ale parametrilor metoda celor mai mici pătrate. implementarea relaţiei (17) presupune scrierea unei singure linii de cod: A = (! ( ( + + X ) * X ) ) * ( + + X ) * Y (18) Aşadar. Referitor la lucrul cu matrice în general. În [3] se demonstrează că prin minimizarea relaţiei (16) se ajunge la expresia: a 0 . În ultimii ani memoria nu mai constituie o problemă. fie nu se punea problema determinării lor. Având deja definiţii operatorii de transpunere. justifică pe deplin introducerea în aplicaţiile informatice asociate a unor structuri de date adaptate acestor particularităţi. matriceal. considerată a fi imposibilă. . pentru aflarea matricei A sunt necesare două operaţii de transpunere. a1 şi a 2 .

P6-Alocarea si initializarea celei de-a doua matrice prin procedura “incarcare”.float *vel2.int n) care primeste ca parametri un pointer catre o matrice de numere reale prin referinta pentru a permite modificarea sa si dimensiunile matricei.float *&v3) care primeste ca parametri un pointer la matrice.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. • O procedura care calculeaza diferenta dintre doua matrice rare comprimate in prealabil: int scadere(float *vel1. 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) .int *&v1. P8-Compresia celei de-a doua matrice prin procedura “ matrar“ . in al doilea vector si elementul nenul din matrice in cel de-al treilea vector. P9-Dezalocarea celei de-a doua matrice prin procedura “ distruge“. rangul coloanei. • O procedura care aduna doua matrice rare ce au fost in prealabil comprimate : int adunare(float *vel1.int n2.int *&v2.int *&vcr.float *&velr.int n.int n1.int *vl2. P10-Suma celor doua matrice prin procedura “ adunare”. dimensiunile matricei. iar daca este se trece la pasul usmator.int *vc2. 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 .float *&velr. P2.float *vel2. Programul contine urmatoarele proceduri : • O procedura de alocare si initiere de la tastatura a unei matrice: void incarcare(float **&a.int *vc2.int *&vcr. 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. in primul vector. P11-Diferenta celor doua matrice prin procedura “ scadere”.Suma si diferenţa 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 .int *vc1.int *&vlr) care primeste ca parametri trei pointeri catre cei trei vectori corespunzatori primei matrice si dimensiunea lor. O matrice rara este o matrice ce contine mai mult de doua treimi valori nule.int n2. • O procedura care transforma o matrice rara in cei trei vectori despre care am vorbit mai sus: void matrara(float **a.int *vl2. 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.int m.int n) care primeste ca parametri un pointer la matrice transmis prin referinta si dimensiunile ei.int k. iar pentru fiecare iteratie se parcurg pasii P3-P5. primiti prin referinta .int n1. Al treilea vector va fi ordonat dupa primul vector si dupa cel de-al doilea vector.int m. numarul de elemente nenule din matrice si cate un pointer la fiecare din cei trei vectori care rezulta.int *vl1. • O procedura care dezaloca o matrice alocata dinamic: void distruge(float **&a. P5-Dezalocarea primei matrice prin procedura “ distruge“.int *vl1. • O procedura care verifica daca o matrice este rara: int ifrar(float **a.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. P4-Compresia primei matrice prin procedura “ matrar“ .int m. P3.Parcurgerea vectorilor primei matrice.int *vc1. iar daca este se trece la pasul urmator. . 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. Pe fiecare pozitie din cei trei vectori se vor gasi rangul liniei. P2-Alocarea si initializarea primei matrice prin procedura “incarcare”.int m. Procedura “ adunare” are urmatorii pasi: P1-Alocarea celor trei vectori corespunzatori rezultatului.int *&vlr) avand aceiasi parametri de intrare si returnand tot dimensiunea vectorilor rezultati.

int v2[34].int m.int v1[34].h> //procedura de compresie a unei matrice rare(normalizarea sa) void matrara(float a[10][10].j++) if(a[i][j]) { v1[k]=i. for(int i=0. //introducerea datelor de la tastatura cin>>a[i][j].i<n.int n.i++) for(int j=0.j++) //elementelor if(!a[i][j]) k++. } } //procedura dealocare si incarcare de la tastatura a unei matrice void incarcare(float a[10][10].j<m.int n) { int k=0."<<j+1<<" : ". //cu elementele nenule ale matricei k++. #include<iostream. P7-Se returneaza lungimea vectorilor rezultati.i++) for(int j=0. } } //procedura de verificare a unei matrice daca este rara int ifrar(float a[10][10]. //nule if(k>m*n*2/3) return m*n-k. for(int i=0.j++) { cout<<"Introduceti elementul:"<<i+1<<". } .float v3[34]) { int k=0. //returneaza numarul de elemente nenule else return 0.i<n.int n) { for(int i=0. luate cu semn schimbat. 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. //vectorilor v3[k]=a[i][j].i++) //contorizarea for(int j=0.i<n.j<m. P6-Dupa ce se termina de parcurs vectorii primei matrice. P2-Efectuarea diferentei prin adunarea primei matrice cu matricea a doua inmultita cu -1. //initiere v2[k]=j. 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. Procedura “ scadere” urmeaza pasii: P1-Alocarea si initializarea unui vector auxiliar cu valorile vectorului de elemente corespunzator celei de-a doua matrice.int m.j<m. P3-Returnarea lungimii vectorilor rezultati.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.int m. altfel se trece prin pasul P5.

l+ +. float a. //primei matrice vcr[l]=vc2[j]. l++.i++) // parcurgerea vectorilor primei matrice { for(int j=k. } return l.int vcr[67]. //liniei si coloanei elementului vlr[l]=vl2[j].i<n1.int *vl2.float velr[67]. in continuare in vlr[l]=vl2[i].int *vc2. rezultate vcr[l]=vc2[i]. } } if(k!=n2) de-a doua matrice sunt elemente de for(i=k.int vlr[67]) { int l=0.i<n2.int *vl1.int *vc1. corespunzatoare elementului din vcr[l]=vc1[i]. matrice l++.k++) //parcurgerea vectorilor { // celei de-a doua matrice //pana la egalarea rangului velr[l]=vel2[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].int n2.//procedura de adunare a doua matrici rare memorate in vectori int adunare(float *vel1. vlr[l]=vl2[j].int n1. } else { velr[l]=vel1[i]. matrice element nenul vlr[l]=vl1[i].float *vel2. vcr[l]=vc2[j].(vl1[i]>vl2[j])||((vl1[i]==vl2[j])&&(vc1[i]>vc2[j])). if(a) { velr[l]=a.i++) coloanei mai mare decat al { //ultimului element din vectorii primei matrice velr[l]=vel2[i]. for(int i=0.j++.k=0. //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 . } k++. l++.

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

vl1.j<m.i<l2.h> //procedura de compresie a unei matrice rare(normalizarea sa) void matrara(float **a.i++) //se afiseaza vectorii rezultati cout<<"\n"<<vla[i]<<" "<<vca[i]<<" "<<vela[i].l2. v1=new int[l].i++) //se afiseaza vectorii rezultati cout<<"\n"<<vls[i]<<" "<<vcs[i]<<" "<<vels[i].int k.vl2.//se verifica daca //matricea rezultata este rara cout<<"\n". for( i=0.i<ls.vl2. k=0.for(int i=0. } else cout<<"Nu este matrice rara!!!".int *&v2.l1.vla). for( i=0.l2.//se verifica daca //matricea rezultata este rara cout<<"\n".int *&v1. } "<<vc2[i]<<" #include<iostream.//de-a doua matrice int la=adunare(vel1. int ls=scadere(vel1.vels.l1.i<n. } else cout<<"Nu este matrice rara!!!".i++) for(int j=0.j++) if(a[i][j]) { v1[k]=i.vc1.vca.vel2.int m.//alocare v2=new int[l].//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 ".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 ".i++)//se afiseaza cei trei vectori corespunzatori celei cout<<"\n"<<vl2[i]<<" "<<vel2[i].vc1.// rezultati for(int i=0.i<la.float *&v3) { int l=m*n-k.vc2.// vectori v3=new float[l].vc2. //initiere .vel2.vl1.vela.int n.vcs.

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

corespunzatoare elementului din vcr[l]=vc1[i]. vcr[l]=vc2[j]. in continuare in vlr[l]=vl2[i]. l++. matrice l++. matrice element nenul vlr[l]=vl1[i]. } k=n1+n2-l.int *vc1.i<n2.float *vel2. //liniei si coloanei elementului vlr[l]=vl2[j].int *&vlr) { float *vaux=new float[n2]. /*delete [k](vlr+l).int *vl1. } k++. rezultate vcr[l]=vc2[i]. if(a) { velr[l]=a. //primei matrice vcr[l]=vc2[j].int *vl2. delete [k](velr+l).int *&vcr.int n2. l++. } if((vl1[i]==vl2[j])&&(vc1[i]==vc2[j])) liniei si coloanei sunt { // aceleasi se aduna elementele a=vel1[i]+vel2[j].i<n2.i++) coloanei mai mare decat al { //ultimului element din vectorii primei matrice velr[l]=vel2[i].float *&velr. } else { velr[l]=vel1[i]. vlr[l]=vl2[j].velr[l]=vel2[j]. delete [k](vcr+l). } } if(k!=n2) de-a doua matrice sunt elemente de for(i=k. . //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 n1.*/ return l.i++) vaux[i]=-vel2[i].int *vc2. //se foloseste un vector auxiliar in care se introduc //valor ile nenule cu semn schimbat din prima matrice for(int i=0.

m.//se dezaloca a doua matrice for(int i=0.i++)//se afiseaza cei trei vectori corespunzatori celei cout<<"\n"<<vl2[i]<<" "<<vel2[i].vl1.n).*vl2.vc1.m.i<l2. la tastatura cin>>n.*vca.// se aloca si se initializeaza de la tastatura prima matrice int l1=ifrar(x.velr.vc2.vl1.l1.//se transforma a doua matrice //in trei vectori distruge(y. cin>>m. a doua matrice int l2=ifrar(y.int k=adunare(vel1.m.i<l1.//se face scaderea prin //adunare: a-b=a+(-b) delete [n2]vaux.n).//se verifica daca a doua matrice este rara if(l2) { matrara(y.vc1. // de coloane //se introduc de incarcare(x.m.**y.n2.n).*vel1.//se dezaloca vectorul auxiliar return k.l2.*vl1.m.vl2.n. //numarul de linii si cout<<"Introduceti numarul de coloane:".n1.//se verifica daca prima matrice este rara if(l1) { matrara(x.m.i++) vectori corespunzatori cout<<"\n"<<vl1[i]<<" "<<vel1[i].m.//de-a doua matrice "<<vc2[i]<<" //primei matrice incarcare(y.*vels.// se aloca si se initializeaza de la tastatura "<<vc1[i]<<" //se afiseaza cei trei .vl2.*vc2.vel1).//se declara dimansiunile matricelor //si pointerii la vetorii de ranguri ale liniilor si cocloanelor cout<<"Introduceti numarul de linii:".*vla.n).*vls. //se dezaloca prima matrice for(int i=0.vaux.//se transforma prima matrice in trei vectori distruge(x.vel2).vlr).n.n).m.//se returneaza dimensiunea vectorilor rezultati } //*************************************************************************** ****************** void main () { float **x.//se declara pointerii la cele doua matrice initiale //si la vectorii de elemente int n.vcr.vc2.*vela.*vcs.*vel2.m.n).*vc1.

vc2. for( i=0.vcs.vc1. for( i=0.vels.l1.vc2.//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 ".int la=adunare(vel1.i++) //se afiseaza vectorii rezultati cout<<"\n"<<vls[i]<<" "<<vcs[i]<<" "<<vels[i]. } else cout<<"Nu este matrice rara!!!".//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 ".vc1.vl2.//se verifica daca //matricea rezultata este rara cout<<"\n".l2.vel2.//se verifica daca //matricea rezultata este rara cout<<"\n".vl2.vca.l2. } else cout<<"Nu este matrice rara!!!".vela.vla).i<ls.vl1.i++) //se afiseaza vectorii rezultati cout<<"\n"<<vla[i]<<" "<<vca[i]<<" "<<vela[i]. } .i<la.vls).vl1.l1. int ls=scadere(vel1.vel2.

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->