Saturday, December 30, 2017

Eveline Cismaru, hackerița

Numai după nume îți dai seama că este predestinată să se facă de cacao, deși meseria de cismar este onorabilă, dae asociată cu velina-felina devine dintr-un film horor. Pe lângă faptul că s-a făcut de râs, a dovedit că este vai steaua ei, un fel de insă predestinată la a lua plase în cascade, căci a face ceva care nu este de nasul tău este mai rău decât ai sta în banca ta. . Fără a avea prea multă minte, s-a apucat de chestia aceea jegoasă prin care încearcă să facă rost de bani, condiționând repunerea în drepturi a proprietarului ale cărui resurse le-a uzurpat. Neșansa ei a fost că sunt alții cu mult mai deștepți decât ea care au contracarat acțiunea ei primitivă, având un colaborator tot de teapa ei, dar la fel de nepregătit în domeniu ca și ea. Fără prea multă inteligență fiind, această hackeriță de doi bani jumătate, s-a dat în stambă căutând să atragă atenția, uitându-se într-o oglindă din aceea care deformează de pe la Macys, supradimensionându-se ca orice megalomană primitivă și cu un IQ destul de mititel, dar cu o autosupraevaluare a nivelului său de inteligență, fără drag de muncă, ci doar cu idei fixe, mult prea fixe pentru a reuși undeva, cândva. Și-a dorit ca ziarele să scrie despre ea și a reușit, dar este acum undeva la răcoare alături de colaboratorul său. La 28 de ani am crezut că o femeie are oarece minte. M-am înșelat. Dacă pe colaborator l-aș înțelege din moment ce se zice că bărbații gândesc doar cu 1/2 din creier, pe ea care gândește cu 100% din creier n-aș mai înțelege-o, deși ea ca femeie trebuia să dea dovadă de cu mult mai multă fantezie și să fie un pic mai originală, să aibă un demers mai elaborat. N-a fost să fie. Trebuia ca finalul de an să mai includă doi români care s-au făcut de rahat și ne-au mai tras și pe noi după ei, căci nimeni nu va spune că Eveline Cismaru și Mihai Alexandru Isvanca sunt hackeri proști, ci peste tot se va spune că doi români au făcut și au dres cutare chestie nasoală.  Câtă scârbă îmi provoacă Eveline Cismaru și Mihai Alexandru Isvanca luați la grămadă ca hackeri, căci eu sunt român și eu au pângărit acest nume.

(30 decembrie 2017)

Mihai Alexandru Isvanca

Pe lângă faptul că s-a făcut de râs, a dovedit că este vai steaua lui. Fără a avea prea multă minte, s-a apucat de chestia aceea jegoasă prin care încearcă să facă rost de bani, condiționând repunerea în drepturi a proprietarului ale cărui resurse le-a uzurpat. Neșansa lui a fost că sunt alții cu mult mai deștepți decât el care au contracarat acțiunea lui primitivă. Fără prea multă inteligență fiind, acest hacker de doi bani s-a dat în stambă căutând să atragîă atenția, supradimensionându-se ca orice megaloman primitiv și cu un IQ destul de redus, dar cu o autosupraevaluare a nivelului său de inteligență, fără drag de muncă, ci doar cu idei fixe, mult prea fixe pentru a reuși undeva, cândva. Și-a dorit ca ziarele să scrie despre el și a reușit, dar este acum undeva la răcoare. La 25 de ani am crezut că un bărbat are oarece minte. M-am înșelat.

(30 decembrie 2017)

Fiabilitatea programelor și ordinele de mărime

În programele FORTRAN IV se lucra cu:
- variabile și constante de tip întreg definite pe 4 bytes;
- variabile și constante de tip real definite pe 4 bytes;
- variabile și constante de tip real definite pe 4 bytes;
- variabile și constante de tip logic
- variabile și constante de tip complex definite pe 4+4 bytes.
Fiecare constantă sau variabilă este caracterizată prin magnitudine, adică valoare maximă, respectiv, valoare minimă și prin ordin de mărime, adică număr de cifre maxim ce se stochează în zona de memorie care se alocă.
O constantă de tip întreg care este definită pe 4 bytes are cel mai mare număr ce se stochează acolo egal cu 2 la puterea 31 minus 1, cunoscătorii știu de ce..., adică magnitudinea maximă este de 2147483647. Deci dacă cineva dorește să scrie un program fiabil în care adună două numere IA și IB trebuie să verifice dacă:
  • IA > 2147483647;
  • IB > 2147483647;
  • IA+IB > 2147483647.
