20 ! celor mai mici patrate folosind metoda Gauss-Newton 30 ! cu algoritmul Levenberg-Marquart 40 ! D. CIURCHEA 1993 50 !************************************************************** 60 !* P R O G R A M U L P R I N C I P A L * 70 !************************************************************** 80 RANDOMIZE(.75) 90 CALL CLEAR 100 !CREEN 2 110 ! 120 !------------- Specificarea variabilelor --------------- 130 ! 140 AA=1!Incepe evaluarea preciziei masinii 150 FOR I=1 TO 100 160 REPS=2^(-I) 170 IF AA=AA+REPS THEN 190 180 NEXT I 190 REPS=REPS*2 :: PRINT I-1,REPS :: ! Lungimea mantisei masinii. 200 FOR I=1 TO 70 :: A$=A$&" " :: NEXT I 210 NPCT=121! Nr. punctelor experimentale. 220 NPAR=5! nr. parametrilor din modelul teoretic. 230 DIM D(128)! Vector care contin spectrul experimental. 240 DIM DC(128)! Vector care contine spectrul calculat. 250 DIM W(5),V(5),VT(5),C$(8)! Vect. pt. param. modelului. 260 DIM A(5,5),X(5),B(5),G(5)! Rez. sist. liniar. 270 DIM AINV(5,5)! Calculul matricii inverse. 280 NSIG=5! Nr. cifrelor semn. in raportarea rez. final. 290 PREC=10^(-NSIG) 300 MAXFN=5000! Nr. max. de evaluari ale func. permis de util. 310 PRINT "FITAREA UNUI SPECTRU MOSSBAUER EXPERIMENTAL" 320 PRINT "Programul este in executie" 330 DATA 585,8.4,85,39,69 341 ! Datele experimentale 342 DATA 577,578,575,574,576,574,575,573,574 343 DATA 574,571,578,575,573,575,571,573,575,573 345 DATA 570,573,569,572,569,573,569,575,565,568 346 DATA 569,564,569,560,555,554,545,538,535,536 347 DATA 534,542,551,556,558,564,566,566,572,569 348 DATA 569,571,566,571,575,568,571,572,569,570 349 DATA 565,569,568,571,572,577,577,572,573,575 350 DATA 572,570,568,563,565,567,562,557,551,542 351 DATA 537,538,535,539,544,549,557,556,567,564 352 DATA 567,568,566,571,566,570,565,569,570,572 353 DATA 569,573,569,574,570,570,572,572,569,574 354 DATA 574,574,568,570,574,570,577,571,575,573,568,574 359 HEX$="0123456789ABCDEF" 360 RESTORE 330 :: FOR I=1 TO NPAR! Citeste param. adevarati ai spectrului 370 READ V(I)! experimental ai nitroprusiatului de Na. 375 W(I)=V(I) 380 NEXT I 390 RESTORE 342 :: FOR I=1 TO NPCT :: READ BB :: D(I)=BB :: NEXT I 400 !GOSUB 2480 :: GOSUB 3300 :: GOTO 2304 590 ALM=10!100 ! Parametrul Levenberg-Marquart. 630 EPS=SQR(REPS)!*32! Cst. pt. evaluarea derivatei numerice. 640 ! 650 !------------------ INITIALIZARE ----------------- 660 ! 670 FOR I=1 TO NPAR! Initializarea vectorului de lucru. 680 W(I)=V(I) 690 NEXT I 700 GOSUB 2480!Valorarea functiei cu parametrii initiali. 710 F0=F 720 ! 730 !-------------- INCEPUTUL PROCESULUI ITERATIV ------------- 740 ! 750 ! 760 !======= CONSTRUIREA SISTEMULUI LINIAR DE ECUATII ========== 770 ! 780 FOR I=1 TO NPAR! Init. mat. Hessian si a term. liberi. 790 FOR J=I TO NPAR 800 A(I,J)=0 810 A(J,I)=0 820 NEXT J 830 W(I)=V(I)! Actualizarea vectorului de lucru. 840 B(I)=0 850 NEXT I 860 ! 870 !------ Calculul derivatelor numerice in fiecare punct ------ 880 ! 890 GAM=V(2)*V(2)/4 900 FOR IP=1 TO NPCT 910 F1=V(1)-V(2)*V(3)/((IP-V(4))^2+GAM) 920 F1=F1-V(3)*V(2)/((IP-V(5)*2+V(4))^2+GAM) 930 ! F1 este o referinta pentru calculul derivatelor numerice 940 DIF=D(IP)-F1 950 FOR I=1 TO NPAR!Calc. comp.gradientului in punctul IP. 960 AA=ABS(V(I)) :: IF AA<.1 THEN AA=.1! Scala pas. 970 PAS=AA*EPS :: W(I)=V(I)+PAS! Pas deriv.num. 980 GAMW=W(2)*W(2)/4 990 F2=W(1)-W(2)*W(3)/((IP-W(4))^2+GAMW) 1000 F2=F2-W(3)*W(2)/((IP-W(5)*2+W(4))^2+GAMW) 1010 G(I)=(F2-F1)/PAS! Componenta gradientului. 1020 W(I)=V(I)! Refacerea vectorului de lucru. 1030 NEXT I 1040 ! 1050 !--- Calculul matricii Hessian, A si al term. liberi, B -- 1060 ! 1070 FOR I=1 TO NPAR 1080 FOR J=I+1 TO NPAR 1090 A(I,J)=A(I,J)+G(I)*G(J)! Mat. Hessian. 1100 A(J,I)=A(I,J) 1110 NEXT J 1120 A(I,I)=A(I,I)+G(I)*G(I) 1130 B(I)=B(I)+DIF*G(I)! Termenii liberi. 1140 NEXT I 1150 NEXT IP 1160 IFN=IFN+(NPAR*NPAR+NPAR)/2 1170 GOSUB 2640! Rezolvarea sist.liniar printr-o metoda adecvata. 1180 ! 1190 !=================== AJUSTAREA PASULUI ==================== 1200 ! 1210 IF INEF>6 OR IFN>MAXFN THEN 2060 1220 ALFA=1! Incercarea cu un pas cit mai mare 1230 GOSUB 3140 1240 F2=F 1250 IF F2>=F0 THEN 1290 1260 AL=ALFA 1270 F0=F2 1280 GOTO 1540 1290 ALFA=.5! Incercarea cu jumatatea pasului maxim 1300 GOSUB 3140 1310 F1=F 1320 IF F1>=F0 THEN 1360 1330 AL=ALFA 1340 F0=F1 1350 GOTO 1540 1360 ALFA=(3*F0-4*F1+F2)/4/(F0-F1-F1+F2) 1370 ! Ajust. pas. cu o parabola prin abscisele 0, 0.5, 1. 1380 GOSUB 3140 1390 IF F>=F0 THEN 1440 1400 AL=ALFA 1410 F0=F 1420 GOTO 1540 1430 ! 1440 !-------- Decizie pentru cautarea ineficienta ----------- 1450 ! 1460 !IF F0 >= F1 AND F0 >= F2 THEN 1270 1470 ALM=ALM*10.1! Se amplifica param. L-M. 1480 INEF=INEF+1 1490 GOSUB 2410! Schimba semnul si marimea corectiilor. 1500 GOTO 1210!Reia ajustarea pasului. 1510 ! 1520 ! ========== P R O G R E S I N C A U T A R E ========= 1530 ! 1540 ITN=ITN+1 1550 ALM=ALM/2 1560 INEF=0 1570 !CALL CLEAR 1580 FOR I=1 TO NPAR 1590 W(I)=V(I)+AL*X(I) 1600 !LOCATE 13+I,1 1610 DISPLAY AT(6+I,1):USING "v(#)=###.### ":I,V(I) 1620 !LOCATE 13 + I, 65 1630 !PRINT USING " w()=."; I; w(I) 1640 NEXT I 1650 DISPLAY AT(1,1):USING "alfa=###.###^^^^":AL 1660 DISPLAY AT(2,1):USING "Par.L-M=##.##^^^^":ALM 1670 DISPLAY AT(3,1):USING "itn=#####":ITN 1680 DISPLAY AT(4,1):USING "rez=#####.##":F0 1690 NQ=0! Testeaza cifrele semnif. in parametrii calculati. 1700 FOR I=1 TO NPAR 1710 IF ABS(V(I)/W(I)-1)NPAR THEN 2170 2140 A$="TERM.NORMALA." 2150 A$=A$&" ## CIFRE SEMNIF. IN ### ITERATII" 2160 DISPLAY AT(22,1):USING A$:NSIG,ITN :: GOTO 2230 2170 A$="TERM.ANORMALA " 2180 IF INEF=0 THEN 2210 2190 DISPLAY AT(22,1):A$&"datorata cautarii ineficiente" 2200 GOTO 2230 2210 IF IFN8 THEN CALL VCHAR(1,INT(I/8)+1,33,INT(MI/8)) 9141 MI=256 :: MA=0 :: C$(1),C$(2),C$(3),C$(4),C$(5),C$(6),C$(7),C$(8)=B$ 9144 FOR J=9 TO 16 STEP 2 :: K=D(INT(I/2)+INT(J/2)) :: C$(J-8)=RPT$("1",K-1)&"1"&RPT$("0",128-K) 9145 K1=DC(INT(I/2)+INT(J/2)) :: C$(J-7)=RPT$("0",K1-1)&"1"&RPT$("0",128-K1) 9146 MI=MIN(MI,K) :: MA=MAX(MA,K) :: MI=MIN(MI,K1) :: MA=MAX(MA,K1)!CATE SUNT PE VERTICALA 9147 NEXT J 9158 FOR J=INT(MI/8)*8+1 TO MA STEP 8 :: M$="" :: FOR R=1 TO 8 :: K=J+R-1 9160 LOW=VAL(SEG$(C$(5),K,1))*8+VAL(SEG$(C$(6),K,1))*4+VAL(SEG$(C$(7),K,1))*2+VAL(SEG$(C$(8),K,1))+1 9170 HIGH=VAL(SEG$(C$(1),K,1))*8+VAL(SEG$(C$(2),K,1))*4+VAL(SEG$(C$(3),K,1))*2+VAL(SEG$(C$(4),K,1))+1 9172 M$=M$&SEG$(HEX$,HIGH,1)&SEG$(HEX$,LOW,1) 9173 NEXT R 9180 BB=BB-1 :: CALL CHAR(BB,M$) :: CALL VCHAR(J/8+1,INT(I/8)+2,BB) :: NEXT J 9185 IF MI>8 THEN CALL VCHAR(1,INT(I/8)+2,33,INT(MI/8)) 9900 NEXT I!:: FOR I=9 TO 14 :: CALL COLOR(I,2,4) :: NEXT I 9910 RETURN