Având în vedere că în calcule toate variabilele sunt cu aceeași importanță, este rezonabil să se ia în considerare pentru fiecare dintre ele un domeniu care să asigure fiabilitatea programului în orice condiții. Din punctul meu de vedere, domeniul de variație al variabilelor nu trebuie calculat pe bucățele, ci per global, pentru a da generalitate și operaționalitate programului, adică programul să funcționeze în orice condiții, nu uneori da și de o mie de ori, nu.
Dacă se consideră doi operanzi de tip întreg OP1 și OP2 având N1 și respectiv N2 cifre, când se face o operație de adunare sau de scădere rezultatul REZ = OP1 + OP2  va avea un număr de cifre egal cu NREX = max (N1,N2) +1. Ca un program să fie fiabil trebuie ținut seama și de acest aspect. Dacă rezultatul REZ nu trebuie să fie mai mare în valoare absolută decât 2147483647, înseamnă că operanzii OP1 și OP2 nu trebuie să fie mai mari în valoare absolută decât 2147483647/2, adică mai mare decât 1072418237. Sunt chestiuni învățate în școala elementară, despre care foarte mulți dintre noi nu le-am considerat importante atunci, dar care pentru a face programe fiabile revin în forță.
Dacă se consideră doi operanzi de tip întreg OP1 și OP2 având N1 și respectiv N2 cifre, când se face o operație de înmulțire rezultatul REZ = OP1 * OP2  va avea un număr de cifre egal cu NREX =  N1+N2. În acest context OP1 și OP2 nu trebuie să fie mai mari de 46340 pentru a nu avea dureri de cap cu derularea calculelor și fără a fi nevoiți să stabilim numărul de cifre al numărelor stocate în zonele de memorie OP1 sau OP2.
Este rezonabil să introducem prin programele noastre colo și colo instrucțiuni precum:
                  IF((OP1.GT.1072418237).OR.(OP2.GT.1072418237)) GO TO 10
                  REZ = OP1 + OP2
                  IK=1
sau
                  IF((OP1.GT.46340).OR.(OP2.GT.46340)) GO TO 10
                  REZ = OP1 * OP2
                  IK=2
....................
10              IK=0
....................
Unde IK=0 dacă operațiile de calcul nu se efectuează din motive de depășire a capacității sau IK=1 în ideia că operațiile se efectuează. Dacă suntem convinși că trebuie să verificăm efectuarea calculelor se vor face conversii pe real a operanzilor și numai după efectuarea calculelor finale se va face testul dacă rezultatul final este mai mare decât constanta reală 2147483647. ceea ce va conduce la atribuirea valorii IK=0 cum că s-a produs o depășire care duce la trunchiere dacă se face conversie de la real spre întreg.
Fiabilitatea programelor și ordinele de mărime merg mână în mână și în vremurile de demult subdepășirea dar și depășirea de capacitate au dat mari bătăi de cap programatorilor mai ales când erau neglijeate oarece inițializări și se lucra cu operanzii neinițializați spre direcționarea în zone aleatoare a rezultatelor finale.




(30 decembrie 2017)

Friday, December 29, 2017

Coeficienții modelului de regresie

Dacă se consideră modelul de regresie liniară 
Y= B0+B1*X1+B2X2+B3*X3+.....+Bn*Xn
și sunt înregistrate serii de date de M termeni pentru variabila dependentă Y și tot M termeni pentru factorii săi de influență X1, X2, X3, ..., Xn  a estima coeficienții B0, B1, B2, B3,..., Bn înseamnă a efectua calcule matriceale după formula:


unde:
B este vectorul coeficienților având  n+1 termeni B0, B1, B2, B3,..., Bn :
Y este vectorul celor M înregistrări de date pentru variabila dependentă;
X este o matrice cu n+1 coloane și M linii ce corespund seriilor de date pentru cei n factori 
    independenți; trebuie să spun că apare prima coloană cu toate valorile 1 pentru seria de date ce 
    dorespunde termenului liber cu coeficientul B0:
X este transpusa matricei X.
Subprogramul REGRLI(....) pentru estimarea coeficienților modelului de regresie liniară multifactorială, apelează la rândul său următoarele subprograme:
TRANSP - pentru construirea transpuseiXT a matricei X;
PRMAT - pentru calculul produselor XTX de matrice X' * X și, respectiv, XTY pentru  X'*Y
INVMAT - pentru calculul inversei XINV a matricei X'*X.

            SUBROUTINE REGRLI(X,Y,M,N1,B)
            DIMENSION XT(N1,M),XTY(N1),XTX(N1,N1),COEF(N1)
            CALL TRMAT(X,M,N1,XT)
            CALL PRODMT(XT,X,N1,M,M,N1,XTX)
            CALL PRODMT(XT,Y,N1,N1,1,XTY)
            CALL INMAT(XTX,N1,N1,XINV)
            CALL PRODMT(XINV,XTY,N1,N1,1,COEF)
            RETURN
            END
Subprogramul presupune că toate datele sunt corecte și complete și subprogramele apelate nu au variabila de stare IK pentru a simplifica lucrurile. În cazul în care subprogramele apelate ar fi avut variabila de stare IK, înainte de a apela următoarea procedură acea varabilă de stare trebuia testată și continuarea prelucrării era posibilă dacă și numai dacă rezultatul obținut după execuția subprogramului apelat este corect. În caz contrar variabila de stare va avea o valoare să zicem IK=0 care ar corespunde că nu -sau calculat coeficienții ecuației de regresie. Pentru a localiza de unde vine eroarea, variabilei IK i se dau diferite valori după fiecare testare de după execuția fiecărui subprogram.
(30 decembrie 2017)

Calcul coeficient de corelație

Coeficientul de corelație r este unul dintre indicatorii statistici deosebit de importanți. El arată dacă există sau nu o legătură între factori. Este dat de relația:


unde:
XM - media aritmetică a seriei de date formată din șirul X1, X2, X3,...., Xn:
YM - media aritmetică a seriei de date formată din șirul Y1, Y2, Y3,...., Yn:
Xi   - termenul i din seria re date X exogenă;
Yi   - termenul i din seria re date Y endogenă.
Subprogramul este:

             SUBROUTINE COREL(X,Y,N,COEF,IK)
             IF(N.LE.0) GO TO 30
             IK=0
             SX=0.
             SY=0.
             DO  10  I=1,N
             SX=SX+X(I)
             SY=SY+Y(I)
10         CONTINUE
             XM=SX/N
             YM=SY/N
             DIFXY=0.
             DIFX2=0.
             DIFY2=0.
             DO  20  I=1,N
             DIFXY=DIFX+(X(I)-XM)*(Y(I)-YM)
             DIFX2=DIFX2+(X(I)-XM)*(X(I)-XM)
             DIFY2=DIFX2+(Y(I)-YM)*(Y(I)-YM)
20         CONTINUE
             IK=1
             IF(DIFX2*DIFY2.LE.0)  GO TO 30
             IK=2
             COEF=DIFXY/SQRT(DIFX2*DIFY2)
30         CONTINUE
             RETURN
             END
Variabila IK=0 dacă numărul de elemente ale seriilor este incorect, IK=1 dacă sumele pătratelor de diferențe sunt incorecte, iar variabila IK=2 dacă s-a calculat corect coeficientul de corelație.


(30 decembrie 2017)

Produsul matrice cu vector

Produsul matrice cu vector se realizează dacă și numai dacă numărul de coloane ale matricei A este egal cu numărul de elemente ale vectorului X. Vectorul rezultat are un număr de elemente egal cu numărul de linii ale matricei A. Subprogramul seamănă foarte mult cu subprogramul de înmulțire a două matrice.
         SUBROUTINE PROMAT (A,X,AX,M,N)
         DO 20 I=1,M
         DO 20 J=1,N
         CI=0.
         DO 10 L=1,N
10     CI=CI+A(I,L)*B(L)
         C(I)=CI
20     CONTINUE
         RETURN
         END
Având în vedere faptul că vectorul este socotit ca matrice cu o singură coloană, se apelează subprogramul de înmulțire a două matrice particularizat:
         CALL  PROMAT (A,X,AX,M,N,1)
dar ar trebui ca subprogramul de înmulțire a matricelor să fie un pic schimbat pentru ca structura repetitivă cu o singură iterație să nu se execute de M ori.

         SUBROUTINE PROMAT (A,B,C,M,N,K)
         DO 20 J=1,K
         DO 20 I=1,M
         CIJ=0.
         DO 10 L=1,N
10     CIJ=CIJ+A(I,L)*B(L,J)
         C(I,J)=CIJ
20     CONTINUE
         RETURN
         END
Cu această modificare instrucțiunea 
         DO 20 J=1,K
pentru k=1 se va executa o singură dată, ceea ce este ceva mai eficient.


(29 decembrie 2017)

Produs scalar a doi vectori

Se consideră vectorii X și Y de N componente. A calcula produsul scalar al celor doi vectori înseamnă a calcula suma termenilor de forma X(I)*Y(I).
Subprogramul este:

         SUBROUTINE PROSCA(X,Y,N,PRO)
         PRO=0.
         DO   10  I=1,N
         PRO=PRO+X(I)*Y(I)
10     CONTINUE
         RETURN
         END

(29 decembrie 2017)

Coeficienții ecuației de regresie simplă

Modelul de regresie simplă





pentru calculul coeficienților a și b se folosesc formulele 

Image result for linear regression formula












subprogramele de calcul pentru coeficienții a și b sunt următoarele:
SUMVEC - sumă elemente ale unui vector S=X(1)+X(2)+....+X(N);
PATRAT - ridicare la pătrat a elementelor unui vector Z(I)=X(I)*X(I);
PRODEL - calcul produse elemente ale unui vector Z(I)=X(I)*Y(I);
COEF - calculează coeficineții A și B după formulele de mai sus.
         SUBROUTINE SUMVEC(X,N,S)
         S=0.
         DO   10  I=1,N
         S=S+X(I)
10     CONTINUE
         RETURN
         END

         SUBROUTINE PATRAT(X,N,S2)
         S2=0.
         DO   10  I=1,N
         S2=S2+X(I)*X(I)
10     CONTINUE
         RETURN
         END
         SUBROUTINE PRODEL(X,Y,Z,N)
         DO   10  I=1,N
         Z(I)=X(I)*Y(I)
10     CONTINUE
         RETURN
         END
         SUBROUTINE COEF(X,Y,N,A,B,IK)
         IK=0
         IF(N.LE.0) GO TO 10
         AN=N
         IK=1
         CALL PRODEL(X,Y,XY,N)
         CALL  SUMVEC(X,N,SX)
         CALL  SUMVEC(XY,N,SXY)
         CALL  SUMVEC(Y,N,SY)
         CALL  PATRAT(X,XN,SXX)
         A=(AN*SXY-SX*SY)/(AN*SXX-SX*SX)
         B=(SY-A*SX)/AN
10     CONTINUE
         RETURN
         END
Variabila IK este 0 dacă nu se calculează coeficienții că seriile de date sunt vide și IK=1 dacă acești coeficienți se calculează. Subprogramul COEF() se optimizează și dacă se elimină puzderia de apeluri de subprograme, dar devine mai mărișor și cu instrucțiuni ceva mai regrupate după cum urmează:
         SUBROUTINE COEF(X,Y,N,A,B,IK)
         IK=0
         IF(N.LE.0) GO TO 20
         AN=N
         IK=1
         SX=0.
         SY=0.
         SXX=0.
         SXY=0.
         DO   10  I=1,N
         SX=SX+X(I)
         SY=SY+Y(I)
         SXX=SXX+X(I)*X(I)
         SXY=SXY+X(I)*Y(I)
10     CONTINUE
         A=(AN*SXY-SX*SY)/(AN*SXX-SX*SX)
         B=(SY-A*SX)/AN
20     CONTINUE
         RETURN
         END
Dacă subprogramul ar fi scris în limbajul C++ cu siguranță că inițializările s-ar fi scris SX=SY=SXX=SXY=0.; ceea ce ar fi fost cu mult mai drăguț. Coeficienții ecuației de regresie simplă se calculează fie apelând tot felul de alte subprograme simple, fie scriind un subprogram ce include toate calculele. Trebuie ales un echilibru între a apela subprograme și a avea redundanță în program prin nereutilizare de componente de bibliotecă. Programatorul e suveran în programul pe care-l scrie și el alege dacă vrea să fie genial sau penibil, riscuș fiind în ambele cazuri 50% și 50%.



(29 decembrie 2017)

Thursday, December 28, 2017

Alegerea identificatorilor

În limbajul FORTRAN IV căci cu el se scriau programe până în 1977 numele de variabile care se construiau trebuiau să respecte următoarele reguuli:
- lungimea numelui de variabilă era maxim de 6 caractere;
- caracterele utilizate sunt literele mari A-Z, cifrele 0-9 și semnul $;
- primul caracter al numelui de variabilă este obligatoriu o literă.
Astfel, construcțiile:
VALOARE
COST
PROFIT
CERC
G981
$VAR
SUMA3
sunt nume de variabile corecte.
Construcțiile:
1RAZA   nu este corectă că are prim caracter altceva decât o literă;
RAZA+  nu este corectă că are simbolul + care nu este nici literă și nici cifră;
PR_PL    nu este corectă pentru că are în interior caracterul underscore cod HTML _;
A1234567B nu este corectă pentru că are mai mult de 6 caractere în componență.
Chiar dacă erau restricții așa de severe, programatorii de talent știau să aleagă astfel de denumiri ale variabilelor astfel încât să asigure un nivel de ortogonalitate pentru a nu le confunda unele cu altele. Se făceau o serie de convenții precum:
- variabila I era folosită pentru traversarea elementelor unui șir sau a liniilor matricei;
- variabila J era folosită pentru traversarea elementelor de pe coloanele unei matrice;
- variabila TEMP era folosită pentru rezultate temporare, ca și variabila AUX;
- variabilele M și N erau utilizate pentru a stabili număr de elemente sau de linii sau coloane;
- variabila XMED era folosită pentru media aritmetică;
- variabila DISP era folosită pentru dispersie;
- postfixul SORT era folosit pentru a marca faptul că rezultatul este sortat XSORT, YSORT;
- prefixul STOC era folosit pentru stocuri STOCPL, STOCRE, STOCEF;
- postfixul PL era utilizat pentru planificat, RE pentru realizat și EF pentru efectiv.
Fiecare programator își construia propriile reguli de a defini nume de variabile, dar ideia era ca programul să fie cât mai lizibil și el ca programator să nu depună eforturi inutile nici la depanare și nici la mentenanță, ci să meargă la sigur, având reguli pe care și le-a definit și le-a și respectat. 
Programatorii care au lucrat foarte ermtic, definind nume de variabile după niște reguli foarte codificate au avut mari probleme în a depana programele, căci este foarte dificil să se umble într-o secvență care pleacă de la o relație matematică de forma:
să fie recunoscută cu lejeritate în construcția:
S234=S65*S987*S987
în loc de a scrie:
SCERC=PI*R*R
Este rezonabil mai ales când se construiesc subprograme să se utilizeze modalități omogene de definire a numelor de variabile EPS pentru acel epsilon care controlează precizia, ITER pentru numărul de iterații și pentru variabila de stare IK sau ISTARE sau pentru codul de eroare IERR și toți programatorii vor folosi fără retitență bibliotecile de subprograme, altfel le vor evita că sunt greoaie. Alegerea identificatorilor intră în arta programatorilor și adevărații programatori au și reguli de a construi nume de variabile care săă facă programele livibile și ușor de manevrat, fără ca expresiile să fie groaznic de sofusticate. În FORTRAN IV nu există cuvinte cheie și programatorii ar avea la dispoziție să folosească DO, IF, READ, GO TO RETURN ca nume de variabile. M-am jucat și eu cândva cu acestă facilitate și noroc că a fost doar o joacă pentru că un program cu astfel de variabile este o calamitate la depanare, căci există riscul de a distruge din prea mult zel chiar instrucțiuni corect scrise.




(28 decembrie 2017)

Activarea și dezactivarea de termeni

În informatică nu este rezonabil să fie șterse nivi articole din fișiere și nici termeni ai seriilor de date. Ceea ce ar trebui șters, trebuie dezactivat. În acest sens se asociază fiecărui element din șir un alt element care are valoarea 0 dacă este considerat neactiv sau șters din punct de vedere logic și nu fizic. La fișiere în articol se definește un câmp de un byte care este 0 dacă articolul este neactiv sau șters logic și 1 dacă este activ. Prin testarea acelui câmp, dacă are valoarea 1 se for face prelucrări, iar sacă este zero nu va fi utilizat nici articolul și nici elementul din șir.
Subprogramul care însumează elementele active ale șirului X de N componente va avea un subprogram care mai primește ca parametru un vector LL tot de N componente și LL(I) =0 ceea  ce înseamnă că elementul nu este activ, este șters logic și nu intră în calcule, iar dacă LL(I)=1 elementul X(I) este activ și se folosește în prelucrări.

             SUBROUTINE SUMVEC (X,LL,N,SUM)
             SUM=0.

             DO  10 I=1,N
             IF(LL(I).EQ.0) GO TO 10

             SUM=SUM+X(I)
10         CONTINUE
             RETURN
             END
Activând și dezactivând termeni se construiesc tot felul de eșantioane și se verifică tot felul de ipoteze. Prin operații simple se procedează la reconstituirea de toturi de date fără a fi nevoie să se refacă nici seriile de date și nici fișiere. Acum în prelucrările moderne se lucrează în mod curent cu vectori sau câmpuri de stare fără a mai se proceda șa ștergeri de elemente sau la ștergeri de articole.


(28 decembrie 2017)

Calcul medie mobilă

Media mobilă este un indicator statistic utilizat în studierea tendinței pe care o manifestă un fenomen în evoluția sa în timp. Fiind dat un șir X1, x2, x3, ..., xn-1, xn, a calcula media mobilă de ordin doi înseamnă a evalua expresii de forma xmi=(xi+xi+1)/2 cu i=1,2,3,...,n-1. A calcula media mobilă de ordin trei înseamnă a evalua expresii de forma xmi=(xi-1+xi+xi+1)/3 cu i=2,3,4,...,n-1. 
Subprogramul care calculează media măbilă de ordin doi este:

             SUBROUTINE MMOB2(X,N,XM,NN)
             DO 10  I=1,N-1
             XM(I)=(X(I)+X(I+1))/2.
10         CONTINUE
             NN=N-1
             RETURN
             END
Subprogramul care calculează media măbilă de ordin treieste:

             SUBROUTINE MMOB3(X,N,XM,NN)
             DO 10  I=2,N-1
             XM(I)=(X(I-1)+X(I)+X(I+1))/3.
10         CONTINUE
             NN=N-2
             RETURN
             END
Există posibilitatea de a calcula mediile aritmetice în cascadă, adică medie aritmetică de ordin doi din termenii mediei aritmetice de ordin doi, ca în secvența:
........................
             CALL  MMOB2(X,N,XM,NN)
             CALL  MMOB2(XM,NN,XMM,NNN)
........................
XMM=((X(I)+2*X(I+1)+X(I+2))/4. și trendul evoluției unei serii dinamice se vede și mai bine.


(28 decembrie 2017)


     

Wednesday, December 27, 2017

Inversa matricei nesingulare

Inversarea matricei nesingulare este subprogramul cel mai căutat căci nenumărate aplicații folosesc inversa matricei, de la ecuația de regresie până la rezolvarea de sisteme liniare.
Am tot căutat subprograme pentru inversarea unei matrice și dintre toate am găsit unul interesant în cartea PROBLEME DE ANALIZĂ NUMERICĂ REZOLVATE CU CALCULATORUL avându-i ca autori pe acad. Gheorghe MARINESCU, Irona RIZZOLI, Ileana POPESCU și Cristina ȘTEFAN, carte publicată îmn Editura Academiei RSR, în anul 1987 și care la paginile 171-173 prezintă metoda iterativă HOTELLING-BODEWING de inversare a unei matrice. Se construiește șirul lui NEWTON de torma X(n+1) = X(n) +(I-X(n)*A)*X(n), unde A, I, X, sunt matrice pătrate cu m linii și m coloane, iar cifrele cuprinse între paranteze acolo la indici arată numărul iterației. X(n+1) înseamnă matricea X la iterația n+1, iar X(n) înseamnă matricea X la iterația n. I este matricea unitate, A este matricea ce trebuie inversată. Subprogramul are ca prim pas evaluarea expresiei X1=X0 +(I+X0*A)*X0. În final matricea X1 va conține matricea inversă, iar X0 este matricea de start care se obține prin convenție dintr-o evaluare de forma: X0 = 1./(maxaij) * I. Variabila maxaij este de fapt elementul maxim dintre elementele matricei A. În subprogramul INVMAT, X0 se va referi la matricea de la iterația precedentă și X1 se va referi la matyricea de la iterația următoare.
Se observă că aici trebuie să fie apelate alte subprograme precum:
- subprogram de copiere matrice;
- subprogram de adunare matrice;
- subprogram de scădere matrice;
- subprogram de calcul normă matrice;
- subprogram de înmulțire matrice.
Față de programul dat în cartea pe care am citat-o am făcut o serie de modificări, căci m-am gândit ca utilizatorul să fie scutit în a da el acolo valoarea de start X0, eroarea, criteriu de stopare a procesului iterativ și matricea unitate.
         SUBROUTINE START(A,N,X0)
         MAXAIJ=A(1,1)
         DO  10 I=1,N
         DO  10 J=1,N
         IF(MAXAIJ.GT.A(I,J)) GO TO 10
         MAXAIJ=A(I,J)
10     CONTINUE
         DO  20 I=1,N
         DO  20 J=1,N
20     X0(I,J)=0.
         ALFA=1./MAXAIJ
         DO  30 I=1,N
30     X0(I,I)=ALFA
         RETURN
         END
Această subrutină construiește matricea de start X0 ca fiind matricea unitate înmulțită cu inversul elementului maxim din matricea A.
Pentru scăderea a două matrice pătrate având n linii și n coloane se foolosește subprogramul:
         SUBROUTINE ADMAT(A,B,C,N)
         MAXAIJ=A(1,1)
         DO  10 I=1,N
         DO  10 J=1,N
         C(I,J)=A(I,J)+B(I,J) 
10     CONTINUE
         RETURN
         END
Pentru scăderea a două matrice pătrate având n linii și n coloane se foolosește subprogramul:
         SUBROUTINE ADMAT(A,B,C,N)
         MAXAIJ=A(1,1)
         DO  10 I=1,N
         DO  10 J=1,N
         C(I,J)=A(I,J)-B(I,J) 
10     CONTINUE
         RETURN
         END
Pentru copierea matricei A în matricea C, ambele având n linii și n coloane se foolosește subprogramul:
         SUBROUTINE SCMAT(A,C,N)
         MAXAIJ=A(1,1)
         DO  10 I=1,N
         DO  10 J=1,N
         C(I,J)=A(I,J)
10     CONTINUE
         RETURN
         END
Generarea unei matrice unitate de ordin n se face cu subprogramul:
         SUBROUTINE UNIMT(N,UNIT)
         DO  20 I=1,N
         DO  10 J=1,N
         UNIT(I,J)=0.
10     CONTINUE
         UNIT(I,I)=1.
20     CONTINUE
         RETURN
         END
Norma ANOR a matricei A este calculată cu subprogramul:
         SUBROUTINE NMMAT(A,N,ANOR)
         ANOR=ABS(A1,1))
         DO  20 I=1,N
         DO  10 J=1,N
         IF(ANOR.GT.ABS(A(I,J)) GO TO 10
         ANOR=ABS(A(I,J))
10     CONTINUE
         RETURN
         END
Pentru înmulțirea a două matrice A și B pătrate având n linii și n coloane, rezultatul fiind matricea C tot cu n linii și n coloane se foolosește subprogramul:
         SUBROUTINE PRMAT(A,C,N)
         MAXAIJ=A(1,1)
         DO  20 I=1,N
         DO  20 J=1,N
         CIJ=0.
         DO  10 K=1,N
         CIJ=CIJ+A(I,K)*B(K,J)
10     CONTINUE
         C(I,J)=CIJ
20     CONTINUE
         RETURN
         END
Subprogramul pentru calculul matricei inverse AINV a matricei A cu n linii și n coloane este:
         SUBROUTINE INVMAT(A,AINV,N,IK)
         ITER=0
         Q=.01
         EPS=.0001
         CALL START(A,N,X0)
10     CALL UNIMT(N,U)
         CALL PRMAT(A,X0,X1,N)
         CALL SCMAT(UNIT,X1,DIF,N)
         ITER=ITER+1
         CALL PRMAT(DIF,X0,X1,N)
         CALL ADMAT(X0,X1,X1,N)
         CALL NMMAT(X0,N,ANOR)
         IF(Q**ITER*ANOR/(1.-Q).LE.EPS) GO TO 20
         CALL CPMAT(X1,X0,N)        
         GO TO 10
20     CONTINUE
         CALL CPMAT(X1,AINV,N)
         RETURN
         END
Față de varianta inițială, aici sunt date valorile care dau finețea rezultatului, fără a da flexibilitate utilizatorului să obțină el precizia dorită, din dorința de a nu avea mulți paramertrii în listă.

(27 decembrie 2017)

Tuesday, December 26, 2017

Stabilirea tipului de triunghi

Dacă se dau numerele a,b și c trebuie văzut dacă acestea:
- sunt laturile unui triunghi;
- dacă este vorba de triunghi dreptunghic;
- dacă este vorba de triunghi isoscel;
- dacă este vorba de triunghi echilateral;
- dacă este vorba de triunghi oarecare.
Variabila IK=0 dacă a,b,b nu formează laturile unui triunghi, IK=1 dacă este vorba de un triunghi echilateral, IK=2 dacă este vprba de un triunghi dreptunghic oarecare, IK=3 dacă este un triunghi isoscel, IK=4 dacă este un triunghioarecare. IK=5 pentru variabile neinițializate corect.
Subprogramul este:
         SUBROUTINE COMPAR (A,B,C,IK)
         IF(A*B*C.LE.0) GO TO 5
         IK=0
         IF(((A+B).LT.C).OR.((A+C).LT.B).OR.((B+C).LT.A)) GO TO 10
         IK=1
         IF((A.EQ.B).AND.(A.EQ.C).AND.(B.EQ.C)) GO TO 10
         IK=2
         IF(((A*A+B*B).EQ.(C*C)).OR.((A*A+C*C).EQ.(B*B)).OR.((C*C+B*B).EQ.(A*A))) GO TO 10
         IK=3
         IF((A.EQ.B).OR.(A.EQ.C).OR.(B.EQ.C)) GO TO 10
         IK=4
         IF((A+B).GT.C).OR.((A+C).GR.B).OR.((B+C).GR.A)) GO TO 10
5       IK=5
10     CONTINUE
         RETURN
         END

(26 decembrie 2017)

Factorial de n

A calcula un factorial de n înseamnă a calcula produsul Fn =  1*2*3*4*5*...*(n-1)*n. este important ca produsul să fie astfel calculat încât după efectuarea ultimei înmulțiri să nu depășească valoarea maximă a unui întreg ce se memorează pe 4 bytes adică 2.147.483.647 adică 2 la puterea 31 din care se scade 1, căci din cei 32 de biți unul este de semn, iar cel mai mare număr pozitiv are 0 pe prima poziție și 1 pe toate celelalte 31 de poziții, adică numărul scris de mine, adică două miliarde și ceva.

         SUBROUTINE FACTOR (N,IFACT,IK)
         IK=0.
         IF(N.GT:xx) GO TO 20
         FACT=1
         DO 10 I=2,N
         FACT=FACT*I
10     CONTINUE
         IK=1
20     CONTINUE
         RETURN
         END
Pentru a vedea cine este xx se va scrie un subprogram unde se lucrează cu variabile de tip real și se va identifica cel mai mare N care nu duce la valoarea unui factorial care să nu fie memorat ca un întreg de 4 bytes. Programul scris de mine arată că xx este undeva la 12. Cine dorește să calculeze factorial pentru numere mai mari trebuie să se consoleze să lucreze cu obținerea unui rezultat de tip real pe 8 bytes, care are un exponent ce nu depășește valoarea 10 la puterea 75 și numărul de cifre semnificative nu depășește 16, deci precizia are de suferit. E o întreagă discuție și aici, căci lucrurile mult mai bine precizate sunt dacă se lucrează în baza 16. Magnitudinea este 10 la puterea 63, iar precizia este de14 cifre hexazecimale, iar în baza 10 se fac aproximații.

(26 decembrie 2017)

Verificare dacă n este număr prim

Dacă se consideră un număr N se pune problema să se vadă dacă este sau nu număr prim. Acest lucru se realizează prin împărțiri succesive la numere impare mai mici decât radicalul numărului N. Dar ca să nu fie efort făcut fără rost se verifică mai întâi dacă N este număr par. Subprogramul returnează IK=0 dacă numărul N nu este număr prim și IK=1 dacă numărul N este număr prim.

         SUBROUTINE COMPAR (N,IK)
         IK=0
         IF(MOD(N,2).EQ.0) GO TO 20
         A=N
         M=SQRT(A)
         DO 10 I=2,M
         IF(MOD(N,I).EQ.0) GO TO 20
10     CONTINUE
         IK=1
20     CONTINUE
         RETURN
         END




(26 decembrie 2017)

Numărarea elementelor matricei

Una dintre cele mai simple probleme este aceea de a număra elementele pozitive, elementele nule și elementele negative dintr-o matrice A cu m linii și n coloane.
         SUBROUTINE NUMAR (A,M,N,NRPOZ,NRNUL,NTNEG)
         NRPOZ=0
         NRNUL=0
         NRNEG=0
         DO 40 I=1,M
         DO 40 J=1,N
         IF(A(I,J)) 10,20,30
10     NRPOZ=NRPOZ+1
         GO TO 40 
20     NRNUL=NRNUL+1
         GO TO 40 
30     NRNEG=NRNEG+1      
40     CONTINUE
         RETURN
         END
Acest text sursă scris în C++ arată cu mult mai elegant:
..................
       nrpoz=nrnul=nrneg=0;
       if(a[i][j]>0) nrpoz++;
              else if(a[i][j]==0) nrnul++;
                      else nrneg++;
...................................
f[r[ niciun salt necondi'ionat ca ]n programul FORTRAN IV care are două, ceea ce justifică apropierea programatorilor de acest limbaj cu mult mai simplu și mai drăgălaș.


(26 decembrie 2017)

Concatenarea a două matrice

Condiția de a concatena matricele A și B este de a avea același număr de linii cadă prin concatenarea matricei B la matricea A înseamnă a lipi matricea B în dreapta matricei A. Dacă a concatena matricea B sub matricea A înseamnă că cele două matrice să aibe același număr de coloane. Prtopun ca prin concatenare să reculte o martrice C în care se copiază elementele matricelor A și B. 

         SUBROUTINE CONMTS (A,B,C,M,N)
         SUMAT=0.
         DO 10 I=1,M
         DO 10 J=1,N1
10     C(I,J)=A(I,J)
         DO 20 I=1,M
         DO 20 J=1,N2
20     C(I,N1+J)=B(I,J)
         RETURN
         END
Pentru concatenarea una sub alta:
         SUBROUTINE CONMTS (A,B,C,M,N)
         SUMAT=0.
         DO 10 I=1,M1
         DO 10 J=1,N
10     C(I,J)=A(I,J)
         DO 20 I=1,M2
         DO 20 J=1,N
20     C(M1+I,J)=B(I,J)
         RETURN
         END
Trebuie avut grijă la alocare ca matricea C să aibă suficiente linii sau coloane ca să suporte concatenarea.


(26 decembrie 2017)

Monday, December 25, 2017

Urma unei matrice

Urma unei matrice este suma elementelor de pe diagonala principală a matricei.
         SUBROUTINE ADMAT (A,M,N,URMA)
         URMA=0.
         DO 10 I=1,M
10     URMA)=URMA+A(I,I)
         RETURN
         END

Urma unei matrice se realizează și folosind adunarea elementelor unui șir după ce se copiază elementele diagonalei principale a matricei într-un șir. Asta numai pentru a face reutilizare de cod.
         SUBROUTINE CPYDIA (A,M,N,X)
         DO 10 I=1,M
10     X(I)=A(I,I)

         RETURN
         END
         SUBROUTINE SUMSIR (X,N,SUMA)
         SUMA=0.         
         DO 10 I=1,M
10     SUMA=SUMA+X(I)

         RETURN
         END
         SUBROUTINE URMAT (A,M,N,URMA)
         DIMENSION X(1)
         CALL CPYDIA (A,M,N,X)  
         CALL SUMSIR (X,N,SUMA)       
         URMA=SUMA

         RETURN
         END

(26 decembrie 2017)

Sume pe coloane într-o matrice

       Se consideră o matrice A cu m linii și n coloane și se pune problema caculului a n sume SUMCOL(J) cu j=1,2,3, ..., n pentru elementele de pe fiecare coloană.

         SUBROUTINE ADMAT (A,B,C,M,N)
         DO 10 J=1,N
         SUMCOL(J)=0.
         DO 10 I=1,M
10     SUMCOL(J))=SUMCOL(J)+A(I,J)
         RETURN
         END

sau ceva mai îmbunătățit din cauză că se referă o variab ilă elementară și nu una indexată ceea ce reduce numărul de cicluri mașină, numai că apar atribuiri în plus:

         SUBROUTINE ADMAT (A,B,C,M,N)
         DO 20 J=1,N
         SUMCOLJ=0.
         DO 10 I=1,M
10     SUMCOLJ=SUMCOLJ+A(I,J)
         SUMCOL(J)=SUMCOLJ
20     CONTINUE
         RETURN
         END
Sume pe coloane în matrice se fac în multe calcule statistice, dar rezultatele apar într-o linie alăturată din matrice, m+1.
         SUBROUTINE ADMAT (A,B,C,M,N)
         DO 20 J=1,N
         SUMCOLJ=0.
         DO 10 I=1,M
10     SUMCOLJ=SUMCOLJ+A(I,J)
         A(M+1,J)=SUMCOLJ
20     CONTINUE

         RETURN
         END


(26 decembrie 2017)                    

Sume pe linii în matrice

Se consideră o matrice A cu m linii și n coloane și se pune problema caculului a m sume SUMLIN(I) cu i=1,2,3, ..., m pentru elementele de pe fiecare linie.

         SUBROUTINE ADMAT (A,B,C,M,N)
         DO 10 I=1,M
         SUMLIN(I)=0.
         DO 10 J=1,N
10     SUMLIN(I)=SUMLIN(I)+A(I,J)
         RETURN
         END

sau ceva mai îmbunătățit din cauză că se referă o variab ilă elementară și nu una indexată ceea ce reduce numărul de cicluri mașină, numai că apar atribuiri în plus:

         SUBROUTINE ADMAT (A,B,C,M,N)
         DO 20 I=1,M
         SUMLINI=0.
         DO 10 J=1,N
10     SUMLINI=SUMLINI+A(I,J)
         SUMLIN(I)=SUMLINI
20     CONTINUE
         RETURN
         END
Sume pe linii în matrice se fac în multe calcule statistice, dar rezultatele apar într-o linie alăturată din matrice, coloana n+1.
         SUBROUTINE ADMAT (A,B,C,M,N)
         DO 20 I=1,M
         SUMLINI=0.
         DO 10 J=1,N
10     SUMLINI=SUMLINI+A(I,J)
         A(I,N+1)=SUMLINI
20     CONTINUE

         RETURN
         END


(26 decembrie 2017)