![]() |
Millepede-II
V04-00-00
|
00001 00002 ! Code converted using TO_F90 by Alan Miller 00003 ! Date: 2012-03-16 Time: 11:06:00 00004 00087 00194 00348 00350 PROGRAM mptwo 00351 USE mpmod 00352 USE mpdalc 00353 USE mptest1, ONLY: nplan,del,dvd 00354 USE mptest2, ONLY: nlyr,nmx,nmy,sdevx,sdevy 00355 00356 IMPLICIT NONE 00357 REAL :: andf 00358 REAL :: c2ndf 00359 REAL :: deltat 00360 REAL :: diff 00361 REAL :: err 00362 REAL :: gbu 00363 REAL :: gmati 00364 REAL :: rej 00365 REAL :: rloop1 00366 REAL :: rloop2 00367 REAL :: rstext 00368 REAL :: secnd 00369 REAL :: rst 00370 REAL ::rstp 00371 REAL, DIMENSION(2) :: ta 00372 INTEGER :: i 00373 INTEGER :: ii 00374 INTEGER :: ix 00375 INTEGER :: ixv 00376 INTEGER :: iy 00377 INTEGER :: k 00378 INTEGER :: kfl 00379 INTEGER :: lun 00380 INTEGER :: minut 00381 INTEGER :: nhour 00382 INTEGER :: nmxy 00383 INTEGER :: nrc 00384 INTEGER :: nsecnd 00385 INTEGER :: ntot 00386 INTEGER :: ntsec 00387 00388 CHARACTER (LEN=24) :: chdate 00389 CHARACTER (LEN=24) :: chost 00390 00391 INTEGER(KIND=large) :: rows 00392 INTEGER(KIND=large) :: cols 00393 00394 DOUBLE PRECISION :: sums(9) 00395 !$ INTEGER :: OMP_GET_NUM_PROCS,OMP_GET_MAX_THREADS 00396 !$ INTEGER :: MXTHRD 00397 !$ INTEGER :: NPROC 00398 00399 SAVE 00400 ! ... 00401 CALL etime(ta,rstp) 00402 CALL fdate(chdate) 00403 00404 ! millepede.log file 00405 lunlog=8 00406 lvllog=1 00407 CALL mvopen(lunlog,'millepede.log') 00408 CALL getenv('HOSTNAME',chost) 00409 IF (chost(1:1) == ' ') CALL getenv('HOST',chost) 00410 WRITE(*,*) '($Rev: 92 $)' 00411 !$ WRITE(*,*) 'using OpenMP (TM)' 00412 !#ifdef __GFORTRAN__ 00413 ! WRITE(*,111) __GNUC__ , __GNUC_MINOR__ , __GNUC_PATCHLEVEL__ 00414 !111 FORMAT(' compiled with gcc ',i0,'.',i0,'.',i0) 00415 !#endif 00416 WRITE(*,*) ' ' 00417 WRITE(*,*) ' < Millepede II-P starting ... ',chdate 00418 WRITE(*,*) ' ',chost 00419 WRITE(*,*) ' ' 00420 00421 WRITE(8,*) ' ' 00422 WRITE(8,*) 'Log-file Millepede II-P ', chdate 00423 WRITE(8,*) ' ', chost 00424 ! CALL MEGDEB ! debug switched on 00425 00426 ! read command line and text files 00427 00428 CALL filetc ! command line and steering file analysis 00429 CALL filetx ! read text files 00430 lvllog=mprint ! export print level 00431 IF (memdbg > 0) printflagalloc=1 ! debug memory management 00432 !$ WRITE(*,*) 00433 !$ NPROC=1 00434 !$ MXTHRD=1 00435 !$ NPROC=OMP_GET_NUM_PROCS() ! number of processors available 00436 !$ CALL OMP_SET_NUM_THREADS(MTHRD) ! set max number of threads to MTHRD 00437 !$ MXTHRD=OMP_GET_MAX_THREADS() ! get max number of threads back 00438 !$ WRITE(*,*) 'Number of processors available: ', NPROC 00439 !$ WRITE(*,*) 'Maximum number of OpenMP threads: ', MXTHRD 00440 !$ WRITE(*,*) 'Number of threads for processing: ', MTHRD 00441 !$ IF (MXREC.GT.0) MTHRDR=1 ! to get allways the same MXREC records 00442 !$ WRITE(*,*) 'Number of threads for reading: ', MTHRDR 00443 !$POMP INST INIT ! start profiling with ompP 00444 IF (ncache < 0) THEN 00445 ncache=25000000*mthrd ! default cache size (100 MB per thread) 00446 ENDIF 00447 rows=6; cols=mthrdr 00448 CALL mpalloc(readBufferInfo,rows,cols,'read buffer header') 00449 ! histogram file 00450 lun=7 00451 CALL mvopen(lun,'millepede.his') 00452 CALL hmplun(lun) ! unit for histograms 00453 CALL gmplun(lun) ! unit for xy data 00454 00455 ! debugging 00456 IF(nrecpr /= 0.OR.nrecp2 /= 0) THEN 00457 CALL mvopen(1,'mpdebug.txt') 00458 END IF 00459 00460 CALL etime(ta,rstext) 00461 times(0)=rstext-rstp ! time for text processing 00462 00463 ! preparation of data sub-arrays 00464 00465 CALL loop1 00466 CALL etime(ta,rloop1) 00467 times(1)=rloop1-rstext ! time for LOOP1 00468 00469 CALL loop2 00470 IF(chicut /= 0.0) THEN 00471 WRITE(8,*) 'Chi square cut equiv 3 st.dev applied ...' 00472 WRITE(8,*) ' in first iteration with factor',chicut 00473 WRITE(8,*) ' in second iteration with factor',chirem 00474 WRITE(8,*) ' (reduced by sqrt in next iterations)' 00475 END IF 00476 IF(lhuber /= 0) THEN 00477 WRITE(8,*) 'Down-weighting of outliers in', lhuber,' iterations' 00478 WRITE(8,*) 'Cut on downweight fraction',dwcut 00479 END IF 00480 00481 CALL etime(ta,rloop2) 00482 times(2)=rloop2-rloop1 ! time for LOOP2 00483 00484 ! use different solution methods 00485 00486 CALL mstart('Iteration') ! Solution module starting 00487 00488 ! CALL XEXECS ! all methods 00489 00490 CALL xloopn ! all methods 00491 00492 ! IF(NREJEC(1)+NREJEC(2)+NREJEC(3).NE.0) THEN 00493 ! WRITE(*,*) 'Data rejected in last loop: ',NREJEC(1), 00494 ! + ' (Ndf=0) ',NREJEC(2),' (huge) ',NREJEC(3),' (large)' 00495 ! END IF 00496 00497 00498 00499 ! ------------------------------------------------------------------ 00500 00501 IF(nloopn > 2.AND.nhistp /= 0) THEN ! last iteration 00502 CALL hmprnt(3) ! scaled residual of single measurement (with global deriv.) 00503 CALL hmprnt(12) ! scaled residual of single measurement (no global deriv.) 00504 CALL hmprnt(4) ! chi^2/Ndf 00505 END IF 00506 IF(nloopn > 2) THEN 00507 CALL hmpwrt(3) 00508 CALL hmpwrt(12) 00509 CALL hmpwrt(4) 00510 CALL gmpwrt(4) ! location, dispersion (res.) as a function of record nr 00511 IF (nloopn <= lfitnp) THEN 00512 CALL hmpwrt(13) 00513 CALL hmpwrt(14) 00514 CALL gmpwrt(5) 00515 END IF 00516 END IF 00517 IF(nhistp /= 0) THEN 00518 CALL gmprnt(1) 00519 CALL gmprnt(2) 00520 END IF 00521 CALL gmpwrt(1) ! output of xy data 00522 CALL gmpwrt(2) ! output of xy data 00523 ! 'track quality' per binary file 00524 IF (nfilb > 1) THEN 00525 CALL gmpdef(6,1,'log10(#records) vs file number') 00526 CALL gmpdef(7,1,'final rejection fraction vs file number') 00527 CALL gmpdef(8,1, & 00528 'final <Chi^2/Ndf> from accepted local fits vs file number') 00529 CALL gmpdef(9,1, '<Ndf> from accepted local fits vs file number') 00530 00531 DO i=1,nfilb 00532 kfl=kfd(2,i) 00533 nrc=-kfd(1,i) 00534 IF (nrc > 0) THEN 00535 rej=FLOAT(nrc-jfd(kfl))/FLOAT(nrc) 00536 CALL gmpxy(6,FLOAT(kfl),ALOG10(FLOAT(nrc))) ! log10(#records) vs file 00537 CALL gmpxy(7,FLOAT(kfl),rej) ! rejection fraction vs file 00538 END IF 00539 IF (jfd(kfl) > 0) THEN 00540 c2ndf=cfd(kfl)/FLOAT(jfd(kfl)) 00541 CALL gmpxy(8,FLOAT(kfl),c2ndf) ! <Chi2/NDF> vs file 00542 andf=FLOAT(dfd(kfl))/FLOAT(jfd(kfl)) 00543 CALL gmpxy(9,FLOAT(kfl),andf) ! <NDF> vs file 00544 END IF 00545 END DO 00546 IF(nhistp /= 0) THEN 00547 CALL gmprnt(6) 00548 CALL gmprnt(7) 00549 CALL gmprnt(8) 00550 CALL gmprnt(9) 00551 END IF 00552 CALL gmpwrt(6) ! output of xy data 00553 CALL gmpwrt(7) ! output of xy data 00554 CALL gmpwrt(8) ! output of xy data 00555 CALL gmpwrt(9) ! output of xy data 00556 END IF 00557 00558 IF(ictest == 1) THEN 00559 WRITE(*,*) ' ' 00560 WRITE(*,*) 'Misalignment test wire chamber' 00561 WRITE(*,*) ' ' 00562 00563 CALL hmpdef( 9,-0.0015,+0.0015,'True - fitted displacement') 00564 CALL hmpdef(10,-0.0015,+0.0015,'True - fitted Vdrift') 00565 DO i=1,4 00566 sums(i)=0.0D0 00567 END DO 00568 DO i=1,nplan 00569 diff=SNGL(-del(i)-globalParameter(i)) 00570 sums(1)=sums(1)+diff 00571 sums(2)=sums(2)+diff*diff 00572 diff=SNGL(-dvd(i)-globalParameter(100+i)) 00573 sums(3)=sums(3)+diff 00574 sums(4)=sums(4)+diff*diff 00575 END DO 00576 sums(1)=0.01D0*sums(1) 00577 sums(2)=SQRT(0.01D0*sums(2)) 00578 sums(3)=0.01D0*sums(3) 00579 sums(4)=SQRT(0.01D0*sums(4)) 00580 WRITE(*,143) 'Parameters 1 - 100: mean =',sums(1), 'rms =',sums(2) 00581 WRITE(*,143) 'Parameters 101 - 200: mean =',sums(3), 'rms =',sums(4) 00582 143 FORMAT(6X,a28,f9.6,3X,a5,f9.6) 00583 WRITE(*,*) ' ' 00584 WRITE(*,*) ' ' 00585 WRITE(*,*) ' I ' 00586 WRITE(*,*) ' --- ' 00587 DO i=1,100 00588 WRITE(*,102) i,-del(i),globalParameter(i),-del(i)-globalParameter(i), & 00589 -dvd(i),globalParameter(100+i),-dvd(i)-globalParameter(100+i) 00590 diff=SNGL(-del(i)-globalParameter(i)) 00591 CALL hmpent( 9,diff) 00592 diff=SNGL(-dvd(i)-globalParameter(100+i)) 00593 CALL hmpent(10,diff) 00594 END DO 00595 IF(nhistp /= 0) THEN 00596 CALL hmprnt( 9) 00597 CALL hmprnt(10) 00598 END IF 00599 CALL hmpwrt( 9) 00600 CALL hmpwrt(10) 00601 END IF 00602 IF(ictest > 1) THEN 00603 WRITE(*,*) ' ' 00604 WRITE(*,*) 'Misalignment test Si tracker' 00605 WRITE(*,*) ' ' 00606 00607 CALL hmpdef( 9,-0.0025,+0.0025,'True - fitted displacement X') 00608 CALL hmpdef(10,-0.025,+0.025,'True - fitted displacement Y') 00609 DO i=1,9 00610 sums(i)=0.0D0 00611 END DO 00612 nmxy=nmx*nmy 00613 ix=0 00614 iy=ntot 00615 DO i=1,nlyr 00616 DO k=1,nmxy 00617 ix=ix+1 00618 diff=SNGL(-sdevx((i-1)*nmxy+k)-globalParameter(ix)) 00619 sums(1)=sums(1)+1.0D0 00620 sums(2)=sums(2)+diff 00621 sums(3)=sums(3)+diff*diff 00622 ixv=globalParLabelIndex(2,ix) 00623 IF (ixv > 0.AND.metsol == 1.OR.metsol == 2) THEN 00624 ii=(ixv*ixv+ixv)/2 00625 gmati=SNGL(globalMatD(ii)) 00626 ERR=SQRT(ABS(gmati)) 00627 diff=diff/ERR 00628 sums(7)=sums(7)+1.0D0 00629 sums(8)=sums(8)+diff 00630 sums(9)=sums(9)+diff*diff 00631 END IF 00632 END DO 00633 IF (MOD(i,3) == 1) THEN 00634 DO k=1,nmxy 00635 iy=iy+1 00636 diff=-SNGL(sdevy((i-1)*nmxy+k)-globalParameter(iy)) 00637 sums(4)=sums(4)+1.0D0 00638 sums(5)=sums(5)+diff 00639 sums(6)=sums(6)+diff*diff 00640 ixv=globalParLabelIndex(2,iy) 00641 IF (ixv > 0.AND.metsol == 1.OR.metsol == 2) THEN 00642 ii=(ixv*ixv+ixv)/2 00643 gmati=SNGL(globalMatD(ii)) 00644 ERR=SQRT(ABS(gmati)) 00645 diff=diff/ERR 00646 sums(7)=sums(7)+1.0D0 00647 sums(8)=sums(8)+diff 00648 sums(9)=sums(9)+diff*diff 00649 END IF 00650 END DO 00651 END IF 00652 END DO 00653 sums(2)=sums(2)/sums(1) 00654 sums(3)=SQRT(sums(3)/sums(1)) 00655 sums(5)=sums(5)/sums(4) 00656 sums(6)=SQRT(sums(6)/sums(4)) 00657 WRITE(*,143) 'Parameters 1 - 500: mean =',sums(2), 'rms =',sums(3) 00658 WRITE(*,143) 'Parameters 501 - 700: mean =',sums(5), 'rms =',sums(6) 00659 IF (sums(7) > 0.5D0) THEN 00660 sums(8)=sums(8)/sums(7) 00661 sums(9)=SQRT(sums(9)/sums(7)) 00662 WRITE(*,143) 'Parameter pulls, all: mean =',sums(8), 'rms =',sums(9) 00663 END IF 00664 WRITE(*,*) ' ' 00665 WRITE(*,*) ' ' 00666 WRITE(*,*) ' I ' 00667 WRITE(*,*) ' --- ' 00668 ix=0 00669 iy=ntot 00670 DO i=1,nlyr 00671 DO k=1,nmxy 00672 ix=ix+1 00673 diff=SNGL(-sdevx((i-1)*nmxy+k)-globalParameter(ix)) 00674 CALL hmpent( 9,diff) 00675 WRITE(*,102) ix,-sdevx((i-1)*nmxy+k),globalParameter(ix),-diff 00676 END DO 00677 END DO 00678 DO i=1,nlyr 00679 IF (MOD(i,3) == 1) THEN 00680 DO k=1,nmxy 00681 iy=iy+1 00682 diff=SNGL(-sdevy((i-1)*nmxy+k)-globalParameter(iy)) 00683 CALL hmpent(10,diff) 00684 WRITE(*,102) iy,-sdevy((i-1)*nmxy+k),globalParameter(iy),-diff 00685 END DO 00686 END IF 00687 END DO 00688 IF(nhistp /= 0) THEN 00689 CALL hmprnt( 9) 00690 CALL hmprnt(10) 00691 END IF 00692 CALL hmpwrt( 9) 00693 CALL hmpwrt(10) 00694 END IF 00695 00696 IF(nrec1+nrec2 > 0) THEN 00697 WRITE(8,*) ' ' 00698 IF(nrec1 > 0) THEN 00699 WRITE(8,*) 'Record',nrec1,' has largest residual:',value1 00700 END IF 00701 IF(nrec2 > 0) THEN 00702 WRITE(8,*) 'Record',nrec2,' has largest Chi^2/Ndf:',value2 00703 END IF 00704 END IF 00705 IF(nrec3 < maxi4) THEN 00706 WRITE(8,*) 'Record',nrec3, ' is first with error (rank deficit/NaN)' 00707 END IF 00708 WRITE(8,*) ' ' 00709 WRITE(8,*) 'In total 2 +',nloopn,' loops through the data files' 00710 IF (mnrsit > 0) THEN 00711 WRITE(8,*) ' ' 00712 WRITE(8,*) 'In total ',mnrsit,' internal MINRES iterations' 00713 END IF 00714 00715 WRITE(8,103) times(0),times(1),times(2),times(4),times(7), & 00716 times(5),times(8),times(3),times(6) 00717 CALL etime(ta,rst) 00718 deltat=rst-rstp 00719 ntsec=nint(deltat) 00720 CALL sechms(deltat,nhour,minut,secnd) 00721 nsecnd=nint(secnd) ! round 00722 WRITE(8,*) 'Total time =',ntsec,' seconds =',nhour,' h',minut, & 00723 ' m',nsecnd,' seconds' 00724 CALL fdate(chdate) 00725 WRITE(8,*) 'end ', chdate 00726 gbu=4.02E-9*FLOAT(maxwordsalloc) ! GB used 00727 WRITE(8,*) ' ' 00728 WRITE(8,105) gbu 00729 00730 ! Rejects ---------------------------------------------------------- 00731 00732 IF(nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) /= 0) THEN 00733 WRITE(8,*) ' ' 00734 WRITE(8,*) 'Data rejected in last iteration: ' 00735 WRITE(8,*) ' ', & 00736 nrejec(0), ' (rank deficit/NaN) ',nrejec(1),' (Ndf=0) ', & 00737 nrejec(2), ' (huge) ',nrejec(3),' (large)' 00738 WRITE(8,*) ' ' 00739 END IF 00740 CALL explfc(8) 00741 00742 WRITE(*,*) ' ' 00743 WRITE(*,*) ' < Millepede II-P ending ... ', chdate ! with exit code',ITEXIT,' >' 00744 WRITE(*,*) ' ' 00745 gbu=4.0E-9*FLOAT(maxwordsalloc) ! GB used 00746 WRITE(*,105) gbu 00747 WRITE(*,*) ' ' 00748 00749 102 FORMAT(2X,i4,2X,3F10.5,2X,3F10.5) 00750 103 FORMAT(' Times [in sec] for text processing',f12.3/ & 00751 ' LOOP1',f12.3/ & 00752 ' LOOP2',f12.3/ & 00753 ' func. value ',f12.3,' *',f4.0/ & 00754 ' func. value, global matrix, solution',f12.3,' *',f4.0/ & 00755 ' new solution',f12.3,' *',f4.0/) 00756 105 FORMAT(' Peak dynamic memory allocation: ',f11.6,' GB') 00757 END PROGRAM mptwo ! Mille 00758 00759 00766 00767 SUBROUTINE solglo(ivgbi) 00768 USE mpmod 00769 00770 IMPLICIT NONE 00771 REAL :: dpa 00772 REAL :: err 00773 REAL :: gcor2 00774 REAL :: par 00775 INTEGER :: iph 00776 INTEGER :: istop 00777 INTEGER :: itgbi 00778 INTEGER :: itgbl 00779 INTEGER :: itn 00780 INTEGER :: itnlim 00781 INTEGER :: nout 00782 00783 INTEGER, INTENT(IN) :: ivgbi 00784 00785 DOUBLE PRECISION :: shift 00786 DOUBLE PRECISION :: rtol 00787 DOUBLE PRECISION :: anorm 00788 DOUBLE PRECISION :: acond 00789 DOUBLE PRECISION :: rnorm 00790 DOUBLE PRECISION :: ynorm 00791 DOUBLE PRECISION :: gmati 00792 DOUBLE PRECISION :: diag 00793 INTEGER(KIND=large) :: ijadd 00794 INTEGER(KIND=large) :: jk 00795 INTEGER(KIND=large) :: ii 00796 LOGICAL :: checka 00797 EXTERNAL avprod, mcsolv, mvsolv 00798 SAVE 00799 DATA iph/0/ 00800 ! ... 00801 IF(iph == 0) THEN 00802 iph=1 00803 WRITE(*,101) 00804 END IF 00805 itgbi=globalParVarToTotal(ivgbi) 00806 itgbl=globalParLabelIndex(1,itgbi) 00807 00808 globalVector=0.0D0 ! reset rhs vector IGVEC 00809 globalVector(ivgbi)=1.0D0 00810 00811 ! NOUT =6 00812 nout =0 00813 itnlim=200 00814 shift =0.0D0 00815 rtol = mrestl ! from steering 00816 checka=.FALSE. 00817 00818 IF(mbandw == 0) THEN ! default preconditioner 00819 CALL minres(nagb,globalVector, & 00820 workspaceD(1), workspaceD(1+nagb), workspaceD(1+2*nagb), & 00821 workspaceD(1+3*nagb),workspaceD(1+4*nagb),workspaceD(1+5*nagb), & 00822 globalCorrections,workspaceMinres, avprod, mcsolv, checka ,.TRUE. , shift, & 00823 nout , itnlim, rtol, istop, itn, anorm, acond, rnorm, ynorm) 00824 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner 00825 CALL minres(nagb,globalVector, & 00826 workspaceD(1), workspaceD(1+nagb), workspaceD(1+2*nagb), & 00827 workspaceD(1+3*nagb),workspaceD(1+4*nagb),workspaceD(1+5*nagb), & 00828 globalCorrections,workspaceMinres, avprod, mvsolv, checka ,.TRUE. , shift, & 00829 nout, itnlim, rtol, istop, itn, anorm, acond, rnorm, ynorm) 00830 ELSE 00831 CALL minres(nagb,globalVector, & 00832 workspaceD(1), workspaceD(1+nagb), workspaceD(1+2*nagb), & 00833 workspaceD(1+3*nagb),workspaceD(1+4*nagb),workspaceD(1+5*nagb), & 00834 globalCorrections,workspaceMinres, avprod, mvsolv, checka ,.FALSE., shift, & 00835 nout, itnlim, rtol, istop, itn, anorm, acond, rnorm, ynorm) 00836 END IF 00837 00838 ! subroutine MINRES( n, b, r1, r2, v, w, w1, w2, x, y, 00839 ! $ AVPROD, Msolve, .TRUE. , .FALSE. , SHIFT, 00840 ! $ NOUT , ITNLIM, rtol, 00841 ! $ ISTOP, ITN, Anorm, Acond, rnorm, ynorm ) 00842 00843 par=SNGL(globalParameter(itgbi)) 00844 dpa=par-globalParStart(itgbi) 00845 gmati=globalCorrections(ivgbi) 00846 ERR=SQRT(ABS(SNGL(gmati))) 00847 IF(gmati < 0.0D0) ERR=-ERR 00848 IF(matsto == 1) THEN ! normal matrix ! ??? 00849 ii=ivgbi 00850 jk=(ii*ii+ii)/2 00851 ELSE IF(matsto == 2) THEN ! sparse matrix 00852 jk=ijadd(ivgbi,ivgbi) 00853 END IF 00854 IF (jk > 0) THEN 00855 diag=globalMatD(jk) 00856 ELSE 00857 diag=DBLE(globalMatF(-jk)) 00858 END IF 00859 gcor2=SNGL(1.0D0-1.0D0/(gmati*diag)) ! global correlation (squared) 00860 WRITE(*,102) itgbl,par,globalParPreSigma(itgbi),dpa,ERR,gcor2,itn 00861 101 FORMAT(1X,' label parameter presigma differ', & 00862 ' Error gcor^2 iit'/ 1X,'---------',2X,5('-----------'),2X,'----') 00863 102 FORMAT(i10,2X,4G12.4,f7.4,i6,i4) 00864 END SUBROUTINE solglo 00865 00867 SUBROUTINE addcst 00868 USE mpmod 00869 00870 IMPLICIT NONE 00871 REAL :: climit 00872 REAL :: factr 00873 REAL :: hugeVal 00874 REAL :: sgm 00875 00876 INTEGER :: i 00877 INTEGER :: icgb 00878 INTEGER :: irhs 00879 INTEGER :: itgbi 00880 INTEGER :: ivgb 00881 INTEGER :: l 00882 INTEGER :: label 00883 INTEGER :: nop 00884 INTEGER :: inone 00885 00886 DOUBLE PRECISION :: rhs 00887 DOUBLE PRECISION :: drhs(4) 00888 INTEGER :: idrh (4) 00889 SAVE 00890 ! ... 00891 nop=0 00892 hugeVal=1.0 ! E6 00893 IF(lenConstraints == 0) RETURN ! no constraints 00894 climit=1.0E-5 ! limit for printout 00895 irhs=0 ! number of values in DRHS(.), to be printed 00896 00897 i=1 00898 DO icgb=1,ncgb 00899 rhs=listConstraints(i )%value ! right hand side 00900 sgm=listConstraints(i+1)%value ! sigma parameter 00901 i=i+2 00902 DO 00903 label=listConstraints(i)%label 00904 factr=listConstraints(i)%value 00905 itgbi=inone(label) ! -> ITGBI= index of parameter label 00906 ivgb =globalParLabelIndex(2,itgbi) ! -> variable-parameter index 00907 00908 IF(icalcm == 1.AND.ivgb > 0) THEN 00909 CALL mupdat(nvgb+icgb,ivgb,DBLE(hugeVal*factr)) ! add to matrix 00910 END IF 00911 00912 rhs=rhs-factr*globalParameter(itgbi) ! reduce residuum 00913 i=i+1 00914 IF(i > lenConstraints) EXIT 00915 IF(listConstraints(i)%label == 0) EXIT 00916 END DO 00917 IF(ABS(rhs) > climit) THEN 00918 irhs=irhs+1 00919 idrh(irhs)=icgb 00920 drhs(irhs)=rhs 00921 nop=1 00922 IF(irhs == 4) THEN 00923 WRITE(*,101) (idrh(l),drhs(l),l=1,irhs) 00924 irhs=0 00925 END IF 00926 END IF 00927 IF(rhs == 0.0) rhs=1.0E-9 00928 globalVector(nvgb+icgb)=rhs*hugeVal 00929 END DO 00930 00931 IF(irhs /= 0) THEN 00932 WRITE(*,101) (idrh(l),drhs(l),l=1,irhs) 00933 END IF 00934 IF(nop == 0) RETURN 00935 WRITE(*,102) ' Constraints: only equation values >', climit,' are printed' 00936 101 FORMAT(' ',4(i4,g11.3)) 00937 102 FORMAT(a,g11.2,a) 00938 END SUBROUTINE addcst 00939 00943 00944 SUBROUTINE feasma 00945 USE mpmod 00946 USE mpdalc 00947 00948 IMPLICIT NONE 00949 REAL :: factr 00950 REAL :: sgm 00951 INTEGER :: i 00952 INTEGER :: icgb 00953 INTEGER :: ij 00954 INTEGER :: itgbi 00955 INTEGER :: ivgb 00956 INTEGER :: j 00957 INTEGER :: l 00958 INTEGER :: label 00959 INTEGER :: nrank 00960 INTEGER :: inone 00961 00962 DOUBLE PRECISION:: rhs 00963 INTEGER(KIND=large):: length 00964 DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: vecConstraints 00965 DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: matConstraintsT 00966 DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: auxVectorD 00967 INTEGER, DIMENSION(:), ALLOCATABLE :: auxVectorI 00968 SAVE 00969 ! ... 00970 IF(lenConstraints == 0) RETURN ! no constraints 00971 00972 length=(ncgb*ncgb+ncgb)/2 00973 CALL mpalloc(matConsProduct, length, 'product matrix of constraints') 00974 matConsProduct=0.0D0 00975 length=ncgb 00976 CALL mpalloc(vecConsResiduals, length, 'residuals of constraints') 00977 CALL mpalloc(vecConstraints,length,'rhs vector') ! double precision vector 00978 CALL mpalloc(auxVectorI,length,'auxiliary array (I)') ! int aux 1 00979 CALL mpalloc(auxVectorD,length,'auxiliary array (D)') ! double aux 1 00980 ! constraint matrix A and product A A^T (A is stored as transposed) 00981 length = ncgb*nvgb 00982 CALL mpalloc(matConstraintsT,length,'transposed matrix of constraints') 00983 matConstraintsT=0.0D0 00984 00985 i=1 00986 DO icgb=1,ncgb 00987 rhs=listConstraints(i )%value ! right hand side 00988 sgm=listConstraints(i+1)%value ! sigma parameter 00989 i=i+2 00990 DO 00991 label=listConstraints(i)%label 00992 factr=listConstraints(i)%value 00993 itgbi=inone(label) ! -> ITGBI= index of parameter label 00994 ivgb =globalParLabelIndex(2,itgbi) ! -> variable-parameter index 00995 IF(ivgb > 0) matConstraintsT(icgb+(ivgb-1)*ncgb)=factr ! matrix element 00996 rhs=rhs-factr*globalParameter(itgbi) ! reduce residuum 00997 i=i+1 00998 IF(i > lenConstraints) EXIT 00999 IF(listConstraints(i)%label == 0) EXIT 01000 END DO 01001 vecConstraints(icgb)=rhs ! constraint discrepancy 01002 END DO 01003 01004 DO l=1,nvgb 01005 ij=0 01006 DO i=1,ncgb 01007 DO j=1,i 01008 ij=ij+1 01009 matConsProduct(ij)=matConsProduct(ij)+matConstraintsT((l-1)*ncgb+i)*matConstraintsT((l-1)*ncgb+j) 01010 END DO 01011 END DO 01012 END DO 01013 01014 ! inversion of product matrix of constraints 01015 CALL sqminv(matConsProduct,vecConstraints,ncgb,nrank, auxVectorD, auxVectorI) 01016 01017 nmiss1=ncgb-nrank 01018 01019 WRITE(*,*) ' ' 01020 WRITE(*,*) 'Rank of product matrix of constraints is',nrank, & 01021 ' for',ncgb,' constraint equations' 01022 WRITE(8,*) 'Rank of product matrix of constraints is',nrank, & 01023 ' for',ncgb,' constraint equations' 01024 IF(nrank < ncgb) THEN 01025 WRITE(*,*) 'Warning: insufficient constraint equations!' 01026 WRITE(8,*) 'Warning: insufficient constraint equations!' 01027 IF (iforce == 0) THEN 01028 isubit=1 01029 WRITE(*,*) ' --> enforcing SUBITO mode' 01030 WRITE(8,*) ' --> enforcing SUBITO mode' 01031 END IF 01032 END IF 01033 01034 CALL mpdealloc(matConstraintsT) 01035 CALL mpdealloc(auxVectorD) 01036 CALL mpdealloc(auxVectorI) 01037 CALL mpdealloc(vecConstraints) 01038 01039 RETURN 01040 END SUBROUTINE feasma ! matrix for feasible solution 01041 01049 SUBROUTINE feasib(concut,iact) 01050 USE mpmod 01051 USE mpdalc 01052 01053 IMPLICIT NONE 01054 REAL :: factr 01055 REAL :: sgm 01056 INTEGER :: i 01057 INTEGER :: icgb 01058 INTEGER :: iter 01059 INTEGER :: itgbi 01060 INTEGER :: ivgb 01061 INTEGER :: label 01062 INTEGER :: inone 01063 01064 REAL, INTENT(IN) :: concut 01065 INTEGER, INTENT(OUT) :: iact 01066 01067 DOUBLE PRECISION :: rhs 01068 DOUBLE PRECISION ::sum1 01069 DOUBLE PRECISION ::sum2 01070 DOUBLE PRECISION ::sum3 01071 INTEGER(KIND=large) :: length 01072 01073 ! ! acts on subarray "0" 01074 DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: auxVectorD 01075 DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: vecCorrections 01076 SAVE 01077 01078 iact=0 01079 IF(lenConstraints == 0) RETURN ! no constraints 01080 01081 DO iter=1,2 01082 vecConsResiduals=0.0D0 01083 01084 ! calculate right constraint equation discrepancies 01085 i=1 01086 DO icgb=1,ncgb 01087 rhs=listConstraints(i )%value ! right hand side 01088 sgm=listConstraints(i+1)%value ! sigma parameter 01089 i=i+2 01090 DO 01091 label=listConstraints(i)%label 01092 factr=listConstraints(i)%value 01093 itgbi=inone(label) ! -> ITGBI= index of parameter label 01094 rhs=rhs-factr*globalParameter(itgbi) ! reduce residuum 01095 i=i+1 01096 IF(i > lenConstraints) EXIT 01097 IF(listConstraints(i)%label == 0) EXIT 01098 ENDDO 01099 vecConsResiduals(icgb)=rhs ! constraint discrepancy 01100 END DO 01101 01102 ! constraint equation discrepancies ------------------------------- 01103 01104 sum1=0.0D0 01105 sum2=0.0D0 01106 sum3=0.0D0 01107 DO icgb=1,ncgb 01108 sum1=sum1+vecConsResiduals(icgb)**2 01109 sum2=sum2+ABS(vecConsResiduals(icgb)) 01110 sum3=MAX(sum3,ABS(vecConsResiduals(icgb))) 01111 END DO 01112 sum1=SQRT(sum1/dfloat(ncgb)) 01113 sum2=sum2/dfloat(ncgb) 01114 01115 IF(iter == 1.AND.sum1 < concut) RETURN ! do nothing if correction small 01116 01117 IF(iter == 1.AND.ncgb <= 12) THEN 01118 WRITE(*,*) ' ' 01119 WRITE(*,*) 'Constraint equation discrepancies:' 01120 WRITE(*,101) (icgb,vecConsResiduals(icgb),icgb=1,ncgb) 01121 101 FORMAT(4X,4(i5,g12.4)) 01122 WRITE(*,103) concut 01123 103 FORMAT(10X,' Cut on rms value is',g8.1) 01124 END IF 01125 01126 IF(iact == 0) THEN 01127 WRITE(*,*) ' ' 01128 WRITE(*,*) 'Improve constraints' 01129 END IF 01130 iact=1 01131 01132 WRITE(*,102) iter,sum1,sum2,sum3 01133 102 FORMAT(i6,' rms',g12.4,' avrg_abs',g12.4,' max_abs',g12.4) 01134 01135 length=ncgb 01136 CALL mpalloc(auxVectorD,length,'auxiliary vector (D)') 01137 length=nvgb 01138 CALL mpalloc(vecCorrections,length,'constraint corrections') 01139 vecCorrections=0.0D0 01140 01141 ! multiply inverse matrix and constraint vector 01142 CALL dbsvx(matConsProduct,vecConsResiduals,auxVectorD,ncgb) 01143 01144 i=1 01145 DO icgb=1,ncgb 01146 rhs=listConstraints(i )%value ! right hand side 01147 sgm=listConstraints(i+1)%value ! sigma parameter 01148 i=i+2 01149 DO 01150 label=listConstraints(i)%label 01151 factr=listConstraints(i)%value 01152 itgbi=inone(label) ! -> ITGBI= index of parameter label 01153 ivgb =globalParLabelIndex(2,itgbi) ! -> variable-parameter index 01154 IF(ivgb > 0) THEN 01155 vecCorrections(ivgb)=vecCorrections(ivgb)+auxVectorD(icgb)*factr 01156 END IF 01157 i=i+1 01158 IF(i > lenConstraints) EXIT 01159 IF(listConstraints(i)%label == 0) EXIT 01160 ENDDO 01161 END DO 01162 01163 DO i=1,nvgb ! add corrections 01164 itgbi=globalParVarToTotal(i) 01165 globalParameter(itgbi)=globalParameter(itgbi)+vecCorrections(i) 01166 END DO 01167 01168 CALL mpdealloc(vecCorrections) 01169 CALL mpdealloc(auxVectorD) 01170 01171 END DO ! iteration 1 and 2 01172 01173 END SUBROUTINE feasib ! make parameters feasible 01174 01207 SUBROUTINE peread(more) 01208 USE mpmod 01209 01210 IMPLICIT NONE 01211 INTEGER :: i 01212 INTEGER :: iact 01213 INTEGER :: ierrc 01214 INTEGER :: ierrf 01215 INTEGER :: inder 01216 INTEGER :: ioffp 01217 INTEGER :: ithr 01218 INTEGER :: jfile 01219 INTEGER :: jrec 01220 INTEGER :: k 01221 INTEGER :: kfile 01222 INTEGER :: l 01223 INTEGER :: lun 01224 INTEGER :: mpri 01225 INTEGER :: n 01226 INTEGER :: nact 01227 INTEGER :: nbuf 01228 INTEGER :: ndata 01229 INTEGER :: noff 01230 INTEGER :: npointer 01231 INTEGER :: npri 01232 INTEGER :: nr 01233 INTEGER :: nrc 01234 INTEGER :: nrd 01235 INTEGER :: nrpr 01236 INTEGER :: nthr 01237 INTEGER :: ntot 01238 INTEGER :: maxRecordSize 01239 INTEGER :: maxRecordFile 01240 01241 INTEGER, INTENT(OUT) :: more 01242 01243 LOGICAL :: lprint 01244 LOGICAL :: floop 01245 LOGICAL :: eof 01246 DOUBLE PRECISION :: ds0 01247 DOUBLE PRECISION :: ds1 01248 DOUBLE PRECISION :: ds2 01249 DOUBLE PRECISION :: dw 01250 !$ INTEGER :: OMP_GET_THREAD_NUM 01251 SAVE 01252 01253 inder(i)=readBufferDataI(i) 01254 01255 DATA lprint/.TRUE./ 01256 DATA floop/.TRUE./ 01257 DATA npri / 0 /, mpri / 1000 / 01258 ! ... 01259 IF(ifile == 0) THEN ! start/restart 01260 nrec=0 01261 ntot=0 01262 sumRecords=0 01263 skippedRecords=0 01264 numBlocks=0 01265 minRecordsInBlock=size(readBufferDataI) 01266 maxRecordsInBlock=0 01267 readBufferInfo=0 ! reset management info 01268 nrpr=1 01269 nthr=mthrdr 01270 nact=0 ! active threads (have something still to read) 01271 DO k=1,nthr 01272 IF (ifile < nfilb) THEN 01273 ifile=ifile+1 01274 readBufferInfo(1,k)=ifile 01275 readBufferInfo(2,k)=nact 01276 nact=nact+1 01277 END IF 01278 END DO 01279 END IF 01280 nPointer=size(readBufferPointer)/nact 01281 nData=size(readBufferDataI)/nact 01282 more=-1 01283 DO k=1,nthr 01284 iact=readBufferInfo(2,k) 01285 readBufferInfo(4,k)=0 ! reset counter 01286 readBufferInfo(5,k)=iact*nData ! reset offset 01287 END DO 01288 numBlocks=numBlocks+1 ! new block 01289 01290 !$OMP PARALLEL & 01291 !$OMP DEFAULT(PRIVATE) & 01292 !$OMP SHARED(readBufferInfo,readBufferPointer,readBufferDataI,readBufferDataF, & 01293 !$OMP nPointer,nData,skippedRecords,ndimbuf,NTHR,NFILF,FLOOP, & 01294 !$OMP IFD,KFD,IFILE,NFILB,WFD,XFD) & 01295 !$OMP NUM_THREADS(NTHR) 01296 01297 ithr=1 01298 !$ ITHR=OMP_GET_THREAD_NUM()+1 ! thread number 01299 jfile=readBufferInfo(1,ithr) ! file index 01300 iact =readBufferInfo(2,ithr) ! active thread number 01301 jrec =readBufferInfo(3,ithr) ! records read 01302 ioffp=iact*nPointer 01303 01304 files: DO WHILE (jfile > 0) 01305 kfile=kfd(2,jfile) 01306 records: DO 01307 nbuf=readBufferInfo(4,ithr)+1 01308 noff=readBufferInfo(5,ithr)+2 ! 2 header words per record 01309 nr=ndimbuf 01310 IF(kfile <= nfilf) THEN ! Fortran file 01311 lun=kfile+10 01312 READ(lun,IOSTAT=ierrf) n,(readBufferDataF(noff+i),i=1,min(n/2,nr)),& 01313 (readBufferDataI(noff+i),i=1,min(n/2,nr)) 01314 nr=n/2 01315 IF (ierrf < 0) REWIND lun ! end-of-file 01316 eof=(ierrf /= 0) 01317 ELSE ! C file 01318 lun=kfile-nfilf 01319 #ifdef READ_C_FILES 01320 CALL readc(readBufferDataF(noff+1),readBufferDataI(noff+1),nr,lun,ierrc) 01321 n=nr+nr 01322 #else 01323 ierrc=0 01324 #endif 01325 eof=(ierrc <= 0.AND.ierrc /= -4) ! allow buffer overruns -> skip record 01326 END IF 01327 IF(eof) EXIT records ! end-of-files or error 01328 01329 jrec=jrec+1 01330 readBufferInfo(3,ithr)=jrec 01331 IF(floop) THEN 01332 xfd(jfile)=max(xfd(jfile),n) 01333 IF(ithr == 1) THEN 01334 CALL hmplnt(1,n) 01335 IF(inder(noff+1) /= 0) CALL hmpent(8,FLOAT(inder(noff+1))) 01336 END IF 01337 END IF 01338 01339 IF (nr <= ndimbuf) THEN 01340 readBufferInfo(4,ithr)=nbuf 01341 readBufferInfo(5,ithr)=noff+nr 01342 01343 readBufferPointer(ioffp+nbuf)=noff ! pointer to start of buffer 01344 readBufferDataI(noff )=noff+nr ! pointer to end of buffer 01345 readBufferDataI(noff-1)=ifd(kfile)+jrec ! global record number (available with LOOP2) 01346 readBufferDataF(noff )=real(kfile) ! file number 01347 readBufferDataF(noff-1)=wfd(kfile) ! weight 01348 01349 IF ((noff+nr+2+ndimbuf >= nData*(iact+1)).OR.(nbuf >= nPointer)) EXIT files ! buffer full 01350 ELSE 01351 !$OMP ATOMIC 01352 skippedRecords=skippedRecords+1 01353 CYCLE records 01354 END IF 01355 01356 END DO records 01357 01358 readBufferInfo(1,ithr)=-jfile ! flag eof 01359 IF (kfd(1,jfile) == 0) THEN 01360 PRINT *, 'PEREAD: file ', kfile, 'read the first time, found',jrec,' records' 01361 kfd(1,jfile)=-jrec 01362 END IF 01363 ! take next file 01364 !$OMP CRITICAL 01365 IF (ifile < nfilb) THEN 01366 ifile=ifile+1 01367 jrec=0 01368 readBufferInfo(1,ithr)=ifile 01369 readBufferInfo(3,ithr)=jrec 01370 END IF 01371 !$OMP END CRITICAL 01372 jfile=readBufferInfo(1,ithr) 01373 01374 END DO files 01375 !$OMP END PARALLEL 01376 ! compress pointers 01377 nrd=readBufferInfo(4,1) ! buffers from 1 .thread 01378 DO k=2,nthr 01379 iact =readBufferInfo(2,k) 01380 ioffp=iact*nPointer 01381 nbuf=readBufferInfo(4,k) 01382 DO l=1,nbuf 01383 readBufferPointer(nrd+l)=readBufferPointer(ioffp+l) 01384 END DO 01385 nrd=nrd+nbuf 01386 END DO 01387 01388 more=0 01389 DO k=1,nthr 01390 jfile=readBufferInfo(1,k) 01391 IF (jfile > 0) THEN ! no eof yet 01392 readBufferInfo(2,k)=more 01393 more=more+1 01394 ELSE 01395 ! no more files, thread retires 01396 readBufferInfo(1,k)=0 01397 readBufferInfo(2,k)=-1 01398 readBufferInfo(3,k)=0 01399 END IF 01400 END DO 01401 ! record limit ? 01402 IF (mxrec > 0.AND.(ntot+nrd) >= mxrec) THEN 01403 nrd=mxrec-ntot 01404 more=-1 01405 DO k=1,nthr 01406 jfile=readBufferInfo(1,k) 01407 IF (jfile > 0) THEN ! rewind files 01408 nrc=readBufferInfo(3,k) 01409 IF (kfd(1,jfile) == 0) kfd(1,jfile)=-nrc 01410 IF (kfile <= nfilf) THEN 01411 lun=kfile+10 01412 REWIND lun 01413 ELSE 01414 lun=kfile-nfilf 01415 #ifdef READ_C_FILES 01416 CALL resetc(lun) 01417 #endif 01418 END IF 01419 END IF 01420 END DO 01421 END IF 01422 01423 ntot=ntot+nrd 01424 nrec=ntot 01425 numReadbuffer=nrd 01426 01427 sumRecords=sumRecords+nrd 01428 minRecordsInBlock=MIN(minRecordsInBlock,nrd) 01429 maxRecordsInBlock=MAX(maxRecordsInBlock,nrd) 01430 01431 DO WHILE (nloopn == 0.AND.ntot >= nrpr) 01432 WRITE(*,*) ' Record ',nrpr 01433 IF (nrpr < 100000) THEN 01434 nrpr=nrpr*10 01435 ELSE 01436 nrpr=nrpr+100000 01437 END IF 01438 END DO 01439 01440 IF (ncache > 0.AND.nloopn <= 1.AND. npri < mpri.AND.mprint > 1) THEN 01441 npri=npri+1 01442 IF (npri == 1) WRITE(*,100) 01443 WRITE(*,101) nrec, nrd, more ,ifile 01444 100 FORMAT(/' PeRead records active file' & 01445 /' total block threads number') 01446 101 FORMAT(' PeRead',4I10) 01447 END IF 01448 01449 IF (more <= 0) THEN 01450 ifile=0 01451 IF (floop) THEN 01452 ! check for file weights 01453 ds0=0.0D0 01454 ds1=0.0D0 01455 ds2=0.0D0 01456 maxRecordSize=0 01457 maxRecordFile=0 01458 DO k=1,nfilb 01459 IF (xfd(k) > maxRecordSize) THEN 01460 maxRecordSize=xfd(k) 01461 maxRecordFile=k 01462 END IF 01463 dw=dfloat(-kfd(1,k)) 01464 IF (wfd(k) /= 1.0) nfilw=nfilw+1 01465 ds0=ds0+dw 01466 ds1=ds1+dw*DBLE(wfd(k)) 01467 ds2=ds2+dw*DBLE(wfd(k)**2) 01468 END DO 01469 PRINT *, 'PEREAD: file ', maxRecordFile, 'with max record size ', maxRecordSize 01470 IF (nfilw > 0.AND.ds0 > 0.0D0) THEN 01471 ds1=ds1/ds0 01472 ds2=ds2/ds0-ds1*ds1 01473 DO lun=6,lunlog,2 01474 WRITE(lun,177) nfilw,SNGL(ds1),SNGL(ds2) 01475 177 FORMAT(/' !!!!!',i4,' weighted binary files', & 01476 /' !!!!! mean, variance of weights =',2G12.4) 01477 END DO 01478 END IF 01479 ! integrate record numbers 01480 DO k=2,nfilb 01481 ifd(k)=ifd(k-1)-kfd(1,k-1) 01482 END DO 01483 ! sort 01484 IF (nthr > 1) CALL sort2k(kfd,nfilb) 01485 IF (skippedRecords > 0) THEN 01486 PRINT *, 'PEREAD skipped records: ', skippedRecords 01487 ndimbuf=maxRecordSize/2 ! adjust buffer size 01488 END IF 01489 END IF 01490 lprint=.FALSE. 01491 floop=.FALSE. 01492 IF (ncache > 0.AND.nloopn <= 1.AND.mprint > 0) & 01493 WRITE(*,179) numBlocks, sumRecords, minRecordsInBlock, maxRecordsInBlock 01494 179 FORMAT(/' Read cache usage (#blocks, #records, ', & 01495 'min,max records/block'/17X,4I10) 01496 END IF 01497 RETURN 01498 01499 END SUBROUTINE peread 01500 01508 SUBROUTINE peprep(mode) 01509 USE mpmod 01510 01511 IMPLICIT NONE 01512 01513 INTEGER, INTENT(IN) :: mode 01514 01515 INTEGER :: ibuf 01516 INTEGER :: ichunk 01517 INTEGER :: iproc 01518 INTEGER :: isfrst 01519 INTEGER :: islast 01520 INTEGER :: ist 01521 INTEGER :: j 01522 INTEGER :: ja 01523 INTEGER :: jb 01524 INTEGER :: jsp 01525 INTEGER :: nst 01526 INTEGER :: inone 01527 !$ INTEGER :: OMP_GET_THREAD_NUM 01528 01529 01530 isfrst(ibuf)=readBufferPointer(ibuf)+1 01531 islast(ibuf)=readBufferDataI(readBufferPointer(ibuf)) 01532 01533 IF (mode > 0) THEN 01534 ichunk=MIN((numReadBuffer+mthrd-1)/mthrd/32+1,256) 01535 ! parallelize record loop 01536 !$OMP PARALLEL DO & 01537 !$OMP DEFAULT(PRIVATE) & 01538 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,readBufferDataF,ICHUNK) & 01539 !$OMP SCHEDULE(DYNAMIC,ICHUNK) 01540 DO ibuf=1,numReadBuffer ! buffer for current record 01541 iproc=0 01542 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number 01543 ist=isfrst(ibuf) 01544 nst=islast(ibuf) 01545 DO ! loop over measurements 01546 CALL isjajb(nst,ist,ja,jb,jsp) 01547 IF(jb == 0) EXIT 01548 DO j=1,ist-jb 01549 readBufferDataI(jb+j)=inone( readBufferDataI(jb+j) ) ! translate to index 01550 END DO 01551 END DO 01552 END DO 01553 !$OMP END PARALLEL DO 01554 END IF 01555 01556 !$POMP INST BEGIN(peprep) 01557 IF (mode <= 0) THEN 01558 DO ibuf=1,numReadBuffer ! buffer for current record 01559 ist=isfrst(ibuf) 01560 nst=islast(ibuf) 01561 DO ! loop over measurements 01562 CALL isjajb(nst,ist,ja,jb,jsp) 01563 IF(jb == 0) EXIT 01564 DO j=1,ist-jb 01565 readBufferDataI(jb+j)=inone( readBufferDataI(jb+j) ) ! translate to index 01566 END DO 01567 END DO 01568 END DO 01569 END IF 01570 !$POMP INST END(peprep) 01571 01572 END SUBROUTINE peprep 01573 01596 SUBROUTINE isjajb(nst,is,ja,jb,jsp) 01597 USE mpmod 01598 01599 IMPLICIT NONE 01600 REAL :: glder 01601 INTEGER :: i 01602 INTEGER :: inder 01603 01604 INTEGER, INTENT(IN) :: nst 01605 INTEGER, INTENT(IN OUT) :: is 01606 INTEGER, INTENT(OUT) :: ja 01607 INTEGER, INTENT(OUT) :: jb 01608 INTEGER, INTENT(OUT) :: jsp 01609 SAVE 01610 ! ... 01611 inder(i)=readBufferDataI(i) 01612 glder(i)=readBufferDataF(i) 01613 01614 jsp=0 01615 DO 01616 ja=0 01617 jb=0 01618 IF(is >= nst) RETURN 01619 DO 01620 is=is+1 01621 IF(inder(is) == 0) EXIT 01622 END DO 01623 ja=is 01624 DO 01625 is=is+1 01626 IF(inder(is) == 0) EXIT 01627 END DO 01628 jb=is 01629 DO WHILE(inder(is+1) /= 0.AND.is < nst) 01630 is=is+1 01631 END DO 01632 IF(ja+1 /= jb.OR.glder(jb) >= 0.0) EXIT 01633 ! special data 01634 jsp=jb ! pointer to special data 01635 is=is+IFIX(-glder(jb)+0.5) ! skip NSP words 01636 END DO 01637 01638 END SUBROUTINE isjajb 01639 01640 01641 !*********************************************************************** 01642 ! LOOPN ... 01648 01649 SUBROUTINE loopn 01650 USE mpmod 01651 01652 IMPLICIT NONE 01653 REAL :: dsum 01654 REAL :: elmt 01655 REAL :: factrj 01656 REAL :: factrk 01657 REAL :: glder 01658 REAL :: peakd 01659 REAL :: peaki 01660 REAL :: ratae 01661 REAL :: rhs 01662 REAL :: rloop 01663 REAL :: sgm 01664 REAL :: used 01665 REAL :: usei 01666 REAL :: weight 01667 INTEGER :: i 01668 INTEGER :: ia 01669 INTEGER :: ib 01670 INTEGER :: ibuf 01671 INTEGER :: inder 01672 INTEGER :: ioffb 01673 INTEGER :: ipr 01674 INTEGER :: isfrst 01675 INTEGER :: islast 01676 INTEGER :: itgbi 01677 INTEGER :: itgbij 01678 INTEGER :: itgbik 01679 INTEGER :: ivgb 01680 INTEGER :: ivgbij 01681 INTEGER :: ivgbik 01682 INTEGER :: j 01683 INTEGER :: k 01684 INTEGER :: lastit 01685 INTEGER :: lun 01686 INTEGER :: ncrit 01687 INTEGER :: ndfs 01688 INTEGER :: ngras 01689 INTEGER :: nparl 01690 INTEGER :: nr 01691 INTEGER :: nrej 01692 INTEGER:: inone 01693 01694 DOUBLE PRECISION:: adder 01695 DOUBLE PRECISION::funref 01696 DOUBLE PRECISION::dchi2s 01697 DOUBLE PRECISION::sndf 01698 INTEGER(KIND=large):: ii 01699 SAVE 01700 ! ... 01701 isfrst(ibuf)=readBufferPointer(ibuf)+1 01702 islast(ibuf)=readBufferDataI(readBufferPointer(ibuf)) 01703 inder(i)=readBufferDataI(i) 01704 glder(i)=readBufferDataF(i) 01705 ! ----- book and reset --------------------------------------------- 01706 IF(nloopn == 0) THEN ! first call 01707 lastit=-1 01708 iitera=0 01709 END IF 01710 01711 nloopn=nloopn+1 ! increase loop counter 01712 ndfsum=0 01713 sumndf=0.0D0 01714 funref=0.0D0 01715 01716 IF(nloopn == 1) THEN ! book histograms for 1. iteration 01717 CALL gmpdef(1,4,'Function value in iterations') 01718 IF (metsol == 3) THEN ! extend to GMRES, i.e. 4? 01719 CALL gmpdef(2,3,'Number of MINRES steps vs iteration nr') 01720 END IF 01721 CALL hmpdef( 5,0.0,0.0,'Number of degrees of freedom') 01722 CALL hmpdef(11,0.0,0.0,'Number of local parameters') 01723 CALL hmpdef(23,0.0,0.0, 'SQRT of diagonal elements without presigma') 01724 CALL hmpdef(24,0.0,0.0, 'Log10 of off-diagonal elements') 01725 CALL hmpdef(25,0.0,0.0, 'Relative individual pre-sigma') 01726 CALL hmpdef(26,0.0,0.0, 'Relative global pre-sigma') 01727 END IF 01728 01729 01730 CALL hmpdef(3,-prange,prange, & ! book 01731 'Normalized residuals of single (global) measurement') 01732 CALL hmpdef(12,-prange,prange, & ! book 01733 'Normalized residuals of single (local) measurement') 01734 CALL hmpdef(13,-prange,prange, & ! book 01735 'Pulls of single (global) measurement') 01736 CALL hmpdef(14,-prange,prange, & ! book 01737 'Pulls of single (local) measurement') 01738 CALL hmpdef(4,0.0,0.0,'Chi^2/Ndf after local fit') 01739 CALL gmpdef(4,5,'location, dispersion (res.) vs record nr') 01740 CALL gmpdef(5,5,'location, dispersion (pull) vs record nr') 01741 01742 ! WRITE(*,*) 'LOOPN ', NLOOPN, ' executing ICALCM=', ICALCM 01743 01744 ! reset 01745 01746 globalVector=0.0D0 ! reset rhs vector IGVEC 01747 IF(icalcm == 1) THEN 01748 globalMatD=0.0D0 01749 globalMatF=0. 01750 IF (metsol >= 3) matPreCond=0.0D0 01751 END IF 01752 01753 IF(nloopn == 2) CALL hmpdef(6,0.0,0.0,'Down-weight fraction') 01754 01755 newite=.FALSE. 01756 IF(iterat /= lastit) THEN ! new iteration 01757 newite=.TRUE. 01758 funref=fvalue 01759 IF(nloopn > 1) THEN 01760 nrej=nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) 01761 ! CALL MEND 01762 IF(iterat == 1) THEN 01763 chicut=chirem 01764 ELSE IF(iterat >= 1) THEN 01765 chicut=SQRT(chicut) 01766 IF(chicut /= 0.0.AND.chicut < 1.5) chicut=1.0 01767 IF(chicut /= 0.0.AND.nrej == 0) chicut=1.0 01768 END IF 01769 END IF 01770 ! WRITE(*,111) ! header line 01771 END IF 01772 01773 DO i=0,3 01774 nrejec(i)=0 ! reset reject counter 01775 END DO 01776 DO k=3,6 01777 writeBufferHeader(k)=0 ! cache usage 01778 writeBufferHeader(-k)=0 01779 END DO 01780 ! statistics per binary file 01781 DO i=1,nfilb 01782 jfd(i)=0 01783 cfd(i)=0.0 01784 dfd(i)=0 01785 END DO 01786 ! ----- read next data ---------------------------------------------- 01787 DO 01788 CALL peread(nr) ! read records 01789 CALL peprep(1) ! prepare records 01790 ndfs =0 01791 sndf =0.0D0 01792 dchi2s=0.0D0 01793 CALL loopbf(nrejec,ndfs,sndf,dchi2s,nfiles,jfd,cfd,dfd) 01794 ndfsum=ndfsum+ndfs 01795 sumndf=sumndf+sndf 01796 CALL addsum(dchi2s) 01797 IF (nr <= 0) EXIT ! next block of events ? 01798 END DO 01799 ! sum up RHS (over threads) once (reduction in LOOPBF: summation for each block) 01800 ioffb=0 01801 DO ipr=2,mthrd 01802 ioffb=ioffb+lenGlobalVec 01803 DO k=1,lenGlobalVec 01804 globalVector(k)=globalVector(k)+globalVector(ioffb+k) 01805 END DO 01806 END DO 01807 01808 IF (icalcm == 1) THEN 01809 ! PRINT *, ' cache/w ',(writeBufferHeader(-K),K=3,6),(writeBufferHeader(K),K=3,6) 01810 nparl=writeBufferHeader(3) 01811 ncrit=writeBufferHeader(4) 01812 used=FLOAT(writeBufferHeader(-5))/FLOAT(writeBufferHeader(-3))*0.1 01813 usei=FLOAT(writeBufferHeader(5))/FLOAT(writeBufferHeader(3))*0.1 01814 peakd=FLOAT(writeBufferHeader(-6))*0.1 01815 peaki=FLOAT(writeBufferHeader(6))*0.1 01816 WRITE(*,111) nparl,ncrit,usei,used,peaki,peakd 01817 111 FORMAT(' Write cache usage (#flush,#overrun,<levels>,', & 01818 'peak(levels))'/2I7,',',4(f6.1,'%')) 01819 END IF 01820 01821 ! ----- after end-of-data add contributions from pre-sigma --------- 01822 01823 IF(nloopn == 1) THEN 01824 ! plot diagonal elements 01825 elmt=0.0 01826 DO i=1,nvgb ! diagonal elements 01827 ii=0 01828 IF(matsto == 1) THEN 01829 ii=i 01830 ii=(ii*ii+ii)/2 01831 END IF 01832 IF(matsto == 2) ii=i 01833 IF(matsto == 3) ii=i 01834 IF(ii /= 0) THEN 01835 elmt=SNGL(globalMatD(ii)) 01836 IF(elmt > 0.0) CALL hmpent(23,1.0/SQRT(elmt)) 01837 END IF 01838 END DO 01839 END IF 01840 01841 01842 01843 ! add pre-sigma contributions to matrix diagonal 01844 01845 ! WRITE(*,*) 'Adding to diagonal ICALCM IND6',ICALCM,IND6 01846 01847 IF(icalcm == 1) THEN 01848 DO ivgb=1,nvgb ! add evtl. pre-sigma 01849 ! WRITE(*,*) 'Index ',IVGB,IVGB,QM(IND6+IVGB) 01850 IF(globalParPreWeight(ivgb) /= 0.0) THEN 01851 IF(ivgb > 0) CALL mupdat(ivgb,ivgb,DBLE(globalParPreWeight(ivgb))) 01852 END IF 01853 END DO 01854 END IF 01855 01856 CALL hmpwrt(23) 01857 CALL hmpwrt(24) 01858 CALL hmpwrt(25) 01859 CALL hmpwrt(26) 01860 01861 01862 ! add regularization term to F and to rhs -------------------------- 01863 01864 ! WRITE(*,*) 'NREGUL ',NREGUL,NLOOPN 01865 01866 IF(nregul /= 0) THEN ! add regularization term to F and to rhs 01867 DO ivgb=1,nvgb 01868 itgbi=globalParVarToTotal(ivgb) ! global parameter index 01869 globalVector(ivgb)=globalVector(ivgb) -globalParameter(itgbi)*globalParPreWeight(ivgb) 01870 adder=globalParPreWeight(ivgb)*globalParameter(itgbi)**2 01871 CALL addsum(adder) 01872 END DO 01873 END IF 01874 01875 01876 ! ----- add contributions from "measurement" ----------------------- 01877 01878 01879 i=1 01880 DO WHILE (i <= lenMeasurements) 01881 rhs=listMeasurements(i )%value ! right hand side 01882 sgm=listMeasurements(i+1)%value ! sigma parameter 01883 i=i+2 01884 weight=0.0 01885 IF(sgm > 0.0) weight=1.0/sgm**2 01886 01887 dsum=-rhs 01888 01889 ! loop over label/factor pairs 01890 ia=i 01891 DO 01892 i=i+1 01893 IF(i > lenMeasurements) EXIT 01894 IF(listMeasurements(i)%label == 0) EXIT 01895 END DO 01896 ib=i-1 01897 01898 DO j=ia,ib 01899 factrj=listMeasurements(j)%value 01900 itgbij=inone(listMeasurements(j)%label) ! total parameter index 01901 IF(itgbij /= 0) THEN 01902 dsum=dsum+factrj*SNGL(globalParameter(itgbij)) ! residuum 01903 END IF 01904 ! add to vector 01905 ivgbij=0 01906 IF(itgbij /= 0) ivgbij=globalParLabelIndex(2,itgbij) ! variable-parameter index 01907 IF(ivgbij > 0) THEN 01908 globalVector(ivgbij)=globalVector(ivgbij) -weight*dsum*factrj ! vector 01909 END IF 01910 01911 IF(icalcm == 1.AND.ivgbij > 0) THEN 01912 DO k=ia,j 01913 factrk=listMeasurements(k)%value 01914 itgbik=inone(listMeasurements(k)%label) ! total parameter index 01915 ! add to matrix 01916 ivgbik=0 01917 IF(itgbik /= 0) ivgbik=globalParLabelIndex(2,itgbik) ! variable-parameter index 01918 IF(ivgbij > 0.AND.ivgbik > 0) THEN ! 01919 CALL mupdat(ivgbij,ivgbik,DBLE(weight*factrj*factrk)) 01920 END IF 01921 END DO 01922 END IF 01923 END DO 01924 01925 adder=weight*dsum**2 01926 CALL addsum(adder) ! accumulate chi-square 01927 01928 END DO 01929 01930 ! ----- printout --------------------------------------------------- 01931 01932 01933 CALL getsum(fvalue) ! get accurate sum (Chi^2) 01934 flines=0.5D0*fvalue ! Likelihood function value 01935 rloop=iterat+0.01*nloopn 01936 actfun=SNGL(funref-fvalue) 01937 IF(nloopn == 1) actfun=0.0 01938 ngras=nint(angras) 01939 ratae=0.0 !!! 01940 IF(delfun /= 0.0) THEN 01941 ratae=MIN(99.9,actfun/delfun) !!! 01942 ratae=MAX(-99.9,ratae) 01943 END IF 01944 01945 ! rejects ... 01946 01947 nrej =nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) 01948 IF(nloopn == 1) THEN 01949 IF(nrej /= 0) THEN 01950 WRITE(*,*) ' ' 01951 WRITE(*,*) 'Data rejected in initial loop:' 01952 WRITE(*,*) ' ', & 01953 nrejec(0), ' (rank deficit/NaN) ',nrejec(1),' (Ndf=0) ', & 01954 nrejec(2), ' (huge) ',nrejec(3),' (large)' 01955 END IF 01956 END IF 01957 ! IF(NREJEC(1)+NREJEC(2)+NREJEC(3).NE.0) THEN 01958 ! WRITE(LUNLOG,*) 'Data rejected in initial loop:',NREJEC(1), 01959 ! + ' (Ndf=0) ',NREJEC(2),' (huge) ',NREJEC(3),' (large)' 01960 ! END IF 01961 01962 01963 IF(newite.AND.iterat == 2) THEN 01964 IF(nrecpr /= 0.OR.nrecp2 /= 0) nrecer=nrec3 01965 IF(nrecpr < 0) THEN 01966 nrecpr=nrec1 01967 END IF 01968 IF(nrecp2 < 0) THEN 01969 nrecp2=nrec2 01970 END IF 01971 END IF 01972 01973 IF(nloopn <= 2) THEN 01974 IF(nhistp /= 0) THEN 01975 ! CALL HMPRNT(3) ! scaled residual of single measurement 01976 ! CALL HMPRNT(12) ! scaled residual of single measurement 01977 ! CALL HMPRNT(4) ! chi^2/Ndf 01978 END IF 01979 CALL hmpwrt(3) 01980 CALL hmpwrt(12) 01981 CALL hmpwrt(4) 01982 CALL gmpwrt(4) ! location, dispersion (res.) as a function of record nr 01983 IF (nloopn <= lfitnp) THEN 01984 CALL hmpwrt(13) 01985 CALL hmpwrt(14) 01986 CALL gmpwrt(5) ! location, dispersion (pull) as a function of record nr 01987 END IF 01988 END IF 01989 ! IF(NLOOPN.EQ.2.AND.NHISTP.NE.0) CALL HMPRNT(6) 01990 IF(nloopn == 2) CALL hmpwrt(6) 01991 IF(nloopn <= 1) THEN 01992 ! IF(NHISTP.NE.0) CALL HMPRNT(5) ! number of degrees of freedom 01993 ! IF(NHISTP.NE.0) CALL HMPRNT(11) ! Nlocal 01994 CALL hmpwrt(5) 01995 CALL hmpwrt(11) 01996 END IF 01997 01998 ! local fit: band matrix structure !? 01999 IF (nloopn == 1.AND.nbndr > 0) THEN 02000 DO lun=6,8,2 02001 WRITE(lun,*) ' ' 02002 WRITE(lun,*) ' === local fits have bordered band matrix structure ===' 02003 WRITE(lun,101) ' NBNDR',nbndr,'number of records' 02004 WRITE(lun,101) ' NBDRX',nbdrx,'max border size' 02005 WRITE(lun,101) ' NBNDX',nbndx,'max band width' 02006 END DO 02007 END IF 02008 02009 lastit=iterat 02010 02011 101 FORMAT(1X,a6,' =',i10,' = ',a) 02012 ! 101 FORMAT(' LOOPN',I6,' Function value',F22.8,10X,I6,' records') 02013 ! 102 FORMAT(' incl. constraint penalty',F22.8) 02014 ! 103 FORMAT(I13,3X,A,G12.4) 02015 END SUBROUTINE loopn ! loop with fits 02016 02020 02021 SUBROUTINE ploopa(lunp) 02022 USE mpmod 02023 02024 IMPLICIT NONE 02025 02026 INTEGER, INTENT(IN) :: lunp 02027 ! .. 02028 WRITE(lunp,*) ' ' 02029 WRITE(lunp,101) ! header line 02030 WRITE(lunp,102) ! header line 02031 101 FORMAT(' it fc',' fcn_value dfcn_exp slpr costh iit st', & 02032 ' ls step cutf',1X,'rejects hmmsec FMS') 02033 102 FORMAT(' -- --',' ----------- -------- ---- ----- --- --', & 02034 ' -- ---- ----',1X,'------- ------ ---') 02035 RETURN 02036 END SUBROUTINE ploopa ! title for iteration 02037 02041 02042 SUBROUTINE ploopb(lunp) 02043 USE mpmod 02044 02045 IMPLICIT NONE 02046 INTEGER :: ma 02047 INTEGER :: minut 02048 INTEGER :: nfa 02049 INTEGER :: nhour 02050 INTEGER :: nrej 02051 INTEGER :: nsecnd 02052 REAL :: ratae 02053 REAL :: rstb 02054 REAL :: secnd 02055 REAL :: slopes(3) 02056 REAL :: steps(3) 02057 REAL, DIMENSION(2) :: ta 02058 02059 INTEGER, INTENT(IN) :: lunp 02060 02061 CHARACTER (LEN=4):: ccalcm(4) 02062 DATA ccalcm / ' end',' S', ' F ',' FMS' / 02063 SAVE 02064 02065 nrej=nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) ! rejects 02066 IF(nrej > 9999999) nrej=9999999 02067 CALL etime(ta,rstb) 02068 deltim=rstb-rstart 02069 CALL sechms(deltim,nhour,minut,secnd) ! time 02070 nsecnd=nint(secnd) 02071 IF(iterat == 0) THEN 02072 WRITE(lunp,103) iterat,nloopn,fvalue, & 02073 chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm) 02074 ELSE 02075 CALL ptlopt(nfa,ma,slopes,steps) ! slopes steps 02076 ratae=ABS(slopes(2)/slopes(1)) 02077 stepl=steps(2) 02078 WRITE(lunp,104) iterat,nloopn,fvalue,delfun,ratae,angras, & 02079 iitera,istopa,lsinfo,stepl, chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm) 02080 END IF 02081 103 FORMAT(i3,i3,e12.5,38X,f5.1, 1X,i7, i2,i2,i3,a4) 02082 104 FORMAT(i3,i3,e12.5,1X,e8.2,f6.3,f6.3,i5,2I3,f6.2,f5.1, & 02083 1X,i7, i2,i2,i3,a4) 02084 RETURN 02085 END SUBROUTINE ploopb ! iteration line 02086 02090 02091 SUBROUTINE ploopc(lunp) 02092 USE mpmod 02093 02094 IMPLICIT NONE 02095 INTEGER :: ma 02096 INTEGER :: minut 02097 INTEGER :: nfa 02098 INTEGER :: nhour 02099 INTEGER :: nrej 02100 INTEGER :: nsecnd 02101 REAL :: ratae 02102 REAL :: rstb 02103 REAL :: secnd 02104 REAL :: slopes(3) 02105 REAL :: steps(3) 02106 REAL, DIMENSION(2) :: ta 02107 02108 INTEGER, INTENT(IN) :: lunp 02109 CHARACTER (LEN=4):: ccalcm(4) 02110 DATA ccalcm / ' end',' S', ' F ',' FMS' / 02111 SAVE 02112 02113 nrej=nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) ! rejects 02114 IF(nrej > 9999999) nrej=9999999 02115 CALL etime(ta,rstb) 02116 deltim=rstb-rstart 02117 CALL sechms(deltim,nhour,minut,secnd) ! time 02118 nsecnd=nint(secnd) 02119 CALL ptlopt(nfa,ma,slopes,steps) ! slopes steps 02120 ratae=ABS(slopes(2)/slopes(1)) 02121 stepl=steps(2) 02122 WRITE(lunp,105) nloopn,fvalue, ratae,lsinfo, & 02123 stepl,nrej,nhour,minut,nsecnd,ccalcm(lcalcm) 02124 105 FORMAT(3X,i3,e12.5,9X, f6.3,14X,i3,f6.2,6X, i7, i2,i2,i3,a4) 02125 RETURN 02126 02127 END SUBROUTINE ploopc ! sub-iteration line 02128 02132 02133 SUBROUTINE ploopd(lunp) 02134 USE mpmod 02135 IMPLICIT NONE 02136 INTEGER :: minut 02137 INTEGER :: nhour 02138 INTEGER :: nsecnd 02139 REAL :: rstb 02140 REAL :: secnd 02141 REAL, DIMENSION(2) :: ta 02142 02143 INTEGER, INTENT(IN) :: lunp 02144 CHARACTER (LEN=4):: ccalcm(4) 02145 DATA ccalcm / ' end',' S', ' F ',' FMS' / 02146 SAVE 02147 CALL etime(ta,rstb) 02148 deltim=rstb-rstart 02149 CALL sechms(deltim,nhour,minut,secnd) ! time 02150 nsecnd=IFIX(secnd+0.5) 02151 02152 WRITE(lunp,106) nhour,minut,nsecnd,ccalcm(lcalcm) 02153 106 FORMAT(69X,i2,i2,i3,a4) 02154 RETURN 02155 END SUBROUTINE ploopd 02156 02158 SUBROUTINE explfc(lunit) 02159 IMPLICIT NONE 02160 INTEGER:: lunit 02161 WRITE(lunit,*) ' ' 02162 WRITE(lunit,102) 'Explanation of iteration table' 02163 WRITE(lunit,102) '==============================' 02164 WRITE(lunit,101) 'it', & 02165 'iteration number. Global parameters are improved for it > 0.' 02166 WRITE(lunit,102) 'First function evaluation is called iteraton 0.' 02167 WRITE(lunit,101) 'fc', 'number of function evaluations.' 02168 WRITE(lunit,101) 'fcn_value', 'value of 2 x Likelihood function (LF).' 02169 WRITE(lunit,102) 'The final value is the chi^2 value of the fit and should' 02170 WRITE(lunit,102) 'be about equal to the NDF (see below).' 02171 WRITE(lunit,101) 'dfcn_exp', & 02172 'expected reduction of the value of the Likelihood function (LF)' 02173 WRITE(lunit,101) 'slpr', 'ratio of the actual slope to inital slope.' 02174 WRITE(lunit,101) 'costh', & 02175 'cosine of angle between search direction and -gradient' 02176 WRITE(lunit,101) 'iit', & 02177 'number of internal iterations in GMRES/MINRES algorithmus' 02178 WRITE(lunit,101) 'st', 'stop code of GMRES/MINRES algorithmus' 02179 WRITE(lunit,102) '< 0: rhs is very special, with beta2 = 0' 02180 WRITE(lunit,102) '= 0: rhs b = 0, i.e. the exact solution is x = 0' 02181 WRITE(lunit,102) '= 1 requested accuracy achieved, as determined by rtol' 02182 WRITE(lunit,102) '= 2 reasonable accuracy achieved, given eps' 02183 WRITE(lunit,102) '= 3 x has converged to an eigenvector' 02184 WRITE(lunit,102) '= 4 matrix ill-conditioned (Acond has exceeded 0.1/eps)' 02185 WRITE(lunit,102) '= 5 the iteration limit was reached' 02186 WRITE(lunit,102) '= 6 Matrix x vector does not define a symmetric matrix' 02187 WRITE(lunit,102) '= 7 Preconditioner does not define a symmetric matrix' 02188 WRITE(lunit,101) 'ls', 'line search info' 02189 WRITE(lunit,102) '< 0 recalculate function' 02190 WRITE(lunit,102) '= 0: N or STP lt 0 or step not descending' 02191 WRITE(lunit,102) '= 1: Linesearch convergence conditions reached' 02192 WRITE(lunit,102) '= 2: interval of uncertainty at lower limit' 02193 WRITE(lunit,102) '= 3: max nr of line search calls reached' 02194 WRITE(lunit,102) '= 4: step at the lower bound' 02195 WRITE(lunit,102) '= 5: step at the upper bound' 02196 WRITE(lunit,102) '= 6: rounding error limitation' 02197 WRITE(lunit,101) 'step', & 02198 'the factor for the Newton step during the line search. Usually' 02199 WRITE(lunit,102) & 02200 'a value of 1 gives a sufficient reduction of the LF. Oherwise' 02201 WRITE(lunit,102) 'other step values are tried.' 02202 WRITE(lunit,101) 'cutf', & 02203 'cut factor. Local fits are rejected, if their chi^2 value' 02204 WRITE(lunit,102) & 02205 'is larger than the 3-sigma chi^2 value times the cut factor.' 02206 WRITE(lunit,102) 'A cut factor of 1 is used finally, but initially a larger' 02207 WRITE(lunit,102) 'factor may be used. A value of 0.0 means no cut.' 02208 WRITE(lunit,101) 'rejects', 'total number of rejected local fits.' 02209 WRITE(lunit,101) 'hmmsec', 'the time in hours (h), minutes (mm) and seconds.' 02210 WRITE(lunit,101) 'FMS', 'calculation of Function value, Matrix, Solution.' 02211 WRITE(lunit,*) ' ' 02212 02213 101 FORMAT(a9,' = ',a) 02214 102 FORMAT(13X,a) 02215 END SUBROUTINE explfc 02216 02224 02225 SUBROUTINE mupdat(i,j,add) ! 02226 USE mpmod 02227 02228 IMPLICIT NONE 02229 02230 INTEGER, INTENT(IN) :: i 02231 INTEGER, INTENT(IN) :: j 02232 DOUBLE PRECISION, INTENT(IN) :: add 02233 02234 INTEGER(KIND=large):: ijadd 02235 INTEGER(KIND=large):: ia 02236 INTEGER(KIND=large):: ja 02237 INTEGER(KIND=large):: ij 02238 ! ... 02239 IF(i <= 0.OR.j <= 0) RETURN 02240 ia=MAX(i,j) ! larger 02241 ja=MIN(i,j) ! smaller 02242 ij=0 02243 IF(matsto == 1) THEN ! full symmetric matrix 02244 ij=ja+(ia*ia-ia)/2 ! ISYM index 02245 globalMatD(ij)=globalMatD(ij)+add 02246 ELSE IF(matsto == 2) THEN ! sparse symmetric matrix 02247 ij=ijadd(i,j) ! inline code requires same time 02248 IF (ij == 0) RETURN ! pair is suppressed 02249 IF (ij > 0) THEN 02250 globalMatD(ij)=globalMatD(ij)+add 02251 ELSE 02252 globalMatF(-ij)=globalMatF(-ij)+SNGL(add) 02253 END IF 02254 END IF 02255 IF(metsol >= 3) THEN 02256 IF(mbandw > 0) THEN ! for Cholesky decomposition 02257 IF(ia <= nvgb) THEN ! variable global parameter 02258 ij=indPreCond(ia)-ia+ja 02259 IF(ia > 1.AND.ij <= indPreCond(ia-1)) ij=0 02260 IF(ij /= 0) matPreCond(ij)=matPreCond(ij)+add 02261 IF(ij < 0.OR.ij > size(matPreCond)) STOP 'mupdat: bad index' 02262 ELSE ! Lagrange multiplier 02263 ij=indPreCond(nvgb)+(ia-nvgb-1)*nvgb+ja 02264 IF(ij /= 0) matPreCond(ij)=matPreCond(ij)+add 02265 END IF 02266 ELSE IF(mbandw == 0) THEN ! default preconditioner 02267 IF(ia <= nvgb) THEN ! variable global parameter 02268 IF(ja == ia) matPreCond(ia)=matPreCond(ia)+add ! diag 02269 ELSE ! Lagrange multiplier 02270 ij=nvgb+(ia-nvgb-1)*nvgb+ja 02271 IF(ij /= 0) matPreCond(ij)=matPreCond(ij)+add 02272 END IF 02273 END IF 02274 END IF 02275 END SUBROUTINE mupdat 02276 02277 02307 02308 SUBROUTINE loopbf(nrej,ndfs,sndf,dchi2s, numfil,naccf,chi2f,ndff) 02309 USE mpmod 02310 02311 IMPLICIT NONE 02312 REAL :: cauchy 02313 REAL :: chichi 02314 REAL :: chlimt 02315 REAL :: chndf 02316 REAL :: chuber 02317 REAL :: down 02318 REAL :: glder 02319 REAL :: pull 02320 REAL :: r1 02321 REAL :: r2 02322 REAL :: rec 02323 REAL :: rerr 02324 REAL :: resid 02325 REAL :: resing 02326 REAL :: resmax 02327 REAL :: rmeas 02328 REAL :: rmloc 02329 REAL :: suwt 02330 REAL :: used 02331 REAL :: wght 02332 REAL :: wrc 02333 REAL :: chindl 02334 INTEGER :: i 02335 INTEGER :: ia 02336 INTEGER :: ib 02337 INTEGER :: ibuf 02338 INTEGER :: ichunk 02339 INTEGER :: icmn 02340 INTEGER :: icost 02341 INTEGER :: id 02342 INTEGER :: idiag 02343 INTEGER :: iext 02344 INTEGER :: ij 02345 INTEGER :: ije 02346 INTEGER :: ijn 02347 INTEGER :: ijsym 02348 INTEGER :: ik 02349 INTEGER :: ike 02350 INTEGER :: im 02351 INTEGER :: imeas 02352 INTEGER :: in 02353 INTEGER :: inder 02354 INTEGER :: inv 02355 INTEGER :: ioffb 02356 INTEGER :: ioffc 02357 INTEGER :: ioffd 02358 INTEGER :: ioffe 02359 INTEGER :: ioffi 02360 INTEGER :: iprdbg 02361 INTEGER :: iproc 02362 INTEGER :: irow 02363 INTEGER :: isfrst 02364 INTEGER :: islast 02365 INTEGER :: ist 02366 INTEGER :: iter 02367 INTEGER :: itgbi 02368 INTEGER :: ivgbj 02369 INTEGER :: ivgbk 02370 INTEGER :: j 02371 INTEGER :: ja 02372 INTEGER :: jb 02373 INTEGER :: jk 02374 INTEGER :: jn 02375 INTEGER :: joffd 02376 INTEGER :: joffi 02377 INTEGER :: jproc 02378 INTEGER :: jsp 02379 INTEGER :: k 02380 INTEGER :: kbdr 02381 INTEGER :: kbdrx 02382 INTEGER :: kbnd 02383 INTEGER :: kfl 02384 INTEGER :: kx 02385 INTEGER :: mbdr 02386 INTEGER :: mbnd 02387 INTEGER :: nalc 02388 INTEGER :: nalg 02389 INTEGER :: nan 02390 INTEGER :: nb 02391 INTEGER :: ndf 02392 INTEGER :: ndfsd 02393 INTEGER :: ndown 02394 INTEGER :: neq 02395 INTEGER :: nfred 02396 INTEGER :: nfrei 02397 INTEGER :: ngg 02398 INTEGER :: nprdbg 02399 INTEGER :: nrank 02400 INTEGER :: nrc 02401 INTEGER :: nst 02402 INTEGER :: nter 02403 INTEGER :: nweig 02404 02405 INTEGER, INTENT(IN OUT) :: nrej(0:3) 02406 INTEGER, INTENT(IN OUT) :: ndfs 02407 DOUBLE PRECISION, INTENT(IN OUT) :: sndf 02408 DOUBLE PRECISION, INTENT(IN OUT) :: dchi2s 02409 INTEGER, INTENT(IN) :: numfil 02410 INTEGER, INTENT(IN OUT) :: naccf(numfil) 02411 REAL, INTENT(IN OUT) :: chi2f(numfil) 02412 INTEGER, INTENT(IN OUT) :: ndff(numfil) 02413 02414 DOUBLE PRECISION::dch2sd 02415 DOUBLE PRECISION:: dchi2 02416 DOUBLE PRECISION::dvar 02417 DOUBLE PRECISION:: dw1 02418 DOUBLE PRECISION::dw2 02419 DOUBLE PRECISION::summ 02420 02421 !$ INTEGER OMP_GET_THREAD_NUM 02422 02423 LOGICAL:: lprnt 02424 LOGICAL::lhist 02425 CHARACTER (LEN=3):: chast 02426 DATA chuber/1.345/ ! constant for Huber down-weighting 02427 DATA cauchy/2.3849/ ! constant for Cauchy down-weighting 02428 SAVE chuber,cauchy 02429 ! ... 02430 ijsym(i,j)=MIN(i,j)+(MAX(i,j)*MAX(i,j)-MAX(i,j))/2 02431 isfrst(ibuf)=readBufferPointer(ibuf)+1 02432 islast(ibuf)=readBufferDataI(readBufferPointer(ibuf)) 02433 inder(i)=readBufferDataI(i) 02434 glder(i)=readBufferDataF(i) 02435 02436 ichunk=MIN((numReadBuffer+mthrd-1)/mthrd/32+1,256) 02437 ! reset header, 3 words per thread: 02438 ! number of entries, offset to data, indices 02439 writeBufferInfo=0 02440 writeBufferData=0. 02441 ! IF (ICALCM.EQ.1) print *, ' ICHUNK ', MQ(IDOT3),MTHRD,ICHUNK 02442 nprdbg=0 02443 iprdbg=-1 02444 02445 ! parallelize record loop 02446 ! private copy of NDFS,.. for each thread, combined at end, init with 0. 02447 !$OMP PARALLEL DO & 02448 !$OMP DEFAULT(PRIVATE) & 02449 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI, & 02450 !$OMP readBufferDataF,writeBufferHeader,writeBufferInfo, & 02451 !$OMP writeBufferData,writeBufferIndices,writeBufferUpdates,globalVector, & 02452 !$OMP globalParameter,globalParLabelIndex,globalIndexUsage,backIndexUsage, & 02453 !$OMP NAGB,NVGB,NAGBN,ICALCM,ICHUNK,NLOOPN,NRECER,NPRDBG,IPRDBG, & 02454 !$OMP NEWITE,CHICUT,LHUBER,CHUBER,ITERAT,NRECPR,MTHRD, & 02455 !$OMP DWCUT,CHHUGE,NRECP2,CAUCHY,LFITNP,LFITBB) & 02456 !$OMP REDUCTION(+:NDFS,SNDF,DCHI2S,NREJ,NBNDR,NACCF,CHI2F,NDFF) & 02457 !$OMP REDUCTION(MAX:NBNDX,NBDRX) & 02458 !$OMP REDUCTION(MIN:NREC3) & 02459 !$OMP SCHEDULE(DYNAMIC,ICHUNK) 02460 DO ibuf=1,numReadBuffer ! buffer for current record 02461 nrc=readBufferDataI(isfrst(ibuf)-2) ! record 02462 kfl=NINT(readBufferDataF(isfrst(ibuf)-1)) ! file 02463 wrc=readBufferDataF(isfrst(ibuf)-2) ! weight 02464 dw1=DBLE(wrc) 02465 dw2=DSQRT(dw1) 02466 02467 iproc=0 02468 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number 02469 ioffb=nagb*iproc ! offset 'f'. 02470 ioffc=nagbn*iproc ! offset 'c'. 02471 ioffe=nvgb*iproc ! offset 'e' 02472 ioffd=writeBufferHeader(-1)*iproc+writeBufferInfo(2,iproc+1) ! offset data 02473 ioffi=writeBufferHeader(1)*iproc+writeBufferInfo(3,iproc+1)+2 ! offset indices 02474 ! ----- reset ------------------------------------------------------ 02475 lprnt=.FALSE. 02476 lhist=(iproc == 0) 02477 REC=nrc ! floating point value 02478 IF(nloopn == 1.AND.MOD(nrc,100000) == 0) THEN 02479 WRITE(*,*) 'Record',nrc,' ... still reading' 02480 END IF 02481 02482 ! printout/debug only for one thread at a time 02483 02484 02485 ! flag for record printout ----------------------------------------- 02486 02487 lprnt=.FALSE. 02488 IF(newite.AND.(iterat == 1.OR.iterat == 3)) THEN 02489 IF(nrc == nrecpr) lprnt=.TRUE. 02490 IF(nrc == nrecp2) lprnt=.TRUE. 02491 IF(nrc == nrecer) lprnt=.TRUE. 02492 END IF 02493 IF (lprnt)THEN 02494 !$OMP ATOMIC 02495 nprdbg=nprdbg+1 ! number of threads with debug 02496 IF (nprdbg == 1) iprdbg=iproc ! first thread with debug 02497 IF (iproc /= iprdbg) lprnt=.FALSE. 02498 ! print *, ' LPRNT ', NRC, NPRDBG, IPRDBG, IPROC, LPRNT 02499 END IF 02500 IF(lprnt) THEN 02501 WRITE(1,*) ' ' 02502 WRITE(1,*) '------------------ Loop',nloopn, & 02503 ': Printout for record',nrc,iproc 02504 WRITE(1,*) ' ' 02505 END IF 02506 02507 ! ----- print data ------------------------------------------------- 02508 02509 IF(lprnt) THEN 02510 imeas=0 ! local derivatives 02511 ist=isfrst(ibuf) 02512 nst=islast(ibuf) 02513 DO ! loop over measurements 02514 CALL isjajb(nst,ist,ja,jb,jsp) 02515 IF(ja == 0) EXIT 02516 IF(imeas == 0) WRITE(1,1121) 02517 imeas=imeas+1 02518 WRITE(1,1122) imeas,glder(ja),glder(jb), & 02519 (inder(ja+j),glder(ja+j),j=1,jb-ja-1) 02520 END DO 02521 1121 FORMAT(/'Measured value and local derivatives'/ & 02522 ' i measured std_dev index...derivative ...') 02523 1122 FORMAT(i3,2G12.4,3(i3,g12.4)/(27X,3(i3,g12.4))) 02524 02525 imeas=0 ! global derivatives 02526 ist=isfrst(ibuf) 02527 nst=islast(ibuf) 02528 DO ! loop over measurements 02529 CALL isjajb(nst,ist,ja,jb,jsp) 02530 IF(ja == 0) EXIT 02531 IF(imeas == 0) WRITE(1,1123) 02532 imeas=imeas+1 02533 IF (jb < ist) THEN 02534 IF(ist-jb > 2) THEN 02535 WRITE(1,1124) imeas,(globalParLabelIndex(1,inder(jb+j)),inder(jb+j), & 02536 globalParLabelIndex(2,inder(jb+j)),glder(jb+j),j=1,ist-jb) 02537 ELSE 02538 WRITE(1,1125) imeas,(globalParLabelIndex(1,inder(jb+j)),inder(jb+j), & 02539 globalParLabelIndex(2,inder(jb+j)),glder(jb+j),j=1,ist-jb) 02540 END IF 02541 END IF 02542 END DO 02543 1123 FORMAT(/'Global derivatives'/ & 02544 ' i label gindex vindex derivative ...') 02545 1124 FORMAT(i3,2(i9,i7,i7,g12.4)/(3X,2(i9,i7,i7,g12.4))) 02546 1125 FORMAT(i3,2(i9,i7,i7,g12.4)) 02547 END IF 02548 02549 ! ----- first loop ------------------------------------------------- 02550 ! ------ prepare local fit ------ 02551 ! count local and global derivates 02552 ! subtract actual alignment parameters from the measured data 02553 02554 IF(lprnt) THEN 02555 WRITE(1,*) ' ' 02556 WRITE(1,*) 'Data corrections using values of global parameters' 02557 WRITE(1,*) '==================================================' 02558 WRITE(1,101) 02559 END IF 02560 nalg=0 ! count number of global derivatives 02561 nalc=0 ! count number of local derivatives 02562 imeas=0 02563 ist=isfrst(ibuf) 02564 nst=islast(ibuf) 02565 DO ! loop over measurements 02566 CALL isjajb(nst,ist,ja,jb,jsp) 02567 IF(ja == 0) EXIT 02568 rmeas=glder(ja) ! data 02569 ! subtract global ... from measured value 02570 DO j=1,ist-jb ! global parameter loop 02571 itgbi=inder(jb+j) ! global parameter label 02572 rmeas=rmeas-glder(jb+j)*SNGL(globalParameter(itgbi)) ! subtract !!! reversed 02573 IF (icalcm == 1) THEN 02574 ij=globalParLabelIndex(2,itgbi) ! index of variable global parameter 02575 IF(ij > 0) THEN 02576 ijn=backIndexUsage(ioffe+ij) ! get index of index 02577 IF(ijn == 0) THEN ! not yet included 02578 nalg=nalg+1 ! count 02579 globalIndexUsage(ioffc+nalg)=ij ! store global index 02580 backIndexUsage(ioffe+ij)=nalg ! store back index 02581 END IF 02582 END IF 02583 END IF 02584 END DO 02585 IF(lprnt) THEN 02586 imeas=imeas+1 02587 IF (jb < ist) WRITE(1,102) imeas,glder(ja),rmeas,glder(jb) 02588 END IF 02589 readBufferDataF(ja)=rmeas ! global contribution subtracted 02590 DO j=1,jb-ja-1 ! local parameter loop 02591 ij=inder(ja+j) 02592 nalc=MAX(nalc,ij) ! number of local parameters 02593 END DO 02594 END DO 02595 101 FORMAT(' index measvalue corrvalue sigma') 02596 102 FORMAT(i6,2X,2G12.4,' +-',g12.4) 02597 02598 IF(nalc <= 0) GO TO 90 02599 02600 ngg=(nalg*nalg+nalg)/2 02601 IF (icalcm == 1) THEN 02602 DO k=1,nalg*nalc 02603 localGlobalMatrix(k)=0.0D0 ! reset global-local matrix 02604 END DO 02605 writeBufferIndices(ioffi-1)=nrc ! index header: 02606 writeBufferIndices(ioffi )=nalg ! event number, number of global par 02607 CALL sort1k(globalIndexUsage(ioffc+1),nalg) ! sort global par. 02608 DO k=1,nalg 02609 iext=globalIndexUsage(ioffc+k) 02610 writeBufferIndices(ioffi+k)=iext ! global par indices 02611 backIndexUsage(ioffe+iext)=k ! update back index 02612 END DO 02613 DO k=1,ngg 02614 writeBufferUpdates(ioffd+k)=0.0D0 ! reset global-global matrix 02615 END DO 02616 END IF 02617 ! ----- iteration start and check --------------------------------- 02618 02619 nter=1 ! first loop without down-weighting 02620 IF(nloopn /= 1.AND.lhuber /= 0) nter=lhuber 02621 02622 ! check matrix for bordered band structure (MBDR+MBND+1 <= NALC) 02623 mbnd=-1 02624 mbdr=nalc 02625 DO i=1, nalc 02626 ibandh(i)=0 02627 END DO 02628 irow=1 02629 idiag=1 02630 ndfsd=0 02631 02632 iter=0 02633 resmax=0.0 02634 DO WHILE(iter < nter) ! outlier suppresssion iteration loop 02635 iter=iter+1 02636 resmax=0.0 02637 IF(lprnt) THEN 02638 WRITE(1,*) ' ' 02639 WRITE(1,*) 'Outlier-suppression iteration',iter,' of',nter 02640 WRITE(1,*) '==========================================' 02641 WRITE(1,*) ' ' 02642 imeas=0 02643 END IF 02644 02645 ! ----- second loop ------------------------------------------------ 02646 ! accumulate normal equations for local fit and determine solution 02647 DO i=1,nalc 02648 blvec(i)=0.0D0 ! reset vector 02649 END DO 02650 DO i=1,(nalc*nalc+nalc)/2 ! GF: FIXME - not really, local parameter number... 02651 clmat(i)=0.0D0 ! (p)reset matrix 02652 END DO 02653 neq=0 02654 ndown=0 02655 nweig=0 02656 ist=isfrst(ibuf) 02657 nst=islast(ibuf) 02658 DO ! loop over measurements 02659 CALL isjajb(nst,ist,ja,jb,jsp) 02660 IF(ja == 0) EXIT 02661 rmeas=glder(ja) ! data 02662 rerr =glder(jb) ! ... and the error 02663 wght =1.0/rerr**2 ! weight from error 02664 neq=neq+1 ! count equation 02665 nweig=nweig+1 02666 resid=rmeas-localCorrections(neq) ! subtract previous fit 02667 IF(nloopn /= 1.AND.iter /= 1.AND.lhuber /= 0) THEN 02668 IF(iter <= 3) THEN 02669 IF(ABS(resid) > chuber*rerr) THEN ! down-weighting 02670 wght=wght*chuber*rerr/ABS(resid) 02671 ndown=ndown+1 02672 END IF 02673 ELSE ! Cauchy 02674 wght=wght/(1.0+(resid/rerr/cauchy)**2) 02675 END IF 02676 END IF 02677 02678 IF(lprnt.AND.iter /= 1.AND.nter /= 1) THEN 02679 chast=' ' 02680 IF(ABS(resid) > chuber*rerr) chast='* ' 02681 IF(ABS(resid) > 3.0*rerr) chast='** ' 02682 IF(ABS(resid) > 6.0*rerr) chast='***' 02683 IF(imeas == 0) WRITE(1,*) 'Second loop: accumulate' 02684 IF(imeas == 0) WRITE(1,103) 02685 imeas=imeas+1 02686 down=1.0/SQRT(wght) 02687 r1=resid/rerr 02688 r2=resid/down 02689 WRITE(1,104) imeas,rmeas,resid,rerr,r1,chast,r2 02690 END IF 02691 103 FORMAT(' index corrvalue residuum sigma', & 02692 ' nresid cnresid') 02693 104 FORMAT(i6,2X,2G12.4,' +-',g12.4,f7.2,1X,a3,f8.2) 02694 02695 DO j=1,jb-ja-1 ! normal equations, local parameter loop 02696 ij=inder(ja+j) ! local parameter index J 02697 blvec(ij)=blvec(ij)+DBLE(wght)*DBLE(rmeas)*DBLE(glder(ja+j)) 02698 DO k=1,j 02699 ik=inder(ja+k) ! local parameter index K 02700 jk=ijsym(ij,ik) ! index in symmetric matrix 02701 clmat(jk)=clmat(jk) & ! force double precision 02702 +DBLE(wght)*DBLE(glder(ja+j))*DBLE(glder(ja+k)) 02703 ! check for band matrix substructure 02704 IF (iter == 1) THEN 02705 id=IABS(ij-ik)+1 02706 im=MIN(ij,ik) 02707 ibandh(id)=MAX(ibandh(id),im) 02708 END IF 02709 END DO 02710 END DO 02711 END DO 02712 ! for non trivial fits check for bordered band matrix structure 02713 IF (iter == 1.AND.nalc > 5.AND.lfitbb > 0) THEN 02714 kx=-1 02715 kbdr=0 02716 kbdrx=0 02717 icmn=nalc**3 ! cost (*6) should improve by at least factor 2 02718 DO k=nalc,2,-1 02719 kbnd=k-2 02720 kbdr=MAX(kbdr,ibandh(k)) 02721 icost=6*(nalc-kbdr)*(kbnd+kbdr+1)**2+2*kbdr**3 02722 IF (icost < icmn) THEN 02723 icmn=icost 02724 kx=k 02725 kbdrx=kbdr 02726 END IF 02727 END DO 02728 IF (kx > 0) THEN 02729 mbnd=kx-2 02730 mbdr=kbdrx 02731 END IF 02732 END IF 02733 02734 IF (mbnd >= 0) THEN 02735 ! fast solution for border banded matrix (inverse for ICALCM>0) 02736 IF (nloopn == 1) THEN 02737 nbndr=nbndr+1 02738 nbdrx=MAX(nbdrx,mbdr) 02739 nbndx=MAX(nbndx,mbnd) 02740 END IF 02741 02742 inv=0 02743 IF (nloopn <= lfitnp.AND.iter == 1) inv=1 ! band part of inverse (for pulls) 02744 IF (icalcm == 1.OR.lprnt) inv=2 ! complete inverse 02745 CALL sqmibb(clmat,blvec,nalc,mbdr,mbnd,inv,nrank, & 02746 vbnd,vbdr,aux,vbk,vzru,scdiag,scflag) 02747 ELSE 02748 ! full inversion and solution 02749 inv=2 02750 CALL sqminv(clmat,blvec,nalc,nrank,scdiag,scflag) 02751 END IF 02752 ! check for NaNs 02753 nan=0 02754 DO k=1, nalc 02755 IF ((.NOT.(blvec(k) <= 0.0D0)).AND. (.NOT.(blvec(k) > 0.0D0))) nan=nan+1 02756 END DO 02757 02758 IF(lprnt) THEN 02759 WRITE(1,*) ' ' 02760 WRITE(1,*) 'Parameter determination:',nalc,' parameters,', ' rank=',nrank 02761 WRITE(1,*) '-----------------------' 02762 IF(ndown /= 0) WRITE(1,*) ' ',ndown,' data down-weighted' 02763 WRITE(1,*) ' ' 02764 END IF 02765 02766 ! ----- third loop ------------------------------------------------- 02767 ! calculate single residuals remaining after local fit and chi^2 02768 02769 summ=0.0D0 02770 suwt=0.0 02771 neq=0 02772 imeas=0 02773 ist=isfrst(ibuf) 02774 nst=islast(ibuf) 02775 DO ! loop over measurements 02776 CALL isjajb(nst,ist,ja,jb,jsp) 02777 IF(ja == 0) EXIT 02778 rmeas=glder(ja) ! data (global contrib. subtracted) 02779 rerr =glder(jb) ! ... and the error 02780 wght =1.0/rerr**2 ! weight from error 02781 neq=neq+1 ! count equation 02782 rmloc=0.0 ! local fit result reset 02783 DO j=1,jb-ja-1 ! local parameter loop 02784 ij=inder(ja+j) 02785 rmloc=rmloc+glder(ja+j)*SNGL(blvec(ij)) ! local fit result 02786 END DO 02787 localCorrections(neq)=rmloc ! save local fit result 02788 rmeas=rmeas-rmloc ! reduced to residual 02789 02790 ! calculate pulls? (needs covariance matrix) 02791 IF(iter == 1.AND.inv > 0.AND.nloopn <= lfitnp) THEN 02792 dvar=0.0D0 02793 DO j=1,jb-ja-1 02794 ij=inder(ja+j) 02795 DO k=1,jb-ja-1 02796 ik=inder(ja+k) 02797 jk=ijsym(ij,ik) 02798 dvar=dvar+clmat(jk)*DBLE(glder(ja+j))*DBLE(glder(ja+k)) 02799 END DO 02800 END DO 02801 ! some variance left to define a pull? 02802 IF (0.999999D0/DBLE(wght) > dvar) THEN 02803 pull=rmeas/SNGL(DSQRT(1.0D0/DBLE(wght)-dvar)) 02804 IF (lhist) THEN 02805 IF (jb < ist) THEN 02806 CALL hmpent(13,pull) ! histogram pull 02807 CALL gmpms(5,REC,pull) 02808 ELSE 02809 CALL hmpent(14,pull) ! histogram pull 02810 END IF 02811 END IF 02812 END IF 02813 END IF 02814 02815 IF(iter == 1.AND.jb < ist.AND.lhist) & 02816 CALL gmpms(4,REC,rmeas/rerr) ! residual (with global deriv.) 02817 02818 dchi2=wght*rmeas*rmeas 02819 ! DCHIT=DCHI2 02820 resid=rmeas 02821 IF(nloopn /= 1.AND.iter /= 1.AND.lhuber /= 0) THEN 02822 IF(iter <= 3) THEN 02823 IF(ABS(resid) > chuber*rerr) THEN ! down-weighting 02824 wght=wght*chuber*rerr/ABS(resid) 02825 dchi2=2.0*chuber*(ABS(resid)/rerr-0.5*chuber) 02826 END IF 02827 ELSE 02828 wght=wght/(1.0+(resid/rerr/cauchy)**2) 02829 dchi2=LOG(1.0+(resid/rerr/cauchy)**2)*cauchy**2 02830 END IF 02831 END IF 02832 02833 down=1.0/SQRT(wght) 02834 02835 ! SUWT=SUWT+DCHI2/DCHIT 02836 suwt=suwt+rerr/down 02837 IF(lprnt) THEN 02838 chast=' ' 02839 IF(ABS(resid) > chuber*rerr) chast='* ' 02840 IF(ABS(resid) > 3.0*rerr) chast='** ' 02841 IF(ABS(resid) > 6.0*rerr) chast='***' 02842 IF(imeas == 0) WRITE(1,*) 'Third loop: single residuals' 02843 IF(imeas == 0) WRITE(1,105) 02844 imeas=imeas+1 02845 r1=resid/rerr 02846 r2=resid/down 02847 IF(resid < 0.0) r1=-r1 02848 IF(resid < 0.0) r2=-r2 02849 WRITE(1,106) imeas,glder(ja),rmeas,rerr,r1,chast,r2 02850 END IF 02851 105 FORMAT(' index corrvalue residuum sigma', & 02852 ' nresid cnresid') 02853 106 FORMAT(i6,2X,2G12.4,' +-',g12.4,f7.2,1X,a3,f8.2) 02854 02855 IF(iter == nter) THEN 02856 readBufferDataF(ja)=rmeas ! store remaining residual 02857 resmax=MAX(resmax,ABS(rmeas)/rerr) 02858 END IF 02859 02860 IF(iter == 1.AND.lhist) THEN 02861 IF (jb < ist) THEN 02862 CALL hmpent( 3,rmeas/rerr) ! histogram norm residual 02863 ELSE 02864 CALL hmpent(12,rmeas/rerr) ! histogram norm residual 02865 END IF 02866 END IF 02867 summ=summ+dchi2 ! accumulate chi-square sum 02868 END DO 02869 ndf=neq-nrank 02870 ! external seed ? 02871 dch2sd=0.0D0 02872 resing=(FLOAT(nweig)-suwt)/FLOAT(nweig) 02873 IF (lhist) THEN 02874 IF(iter == 1) CALL hmpent( 5,FLOAT(ndf)) ! histogram Ndf 02875 IF(iter == 1) CALL hmpent(11,FLOAT(nalc)) ! histogram Nlocal 02876 IF(nloopn == 2.AND.iter == nter) CALL hmpent(6,resing) 02877 END IF 02878 IF(lprnt) THEN 02879 WRITE(1,*) ' ' 02880 WRITE(1,*) 'Chi^2=',summ,' at',ndf,' degrees of freedom: ', & 02881 '3-sigma limit is',chindl(3,ndf)*FLOAT(ndf) 02882 WRITE(1,*) suwt,' is sum of factors, compared to',nweig, & 02883 ' Downweight fraction:',resing 02884 END IF 02885 IF(nrank /= nalc.OR.nan > 0) THEN 02886 nrej(0)=nrej(0)+1 ! count cases 02887 IF (nrec3 == maxi4) nrec3=nrc 02888 IF(lprnt) THEN 02889 WRITE(1,*) ' rank deficit/NaN ', nalc, nrank, nan 02890 WRITE(1,*) ' ---> rejected!' 02891 END IF 02892 GO TO 90 02893 END IF 02894 IF(ndf <= 0) THEN 02895 nrej(1)=nrej(1)+1 ! count cases 02896 IF(lprnt) THEN 02897 WRITE(1,*) ' ---> rejected!' 02898 END IF 02899 GO TO 90 02900 END IF 02901 02902 chndf=SNGL(summ/dfloat(ndf)) 02903 02904 IF(iter == 1.AND.lhist) CALL hmpent(4,chndf) ! histogram chi^2/Ndf 02905 END DO ! outlier iteration loop 02906 02907 ndfs=ndfs+ndf ! (local) sum of Ndf 02908 sndf=sndf+dfloat(ndf)*dw1 ! (local) weighted sum of Ndf 02909 02910 ! ----- reject eventually ------------------------------------------ 02911 02912 IF(newite.AND.iterat == 2) THEN ! find record with largest Chi^2/Ndf 02913 IF(nrecp2 < 0.AND.chndf > writeBufferData(2,iproc+1)) THEN 02914 writeBufferData(2,iproc+1)=chndf 02915 writeBufferInfo(7,iproc+1)=nrc 02916 END IF 02917 END IF 02918 02919 chichi=chindl(3,ndf)*FLOAT(ndf) 02920 ! GF IF(SUMM.GT.50.0*CHICHI) THEN ! huge 02921 ! CHK CHICUT<0: NO cut (1st iteration) 02922 IF(chicut >= 0.0) THEN 02923 IF(summ > chhuge*chichi) THEN ! huge 02924 nrej(2)=nrej(2)+1 ! count cases with huge chi^2 02925 IF(lprnt) THEN 02926 WRITE(1,*) ' ---> rejected!' 02927 END IF 02928 GO TO 90 02929 END IF 02930 02931 IF(chicut > 0.0) THEN 02932 chlimt=chicut*chichi 02933 ! WRITE(*,*) 'chi^2 ',SUMM,CHLIMT,CHICUT,CHINDL(3,NDF),NDF 02934 IF(summ > chlimt) THEN 02935 IF(lprnt) THEN 02936 WRITE(1,*) ' ---> rejected!' 02937 END IF 02938 ! add to FVALUE 02939 dchi2=chlimt ! total contribution limit 02940 dchi2s=dchi2s+dchi2*dw1 ! add total contribution 02941 nrej(3)=nrej(3)+1 ! count cases with large chi^2 02942 GO TO 90 02943 END IF 02944 END IF 02945 END IF 02946 02947 IF(lhuber > 1.AND.dwcut /= 0.0.AND.resing > dwcut) THEN 02948 ! add to FVALUE 02949 dchi2=summ ! total contribution 02950 dchi2s=dchi2s+dchi2*dw1 ! add total contribution 02951 nrej(3)=nrej(3)+1 ! count cases with large chi^2 02952 ! WRITE(*,*) 'Downweight fraction cut ',RESING,DWCUT,SUMM 02953 IF(lprnt) THEN 02954 WRITE(1,*) ' ---> rejected!' 02955 END IF 02956 GO TO 90 02957 END IF 02958 02959 IF(newite.AND.iterat == 2) THEN ! find record with largest residual 02960 IF(nrecpr < 0.AND.resmax > writeBufferData(1,iproc+1)) THEN 02961 writeBufferData(1,iproc+1)=resmax 02962 writeBufferInfo(6,iproc+1)=nrc 02963 END IF 02964 END IF 02965 ! 'track quality' per binary file: accepted records 02966 naccf(kfl)=naccf(kfl)+1 02967 ndff(kfl) =ndff(kfl) +ndf 02968 chi2f(kfl)=chi2f(kfl)+chndf 02969 02970 ! ----- fourth loop ------------------------------------------------ 02971 ! update of global matrix and vector according to the "Millepede" 02972 ! principle, from the global/local information 02973 02974 dchi2s=dchi2s+dch2sd 02975 02976 ist=isfrst(ibuf) 02977 nst=islast(ibuf) 02978 DO ! loop over measurements 02979 CALL isjajb(nst,ist,ja,jb,jsp) 02980 IF(ja <= 0) EXIT 02981 02982 rmeas=glder(ja) ! data residual 02983 rerr =glder(jb) ! ... and the error 02984 wght =1.0/rerr**2 ! weight from measurement error 02985 dchi2=wght*rmeas*rmeas ! least-square contribution 02986 02987 IF(nloopn /= 1.AND.lhuber /= 0) THEN ! check residual 02988 resid=ABS(rmeas) 02989 IF(resid > chuber*rerr) THEN 02990 wght=wght*chuber*rerr/resid ! down-weighting 02991 dchi2=2.0*chuber*(resid/rerr-0.5*chuber) ! modified contribution 02992 END IF 02993 END IF 02994 dchi2s=dchi2s+dchi2*dw1 ! add to total objective function 02995 02996 ! global-global matrix contribution: add directly to gg-matrix 02997 02998 DO j=1,ist-jb 02999 ivgbj=globalParLabelIndex(2,inder(jb+j)) ! variable-parameter index 03000 IF(ivgbj > 0) THEN 03001 globalVector(ioffb+ivgbj)=globalVector(ioffb+ivgbj) & 03002 +dw1*wght*rmeas*glder(jb+j) ! vector !!! reverse 03003 IF(icalcm == 1) THEN 03004 ije=backIndexUsage(ioffe+ivgbj) ! get index of index, non-zero 03005 DO k=1,j 03006 ivgbk=globalParLabelIndex(2,inder(jb+k)) 03007 IF(ivgbk > 0) THEN 03008 ike=backIndexUsage(ioffe+ivgbk) ! get index of index, non-zero 03009 ia=MAX(ije,ike) ! larger 03010 ib=MIN(ije,ike) ! smaller 03011 ij=ib+(ia*ia-ia)/2 03012 writeBufferUpdates(ioffd+ij)=writeBufferUpdates(ioffd+ij) & 03013 -dw1*wght*glder(jb+j)*glder(jb+k) 03014 END IF 03015 END DO 03016 END IF 03017 END IF 03018 END DO 03019 03020 ! normal equations - rectangular matrix for global/local pars 03021 ! global-local matrix contribution: accumulate rectangular matrix 03022 IF (icalcm /= 1) CYCLE 03023 DO j=1,ist-jb 03024 ivgbj=globalParLabelIndex(2,inder(jb+j)) ! variable-parameter index 03025 IF(ivgbj > 0) THEN 03026 ije=backIndexUsage(ioffe+ivgbj) ! get index of index, non-zero 03027 DO k=1,jb-ja-1 03028 ik=inder(ja+k) ! local index 03029 jk=ik+(ije-1)*nalc ! matrix index 03030 localGlobalMatrix(jk)=localGlobalMatrix(jk)+dw2*wght*glder(jb+j)*glder(ja+k) 03031 END DO 03032 END IF 03033 END DO 03034 END DO 03035 03036 03037 ! ----- final matrix update ---------------------------------------- 03038 ! update global matrices and vectors 03039 IF(icalcm /= 1) GO TO 90 ! matrix update 03040 ! (inverse local matrix) * (rectang. matrix) -> CORM 03041 ! T 03042 ! resulting symmetrix matrix = G * Gamma^{-1} * G 03043 03044 CALL dbavat(clmat,localGlobalMatrix,writeBufferUpdates(ioffd+1),nalc,-nalg) 03045 03046 ! (rectang. matrix) * (local param vector) -> CORV 03047 ! resulting vector = G * q (q = local parameter) 03048 ! CALL DBGAX(DQ(IGLMA/2+1),BLVEC,DQ(ICORV/2+1),NALG,NALC) ! not done 03049 ! the vector update is not done, because after local fit it is zero! 03050 03051 ! update cache status 03052 writeBufferInfo(1,iproc+1)=writeBufferInfo(1,iproc+1)+1 03053 writeBufferInfo(2,iproc+1)=writeBufferInfo(2,iproc+1)+ngg 03054 writeBufferInfo(3,iproc+1)=writeBufferInfo(3,iproc+1)+nalg+2 03055 ! check free space 03056 nfred=writeBufferHeader(-1)-writeBufferInfo(2,iproc+1)-writeBufferHeader(-2) 03057 nfrei=writeBufferHeader(1)-writeBufferInfo(3,iproc+1)-writeBufferHeader(2) 03058 IF (nfred < 0.OR.nfrei < 0) THEN ! need to flush 03059 nb=writeBufferInfo(1,iproc+1) 03060 joffd=writeBufferHeader(-1)*iproc ! offset data 03061 joffi=writeBufferHeader(1)*iproc+2 ! offset indices 03062 used=FLOAT(writeBufferInfo(2,iproc+1))/FLOAT(writeBufferHeader(-1)) 03063 writeBufferInfo(4,iproc+1)=writeBufferInfo(4,iproc+1) +IFIX(1000.0*used+0.5) 03064 used=FLOAT(writeBufferInfo(3,iproc+1))/FLOAT(writeBufferHeader(1)) 03065 writeBufferInfo(5,iproc+1)=writeBufferInfo(5,iproc+1) +IFIX(1000.0*used+0.5) 03066 !$OMP CRITICAL 03067 writeBufferHeader(-4)=writeBufferHeader(-4)+1 03068 writeBufferHeader(4)=writeBufferHeader(4)+1 03069 03070 DO ib=1,nb 03071 ijn=0 03072 DO in=1,writeBufferIndices(joffi) 03073 i=writeBufferIndices(joffi+in) 03074 ! DQ(IGVEC/2+I)=DQ(IGVEC/2+I)+DQ(ICORV/2+IN) ! not done: = zero 03075 DO jn=1,in 03076 ijn=ijn+1 03077 j=writeBufferIndices(joffi+jn) 03078 CALL mupdat(i,j,-writeBufferUpdates(joffd+ijn)) ! matrix update 03079 END DO 03080 END DO 03081 joffd=joffd+ijn 03082 joffi=joffi+writeBufferIndices(joffi)+2 03083 END DO 03084 !$OMP END CRITICAL 03085 ! reset counter, pointers 03086 DO k=1,3 03087 writeBufferInfo(k,iproc+1)=0 03088 END DO 03089 END IF 03090 03091 90 IF(lprnt) THEN 03092 WRITE(1,*) ' ' 03093 WRITE(1,*) '------------------ End of printout for record',nrc 03094 WRITE(1,*) ' ' 03095 END IF 03096 03097 DO i=1,nalg ! reset global index array 03098 iext=globalIndexUsage(ioffc+i) 03099 backIndexUsage(ioffe+iext)=0 03100 END DO 03101 03102 END DO 03103 !$OMP END PARALLEL DO 03104 03105 IF (icalcm == 1) THEN 03106 ! flush remaining matrices 03107 DO k=1,mthrd ! update statistics 03108 writeBufferHeader(-3)=writeBufferHeader(-3)+1 03109 used=FLOAT(writeBufferInfo(2,k))/FLOAT(writeBufferHeader(-1)) 03110 writeBufferInfo(4,k)=writeBufferInfo(4,k)+IFIX(1000.0*used+0.5) 03111 writeBufferHeader(-5)=writeBufferHeader(-5)+writeBufferInfo(4,k) 03112 writeBufferHeader(-6)=MAX(writeBufferHeader(-6),writeBufferInfo(4,k)) 03113 writeBufferInfo(4,k)=0 03114 writeBufferHeader(3)=writeBufferHeader(3)+1 03115 used=FLOAT(writeBufferInfo(3,k))/FLOAT(writeBufferHeader(1)) 03116 writeBufferInfo(5,k)=writeBufferInfo(5,k)+IFIX(1000.0*used+0.5) 03117 writeBufferHeader(5)=writeBufferHeader(5)+writeBufferInfo(5,k) 03118 writeBufferHeader(6)=MAX(writeBufferHeader(6),writeBufferInfo(5,k)) 03119 writeBufferInfo(5,k)=0 03120 END DO 03121 03122 !$OMP PARALLEL & 03123 !$OMP DEFAULT(PRIVATE) & 03124 !$OMP SHARED(writeBufferHeader,writeBufferInfo,writeBufferIndices,writeBufferUpdates,MTHRD) 03125 iproc=0 03126 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number 03127 DO jproc=0,mthrd-1 03128 nb=writeBufferInfo(1,jproc+1) 03129 ! print *, ' flush end ', JPROC, NRC, NB 03130 joffd=writeBufferHeader(-1)*jproc ! offset data 03131 joffi=writeBufferHeader(1)*jproc+2 ! offset indices 03132 DO ib=1,nb 03133 ! print *, ' buf end ', JPROC,IB,writeBufferIndices(JOFFI-1),writeBufferIndices(JOFFI) 03134 ijn=0 03135 DO in=1,writeBufferIndices(joffi) 03136 i=writeBufferIndices(joffi+in) 03137 !$ IF (MOD(I,MTHRD).EQ.IPROC) THEN 03138 DO jn=1,in 03139 ijn=ijn+1 03140 j=writeBufferIndices(joffi+jn) 03141 CALL mupdat(i,j,-writeBufferUpdates(joffd+ijn)) ! matrix update 03142 END DO 03143 !$ ELSE 03144 !$ IJN=IJN+IN 03145 !$ ENDIF 03146 END DO 03147 joffd=joffd+ijn 03148 joffi=joffi+writeBufferIndices(joffi)+2 03149 END DO 03150 END DO 03151 !$OMP END PARALLEL 03152 END IF 03153 03154 IF(newite.AND.iterat == 2) THEN ! get worst records (for printrecord -1 -1) 03155 IF (nrecpr < 0) THEN 03156 DO k=1,mthrd 03157 IF (writeBufferData(1,k) > value1) THEN 03158 value1=writeBufferData(1,k) 03159 nrec1 =writeBufferInfo(6,k) 03160 END IF 03161 END DO 03162 END IF 03163 IF (nrecp2 < 0) THEN 03164 DO k=1,mthrd 03165 IF (writeBufferData(2,k) > value2) THEN 03166 value2=writeBufferData(2,k) 03167 nrec2 =writeBufferInfo(7,k) 03168 END IF 03169 END DO 03170 END IF 03171 END IF 03172 03173 END SUBROUTINE loopbf 03174 03175 03176 03177 03178 !*********************************************************************** 03179 03191 SUBROUTINE prtglo 03192 USE mpmod 03193 03194 IMPLICIT NONE 03195 REAL:: dpa 03196 REAL:: err 03197 REAL:: gcor 03198 INTEGER:: i 03199 INTEGER:: ie 03200 INTEGER:: iev 03201 INTEGER:: ij 03202 INTEGER:: imin 03203 INTEGER:: iprlim 03204 INTEGER:: isub 03205 INTEGER:: itgbi 03206 INTEGER:: itgbl 03207 INTEGER:: ivgbi 03208 INTEGER:: j 03209 INTEGER:: label 03210 INTEGER:: lup 03211 REAL:: par 03212 03213 DOUBLE PRECISION:: diag 03214 DOUBLE PRECISION::gmati 03215 DOUBLE PRECISION::gcor2 03216 INTEGER:: labele(3) 03217 INTEGER(KIND=large):: ii 03218 REAL:: compnt(3) 03219 SAVE 03220 ! ... 03221 03222 lup=09 03223 CALL mvopen(lup,'millepede.res') 03224 03225 WRITE(*,*) ' ' 03226 WRITE(*,*) ' Result of fit for global parameters' 03227 WRITE(*,*) ' ===================================' 03228 WRITE(*,*) ' ' 03229 03230 WRITE(*,101) 03231 03232 WRITE(lup,*) 'Parameter ! first 3 elements per line are', & 03233 ' significant (if used as input)' 03234 iprlim=10 03235 DO itgbi=1,ntgb ! all parameter variables 03236 itgbl=globalParLabelIndex(1,itgbi) 03237 ivgbi=globalParLabelIndex(2,itgbi) 03238 par=SNGL(globalParameter(itgbi)) ! initial value 03239 IF(ivgbi > 0) THEN 03240 dpa=par-globalParStart(itgbi) ! difference 03241 IF(metsol == 1.OR.metsol == 2) THEN 03242 ii=ivgbi 03243 ii=(ii*ii+ii)/2 03244 gmati=globalMatD(ii) 03245 ERR=SQRT(ABS(SNGL(gmati))) 03246 IF(gmati < 0.0D0) ERR=-ERR 03247 diag=workspaceD(ivgbi) 03248 gcor=-1.0 03249 IF(gmati*diag > 0.0D0) THEN ! global correlation 03250 gcor2=1.0D0-1.0D0/(gmati*diag) 03251 IF(gcor2 >= 0.0D0.AND.gcor2 <= 1.0D0) gcor=SNGL(DSQRT(gcor2)) 03252 END IF 03253 END IF 03254 END IF 03255 IF(itgbi <= iprlim) THEN 03256 IF(ivgbi <= 0) THEN 03257 WRITE(* ,102) itgbl,par,globalParPreSigma(itgbi) 03258 ELSE 03259 IF(metsol == 1.OR.metsol == 2) THEN 03260 IF (igcorr == 0) THEN 03261 WRITE(*,102) itgbl,par,globalParPreSigma(itgbi),dpa,ERR 03262 ELSE 03263 WRITE(*,102) itgbl,par,globalParPreSigma(itgbi),dpa,ERR,gcor 03264 END IF 03265 ELSE 03266 WRITE(*,102) itgbl,par,globalParPreSigma(itgbi),dpa 03267 END IF 03268 END IF 03269 ELSE IF(itgbi == iprlim+1) THEN 03270 WRITE(* ,*) '... (further printout suppressed, but see log file)' 03271 END IF 03272 03273 ! file output 03274 IF(ivgbi <= 0) THEN 03275 WRITE(lup,102) itgbl,par,globalParPreSigma(itgbi) 03276 ELSE 03277 IF(metsol == 1.OR.metsol == 2) THEN 03278 IF (igcorr == 0) THEN 03279 WRITE(lup,102) itgbl,par,globalParPreSigma(itgbi),dpa,ERR 03280 ELSE 03281 WRITE(lup,102) itgbl,par,globalParPreSigma(itgbi),dpa,ERR,gcor 03282 END IF 03283 ELSE 03284 WRITE(lup,102) itgbl,par,globalParPreSigma(itgbi),dpa 03285 END IF 03286 END IF 03287 END DO 03288 REWIND lup 03289 CLOSE(UNIT=lup) 03290 03291 IF(metsol == 2) THEN ! diagonalisation: write eigenvectors 03292 CALL mvopen(lup,'millepede.eve') 03293 imin=1 03294 DO i=nagb,1,-1 03295 IF(workspaceEigenValues(i) > 0.0D0) THEN 03296 imin=i ! index of smallest pos. eigenvalue 03297 EXIT 03298 ENDIF 03299 END DO 03300 iev=0 03301 03302 DO isub=0,MIN(15,imin-1) 03303 IF(isub < 10) THEN 03304 i=imin-isub 03305 ELSE 03306 i=isub-9 03307 END IF 03308 03309 ! DO I=IMIN,MAX(1,IMIN-9),-1 ! backward loop, up to 10 vectors 03310 WRITE(*,*) 'Eigenvector ',i,' with eigenvalue',workspaceEigenValues(i) 03311 WRITE(lup,*) 'Eigenvector ',i,' with eigenvalue',workspaceEigenValues(i) 03312 DO j=1,nagb 03313 ij=j+(i-1)*nagb ! index with eigenvector array 03314 IF(j <= nvgb) THEN 03315 itgbi=globalParVarToTotal(j) 03316 label=globalParLabelIndex(1,itgbi) 03317 ELSE 03318 label=nvgb-j ! label negative for constraints 03319 END IF 03320 iev=iev+1 03321 labele(iev)=label 03322 compnt(iev)=SNGL(workspaceEigenVectors(ij)) ! component 03323 IF(iev == 3) THEN 03324 WRITE(lup,103) (labele(ie),compnt(ie),ie=1,iev) 03325 iev=0 03326 END IF 03327 END DO 03328 IF(iev /= 0) WRITE(lup,103) (labele(ie),compnt(ie),ie=1,iev) 03329 iev=0 03330 WRITE(lup,*) ' ' 03331 END DO 03332 03333 END IF 03334 03335 101 FORMAT(1X,' label parameter presigma differ', & 03336 ' error'/ 1X,'-----------',4X,4('-------------')) 03337 102 FORMAT(i10,2X,4G14.5,f8.3) 03338 103 FORMAT(3(i11,f11.7,2X)) 03339 END SUBROUTINE prtglo ! print final log file 03340 03341 03350 03351 SUBROUTINE avprod(n,x,b) 03352 USE mpmod 03353 03354 IMPLICIT NONE 03355 INTEGER :: i 03356 INTEGER :: iencdb 03357 INTEGER :: iencdm 03358 INTEGER :: iproc 03359 INTEGER :: ir 03360 INTEGER :: j 03361 INTEGER :: jc 03362 INTEGER :: jj 03363 INTEGER :: jn 03364 03365 INTEGER, INTENT(IN) :: n 03366 DOUBLE PRECISION, INTENT(IN) :: x(n) 03367 DOUBLE PRECISION, INTENT(OUT) :: b(n) 03368 INTEGER(KIND=large) :: k 03369 INTEGER(KIND=large) :: kk 03370 INTEGER(KIND=large) :: kl 03371 INTEGER(KIND=large) :: ku 03372 INTEGER(KIND=large) :: ll 03373 INTEGER(KIND=large) :: lj 03374 INTEGER(KIND=large) :: indij 03375 INTEGER(KIND=large) :: indid 03376 INTEGER(KIND=large) :: ij 03377 INTEGER :: ichunk 03378 !$ INTEGER OMP_GET_THREAD_NUM 03379 SAVE 03380 ! ... 03381 !$ DO i=1,n 03382 !$ b(i)=0.0D0 ! reset 'global' B() 03383 !$ END DO 03384 ichunk=MIN((n+mthrd-1)/mthrd/8+1,1024) 03385 IF(matsto == 1) THEN 03386 ! full symmetric matrix 03387 ! parallelize row loop 03388 ! private copy of B(N) for each thread, combined at end, init with 0. 03389 ! slot of 1024 'I' for next idle thread 03390 !$OMP PARALLEL DO & 03391 !$OMP PRIVATE(J,IJ) & 03392 !$OMP REDUCTION(+:B) & 03393 !$OMP SCHEDULE(DYNAMIC,ichunk) 03394 DO i=1,n 03395 ij=i 03396 ij=(ij*ij-ij)/2 03397 b(i)=globalMatD(ij+i)*x(i) 03398 DO j=1,i-1 03399 b(j)=b(j)+globalMatD(ij+j)*x(i) 03400 b(i)=b(i)+globalMatD(ij+j)*x(j) 03401 END DO 03402 END DO 03403 !$OMP END PARALLEL DO 03404 ELSE 03405 ! sparse, compressed matrix 03406 IF(sparseMatrixOffsets(2,1) /= n+1) STOP 'AVPROD: mismatched vector and matrix' 03407 iencdb=nencdb 03408 iencdm=ishft(1,iencdb)-1 03409 ! parallelize row loop 03410 ! slot of 1024 'I' for next idle thread 03411 !$OMP PARALLEL DO & 03412 !$OMP PRIVATE(IR,K,KK,LL,KL,KU,INDID,INDIJ,J,JC,JN,LJ,JJ) & 03413 !$OMP REDUCTION(+:B) & 03414 !$OMP SCHEDULE(DYNAMIC,ichunk) 03415 DO i=1,n 03416 iproc=0 03417 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number 03418 b(i)=globalMatD(i)*x(i) ! diagonal elements 03419 ! ! off-diagonals double precision 03420 ir=i 03421 kk=sparseMatrixOffsets(1,ir) ! offset in 'd' (column lists) 03422 ll=sparseMatrixOffsets(2,ir) ! offset in 'j' (matrix) 03423 kl=0 03424 ku=sparseMatrixOffsets(1,ir+1)-1-kk 03425 indid=kk 03426 indij=ll 03427 IF (sparseMatrixColumns(indid) /= 0) THEN ! no compression 03428 DO k=kl,ku 03429 j=sparseMatrixColumns(indid+k) 03430 b(j)=b(j)+globalMatD(indij+k)*x(i) 03431 b(i)=b(i)+globalMatD(indij+k)*x(j) 03432 END DO 03433 ELSE 03434 lj=0 03435 ku=((ku+1)*8)/9-1 ! number of regions (-1) 03436 indid=indid+ku/8+1 ! skip group offsets 03437 DO kl=0,ku 03438 jc=sparseMatrixColumns(indid+kl) 03439 j=ishft(jc,-iencdb) 03440 jn=IAND(jc, iencdm) 03441 DO jj=1,jn 03442 b(j)=b(j)+globalMatD(indij+lj)*x(i) 03443 b(i)=b(i)+globalMatD(indij+lj)*x(j) 03444 j=j+1 03445 lj=lj+1 03446 END DO 03447 END DO 03448 END IF 03449 03450 IF (nspc > 1) THEN 03451 ir=i+n+1 ! off-diagonals single precision 03452 kk=sparseMatrixOffsets(1,ir) ! offset in 'd' (column lists) 03453 ll=sparseMatrixOffsets(2,ir) ! offset in '.' (matrix) 03454 kl=0 03455 ku=sparseMatrixOffsets(1,ir+1)-1-kk 03456 indid=kk 03457 indij=ll 03458 IF (sparseMatrixColumns(indid) /= 0) THEN ! no compression 03459 DO k=kl,ku 03460 j=sparseMatrixColumns(indid+k) 03461 b(j)=b(j)+DBLE(globalMatF(indij+k))*x(i) 03462 b(i)=b(i)+DBLE(globalMatF(indij+k))*x(j) 03463 END DO 03464 ELSE 03465 lj=0 03466 ku=((ku+1)*8)/9-1 ! number of regions (-1) 03467 indid=indid+ku/8+1 ! skip group offsets 03468 DO kl=0,ku 03469 jc=sparseMatrixColumns(indid+kl) 03470 j=ishft(jc,-iencdb) 03471 jn=IAND(jc, iencdm) 03472 DO jj=1,jn 03473 b(j)=b(j)+DBLE(globalMatF(indij+lj))*x(i) 03474 b(i)=b(i)+DBLE(globalMatF(indij+lj))*x(j) 03475 j=j+1 03476 lj=lj+1 03477 END DO 03478 END DO 03479 END IF 03480 END IF 03481 END DO 03482 !$OMP END PARALLEL DO 03483 ENDIF 03484 03485 END SUBROUTINE avprod 03486 03494 03495 FUNCTION ijadd(itema,itemb) ! index using "d" and "z" 03496 USE mpmod 03497 03498 IMPLICIT NONE 03499 INTEGER :: iencdb 03500 INTEGER :: iencdm 03501 INTEGER :: isgn 03502 INTEGER :: ispc 03503 INTEGER :: item2 03504 INTEGER :: jtem 03505 INTEGER :: jtemc 03506 INTEGER :: jtemn 03507 03508 INTEGER, INTENT(IN) :: itema 03509 INTEGER, INTENT(IN) :: itemb 03510 03511 INTEGER(KIND=large) :: ijadd 03512 INTEGER(KIND=large) :: k 03513 INTEGER(KIND=large) :: kk 03514 INTEGER(KIND=large) :: kl 03515 INTEGER(KIND=large) :: ku 03516 INTEGER(KIND=large) :: indid 03517 INTEGER(KIND=large) :: nd 03518 INTEGER(KIND=large) :: ll 03519 INTEGER(KIND=large) :: k8 03520 INTEGER(KIND=large) :: item1 03521 ! ... 03522 ijadd=0 03523 nd=sparseMatrixOffsets(2,1)-1 ! dimension of matrix 03524 item1=MAX(itema,itemb) ! larger index 03525 item2=MIN(itema,itemb) ! smaller index 03526 IF(item2 <= 0.OR.item1 > nd) RETURN 03527 IF(item1 == item2) THEN ! diagonal element 03528 ijadd=item1 03529 RETURN 03530 END IF 03531 ! ! off-diagonal element 03532 iencdb=nencdb ! encoding info 03533 iencdm=ishft(1,iencdb)-1 03534 isgn=-1 03535 outer: DO ispc=1,nspc 03536 kk=sparseMatrixOffsets(1,item1) ! offset in 'd' (column lists) 03537 ll=sparseMatrixOffsets(2,item1) ! offset in 'j' (matrix) 03538 kl=0 03539 ku=sparseMatrixOffsets(1,item1+1)-1-kk 03540 indid=kk 03541 item1=item1+nd+1 03542 isgn=-isgn 03543 IF (sparseMatrixColumns(indid) == 0) THEN ! compression ? 03544 03545 ku=((ku+1)*8)/9-1 ! number of regions (-1) 03546 indid=indid+ku/8+1 ! skip group offsets 03547 kl=0 03548 IF(ku < kl) CYCLE outer ! not found 03549 DO 03550 k=(kl+ku)/2 ! binary search 03551 jtemc=sparseMatrixColumns(indid+k) ! compressed information 03552 jtem =ishft(jtemc,-iencdb) ! first column of region 03553 jtemn=jtem+IAND(jtemc,iencdm) ! first column after region 03554 IF(item2 >= jtem.AND.item2 < jtemn) EXIT ! found 03555 IF(item2 < jtem) THEN 03556 ku=k-1 03557 ELSE IF(item2 >= jtemn) THEN 03558 kl=k+1 03559 END IF 03560 IF(kl <= ku) CYCLE 03561 CYCLE outer ! not found 03562 END DO 03563 k8=k/8 ! region group (-1) 03564 ll=ll+sparseMatrixColumns(kk+k8) ! offset for group of (8) regions 03565 DO kl=k8*8,k-1 03566 ll=ll+IAND(sparseMatrixColumns(indid+kl),iencdm) ! add region lengths 03567 END DO 03568 ijadd=ll+item2-jtem 03569 03570 ELSE 03571 03572 IF(ku < kl) CYCLE outer ! not found 03573 DO 03574 k=(kl+ku)/2 ! binary search 03575 jtem=sparseMatrixColumns(indid+k) 03576 jtemn=jtem 03577 IF(item2 == jtem) EXIT ! found 03578 IF(item2 < jtem) THEN 03579 ku=k-1 03580 ELSE IF(item2 > jtem) THEN 03581 kl=k+1 03582 END IF 03583 IF(kl <= ku) CYCLE 03584 CYCLE outer ! not found 03585 END DO 03586 ijadd=ll+k 03587 03588 END IF 03589 ijadd=ijadd*isgn 03590 RETURN 03591 END DO outer 03592 03593 END FUNCTION ijadd 03594 03603 03604 SUBROUTINE sechms(deltat,nhour,minut,secnd) 03605 IMPLICIT NONE 03606 REAL, INTENT(IN) :: deltat 03607 INTEGER, INTENT(OUT) :: minut 03608 INTEGER, INTENT(OUT):: nhour 03609 REAL, INTENT(OUT):: secnd 03610 INTEGER:: nsecd 03611 ! DELTAT = time in sec -> NHOUR,MINUT,SECND 03612 ! ... 03613 nsecd=nint(deltat) ! -> integer 03614 nhour=nsecd/3600 03615 minut=nsecd/60-60*nhour 03616 secnd=deltat-60*(minut+60*nhour) 03617 END SUBROUTINE sechms 03618 03646 03647 INTEGER FUNCTION inone(item) ! translate 1-D identifier to nrs 03648 USE mpmod 03649 USE mpdalc 03650 03651 IMPLICIT NONE 03652 INTEGER, INTENT(IN) :: item 03653 INTEGER :: j 03654 INTEGER :: k 03655 INTEGER :: iprime 03656 INTEGER(KIND=large) :: length 03657 INTEGER(KIND=large), PARAMETER :: two = 2 03658 03659 inone=0 03660 IF(item <= 0) RETURN 03661 IF(globalParHeader(-1) == 0) THEN 03662 length=128 ! initial number 03663 CALL mpalloc(globalParLabelIndex,two,length,'INONE: label & index') 03664 CALL mpalloc(globalParHashTable,2*length,'INONE: hash pointer') 03665 globalParHashTable = 0 03666 globalParHeader(-0)=INT(length) ! length of labels/indices 03667 globalParHeader(-1)=0 ! number of stored items 03668 globalParHeader(-2)=0 ! =0 during build-up 03669 globalParHeader(-3)=INT(length) ! next number 03670 globalParHeader(-4)=iprime(globalParHeader(-0)) ! prime number 03671 globalParHeader(-5)=0 ! number of overflows 03672 globalParHeader(-6)=0 ! nr of variable parameters 03673 END IF 03674 outer: DO 03675 j=1+MOD(item,globalParHeader(-4))+globalParHeader(-0) 03676 inner: DO ! normal case: find item 03677 k=j 03678 j=globalParHashTable(k) 03679 IF(j == 0) EXIT inner ! unused hash code 03680 IF(item == globalParLabelIndex(1,j)) EXIT outer ! found 03681 END DO inner 03682 ! not found 03683 IF(globalParHeader(-1) == globalParHeader(-0).OR.globalParHeader(-2) /= 0) THEN 03684 globalParHeader(-5)=globalParHeader(-5)+1 ! overflow 03685 j=0 03686 RETURN 03687 END IF 03688 globalParHeader(-1)=globalParHeader(-1)+1 ! increase number of elements 03689 globalParHeader(-3)=globalParHeader(-1) 03690 j=globalParHeader(-1) 03691 globalParHashTable(k)=j ! hash index 03692 globalParLabelIndex(1,j)=item ! add new item 03693 globalParLabelIndex(2,j)=0 ! reset counter 03694 IF(globalParHeader(-1) /= globalParHeader(-0)) EXIT outer 03695 ! update with larger dimension and redefine index 03696 globalParHeader(-3)=globalParHeader(-3)*2 03697 CALL upone 03698 IF (lvllog > 1) WRITE(lunlog,*) 'INONE: array increased to', & 03699 globalParHeader(-3),' words' 03700 END DO outer 03701 03702 IF(globalParHeader(-2) == 0) THEN 03703 globalParLabelIndex(2,j)=globalParLabelIndex(2,j)+1 ! increase counter 03704 globalParHeader(-7)=globalParHeader(-7)+1 03705 END IF 03706 inone=j 03707 END FUNCTION inone 03708 03710 SUBROUTINE upone 03711 USE mpmod 03712 USE mpdalc 03713 03714 IMPLICIT NONE 03715 INTEGER :: i 03716 INTEGER :: j 03717 INTEGER :: k 03718 INTEGER :: iprime 03719 INTEGER :: nused 03720 LOGICAL :: finalUpdate 03721 INTEGER(KIND=large) :: oldLength 03722 INTEGER(KIND=large) :: newLength 03723 INTEGER(KIND=large), PARAMETER :: two = 2 03724 INTEGER, DIMENSION(:,:), ALLOCATABLE :: tempArr 03725 SAVE 03726 ! ... 03727 finalUpdate=(globalParHeader(-3) == globalParHeader(-1)) 03728 IF(finalUpdate) THEN ! final (cleanup) call 03729 CALL sort2k(globalParLabelIndex,globalParHeader(-1)) ! sort items 03730 END IF 03731 ! save old LabelIndex 03732 nused = globalParHeader(-1) 03733 oldLength = globalParHeader(-0) 03734 CALL mpalloc(tempArr,two,oldLength,'INONE: temp array') 03735 tempArr(:,1:nused)=globalParLabelIndex(:,1:nused) 03736 CALL mpdealloc(globalParLabelIndex) 03737 CALL mpdealloc(globalParHashTable) 03738 ! create new LabelIndex 03739 newLength = globalParHeader(-3) 03740 CALL mpalloc(globalParLabelIndex,two,newLength,'INONE: label & index') 03741 CALL mpalloc(globalParHashTable,2*newLength,'INONE: hash pointer') 03742 globalParHashTable = 0 03743 globalParLabelIndex(:,1:nused) = tempArr(:,1:nused) ! copy back saved content 03744 CALL mpdealloc(tempArr) 03745 globalParHeader(-0)=INT(newLength) ! length of labels/indices 03746 globalParHeader(-3)=globalParHeader(-1) 03747 globalParHeader(-4)=iprime(globalParHeader(-0)) ! prime number < LNDA 03748 ! redefine hash 03749 outer: DO i=1,globalParHeader(-1) 03750 j=1+MOD(globalParLabelIndex(1,i),globalParHeader(-4))+globalParHeader(-0) 03751 inner: DO 03752 k=j 03753 j=globalParHashTable(k) 03754 IF(j == 0) EXIT inner ! unused hash code 03755 IF(j == i) CYCLE outer ! found 03756 ENDDO inner 03757 globalParHashTable(k)=i 03758 END DO outer 03759 IF(.NOT.finalUpdate) RETURN 03760 03761 globalParHeader(-2)=1 ! set flag to inhibit further updates 03762 IF (lvllog > 1) THEN 03763 WRITE(lunlog,*) ' ' 03764 WRITE(lunlog,*) 'INONE: array reduced to',newLength,' words' 03765 WRITE(lunlog,*) 'INONE:',globalParHeader(-1),' items stored.' 03766 END IF 03767 END SUBROUTINE upone ! update, redefine 03768 03773 03774 INTEGER FUNCTION iprime(n) 03775 IMPLICIT NONE 03776 INTEGER, INTENT(IN) :: n 03777 INTEGER :: nprime 03778 INTEGER :: nsqrt 03779 INTEGER :: i 03780 ! ... 03781 SAVE 03782 nprime=n ! max number 03783 IF(MOD(nprime,2) == 0) nprime=nprime+1 ! ... odd number 03784 outer: DO 03785 nprime=nprime-2 ! next lower odd number 03786 nsqrt=IFIX(SQRT(FLOAT(nprime))) 03787 DO i=3,nsqrt,2 ! 03788 IF(i*(nprime/i) == nprime) CYCLE outer ! test prime number 03789 END DO 03790 EXIT outer ! found 03791 END DO outer 03792 iprime=nprime 03793 END FUNCTION iprime 03794 03804 SUBROUTINE loop1 03805 USE mpmod 03806 USE mpdalc 03807 03808 IMPLICIT NONE 03809 INTEGER :: i 03810 INTEGER :: idum 03811 INTEGER :: in 03812 INTEGER :: indab 03813 INTEGER :: itgbi 03814 INTEGER :: itgbl 03815 INTEGER :: ivgbi 03816 INTEGER :: j 03817 INTEGER :: mqi 03818 INTEGER :: nc21 03819 INTEGER :: nr 03820 INTEGER :: nwrd 03821 INTEGER :: inone 03822 REAL :: param 03823 REAL :: presg 03824 REAL :: prewt 03825 03826 REAL :: plvs(3) ! vector array: real and ... 03827 INTEGER :: lpvs(3) ! ... integer 03828 EQUIVALENCE (plvs(1),lpvs(1)) 03829 INTEGER (KIND=large) :: length 03830 SAVE 03831 ! ... 03832 WRITE(lunlog,*) ' ' 03833 WRITE(lunlog,*) 'LOOP1: starting' 03834 CALL mstart('LOOP1') 03835 ! add labels from parameter, constraints, measurements ------------- 03836 DO i=1, lenParameters 03837 idum=inone(listParameters(i)%label) 03838 END DO 03839 DO i=1, lenPreSigmas 03840 idum=inone(listPreSigmas(i)%label) 03841 END DO 03842 DO i=1, lenConstraints 03843 idum=inone(listConstraints(i)%label) 03844 END DO 03845 DO i=1, lenMeasurements 03846 idum=inone(listMeasurements(i)%label) 03847 END DO 03848 03849 IF(globalParHeader(-1) /= 0) THEN 03850 WRITE(lunlog,*) 'LOOP1:',globalParHeader(-1), ' labels from txt data stored' 03851 END IF 03852 WRITE(lunlog,*) 'LOOP1: reading data files' 03853 03854 DO 03855 DO j=1,globalParHeader(-1) 03856 globalParLabelIndex(2,j)=0 ! reset count 03857 END DO 03858 03859 ! read all data files and add all labels to global labels table ---- 03860 03861 IF(mprint /= 0) THEN 03862 WRITE(*,*) 'Read all binary data files:' 03863 END IF 03864 CALL hmpldf(1,'Number of words/record in binary file') 03865 CALL hmpdef(8,0.0,60.0,'not_stored data per record') 03866 ! define read buffer 03867 nc21=ncache/(21*mthrdr) ! split read cache 1 : 10 : 10 for pointers, ints, floats 03868 nwrd=nc21+1 03869 length=nwrd*mthrdr 03870 CALL mpalloc(readBufferPointer,length,'read buffer, pointer') 03871 nwrd=nc21*10+2+ndimbuf 03872 length=nwrd*mthrdr 03873 CALL mpalloc(readBufferDataI,length,'read buffer, integer') 03874 CALL mpalloc(readBufferDataF,length,'read buffer, float') 03875 03876 DO 03877 CALL peread(nr) ! read records 03878 IF (skippedRecords == 0) CALL peprep(0) ! prepare records 03879 IF(nr <= 0) EXIT ! end of data? 03880 END DO 03881 ! release read buffer 03882 CALL mpdealloc(readBufferDataF) 03883 CALL mpdealloc(readBufferDataI) 03884 CALL mpdealloc(readBufferPointer) 03885 IF (skippedRecords == 0) THEN 03886 EXIT 03887 ELSE 03888 WRITE(lunlog,*) 'LOOP1: reading data files again' 03889 END IF 03890 END DO 03891 03892 IF(nhistp /= 0) THEN 03893 CALL hmprnt(1) 03894 CALL hmprnt(8) 03895 END IF 03896 CALL hmpwrt(1) 03897 CALL hmpwrt(8) 03898 CALL upone ! finalize the global label table 03899 ntgb = globalParHeader(-1) ! total number of labels/parameters 03900 WRITE(lunlog,*) 'LOOP1:',ntgb, & 03901 ' is total number NTGB of labels/parameters' 03902 ! histogram number of entries per label ---------------------------- 03903 CALL hmpldf(2,'Number of entries per label') 03904 DO j=1,ntgb 03905 CALL hmplnt(2,globalParLabelIndex(2,j)) 03906 END DO 03907 IF(nhistp /= 0) CALL hmprnt(2) ! print histogram 03908 CALL hmpwrt(2) ! write to his file 03909 03910 ! three subarrays for all global parameters ------------------------ 03911 length=ntgb 03912 CALL mpalloc(globalParameter,length,'global parameters') 03913 globalParameter=0.0D0 03914 CALL mpalloc(globalParPreSigma,length,'pre-sigmas') ! presigmas 03915 globalParPreSigma=0. 03916 CALL mpalloc(globalParStart,length,'global parameters at start') 03917 globalParStart=0. 03918 CALL mpalloc(globalParCopy,length,'copy of global parameters') 03919 03920 DO i=1,lenParameters ! parameter start values 03921 param=listParameters(i)%value 03922 in=inone(listParameters(i)%label) 03923 IF(in /= 0) THEN 03924 globalParameter(in)=param 03925 globalParStart(in)=param 03926 ENDIF 03927 END DO 03928 03929 npresg=0 03930 DO i=1,lenPreSigmas ! pre-sigma values 03931 presg=listPreSigmas(i)%value 03932 in=inone(listPreSigmas(i)%label) 03933 IF(in /= 0) THEN 03934 IF(presg > 0.0) npresg=npresg+1 ! FIXME: check if enough 'entries'? 03935 globalParPreSigma(in)=presg ! insert pre-sigma 0 or > 0 03936 END IF 03937 END DO 03938 WRITE(lunlog,*) 'LOOP1:',npresg,' is number of pre-sigmas' 03939 WRITE(*,*) 'LOOP1:',npresg,' is number of pre-sigmas' 03940 IF(npresg == 0) WRITE(*,*) 'Warning: no pre-sigmas defined' 03941 03942 ! determine flag variable (active) or fixed (inactive) ------------- 03943 03944 indab=0 03945 DO i=1,ntgb 03946 IF(globalParLabelIndex(2,i) >= mreqen.AND.globalParPreSigma(i) >= 0.0) THEN 03947 indab=indab+1 03948 globalParLabelIndex(2,i)=indab ! variable, used in matrix (active) 03949 ELSE 03950 globalParLabelIndex(2,i)=-1 ! fixed, not used in matrix (not active) 03951 END IF 03952 END DO 03953 globalParHeader(-6)=indab ! counted variable 03954 nvgb=indab ! nr of variable parameters 03955 WRITE(lunlog,*) 'LOOP1:',nvgb, ' is number NVGB of variable parameters' 03956 03957 ! translation table of length NVGB of total global indices --------- 03958 length=nvgb 03959 CALL mpalloc(globalParVarToTotal,length,'translation table var -> total') 03960 indab=0 03961 DO i=1,ntgb 03962 IF(globalParLabelIndex(2,i) > 0) THEN 03963 indab=indab+1 03964 globalParVarToTotal(indab)=i 03965 END IF 03966 END DO 03967 03968 ! regularization --------------------------------------------------- 03969 CALL mpalloc(globalParPreWeight,length,'pre-sigmas weights') ! presigma weights 03970 WRITE(*,112) ' Default pre-sigma =',regpre, & 03971 ' (if no individual pre-sigma defined)' 03972 WRITE(*,*) 'Pre-sigma factor is',regula 03973 03974 IF(nregul == 0) THEN 03975 WRITE(*,*) 'No regularization will be done' 03976 ELSE 03977 WRITE(*,*) 'Regularization will be done, using factor',regula 03978 END IF 03979 112 FORMAT(a,e9.2,a) 03980 IF (nvgb <= 0) STOP '... no variable global parameters' 03981 03982 DO ivgbi=1,nvgb ! IVGBI = variable parameter index 03983 itgbi=globalParVarToTotal(ivgbi) ! ITGBI = global parameter index 03984 presg=globalParPreSigma(itgbi) ! get pre-sigma 03985 prewt=0.0 ! pre-weight 03986 IF(presg > 0.0) THEN 03987 prewt=1.0/presg**2 ! 1/presigma^2 03988 ELSE IF(presg == 0.0.AND.regpre > 0.0) THEN 03989 prewt=1.0/regpre**2 ! default 1/presigma^2 03990 END IF 03991 globalParPreWeight(ivgbi)=regula*prewt ! weight = factor / presigma^2 03992 END DO 03993 03994 ! WRITE(*,*) 'GlPa_index GlPa_label array1 array6' 03995 DO i=1,ntgb 03996 itgbl=globalParLabelIndex(1,i) 03997 ivgbi=globalParLabelIndex(2,i) 03998 IF(ivgbi > 0) THEN 03999 ! WRITE(*,111) I,ITGBL,QM(IND1+I),QM(IND6+IVGBI) 04000 ELSE 04001 ! WRITE(*,111) I,ITGBL,QM(IND1+I) 04002 END IF 04003 END DO 04004 ! 111 FORMAT(I5,I10,F10.5,E12.4) 04005 WRITE(*,101) 'NTGB',ntgb,'total number of parameters' 04006 WRITE(*,101) 'NVGB',nvgb,'number of variable parameters' 04007 04008 ! print overview over important numbers ---------------------------- 04009 04010 nrecal=nrec 04011 IF(mprint /= 0) THEN 04012 WRITE(*,*) ' ' 04013 WRITE(*,101) ' NREC',nrec,'number of records' 04014 WRITE(*,101) 'MREQEN',mreqen,'required number of entries' 04015 IF (mreqpe > 1) WRITE(*,101) & 04016 'MREQPE',mreqpe,'required number of pair entries' 04017 IF (msngpe >= 1) WRITE(*,101) & 04018 'MSNGPE',msngpe,'max pair entries single prec. storage' 04019 WRITE(*,101) 'NTGB',ntgb,'total number of parameters' 04020 WRITE(*,101) 'NVGB',nvgb,'number of variable parameters' 04021 IF(mprint > 1) THEN 04022 WRITE(*,*) ' ' 04023 WRITE(*,*) 'Global parameter labels:' 04024 mqi=ntgb 04025 IF(mqi <= 100) THEN 04026 WRITE(*,*) (globalParLabelIndex(2,i),i=1,mqi) 04027 ELSE 04028 WRITE(*,*) (globalParLabelIndex(2,i),i=1,30) 04029 WRITE(*,*) ' ...' 04030 mqi=((mqi-20)/20)*20+1 04031 WRITE(*,*) (globalParLabelIndex(2,i),i=mqi,ntgb) 04032 END IF 04033 END IF 04034 WRITE(*,*) ' ' 04035 WRITE(*,*) ' ' 04036 END IF 04037 WRITE(8,*) ' ' 04038 WRITE(8,101) ' NREC',nrec,'number of records' 04039 WRITE(8,101) 'MREQEN',mreqen,'required number of entries' 04040 04041 WRITE(lunlog,*) 'LOOP1: ending' 04042 WRITE(lunlog,*) ' ' 04043 CALL mend 04044 04045 101 FORMAT(1X,a6,' =',i10,' = ',a) 04046 END SUBROUTINE loop1 04047 04058 04059 SUBROUTINE loop2 04060 USE mpmod 04061 USE mpdalc 04062 04063 IMPLICIT NONE 04064 REAL :: chin2 04065 REAL :: chin3 04066 REAL :: cpr 04067 REAL :: fsum 04068 REAL :: gbc 04069 REAL :: gbu 04070 REAL :: glder 04071 INTEGER :: i 04072 INTEGER :: ia 04073 INTEGER :: ib 04074 INTEGER :: ibuf 04075 INTEGER :: icgb 04076 INTEGER :: iext 04077 INTEGER :: ihis 04078 INTEGER :: ij 04079 INTEGER :: ijn 04080 INTEGER :: inder 04081 INTEGER :: ioff 04082 INTEGER :: iproc 04083 INTEGER :: irecmm 04084 INTEGER :: isfrst 04085 INTEGER :: islast 04086 INTEGER :: ist 04087 INTEGER :: itgbi 04088 INTEGER :: itgbij 04089 INTEGER :: itgbik 04090 INTEGER :: ivgbij 04091 INTEGER :: ivgbik 04092 INTEGER :: j 04093 INTEGER :: ja 04094 INTEGER :: jb 04095 INTEGER :: jcmprs 04096 INTEGER :: jext 04097 INTEGER :: jsp 04098 INTEGER :: k 04099 INTEGER :: kfile 04100 INTEGER :: l 04101 INTEGER :: label 04102 INTEGER :: last 04103 INTEGER :: lu 04104 INTEGER :: lun 04105 INTEGER :: maeqnf 04106 INTEGER :: naeqna 04107 INTEGER :: naeqnf 04108 INTEGER :: naeqng 04109 INTEGER :: nc21 04110 INTEGER :: ncachd 04111 INTEGER :: ncachi 04112 INTEGER :: ncachr 04113 INTEGER :: nda 04114 INTEGER :: ndf 04115 INTEGER :: ndfmax 04116 INTEGER :: nfixed 04117 INTEGER :: nggd 04118 INTEGER :: nggi 04119 INTEGER :: nmatmo 04120 INTEGER :: noff 04121 INTEGER :: nr 04122 INTEGER :: nrecf 04123 INTEGER :: nrecmm 04124 INTEGER :: nst 04125 INTEGER :: nwrd 04126 INTEGER :: inone 04127 REAL :: wgh 04128 REAL :: wolfc3 04129 REAL :: wrec 04130 REAL :: chindl 04131 04132 DOUBLE PRECISION::dstat(3) 04133 INTEGER*8:: noff8 04134 INTEGER(KIND=large):: ndimbi 04135 INTEGER(KIND=large):: ndimsa(4) 04136 INTEGER(KIND=large):: ndgn 04137 INTEGER(KIND=large):: matsiz(2) 04138 INTEGER(KIND=large):: matwords 04139 INTEGER(KIND=large):: length 04140 INTEGER(KIND=large):: rows 04141 INTEGER(KIND=large):: cols 04142 INTEGER(KIND=large), PARAMETER :: two=2 04143 INTEGER:: maxGlobalPar = 0 04144 INTEGER:: maxLocalPar = 0 04145 INTEGER:: maxEquations = 0 04146 04147 INTERFACE ! needed for assumed-shape dummy arguments 04148 SUBROUTINE ndbits(ndims,ncmprs,nsparr,mnpair,ihst,jcmprs) 04149 USE mpdef 04150 INTEGER(KIND=large), DIMENSION(4), INTENT(OUT) :: ndims 04151 INTEGER, DIMENSION(:), INTENT(OUT) :: ncmprs 04152 INTEGER(KIND=large), DIMENSION(:,:), INTENT(OUT) :: nsparr 04153 INTEGER, INTENT(IN) :: mnpair 04154 INTEGER, INTENT(IN) :: ihst 04155 INTEGER, INTENT(IN) :: jcmprs 04156 END SUBROUTINE ndbits 04157 SUBROUTINE spbits(nsparr,nsparc,ncmprs) 04158 USE mpdef 04159 INTEGER(KIND=large), DIMENSION(:,:), INTENT(IN) :: nsparr 04160 INTEGER, DIMENSION(:), INTENT(OUT) :: nsparc 04161 INTEGER, DIMENSION(:), INTENT(IN) :: ncmprs 04162 END SUBROUTINE spbits 04163 END INTERFACE 04164 04165 SAVE 04166 04167 !$ INTEGER :: OMP_GET_THREAD_NUM 04168 04169 isfrst(ibuf)=readBufferPointer(ibuf)+1 04170 islast(ibuf)=readBufferDataI(readBufferPointer(ibuf)) 04171 inder(i)=readBufferDataI(i) 04172 glder(i)=readBufferDataF(i) 04173 ! ... 04174 WRITE(lunlog,*) ' ' 04175 WRITE(lunlog,*) 'LOOP2: starting' 04176 CALL mstart('LOOP2') 04177 04178 ! two subarrays to get the global parameter indices, used in an event 04179 length=nvgb 04180 CALL mpalloc(globalIndexUsage,length,'global index') 04181 CALL mpalloc(backIndexUsage,length,'back index') 04182 backIndexUsage=0 04183 04184 ! constraints - determine number of constraints NCGB 04185 ncgb=0 04186 i=0 04187 last=-1 04188 ! find next constraint header and count nr of constraints 04189 DO WHILE(i < lenConstraints) 04190 i=i+1 04191 label=listConstraints(i)%label 04192 IF(last == 0.AND.label == (-1)) ncgb=ncgb+1 04193 last=label 04194 END DO 04195 WRITE(*,*) 'LOOP2:',ncgb,' constraints' 04196 04197 nagb=nvgb+ncgb ! total number of fit parameters 04198 noff8=int8(nagb)*int8(nagb-1)/2 04199 04200 ! read all data files and add all variable index pairs ------------- 04201 04202 IF(matsto == 2) THEN 04203 IF (mcmprs /= 0) numbit=MAX(numbit,2) ! identify single entries for compression 04204 CALL clbits(nagb,ndimbi,nencdb,numbit) ! get dimension for bit storage, encoding info 04205 END IF 04206 04207 ! reading events===reading events===reading events===reading events= 04208 nrecf =0 ! records with fixed global parameters 04209 naeqng=0 ! count number of equations (with global der.) 04210 naeqnf=0 ! count number of equations ( " , fixed) 04211 naeqna=0 ! all 04212 WRITE(lunlog,*) 'LOOP2: start event reading' 04213 ! monitoring for sparse matrix? 04214 irecmm=0 04215 IF (matsto == 2.AND.matmon /= 0) THEN 04216 nmatmo=0 04217 IF (matmon > 0) THEN 04218 nrecmm=matmon 04219 ELSE 04220 nrecmm=1 04221 END IF 04222 END IF 04223 DO k=1,3 04224 dstat(k)=0.0D0 04225 END DO 04226 ! define read buffer 04227 nc21=ncache/(21*mthrdr) ! split read cache 1 : 10 : 10 for pointers, ints, floats 04228 nwrd=nc21+1 04229 length=nwrd*mthrdr 04230 CALL mpalloc(readBufferPointer,length,'read buffer, pointer') 04231 nwrd=nc21*10+2+ndimbuf 04232 length=nwrd*mthrdr 04233 CALL mpalloc(readBufferDataI,length,'read buffer, integer') 04234 CALL mpalloc(readBufferDataF,length,'read buffer, float') 04235 04236 DO 04237 CALL peread(nr) ! read records 04238 CALL peprep(1) ! prepare records 04239 ioff=0 04240 DO ibuf=1,numReadBuffer ! buffer for current record 04241 nrec=readBufferDataI(isfrst(ibuf)-2) ! record 04242 ! Printout for DEBUG 04243 IF(nrec <= mdebug) THEN 04244 nda=0 04245 kfile=NINT(readBufferDataF(isfrst(ibuf)-1)) ! file 04246 wrec =readBufferDataF(isfrst(ibuf)-2) ! weight 04247 WRITE(*,*) ' ' 04248 WRITE(*,*) 'Record number ',nrec,' from file ',kfile 04249 IF (wgh /= 1.0) WRITE(*,*) ' weight ',wrec 04250 ist=isfrst(ibuf) 04251 nst=islast(ibuf) 04252 DO ! loop over measurements 04253 CALL isjajb(nst,ist,ja,jb,jsp) 04254 IF(ja == 0) EXIT 04255 nda=nda+1 04256 IF(nda > mdebg2) THEN 04257 IF(nda == mdebg2+1) WRITE(*,*) '... and more data' 04258 CYCLE 04259 END IF 04260 WRITE(*,*) ' ' 04261 WRITE(*,*) nda, ' Measured value =',glder(ja),' +- ',glder(jb) 04262 WRITE(*,*) 'Local derivatives:' 04263 WRITE(*,107) (inder(ja+j),glder(ja+j),j=1,jb-ja-1) 04264 107 FORMAT(6(i3,g12.4)) 04265 IF (jb < ist) THEN 04266 WRITE(*,*) 'Global derivatives:' 04267 WRITE(*,108) (globalParLabelIndex(1,inder(jb+j)),inder(jb+j), & 04268 globalParLabelIndex(2,inder(jb+j)),glder(jb+j),j=1,ist-jb) 04269 108 FORMAT(3I11,g12.4) 04270 END IF 04271 IF(nda == 1) THEN 04272 WRITE(*,*) 'total_par_label __label__ var_par_index derivative' 04273 END IF 04274 END DO 04275 WRITE(*,*) ' ' 04276 END IF 04277 04278 nagbn =0 ! count number of global derivatives 04279 nalcn =0 ! count number of local derivatives 04280 naeqn =0 ! count number of equations 04281 maeqnf=naeqnf 04282 ist=isfrst(ibuf) 04283 nst=islast(ibuf) 04284 nwrd=nst-ist+1 04285 DO ! loop over measurements 04286 CALL isjajb(nst,ist,ja,jb,jsp) 04287 IF(ja == 0.AND.jb == 0) EXIT 04288 naeqn=naeqn+1 04289 naeqna=naeqna+1 04290 IF(ja /= 0) THEN 04291 IF (ist > jb) naeqng=naeqng+1 04292 nfixed=0 04293 DO j=1,ist-jb 04294 ij=inder(jb+j) ! index of global parameter 04295 ij=globalParLabelIndex(2,ij) ! change to variable parameter 04296 IF(ij > 0) THEN 04297 ijn=backIndexUsage(ij) ! get index of index 04298 IF(ijn == 0) THEN ! not yet included 04299 nagbn=nagbn+1 ! count 04300 globalIndexUsage(nagbn)=ij ! store variable index 04301 backIndexUsage(ij)=nagbn ! store back index 04302 END IF 04303 ELSE 04304 nfixed=nfixed+1 04305 END IF 04306 END DO 04307 IF (nfixed > 0) naeqnf=naeqnf+1 04308 END IF 04309 04310 IF(ja /= 0.AND.jb /= 0) THEN 04311 DO j=1,jb-ja-1 ! local parameters 04312 ij=inder(ja+j) 04313 nalcn=MAX(nalcn,ij) 04314 END DO 04315 END IF 04316 END DO 04317 04318 ! end-of-event 04319 IF (naeqnf > maeqnf) nrecf=nrecf+1 04320 irecmm=irecmm+1 04321 ! end-of-event-end-of-event-end-of-event-end-of-event-end-of-event-e 04322 04323 maxGlobalPar=MAX(nagbn,maxGlobalPar) ! maximum number of global parameters 04324 maxLocalPar=MAX(nalcn,maxLocalPar) ! maximum number of local parameters 04325 maxEquations=MAX(naeqn,maxEquations) ! maximum number of equations 04326 04327 ! sample statistics for caching 04328 dstat(1)=dstat(1)+dfloat((nwrd+2)*2) ! record size 04329 dstat(2)=dstat(2)+dfloat(nagbn+2) ! indices, 04330 dstat(3)=dstat(3)+dfloat(nagbn*nagbn+nagbn) ! data for MUPDAT 04331 04332 CALL sort1k(globalIndexUsage,nagbn) ! sort global par. 04333 ! overwrite read buffer with lists of global labels 04334 ioff=ioff+1 04335 readBufferPointer(ibuf)=ioff 04336 readBufferDataI(ioff)=ioff+nagbn 04337 DO i=1,nagbn ! reset global index array 04338 iext=globalIndexUsage(i) 04339 backIndexUsage(iext)=0 04340 readBufferDataI(ioff+i)=iext 04341 END DO 04342 ioff=ioff+nagbn 04343 04344 END DO 04345 ioff=0 04346 04347 IF (matsto == 2) THEN 04348 !$OMP PARALLEL & 04349 !$OMP DEFAULT(PRIVATE) & 04350 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,MTHRD) 04351 iproc=0 04352 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number 04353 DO ibuf=1,numReadBuffer 04354 ist=isfrst(ibuf) 04355 nst=islast(ibuf) 04356 DO i=ist,nst ! store all combinations 04357 iext=readBufferDataI(i) ! variable global index 04358 !$ IF (MOD(IEXT,MTHRD).EQ.IPROC) THEN ! distinct rows per thread 04359 DO l=ist,i 04360 jext=readBufferDataI(l) 04361 CALL inbits(iext,jext,1) ! save space 04362 END DO 04363 !$ ENDIF 04364 END DO 04365 END DO 04366 !$OMP END PARALLEL 04367 ! monitoring 04368 IF (matmon /= 0.AND. & 04369 (irecmm >= nrecmm.OR.irecmm == mxrec)) THEN 04370 IF (nmatmo == 0) THEN 04371 WRITE(*,*) 04372 WRITE(*,*) 'Monitoring of sparse matrix construction' 04373 WRITE(*,*) ' records ........ off-diagonal elements ', & 04374 '....... compression memory' 04375 WRITE(*,*) ' non-zero used(double) used', & 04376 '(float) [%] [GB]' 04377 END IF 04378 nmatmo=nmatmo+1 04379 jcmprs=MAX(mcmprs,msngpe) 04380 CALL ckbits(ndimsa,mreqpe,jcmprs) 04381 gbc=4.0E-9*FLOAT(ndimsa(2)+2*ndimsa(3)+ndimsa(4)) ! GB compressed 04382 gbu=1.2E-8*FLOAT(ndimsa(3)+ndimsa(4)) ! GB uncompressed 04383 cpr=100.0*gbc/gbu 04384 WRITE(*,1177) irecmm,ndimsa(1),ndimsa(3),ndimsa(4),cpr,gbc 04385 1177 FORMAT(i9,3I13,f10.2,f11.6) 04386 DO WHILE(irecmm >= nrecmm) 04387 IF (matmon > 0) THEN 04388 nrecmm=nrecmm+matmon 04389 ELSE 04390 nrecmm=nrecmm*2 04391 END IF 04392 END DO 04393 END IF 04394 04395 END IF 04396 04397 IF (nr <= 0) EXIT ! next block of events ? 04398 END DO 04399 ! release read buffer 04400 CALL mpdealloc(readBufferDataF) 04401 CALL mpdealloc(readBufferDataI) 04402 CALL mpdealloc(readBufferPointer) 04403 04404 WRITE(lunlog,*) 'LOOP2: event reading ended - end of data' 04405 DO k=1,3 04406 dstat(k)=dstat(k)/dfloat(nrec) 04407 END DO 04408 ! end=of=data=end=of=data=end=of=data=end=of=data=end=of=data=end=of 04409 04410 IF(matsto == 2) THEN 04411 04412 ! constraints and index pairs with Lagrange multiplier 04413 04414 04415 ! constraints - determine number of constraints NCGB and index-pairs 04416 ! Lagrange multiplier and global parameters 04417 04418 04419 i=0 04420 icgb=0 04421 last=-1 04422 ! find next constraint header 04423 DO WHILE(i < lenConstraints) 04424 i=i+1 04425 label=listConstraints(i)%label 04426 IF(last == 0.AND.label == (-1)) icgb=icgb+1 04427 IF(label > 0) THEN 04428 itgbi=inone(label) 04429 ij=globalParLabelIndex(2,itgbi) ! change to variable parameter 04430 IF(ij > 0) THEN 04431 CALL inbits(nvgb+icgb,ij,mreqpe) 04432 END IF 04433 END IF 04434 last=label 04435 END DO 04436 04437 ! measurements - determine index-pairs 04438 04439 04440 i=1 04441 DO WHILE (i <= lenMeasurements) 04442 i=i+2 04443 ! loop over label/factor pairs 04444 ia=i 04445 DO 04446 i=i+1 04447 IF(i > lenMeasurements) EXIT 04448 IF(listMeasurements(i)%label == 0) EXIT 04449 END DO 04450 ib=i-1 04451 04452 DO j=ia,ib 04453 itgbij=inone(listMeasurements(j)%label) ! total parameter index 04454 ! first index 04455 ivgbij=0 04456 IF(itgbij /= 0) ivgbij=globalParLabelIndex(2,itgbij) ! variable-parameter index 04457 DO k=ia,j 04458 itgbik=inone(listMeasurements(k)%label) ! total parameter index 04459 ! second index 04460 ivgbik=0 04461 IF(itgbik /= 0) ivgbik=globalParLabelIndex(2,itgbik) ! variable-parameter index 04462 IF(ivgbij > 0.AND.ivgbik > 0) THEN 04463 CALL inbits(ivgbij,ivgbik,mreqpe) 04464 IF (mprint > 1) WRITE(*,*) 'add index pair ',ivgbij,ivgbik 04465 END IF 04466 END DO 04467 END DO 04468 04469 END DO 04470 END IF 04471 04472 ! print numbers ---------------------------------------------------- 04473 04474 IF (nagb >= 65536) THEN 04475 noff=INT(noff8/1000) 04476 ELSE 04477 noff=INT(noff8) 04478 END IF 04479 ndgn=0 04480 nspc=1 ! number of precision types (double, single) for matrix storage 04481 matwords=0 04482 IF(matsto == 2) THEN 04483 ihis=0 04484 IF (mhispe > 0) THEN 04485 ihis=15 04486 CALL hmpdef(ihis,0.0,FLOAT(mhispe), 'NDBITS: #off-diagonal elements') 04487 END IF 04488 jcmprs=MAX(mcmprs,msngpe) 04489 IF (jcmprs > 0.AND.numbit > 1) nspc=2 ! mixed precision storage 04490 length=nagb*nspc 04491 CALL mpalloc(sparseMatrixCompression,length,'INBITS: row compression') 04492 sparseMatrixCompression=0 04493 length=(nagb+1)*nspc 04494 CALL mpalloc(sparseMatrixOffsets,two,length, 'sparse matrix row offsets') 04495 CALL ndbits(ndimsa,sparseMatrixCompression,sparseMatrixOffsets, & 04496 mreqpe,ihis,jcmprs) 04497 ndgn=ndimsa(3)+ndimsa(4) ! actual number of off-diagonal elements 04498 matwords=ndimsa(2)+length ! size of sparsity structure 04499 04500 IF (mhispe > 0) THEN 04501 IF (nhistp /= 0) CALL hmprnt(ihis) 04502 CALL hmpwrt(ihis) 04503 END IF 04504 END IF 04505 04506 nagbn=maxGlobalPar ! max number of global parameters in one event 04507 nalcn=maxLocalPar ! max number of local parameters in one event 04508 naeqn=maxEquations ! max number of equations in one event 04509 CALL mpdealloc(globalIndexUsage) 04510 CALL mpdealloc(backIndexUsage) 04511 ! matrices for event matrices 04512 ! split up cache 04513 IF (fcache(2) == 0.0) THEN ! from data (DSTAT) 04514 fcache(1)=SNGL(dstat(1))*fcache(1) ! leave some part free for fluctuations 04515 fcache(2)=SNGL(dstat(2)) 04516 fcache(3)=SNGL(dstat(3)) 04517 END IF 04518 fsum=fcache(1)+fcache(2)+fcache(3) 04519 DO k=1,3 04520 fcache(k)=fcache(k)/fsum 04521 END DO 04522 ncachr=IFIX(FLOAT(ncache)*fcache(1)+0.5) ! read cache 04523 ! define read buffer 04524 nc21=ncachr/(21*mthrdr) ! split read cache 1 : 10 : 10 for pointers, ints, floats 04525 nwrd=nc21+1 04526 length=nwrd*mthrdr 04527 CALL mpalloc(readBufferPointer,length,'read buffer, pointer') 04528 nwrd=nc21*10+2+ndimbuf 04529 length=nwrd*mthrdr 04530 CALL mpalloc(readBufferDataI,length,'read buffer, integer') 04531 CALL mpalloc(readBufferDataF,length,'read buffer, float') 04532 04533 ncachi=IFIX(FLOAT(ncache)*fcache(2)+0.5) ! index cache 04534 ncachd=ncache-ncachr-ncachi ! data cache 04535 nggd=(nagbn*nagbn+nagbn)/2+ncachd/(2*mthrd) ! number of double 04536 nggi=2+nagbn+ncachi/mthrd ! number of ints 04537 length=nagbn*mthrd 04538 CALL mpalloc(globalIndexUsage,length, 'global parameters (dim =max/event)') 04539 length=nvgb*mthrd 04540 CALL mpalloc(backIndexUsage,length,'global variable-index array') 04541 backIndexUsage=0 04542 length=nagbn*nalcn 04543 CALL mpalloc(localGlobalMatrix,length,'local/global matrix') 04544 length=nggd*mthrd 04545 CALL mpalloc(writeBufferUpdates,length,'symmetric update matrices') 04546 writeBufferHeader(-1)=nggd ! number of words per thread 04547 writeBufferHeader(-2)=(nagbn*nagbn+nagbn)/2 ! min free (double) words 04548 length=nggi*mthrd 04549 CALL mpalloc(writeBufferIndices,length,'symmetric update matrix indices') 04550 rows=7; cols=mthrd 04551 CALL mpalloc(writeBufferInfo,rows,cols,'write buffer status (I)') 04552 rows=2; cols=mthrd 04553 CALL mpalloc(writeBufferData,rows,cols,'write buffer status (F)') 04554 writeBufferHeader(1)=nggi ! number of words per thread 04555 writeBufferHeader(2)=nagbn+2 ! min free words 04556 04557 ! print all relevant dimension parameters 04558 04559 DO lu=6,8,2 ! unit 6 and 8 04560 04561 WRITE(*,*) ' ' 04562 WRITE(lu,101) 'NTGB',ntgb,'total number of parameters' 04563 WRITE(lu,102) '(all parameters, appearing in binary files)' 04564 WRITE(lu,101) 'NVGB',nvgb,'number of variable parameters' 04565 WRITE(lu,102) '(appearing in fit matrix/vectors)' 04566 WRITE(lu,101) 'NAGB',nagb,'number of fit parameters' 04567 WRITE(lu,102) '(including Lagrange multiplier or reduced)' 04568 WRITE(lu,101) 'MBANDW',mbandw,'band width of band matrix' 04569 WRITE(lu,102) '(if =0, no band matrix)' 04570 IF (nagb >= 65536) THEN 04571 WRITE(lu,101) 'NOFF/K',noff,'max number of off-diagonal elements' 04572 ELSE 04573 WRITE(lu,101) 'NOFF',noff,'max number of off-diagonal elements' 04574 END IF 04575 IF(ndgn /= 0) & 04576 WRITE(lu,101) 'NDGN',ndgn,'actual number of off-diagonal elements' 04577 WRITE(lu,101) 'NCGB',ncgb,'number of constraints' 04578 WRITE(lu,101) 'NAGBN',nagbn,'max number of global parameters in an event' 04579 WRITE(lu,101) 'NALCN',nalcn,'max number of local parameters in an event' 04580 WRITE(lu,101) 'NAEQN',naeqn,'max number of equations in an event' 04581 IF (mprint > 1) THEN 04582 WRITE(lu,101) 'NAEQNA',naeqna,'number of equations' 04583 WRITE(lu,101) 'NAEQNG',naeqng, & 04584 'number of equations with global derivatives' 04585 WRITE(lu,101) 'NAEQNF',naeqnf, & 04586 'number of equations with fixed global derivatives' 04587 WRITE(lu,101) 'NRECF',nrecf, & 04588 'number of records with fixed global derivatives' 04589 END IF 04590 IF (ncache > 0) THEN 04591 WRITE(lu,101) 'NCACHE',ncache,'number of words for caching' 04592 WRITE(lu,111) (fcache(k)*100.0,k=1,3) 04593 111 FORMAT(22X,'cache splitting ',3(f6.1,' %')) 04594 END IF 04595 WRITE(lu,*) ' ' 04596 IF(matsto == 2) THEN 04597 ! FRUSE=FLOAT(MQ(INDF-1))/FLOAT(NOFF) 04598 ! WRITE(LU,123) 100.0*FRUSE 04599 END IF 04600 ! 123 FORMAT(' Fraction of non-zero off-diagonal elements is', 04601 ! + F6.1,' %') 04602 04603 ! print information about methods and matrix storage modes 04604 04605 WRITE(lu,*) ' ' 04606 WRITE(lu,*) 'Solution method and matrix-storage mode:' 04607 IF(metsol == 1) THEN 04608 WRITE(lu,*) ' METSOL = 1: matrix inversion' 04609 ELSE IF(metsol == 2) THEN 04610 WRITE(lu,*) ' METSOL = 2: diagonalization' 04611 ELSE IF(metsol == 3) THEN 04612 !GF WRITE(LU,*) ' METSOL = 3: MINRES' 04613 WRITE(lu,*) ' METSOL = 3: MINRES (rtol', mrestl,')' 04614 ELSE IF(metsol == 4) THEN 04615 WRITE(lu,*) ' METSOL = 4: GMRES' 04616 END IF 04617 WRITE(lu,*) ' with',mitera,' iterations' 04618 IF(matsto == 1) THEN 04619 WRITE(lu,*) ' MATSTO = 1: symmetric matrix, ', '(n*n+n)/2 elements' 04620 ELSE IF(matsto == 2) THEN 04621 WRITE(lu,*) ' MATSTO = 2: sparse matrix' 04622 END IF 04623 ! END IF 04624 IF(dflim /= 0.0) THEN 04625 WRITE(lu,103) 'Convergence assumed, if expected dF <',dflim 04626 END IF 04627 04628 END DO ! print loop 04629 04630 ! Wolfe conditions 04631 04632 IF(0.0 < wolfc1.AND.wolfc1 < wolfc2.AND.wolfc2 < 1.0) GO TO 32 04633 IF(wolfc1 == 0.0) wolfc1=1.0E-4 04634 IF(wolfc2 == 0.0) wolfc2=0.9 04635 IF(0.0 < wolfc1.AND.wolfc1 < wolfc2.AND.wolfc2 < 1.0) GO TO 32 04636 IF(wolfc1 <= 0.0) wolfc1=1.0E-4 04637 IF(wolfc2 >= 1.0) wolfc2=0.9 04638 IF(wolfc1 > wolfc2) THEN ! exchange 04639 wolfc3=wolfc1 04640 wolfc1=wolfc2 04641 wolfc2=wolfc3 04642 ELSE 04643 wolfc1=1.0E-4 04644 wolfc2=0.9 04645 END IF 04646 WRITE(*,105) wolfc1,wolfc2 04647 WRITE(lun,105) wolfc1,wolfc2 04648 105 FORMAT(' Constants C1, C2 for Wolfe conditions:',g12.4,', ',g12.4) 04649 04650 ! prepare matrix and gradient storage ------------------------------ 04651 !32 CONTINUE 04652 32 matsiz(1)=int8(nagb)*int8(nagb+1)/2 ! number of words for double precision storage 'j' 04653 matsiz(2)=0 ! number of words for single precision storage '.' 04654 IF(matsto == 2) THEN ! sparse matrix 04655 matsiz(1)=ndimsa(3)+nagb 04656 matsiz(2)=ndimsa(4) 04657 CALL mpalloc(sparseMatrixColumns,ndimsa(2),'sparse matrix column list') 04658 CALL spbits(sparseMatrixOffsets,sparseMatrixColumns,sparseMatrixCompression) 04659 END IF 04660 matwords=matwords+matsiz(1)*2+matsiz(2) ! #words for matrix storage 04661 04662 CALL feasma ! prepare constraint matrices 04663 04664 CALL vmprep(matsiz) ! prepare matrix and gradient storage 04665 WRITE(*,*) ' ' 04666 IF (matwords < 250000) THEN 04667 WRITE(*,*) 'Size of global matrix: < 1 MB' 04668 ELSE 04669 WRITE(*,*) 'Size of global matrix:',INT(FLOAT(matwords)*4.0E-6),' MB' 04670 ENDIF 04671 ! print chi^2 cut tables 04672 04673 ndfmax=naeqn-1 04674 WRITE(lunlog,*) ' ' 04675 WRITE(lunlog,*) ' Cut values of Chi^2/Ndf and Chi2,' 04676 WRITE(lunlog,*) ' corresponding to 2 and 3 standard deviations' 04677 WRITE(lunlog,*) ' Ndf Chi^2/Ndf(2) Chi^2(2) ', & 04678 ' Chi^2/Ndf(3) Chi^2(3)' 04679 ndf=0 04680 DO 04681 IF(ndf > naeqn) EXIT 04682 IF(ndf < 10) THEN 04683 ndf=ndf+1 04684 ELSE IF(ndf < 20) THEN 04685 ndf=ndf+2 04686 ELSE IF(ndf < 100) THEN 04687 ndf=ndf+5 04688 ELSE IF(ndf < 200) THEN 04689 ndf=ndf+10 04690 ELSE 04691 EXIT 04692 END IF 04693 chin2=chindl(2,ndf) 04694 chin3=chindl(3,ndf) 04695 WRITE(lunlog,106) ndf,chin2,chin2*FLOAT(ndf),chin3, chin3*FLOAT(ndf) 04696 END DO 04697 04698 WRITE(lunlog,*) 'LOOP2: ending' 04699 WRITE(lunlog,*) ' ' 04700 CALL mend 04701 101 FORMAT(1X,a6,' =',i10,' = ',a) 04702 102 FORMAT(22X,a) 04703 103 FORMAT(1X,a,g12.4) 04704 106 FORMAT(i6,2(3X,f9.3,f12.1,3X)) 04705 END SUBROUTINE loop2 04706 04710 04711 SUBROUTINE vmprep(msize) 04712 USE mpmod 04713 USE mpdalc 04714 04715 IMPLICIT NONE 04716 INTEGER :: i 04717 INTEGER :: nmats 04718 ! 04719 INTEGER(KIND=large), INTENT(IN) :: msize(2) 04720 04721 INTEGER(KIND=large) :: length 04722 SAVE 04723 ! ... 04724 ! Vector/matrix storage 04725 length=nagb*mthrd 04726 CALL mpalloc(globalVector,length,'rhs vector') ! double precision vector 04727 lenGlobalVec=nagb 04728 length=naeqn 04729 CALL mpalloc(localCorrections,length,'residual vector of one record') 04730 length=nalcn*nalcn 04731 CALL mpalloc(aux,length,' local fit scratch array: aux') 04732 CALL mpalloc(vbnd,length,' local fit scratch array: vbnd') 04733 CALL mpalloc(vbdr,length,' local fit scratch array: vbdr') 04734 length=((nalcn+1)*nalcn)/2 04735 CALL mpalloc(clmat,length,' local fit matrix: clmat') 04736 CALL mpalloc(vbk,length,' local fit scratch array: vbk') 04737 length=nalcn 04738 CALL mpalloc(blvec,length,' local fit vector: blvec') 04739 CALL mpalloc(vzru,length,' local fit scratch array: vzru') 04740 CALL mpalloc(scdiag,length,' local fit scratch array: scdiag') 04741 CALL mpalloc(scflag,length,' local fit scratch array: scflag') 04742 CALL mpalloc(ibandh,length,' local fit band width hist.: ibandh') 04743 04744 CALL mpalloc(globalMatD,msize(1),'global matrix (D)' ) 04745 CALL mpalloc(globalMatF,msize(2),'global matrix (F)') 04746 04747 IF(metsol >= 3) THEN ! GMRES/MINRES algorithms 04748 ! array space is: 04749 ! variable-width band matrix or diagonal matrix for parameters 04750 ! followed by rectangular matrix for constraints 04751 ! followed by symmetric matrix for constraints 04752 IF(mbandw > 0) THEN ! variable-width band matrix 04753 length=nagb 04754 CALL mpalloc(indPreCond,length,'pointer-array variable-band matrix') 04755 DO i=1,MIN(mbandw,nvgb) 04756 indPreCond(i)=(i*i+i)/2 ! increasing number 04757 END DO 04758 DO i=MIN(mbandw,nvgb)+1,nvgb 04759 indPreCond(i)=indPreCond(i-1)+mbandw ! fixed band width 04760 END DO 04761 DO i=nvgb+1,nagb ! reset 04762 indPreCond(i)=0 04763 END DO 04764 length=indPreCond(nvgb)+ncgb*nvgb+(ncgb*ncgb+ncgb)/2 04765 CALL mpalloc(matPreCond,length,'variable-band matrix') 04766 ELSE ! default preconditioner 04767 length=nvgb+ncgb*nvgb+(ncgb*ncgb+ncgb)/2 04768 CALL mpalloc(matPreCond,length,'default preconditioner matrix') 04769 END IF 04770 END IF 04771 04772 04773 length=nagb 04774 CALL mpalloc(globalCorrections,length,'corrections') ! double prec corrections 04775 04776 CALL mpalloc(workspaceLinesearch,length,'auxiliary array (D2)') ! double aux 2 04777 CALL mpalloc(workspaceI, length,'auxiliary array (I)') ! int aux 1 04778 CALL mpalloc(workspaceMinres,length,'auxiliary array (D7)') ! double aux 7 04779 04780 IF(metsol == 1) THEN 04781 CALL mpalloc(workspaceD,length,'auxiliary array (D1)') ! double aux 1 04782 ! CALL MEGARR('t D',2*NAGB,'auxiliary array') ! double aux 8 04783 END IF 04784 04785 IF(metsol == 2) THEN 04786 CALL mpalloc(workspaceD,length,'auxiliary array (D1)') ! double aux 1 04787 CALL mpalloc(workspaceDiagonalization,length,'auxiliary array (D3)') ! double aux 3 04788 CALL mpalloc(workspaceEigenValues,length,'auxiliary array (D6)') ! double aux 6 04789 length=nagb*nagb 04790 CALL mpalloc(workspaceEigenVectors,length,'(rotation) matrix U') ! rotation matrix 04791 END IF 04792 04793 IF(metsol >= 3) THEN 04794 nmats=6 04795 length=nmats*nagb 04796 CALL mpalloc(workspaceD,length,'auxiliary array (D1)') ! double aux 1 04797 END IF 04798 04799 END SUBROUTINE vmprep 04800 04804 04805 SUBROUTINE minver 04806 USE mpmod 04807 04808 IMPLICIT NONE 04809 INTEGER :: lun 04810 INTEGER :: ndefec 04811 INTEGER :: nrank 04812 04813 SAVE 04814 ! ... 04815 lun=lunlog ! log file 04816 IF(lunlog == 0) lunlog=6 04817 04818 ! WRITE(*,*) 'MINVER ICALCM=',ICALCM 04819 IF(icalcm == 1) THEN 04820 CALL sqminl(globalMatD, globalCorrections,nagb,nrank, & 04821 workspaceD,workspaceI) 04822 ndefec=nagb-nrank ! rank defect 04823 IF(ndefec /= 0) THEN 04824 WRITE(*,*) 'The rank defect of the symmetric',nagb, & 04825 '-by-',nagb,' matrix is ',ndefec,' (should be zero).' 04826 WRITE(lun,*) 'The rank defect of the symmetric',nagb, & 04827 '-by-',nagb,' matrix is ',ndefec,' (should be zero).' 04828 IF (iforce == 0) THEN 04829 isubit=1 04830 WRITE(*,*) ' --> enforcing SUBITO mode' 04831 WRITE(lun,*) ' --> enforcing SUBITO mode' 04832 END IF 04833 ELSE 04834 WRITE(lun,*) 'No rank defect of the symmetric matrix' 04835 END IF 04836 04837 ELSE ! multiply gradient by inverse matrix 04838 CALL dbsvxl(globalMatD,globalVector,globalCorrections,nagb) 04839 END IF 04840 END SUBROUTINE minver 04841 04843 SUBROUTINE mdiags 04844 USE mpmod 04845 04846 IMPLICIT NONE 04847 REAL :: evalue 04848 INTEGER :: i 04849 INTEGER :: iast 04850 INTEGER :: idia 04851 INTEGER :: imin 04852 INTEGER :: lun 04853 INTEGER :: nmax 04854 INTEGER :: nmin 04855 INTEGER :: ntop 04856 INTEGER :: nvar 04857 ! 04858 INTEGER(KIND=large) :: ii 04859 SAVE 04860 ! ... 04861 04862 lun=lunlog ! log file 04863 IF(lunlog == 0) lun=6 04864 04865 IF(icalcm == 1) THEN 04866 nvar=nagb 04867 DO i=1,nvar ! used in FEASIB 04868 ii=i 04869 workspaceD(i)=globalMatD((ii*ii+ii)/2) ! save diagonal elements 04870 END DO 04871 04872 ! eigenvalues eigenvectors symm_input 04873 CALL devrot(nvar,workspaceEigenValues,workspaceEigenVectors,globalMatD, & 04874 workspaceDiagonalization,workspaceI) 04875 04876 ! histogram of positive eigenvalues 04877 04878 nmax=INT(1.0+LOG10(SNGL(workspaceEigenValues(1)))) ! > log of largest eigenvalue 04879 imin=1 04880 DO i=nagb,1,-1 04881 IF(workspaceEigenValues(i) > 0.0D0) THEN 04882 imin=i ! index of smallest pos. eigenvalue 04883 EXIT 04884 END IF 04885 END DO 04886 nmin=INT(LOG10(SNGL(workspaceEigenValues(imin)))) ! log of smallest pos. eigenvalue 04887 ntop=nmin+6 04888 DO WHILE(ntop < nmax) 04889 ntop=ntop+3 04890 END DO 04891 04892 CALL hmpdef(7,FLOAT(nmin),FLOAT(ntop), 'log10 of positive eigenvalues') 04893 DO idia=1,nagb 04894 IF(workspaceEigenValues(idia) > 0.0D0) THEN ! positive 04895 evalue=LOG10(SNGL(workspaceEigenValues(idia))) 04896 CALL hmpent(7,evalue) 04897 END IF 04898 END DO 04899 IF(nhistp /= 0) CALL hmprnt(7) 04900 CALL hmpwrt(7) 04901 04902 iast=MAX(1,imin-60) 04903 CALL gmpdef(3,2,'low-value end of eigenvalues') 04904 DO i=iast,nagb 04905 evalue=SNGL(workspaceEigenValues(i)) 04906 CALL gmpxy(3,FLOAT(i),evalue) 04907 END DO 04908 IF(nhistp /= 0) CALL gmprnt(3) 04909 CALL gmpwrt(3) 04910 04911 DO i=1,nvar 04912 workspaceDiagonalization(i)=0.0D0 04913 IF(workspaceEigenValues(i) /= 0.0D0) THEN 04914 workspaceDiagonalization(i)=MAX(0.0D0,LOG10(ABS(workspaceEigenValues(i)))+3.0D0) 04915 IF(workspaceEigenValues(i) < 0.0D0) workspaceDiagonalization(i)=-workspaceDiagonalization(i) 04916 END IF 04917 END DO 04918 WRITE(lun,*) ' ' 04919 WRITE(lun,*) 'The first (largest) eigenvalues ...' 04920 WRITE(lun,102) (workspaceEigenValues(i),i=1,MIN(20,nagb)) 04921 WRITE(lun,*) ' ' 04922 WRITE(lun,*) 'The last eigenvalues ... up to',nvgb 04923 WRITE(lun,102) (workspaceEigenValues(i),i=MAX(1,nvgb-19),nvgb) 04924 WRITE(lun,*) ' ' 04925 WRITE(lun,*) 'The eigenvalues from',nvgb+1,' to',nagb 04926 WRITE(lun,102) (workspaceEigenValues(i),i=nvgb+1,nagb) 04927 WRITE(lun,*) ' ' 04928 WRITE(lun,*) 'Log10 + 3 of ',nagb,' eigenvalues in decreasing', ' order' 04929 WRITE(lun,*) '(for Eigenvalue < 0.001 the value 0.0 is shown)' 04930 WRITE(lun,101) (workspaceDiagonalization(i),i=1,nagb) 04931 IF(workspaceDiagonalization(nvar) < 0) WRITE(lun,*) 'Negative values are ', & 04932 'printed for negative eigenvalues' 04933 CALL devsig(nagb,workspaceEigenValues,workspaceEigenVectors,globalVector,workspaceDiagonalization) 04934 WRITE(lun,*) ' ' 04935 WRITE(lun,*) nvgb,' significances: insignificant if ', & 04936 'compatible with N(0,1)' 04937 WRITE(lun,101) (workspaceDiagonalization(i),i=1,nvgb) 04938 04939 04940 101 FORMAT(10F7.1) 04941 102 FORMAT(5E14.6) 04942 04943 END IF 04944 04945 ! solution --------------------------------------------------------- 04946 04947 ! eigenvalues eigenvectors 04948 CALL devsol(nvar,workspaceEigenValues,workspaceEigenVectors,globalVector,globalCorrections,workspaceDiagonalization) 04949 RETURN 04950 END SUBROUTINE mdiags 04951 04953 SUBROUTINE zdiags 04954 USE mpmod 04955 04956 IMPLICIT NONE 04957 ! eigenvalue eigenvectors cov.matrix 04958 CALL devinv(nagb,workspaceEigenValues,workspaceEigenVectors,globalMatD) ! inv 04959 04960 END SUBROUTINE zdiags 04961 04967 04968 SUBROUTINE mminrs 04969 USE mpmod 04970 04971 IMPLICIT NONE 04972 INTEGER :: istop 04973 INTEGER :: itn 04974 INTEGER :: itnlim 04975 INTEGER :: lun 04976 INTEGER :: nout 04977 INTEGER :: nrkd 04978 INTEGER :: nrkd2 04979 04980 DOUBLE PRECISION :: shift 04981 DOUBLE PRECISION :: rtol 04982 DOUBLE PRECISION :: anorm 04983 DOUBLE PRECISION :: acond 04984 DOUBLE PRECISION :: rnorm 04985 DOUBLE PRECISION :: ynorm 04986 LOGICAL :: checka 04987 EXTERNAL avprod, mvsolv, mcsolv 04988 SAVE 04989 ! ... 04990 lun=lunlog ! log file 04991 IF(lunlog == 0) lun=6 04992 04993 nout=lun 04994 itnlim=2000 ! iteration limit 04995 shift =0.0D0 ! not used 04996 rtol = mrestl ! from steering 04997 checka=.FALSE. 04998 04999 ! WRITE(*,*) 'METSOL MATSTO',METSOL,MATSTO 05000 05001 ! WRITE(*,*) 'Input vector' 05002 ! WRITE(*,*) (DQ(IGVEC/2+I),I=1,NAGB) 05003 05004 IF(mbandw == 0) THEN ! default preconditioner 05005 IF(icalcm == 1) THEN 05006 ! WRITE(LUN,*) 'MMINRS: PRECON started' 05007 CALL precon(ncgb,nvgb,matPreCond,matPreCond, matPreCond(1+nvgb), & 05008 matPreCond(1+nvgb+ncgb*nvgb)) 05009 ! WRITE(LUN,*) 'MMINRS: PRECON ended' 05010 END IF 05011 05012 ! WRITE(*,*) 'NAGB MBANDW ',NAGB,MBANDW 05013 ! WRITE(*,*) IGVEC,IDUX1,ISOLV,IDUX7 05014 05015 CALL minres(nagb,globalVector, & 05016 workspaceD(1), workspaceD(1+nagb), workspaceD(1+2*nagb), & 05017 workspaceD(1+3*nagb),workspaceD(1+4*nagb),workspaceD(1+5*nagb), & 05018 globalCorrections,workspaceMinres, avprod, mcsolv, checka ,.TRUE. , shift, & 05019 nout , itnlim, rtol, istop, itn, anorm, acond, rnorm, ynorm) 05020 ! WRITE(*,*) 'MINRES ended' 05021 ! + DQ(IDUX1/2+1),DQ(IDUX8/2+1),DQ(IDUX3/2+1), 05022 ! + DQ(IDUX4/2+1),DQ(IDUX5/2+1),DQ(IDUX6/2+1), 05023 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner 05024 IF(icalcm == 1) THEN 05025 WRITE(lun,*) 'MMINRS: EQUDEC started' 05026 CALL equdec(nvgb,ncgb,matPreCond,indPreCond,nrkd,nrkd2) 05027 WRITE(lun,*) 'MMINRS: EQUDEC ended' 05028 END IF 05029 CALL minres(nagb,globalVector, & 05030 workspaceD(1), workspaceD(1+nagb), workspaceD(1+2*nagb), & 05031 workspaceD(1+3*nagb),workspaceD(1+4*nagb),workspaceD(1+5*nagb), & 05032 globalCorrections,workspaceMinres, avprod, mvsolv, checka ,.TRUE. , shift, & 05033 nout, itnlim, rtol, istop, itn, anorm, acond, rnorm, ynorm) 05034 ELSE 05035 ! IF(ICALCM.NE.0) WRITE(LUN,*) 'MMINRS: no preconditioning !!!' 05036 CALL minres(nagb,globalVector, & 05037 workspaceD(1), workspaceD(1+nagb), workspaceD(1+2*nagb), & 05038 workspaceD(1+3*nagb),workspaceD(1+4*nagb),workspaceD(1+5*nagb), & 05039 globalCorrections,workspaceMinres, avprod, mvsolv, checka ,.FALSE., shift, & 05040 nout, itnlim, rtol, istop, itn, anorm, acond, rnorm, ynorm) 05041 END IF 05042 iitera=itn 05043 istopa=istop 05044 mnrsit=mnrsit+itn 05045 05046 IF (istopa == 0) PRINT *, 'MINRES: istop=0, exact solution x=0.' 05047 ! WRITE(*,*) 'Solution vector' 05048 ! WRITE(*,*) (DQ(ISOLV/2+I),I=1,NAGB) 05049 05050 END SUBROUTINE mminrs 05051 05059 05060 SUBROUTINE mcsolv(n,x,y) ! solve M*y = x 05061 USE mpmod 05062 05063 IMPLICIT NONE 05064 INTEGER,INTENT(IN) :: n 05065 DOUBLE PRECISION, INTENT(IN) :: x(n) 05066 DOUBLE PRECISION, INTENT(OUT) :: y(n) 05067 SAVE 05068 ! ... 05069 CALL presol(ncgb,nvgb,matPreCond,matPreCond(1+nvgb),matPreCond(1+nvgb+ncgb*nvgb),y,x) 05070 END SUBROUTINE mcsolv 05071 05079 05080 SUBROUTINE mvsolv(n,x,y) ! solve M*y = x 05081 USE mpmod 05082 05083 IMPLICIT NONE 05084 REAL :: factr 05085 INTEGER :: i 05086 INTEGER :: icgb 05087 INTEGER :: itgbi 05088 INTEGER :: ivgb 05089 INTEGER :: label 05090 INTEGER :: last 05091 INTEGER :: inone 05092 05093 INTEGER, INTENT(IN) :: n 05094 DOUBLE PRECISION, INTENT(IN) :: x(n) 05095 DOUBLE PRECISION, INTENT(OUT) :: y(n) 05096 SAVE 05097 ! ... 05098 DO i=1,n 05099 y(i)=x(i) ! copy to output vector 05100 END DO 05101 05102 DO icgb=1,ncgb ! copy previous lambda values 05103 ! Y(NVGB+ICGB)=DQ(ISOLV/2+NVGB+ICGB) 05104 END DO 05105 05106 i=0 05107 icgb=0 05108 last=-1 05109 DO WHILE(i < lenConstraints) 05110 i=i+1 05111 label=listConstraints(i)%label 05112 IF(last == 0.AND.label == (-1)) icgb=icgb+1 ! next constraint header 05113 IF(label > 0) THEN 05114 factr=listConstraints(i)%value 05115 itgbi=inone(label) ! -> ITGBI= index of parameter label 05116 ivgb =globalParLabelIndex(2,itgbi) ! -> variable-parameter index 05117 ! - A^T * lambda 05118 IF(ivgb /= 0) THEN 05119 ! Y(IVGB)=Y(IVGB) - DQ(ISOLV/2+NVGB+ICGB)*FACTR 05120 END IF 05121 END IF 05122 last=label 05123 END DO 05124 05125 ! CALL VABSLV(NVGB,DQ(INDV/2+1),MQ(INDU+1),Y) ! solve for Y 05126 ! CALL VABSLV(NAGB,DQ(INDV/2+1),MQ(INDU+1),Y) ! solve for Y 05127 05128 CALL equslv(nvgb,ncgb,matPreCond,indPreCond,y) 05129 END SUBROUTINE mvsolv 05130 05131 05132 05133 !*********************************************************************** 05134 05147 05148 SUBROUTINE xloopn ! 05149 USE mpmod 05150 05151 IMPLICIT NONE 05152 REAL :: catio 05153 REAL :: concu2 05154 REAL :: concut 05155 REAL, DIMENSION(2) :: ta 05156 INTEGER :: i 05157 INTEGER :: iact 05158 INTEGER :: iagain 05159 INTEGER :: idx 05160 INTEGER :: info 05161 INTEGER :: itgbi 05162 INTEGER :: ivgbi 05163 INTEGER :: jcalcm 05164 INTEGER :: k 05165 INTEGER :: labelg 05166 INTEGER :: litera 05167 INTEGER :: lrej 05168 INTEGER :: lun 05169 INTEGER :: lunp 05170 INTEGER :: minf 05171 INTEGER :: mrati 05172 INTEGER :: nan 05173 INTEGER :: nfaci 05174 INTEGER :: nloop 05175 INTEGER :: nrati 05176 INTEGER :: nrej 05177 INTEGER :: nsol 05178 INTEGER :: inone 05179 05180 DOUBLE PRECISION :: stp 05181 DOUBLE PRECISION :: dratio 05182 DOUBLE PRECISION :: dfacin 05183 DOUBLE PRECISION :: djrat 05184 DOUBLE PRECISION :: dwmean 05185 DOUBLE PRECISION :: db 05186 DOUBLE PRECISION :: db1 05187 DOUBLE PRECISION :: db2 05188 DOUBLE PRECISION :: dbdot 05189 LOGICAL :: warner 05190 SAVE 05191 ! ... 05192 05193 ! Printout of algorithm for solution and important parameters ------ 05194 05195 lun=lunlog ! log file 05196 IF(lunlog == 0) lunlog=6 05197 05198 DO lunp=6,lunlog,lunlog-6 05199 WRITE(lunp,*) ' ' 05200 WRITE(lunp,*) 'Solution algorithm: ' 05201 WRITE(lunp,121) '=================================================== ' 05202 05203 IF(metsol == 1) THEN 05204 WRITE(lunp,121) 'solution method:','matrix inversion' 05205 ELSE IF(metsol == 2) THEN 05206 WRITE(lunp,121) 'solution method:','diagonalization' 05207 ELSE 05208 IF(metsol == 3) THEN 05209 WRITE(lunp,121) 'solution method:', 'minres (Paige/Saunders)' 05210 ELSE IF(metsol == 4) THEN 05211 WRITE(lunp,121) 'solution method:', & 05212 'gmres (generalized minimzation of residuals)' 05213 END IF 05214 END IF 05215 WRITE(lunp,123) 'convergence limit at Delta F=',dflim 05216 WRITE(lunp,122) 'maximum number of iterations=',mitera 05217 matrit=MIN(matrit,mitera) 05218 IF(matrit > 1) THEN 05219 WRITE(lunp,122) 'matrix recalculation up to ',matrit, '. iteration' 05220 END IF 05221 IF(metsol >= 3) THEN 05222 IF(matsto == 1) THEN 05223 WRITE(lunp,121) 'matrix storage:','full' 05224 ELSE IF(matsto == 2) THEN 05225 WRITE(lunp,121) 'matrix storage:','sparse' 05226 END IF 05227 WRITE(lunp,122) 'pre-con band-width parameter=',mbandw 05228 IF(mbandw == 0) THEN 05229 WRITE(lunp,121) 'pre-conditioning:','default' 05230 ELSE IF(mbandw < 0) THEN 05231 WRITE(lunp,121) 'pre-conditioning:','none!' 05232 ELSE IF(mbandw > 0) THEN 05233 WRITE(lunp,121) 'pre-conditioning=','band-matrix' 05234 END IF 05235 END IF 05236 IF(regpre == 0.0D0.AND.npresg == 0) THEN 05237 WRITE(lunp,121) 'using pre-sigmas:','no' 05238 ELSE 05239 ! FIXME: NPRESG contains parameters that failed the 'entries' cut... 05240 WRITE(lunp,124) 'pre-sigmas defined for', & 05241 FLOAT(100*npresg)/FLOAT(nvgb),' % of variable parameters' 05242 WRITE(lunp,123) 'default pre-sigma=',regpre 05243 END IF 05244 IF(nregul == 0) THEN 05245 WRITE(lunp,121) 'regularization:','no' 05246 ELSE 05247 WRITE(lunp,121) 'regularization:','yes' 05248 WRITE(lunp,123) 'regularization factor=',regula 05249 END IF 05250 05251 IF(chicut /= 0.0) THEN 05252 WRITE(lunp,121) 'Chi square cut equiv 3 st.dev applied' 05253 WRITE(lunp,123) '... in first iteration with factor',chicut 05254 WRITE(lunp,123) '... in second iteration with factor',chirem 05255 WRITE(lunp,121) ' (reduced by sqrt in next iterations)' 05256 END IF 05257 05258 IF(lhuber /= 0) THEN 05259 WRITE(lunp,122) 'Down-weighting of outliers in', lhuber,' iterations' 05260 WRITE(lunp,123) 'Cut on downweight fraction',dwcut 05261 END IF 05262 05263 05264 121 FORMAT(1X,a40,3X,a) 05265 122 FORMAT(1X,a40,2X,i2,a) 05266 123 FORMAT(1X,a40,2X,e9.2) 05267 124 FORMAT(1X,a40,3X,f5.1,a) 05268 END DO 05269 05270 ! initialization of iterations ------------------------------------- 05271 05272 iitera=0 05273 nloop =0 05274 nsol =0 ! counter for solutions 05275 info =0 05276 lsinfo=0 05277 stp =0.0D0 05278 stepl =SNGL(stp) 05279 concut=1.0E-12 ! initial constraint accuracy 05280 concu2=1.0E-06 ! constraint accuracy 05281 icalcm=1 ! require matrix calculation 05282 iterat=0 ! iteration counter 05283 iterat=-1 05284 litera=-2 05285 nrej=0 ! reset number of rejects 05286 IF(metsol == 1) THEN 05287 wolfc2=0.5 ! not accurate 05288 minf=1 05289 ELSE IF(metsol == 2) THEN 05290 wolfc2=0.5 ! not acurate 05291 minf=2 05292 ELSE IF(metsol == 3) THEN 05293 wolfc2=0.1 ! accurate 05294 minf=3 05295 ELSE IF(metsol == 4) THEN 05296 wolfc2=0.1 ! accurate 05297 minf=3 05298 END IF 05299 05300 ! check initial feasibility of constraint equations ---------------- 05301 05302 WRITE(*,*) ' ' 05303 IF(nofeas == 0) THEN ! make parameter feasible 05304 WRITE(lunlog,*) 'Checking feasibility of parameters:' 05305 WRITE(*,*) 'Checking feasibility of parameters:' 05306 CALL feasib(concut,iact) ! check feasibility 05307 IF(iact /= 0) THEN ! done ... 05308 WRITE(*,102) concut 05309 WRITE(*,*) ' parameters are made feasible' 05310 WRITE(lunlog,102) concut 05311 WRITE(lunlog,*) ' parameters are made feasible' 05312 ELSE ! ... was OK 05313 WRITE(*,*) ' parameters are feasible (i.e. satisfy constraints)' 05314 WRITE(lunlog,*) ' parameters are feasible (i.e. satisfy constraints)' 05315 END IF 05316 concut=concu2 ! cut for constraint check 05317 END IF 05318 iact=1 ! set flag for new data loop 05319 nofeas=0 ! set check-feasibility flag 05320 05321 WRITE(*,*) ' ' 05322 WRITE(*,*)'Reading files and accumulating vectors/matrices ...' 05323 WRITE(*,*) ' ' 05324 05325 CALL etime(ta,rstart) 05326 iterat=-1 05327 litera= 0 05328 jcalcm=-1 05329 iagain= 0 05330 05331 icalcm=1 05332 05333 ! Block 1: data loop with vector (and matrix) calculation ---------- 05334 05335 DO 05336 IF(iterat >= 0) THEN 05337 lcalcm=jcalcm+3 ! mode (1..4) of last loop 05338 IF(jcalcm+1 /= 0) THEN 05339 IF(iterat == 0) THEN 05340 CALL ploopa(6) ! header 05341 CALL ploopb(6) 05342 CALL ploopa(lunlog) ! iteration line 05343 CALL ploopb(lunlog) 05344 iterat=1 05345 CALL gmpxyd(1,FLOAT(nloopn),REAL(fvalue),0.5,0.) ! fcn-value graph (no Delta) 05346 ELSE 05347 IF(iterat /= litera) THEN 05348 CALL ploopb(6) 05349 ! CALL PLOOPA(LUNLOG) 05350 CALL ploopb(lunlog) 05351 litera=iterat 05352 CALL gmpxyd(1,FLOAT(nloopn),REAL(fvalue),0.5,delfun) ! fcn-value (with expected) 05353 IF(metsol == 3) THEN ! extend to 4, i.e. GMRES? 05354 CALL gmpxy(2,FLOAT(iterat),FLOAT(iitera)) ! MINRES iterations 05355 END IF 05356 ELSE 05357 CALL ploopc(6) ! sub-iteration line 05358 CALL ploopc(lunlog) 05359 CALL gmpxyd(1,FLOAT(nloopn),REAL(fvalue),0.5,0.) ! fcn-value graph (no Delta) 05360 END IF 05361 END IF 05362 ELSE 05363 CALL ploopd(6) ! solution line 05364 CALL ploopd(lunlog) 05365 END IF 05366 CALL etime(ta,rstart) 05367 ! CHK 05368 IF (IABS(jcalcm) <= 1) THEN 05369 idx=jcalcm+4 05370 times(idx )=(times(idx )*times(idx+3)+deltim) /(times(idx+3)+1.0) 05371 times(idx+3)= times(idx+3)+1.0 05372 END IF 05373 END IF 05374 jcalcm=icalcm 05375 05376 IF(icalcm >= 0) THEN ! ICALCM = +1 & 0 05377 CALL loopn ! data loop 05378 CALL addcst ! constraints 05379 lrej=nrej 05380 nrej=nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) ! total number of rejects 05381 IF(3*nrej > nrecal) THEN 05382 WRITE(*,*) ' ' 05383 WRITE(*,*) 'Data rejected in previous loop: ' 05384 WRITE(*,*) ' ', & 05385 nrejec(0), ' (rank deficit/NaN) ',nrejec(1),' (Ndf=0) ', & 05386 nrejec(2), ' (huge) ',nrejec(3),' (large)' 05387 WRITE(*,*) 'Too many rejects (>33.3%) - stop' 05388 STOP 05389 END IF 05390 END IF 05391 ! Block 2: new iteration with calculation of solution -------------- 05392 05393 IF(ABS(icalcm) == 1) THEN ! ICALCM = +1 & -1 05394 DO i=1,nagb 05395 globalCorrections(i)=globalVector(i) ! copy rhs 05396 END DO 05397 DO i=1,nvgb 05398 itgbi=globalParVarToTotal(i) 05399 workspaceLinesearch(i)=globalParameter(itgbi) ! copy X for line search 05400 END DO 05401 iterat=iterat+1 ! increase iteration count 05402 IF(metsol == 1) THEN 05403 CALL minver ! inversion 05404 ELSE IF(metsol == 2) THEN 05405 CALL mdiags ! diagonalization 05406 ELSE IF(metsol == 3) THEN 05407 CALL mminrs ! MINRES 05408 ELSE IF(metsol == 4) THEN 05409 WRITE(*,*) '... reserved for GMRES (not yet!)' 05410 CALL mminrs ! GMRES not yet 05411 END IF 05412 05413 ! check feasibility and evtl. make step vector feasible 05414 05415 DO i=1,nvgb 05416 itgbi=globalParVarToTotal(i) 05417 globalParCopy(itgbi)=globalParameter(itgbi) ! save 05418 globalParameter(itgbi)=globalParameter(itgbi)+globalCorrections(i) ! update 05419 END DO 05420 CALL feasib(concut,iact) ! improve constraints 05421 concut=concu2 ! new cut for constraint check 05422 DO i=1,nvgb 05423 itgbi=globalParVarToTotal(i) 05424 globalCorrections(i)=globalParameter(itgbi)-globalParCopy(itgbi) ! feasible stp 05425 globalParameter(itgbi)=globalParCopy(itgbi) ! restore 05426 END DO 05427 05428 ! initialize line search based on slopes and prepare next 05429 05430 CALL ptldef(wolfc2, 10.0, minf,10) 05431 IF(metsol == 1) THEN 05432 wolfc2=0.5 ! not accurate 05433 minf=3 05434 ELSE IF(metsol == 2) THEN 05435 wolfc2=0.5 ! not acurate 05436 minf=3 05437 ELSE IF(metsol == 3) THEN 05438 wolfc2=0.1 ! accurate 05439 minf=4 05440 ELSE IF(metsol == 4) THEN 05441 wolfc2=0.1 ! accurate 05442 minf=4 05443 END IF 05444 db=dbdot(nvgb,globalCorrections,globalVector) 05445 db1=dbdot(nvgb,globalCorrections,globalCorrections) 05446 db2=dbdot(nvgb,globalVector,globalVector) 05447 delfun=SNGL(db) 05448 angras=SNGL(db/DSQRT(db1*db2)) 05449 05450 IF(db <= 0.0D0) THEN 05451 WRITE(*,*) 'Function not decreasing:',db 05452 IF(db <= -1.0D-3) THEN ! 100311, VB/CK: allow some margin for numerics 05453 iagain=iagain+1 05454 IF (iagain <= 1) THEN 05455 WRITE(*,*) '... again matrix calculation' 05456 icalcm=1 05457 CYCLE 05458 ELSE 05459 WRITE(*,*) '... aborting iterations' 05460 GO TO 90 05461 END IF 05462 ELSE 05463 WRITE(*,*) '... stopping iterations' 05464 iagain=0 05465 GO TO 90 05466 END IF 05467 ELSE 05468 iagain=0 05469 END IF 05470 icalcm=0 ! switch 05471 ENDIF 05472 ! Block 3: line searching ------------------------------------------ 05473 05474 IF(icalcm+2 == 0) EXIT 05475 CALL ptline(nagb,workspaceLinesearch, & ! current parameter values 05476 flines, & ! chi^2 function value 05477 globalVector, & ! gradient 05478 globalCorrections, & ! step vector stp 05479 stp, & ! returned step factor 05480 info) ! returned information 05481 ! WRITE(*,*) 'PTLINE returns INFO, STP=',INFO, STP 05482 lsinfo=info 05483 05484 stepl=SNGL(stp) 05485 nan=0 05486 DO i=1,nvgb 05487 itgbi=globalParVarToTotal(i) 05488 IF ((.NOT.(workspaceLinesearch(i) <= 0.0D0)).AND. & 05489 (.NOT.(workspaceLinesearch(i) > 0.0D0))) nan=nan+1 05490 globalParameter(itgbi)=workspaceLinesearch(i) ! current parameter values 05491 END DO 05492 05493 IF (nan > 0) THEN 05494 WRITE(*,*) 'Result vector containes ', nan,' NaNs - stop' 05495 STOP 05496 END IF 05497 05498 ! subito exit, if required ----------------------------------------- 05499 05500 IF(isubit /= 0) THEN ! subito 05501 WRITE(*,*) 'Subito! Exit after first step.' 05502 GO TO 90 05503 END IF 05504 05505 IF(info == 0) THEN 05506 WRITE(*,*) 'INFO=0 should not happen (line search input err)' 05507 IF (iagain <= 0) THEN 05508 icalcm=1 05509 CYCLE 05510 ENDIF 05511 END IF 05512 IF(info < 0) CYCLE 05513 ! Block 4: line search convergence --------------------------------- 05514 05515 CALL ptlprt(lunlog) 05516 CALL feasib(concut,iact) ! check constraints 05517 IF(iact /= 0.OR.chicut > 1.0) THEN 05518 icalcm=-1 05519 IF(iterat < matrit) icalcm=+1 05520 CYCLE ! iterate 05521 END IF 05522 IF(delfun <= dflim) GO TO 90 ! convergence 05523 IF(iterat >= mitera) GO TO 90 ! ending 05524 icalcm=-1 05525 IF(iterat < matrit) icalcm=+1 05526 CYCLE ! next iteration 05527 05528 ! Block 5: iteration ending ---------------------------------------- 05529 05530 90 icalcm=-2 05531 END DO 05532 IF(nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) /= 0) THEN 05533 WRITE(*,*) ' ' 05534 WRITE(*,*) 'Data rejected in last loop: ' 05535 WRITE(*,*) ' ', & 05536 nrejec(0), ' (rank deficit/NaN) ',nrejec(1),' (Ndf=0) ', & 05537 nrejec(2), ' (huge) ',nrejec(3),' (large)' 05538 END IF 05539 05540 dwmean=sumndf/dfloat(ndfsum) 05541 dratio=fvalue/dwmean/dfloat(ndfsum-nagb) 05542 catio=SNGL(dratio) 05543 IF(lhuber /= 0) THEN 05544 IF (lhuber <= 3) THEN 05545 catio=catio/0.9326 ! correction Huber downweighting 05546 ELSE 05547 catio=catio/0.8228 ! correction Cauchy downweighting 05548 END IF 05549 END IF 05550 mrati=nint(100.0*catio) 05551 05552 DO lunp=6,lunlog,lunlog-6 05553 WRITE(lunp,*) ' ' 05554 IF (nfilw <= 0) THEN 05555 WRITE(lunp,*) 'Sum(Chi^2)/Sum(Ndf) =',fvalue 05556 WRITE(lunp,*) ' / (',ndfsum,'-',nagb,')' 05557 WRITE(lunp,*) ' =',dratio 05558 ELSE 05559 WRITE(lunp,*) 'Sum(W*Chi^2)/Sum(Ndf)/<W> =',fvalue 05560 WRITE(lunp,*) ' / (',ndfsum,'-', nagb,')' 05561 WRITE(lunp,*) ' /',dwmean 05562 WRITE(lunp,*) ' =',dratio 05563 END IF 05564 WRITE(lunp,*) ' ' 05565 IF(lhuber /= 0) WRITE(lunp,*) & 05566 ' with correction for down-weighting ',catio 05567 END DO 05568 nrej=nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) ! total number of rejects 05569 05570 ! ... the end with exit code ??????????????????????????????????????? 05571 05572 ! WRITE(*,199) ! write exit code 05573 ! + '-----------------------------------------------------------' 05574 ! IF(ITEXIT.EQ.0) WRITE(*,199) 05575 ! + 'Exit code = 0: Convergence reached' 05576 ! IF(ITEXIT.EQ.1) WRITE(*,199) 05577 ! + 'Exit code = 1: No improvement in last iteration' 05578 ! IF(ITEXIT.EQ.2) WRITE(*,199) 05579 ! + 'Exit code = 2: Maximum number of iterations reached' 05580 ! IF(ITEXIT.EQ.3) WRITE(*,199) 05581 ! + 'Exit code = 3: Failure' 05582 ! WRITE(*,199) 05583 ! + '-----------------------------------------------------------' 05584 ! WRITE(*,199) ' ' 05585 05586 05587 nrati=nint(10000.0*FLOAT(nrej)/FLOAT(nrecal)) 05588 djrat=0.01D0*dfloat(nrati) 05589 nfaci=nint(100.0*SQRT(catio)) 05590 05591 dratio=0.01D0*dfloat(mrati) 05592 dfacin=0.01D0*dfloat(nfaci) 05593 05594 warner=.FALSE. 05595 IF(mrati < 90.OR.mrati > 110) warner=.TRUE. 05596 IF(nrati > 1) warner=.TRUE. 05597 IF(nmiss1 /= 0) warner=.TRUE. 05598 IF(iagain /= 0) warner=.TRUE. 05599 05600 IF(warner) THEN 05601 WRITE(*,199) ' ' 05602 WRITE(*,199) ' ' 05603 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar' 05604 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn' 05605 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni' 05606 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin' 05607 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning' 05608 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW' 05609 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa' 05610 05611 IF(mrati < 90.OR.mrati > 110) THEN 05612 WRITE(*,199) ' ' 05613 WRITE(*,*) ' Chi^2/Ndf = ',dratio, ' (should be close to 1)' 05614 WRITE(*,*) ' => multiply all input standard ', & 05615 'deviations by factor',dfacin 05616 END IF 05617 05618 IF(nrati > 1) THEN 05619 WRITE(*,199) ' ' 05620 WRITE(*,*) ' Fraction of rejects =',djrat,' %', & 05621 ' (should be far below 1 %)' 05622 WRITE(*,*) ' => please provide correct mille data' 05623 END IF 05624 05625 IF(iagain /= 0) THEN 05626 WRITE(*,199) ' ' 05627 WRITE(*,*) ' Matrix not positiv definite '// & 05628 '(function not decreasing)' 05629 WRITE(*,*) ' => please provide correct mille data' 05630 END IF 05631 05632 IF(nmiss1 /= 0) THEN 05633 WRITE(*,199) ' ' 05634 WRITE(*,*) ' Rank defect =',nmiss1, & 05635 ' for constraint equations, should be 0' 05636 WRITE(*,*) ' => please correct constraint definition' 05637 END IF 05638 05639 WRITE(*,199) ' ' 05640 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar' 05641 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn' 05642 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni' 05643 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin' 05644 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning' 05645 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW' 05646 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa' 05647 WRITE(*,199) ' ' 05648 05649 ENDIF 05650 05651 CALL mend ! modul ending 05652 05653 ! ------------------------------------------------------------------ 05654 05655 IF(metsol == 1) THEN 05656 05657 ELSE IF(metsol == 2) THEN 05658 CALL zdiags 05659 ELSE IF(metsol == 3) THEN 05660 ! errors and correlations from MINRES 05661 DO k=1,mnrsel 05662 labelg=lbmnrs(k) 05663 IF(labelg == 0) CYCLE 05664 itgbi=inone(labelg) 05665 ivgbi=0 05666 IF(itgbi /= 0) ivgbi=globalParLabelIndex(2,itgbi) 05667 IF(ivgbi < 0) ivgbi=0 05668 IF(ivgbi == 0) CYCLE 05669 ! determine error and global correlation for parameter IVGBI 05670 CALL solglo(ivgbi) 05671 END DO 05672 05673 ELSE IF(metsol == 4) THEN 05674 05675 END IF 05676 05677 CALL prtglo ! print result 05678 05679 102 FORMAT(' Call FEASIB with cut=',g10.3) 05680 ! 103 FORMAT(1X,A,G12.4) 05681 199 FORMAT(7X,a) 05682 END SUBROUTINE xloopn ! standard solution 05683 05697 05698 SUBROUTINE filetc 05699 USE mpmod 05700 USE mpdalc 05701 05702 IMPLICIT NONE 05703 INTEGER :: i 05704 INTEGER :: ia 05705 INTEGER :: iargc 05706 INTEGER :: ib 05707 INTEGER :: ie 05708 INTEGER :: ierrf 05709 INTEGER :: ieq 05710 INTEGER :: ioff 05711 INTEGER :: iopt 05712 INTEGER :: ios 05713 INTEGER :: iosum 05714 INTEGER :: it 05715 INTEGER :: k 05716 INTEGER :: mat 05717 INTEGER :: nab 05718 INTEGER :: nline 05719 INTEGER :: npat 05720 INTEGER :: ntext 05721 INTEGER :: nu 05722 INTEGER :: nuf 05723 INTEGER :: nums 05724 INTEGER :: nufile 05725 INTEGER :: lenfileInfo 05726 INTEGER :: lenFileNames 05727 INTEGER :: matint 05728 INTEGER, DIMENSION(:,:), ALLOCATABLE :: vecfileInfo 05729 INTEGER, DIMENSION(:,:), ALLOCATABLE :: tempArray 05730 INTEGER(KIND=large) :: rows 05731 INTEGER(KIND=large) :: cols 05732 INTEGER(KIND=large) :: newcols 05733 INTEGER(KIND=large) :: length 05734 05735 CHARACTER (LEN=1024) :: text 05736 CHARACTER (LEN=1024) :: fname 05737 CHARACTER (LEN=14) :: bite(3) 05738 CHARACTER (LEN=32) :: keystx 05739 DOUBLE PRECISION :: dnum(100) 05740 SAVE 05741 DATA bite/'C_binary','text ','Fortran_binary'/ 05742 ! ... 05743 CALL mstart('FILETC/X') 05744 05745 nuf=1 ! C binary is default 05746 DO i=1,8 05747 times(i)=0.0 05748 END DO 05749 05750 ! read command line options ---------------------------------------- 05751 05752 filnam=' ' ! print command line options and find steering file 05753 DO i=1,iargc() 05754 IF(i == 1) THEN 05755 WRITE(*,*) ' ' 05756 WRITE(*,*) 'Command line options: ' 05757 WRITE(*,*) '--------------------- ' 05758 END IF 05759 CALL getarg(i,text) ! get I.th text from command line 05760 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area 05761 WRITE(*,101) i,text(1:nab) ! echo print 05762 IF(text(ia:ia) /= '-') THEN 05763 nu=nufile(text(ia:ib)) ! inquire on file existence 05764 IF(nu == 2) THEN ! existing text file 05765 IF(filnam /= ' ') THEN 05766 WRITE(*,*) 'Second text file in command line - stop' 05767 STOP 05768 ELSE 05769 filnam=text 05770 END IF 05771 ELSE 05772 WRITE(*,*) 'Open error for file:',text(ia:ib),' - stop' 05773 STOP 05774 END IF 05775 ELSE 05776 IF(INDEX(text(ia:ib),'b') /= 0) THEN 05777 mdebug=3 ! debug flag 05778 WRITE(*,*) 'Debugging requested' 05779 END IF 05780 it=INDEX(text(ia:ib),'t') 05781 IF(it /= 0) THEN 05782 ictest=1 ! internal test files 05783 ieq=INDEX(text(ia+it:ib),'=')+it 05784 IF (it /= ieq) THEN 05785 IF (INDEX(text(ia+ieq:ib),'SL0' ) /= 0) ictest=2 05786 IF (INDEX(text(ia+ieq:ib),'SLE' ) /= 0) ictest=3 05787 IF (INDEX(text(ia+ieq:ib),'BP' ) /= 0) ictest=4 05788 IF (INDEX(text(ia+ieq:ib),'BRLF') /= 0) ictest=5 05789 IF (INDEX(text(ia+ieq:ib),'BRLC') /= 0) ictest=6 05790 END IF 05791 END IF 05792 IF(INDEX(text(ia:ib),'s') /= 0) isubit=1 ! like "subito" 05793 IF(INDEX(text(ia:ib),'f') /= 0) iforce=1 ! like "force" 05794 END IF 05795 IF(i == iargc()) WRITE(*,*) '--------------------- ' 05796 END DO 05797 05798 05799 ! create test files for option -t ---------------------------------- 05800 05801 IF(ictest >= 1) THEN 05802 WRITE(*,*) ' ' 05803 IF (ictest == 1) THEN 05804 CALL mptest ! 'wire chamber' 05805 ELSE 05806 CALL mptst2(ictest-2) ! 'silicon tracker' 05807 END IF 05808 IF(filnam == ' ') filnam='mp2str.txt' 05809 WRITE(*,*) ' ' 05810 END IF 05811 05812 ! check default steering file with file-name "steerfile" ----------- 05813 05814 IF(filnam == ' ') THEN ! check default steering file 05815 text='steerfile' 05816 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area 05817 nu=nufile(text(ia:ib)) ! inquire on file existence and type 05818 IF(nu > 0) THEN 05819 filnam=text 05820 ELSE 05821 STOP 'in FILETC: no steering file. .' 05822 END IF 05823 END IF 05824 05825 05826 ! open, read steering file: 05827 ! end 05828 ! fortranfiles 05829 ! cfiles 05830 05831 05832 CALL rltext(filnam,ia,ib,nfnam) ! return indices for non-blank area 05833 WRITE(*,*) ' ' 05834 WRITE(*,*) 'Listing of steering file: ',filnam(1:nfnam) 05835 WRITE(*,*) '-------------------------' 05836 OPEN(10,FILE=filnam(1:nfnam),IOSTAT=ios) 05837 IF(ios /= 0) THEN 05838 WRITE(*,*) 'Open error for steering file - stop' 05839 STOP 05840 END IF 05841 ifile =0 05842 nfiles=0 05843 05844 lenfileInfo=2 05845 lenFileNames=0 05846 rows=6; cols=lenFileInfo 05847 CALL mpalloc(vecfileInfo,rows,cols,'file info from steering') 05848 nline=0 05849 DO 05850 READ(10,102,IOSTAT=ierrf) text ! read steering file 05851 IF (ierrf < 0) EXIT ! eof 05852 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area 05853 nline=nline+1 05854 IF(nline <= 50) THEN ! print up to 50 lines 05855 WRITE(*,101) nline,text(1:nab) 05856 IF(nline == 50) WRITE(*,*) ' ...' 05857 END IF 05858 05859 CALL rltext(text,ia,ib,nab) ! test content 'end' 05860 IF(ib == ia+2) THEN 05861 mat=matint(text(ia:ib),'end',npat,ntext) 05862 IF(mat == 3) THEN 05863 text=' ' 05864 CALL intext(text,nline) 05865 WRITE(*,*) ' end-statement after',nline,' text lines' 05866 EXIT 05867 END IF 05868 END IF 05869 05870 keystx='fortranfiles' 05871 !GF MAT=MATINT(TEXT(IA:IB),KEYSTX,NPAT,NTEXT) 05872 !GF IF(MAT.GE.NTEXT-NTEXT/10) THEN 05873 IF (text(ia:ib) == keystx) THEN ! exact comparison by GF 05874 nuf=3 05875 ! WRITE(*,*) 'Fortran files' 05876 CYCLE 05877 END IF 05878 05879 keystx='Cfiles' 05880 !GF MAT=MATINT(TEXT(IA:IB),KEYSTX,NPAT,NTEXT) 05881 !GF IF(MAT.GE.NTEXT-NTEXT/10) THEN 05882 IF (text(ia:ib) == keystx) THEN ! exact comparison by GF 05883 nuf=1 05884 ! WRITE(*,*) 'Cfiles' 05885 CYCLE 05886 END IF 05887 05888 ! file names 05889 ! check for file options (' -- ') 05890 ie=ib 05891 iopt=INDEX(text(ia:ib),' -- ') 05892 IF (iopt > 0) ie=iopt-1 05893 05894 IF(nab == 0) CYCLE 05895 nu=nufile(text(ia:ie)) ! inquire on file existence 05896 IF(nu > 0) THEN ! existing file 05897 IF (nfiles == lenFileInfo) THEN ! increase length 05898 CALL mpalloc(tempArray,rows,cols,'temp file info from steering') 05899 tempArray=vecfileInfo 05900 CALL mpdealloc(vecfileInfo) 05901 lenFileInfo=lenFileInfo*2 05902 newcols=lenFileInfo 05903 CALL mpalloc(vecfileInfo,rows,newcols,'file info from steering') 05904 vecfileInfo(:,1:cols)=tempArray(:,1:cols) 05905 CALL mpdealloc(tempArray) 05906 cols=newcols 05907 ENDIF 05908 nfiles=nfiles+1 ! count number of files 05909 IF(nu == 1) nu=nuf ! 05910 lenFileNames=lenFileNames+ie-ia+1 ! total length of file names 05911 vecFileInfo(1,nfiles)=nline ! line number 05912 vecFileInfo(2,nfiles)=nu ! cbinary =1, text =2, fbinary=3 05913 vecFileInfo(3,nfiles)=ia ! file name start 05914 vecFileInfo(4,nfiles)=ie ! file name end 05915 vecFileInfo(5,nfiles)=iopt ! option start 05916 vecFileInfo(6,nfiles)=ib ! option end 05917 ELSE 05918 ! WRITE(*,*) 'Open error for file ',TEXT(IA:IB) 05919 ! STOP 05920 END IF 05921 END DO 05922 REWIND 10 05923 ! read again to fill dynamic arrays with file info 05924 length=nfiles 05925 CALL mpalloc(mfd,length,'file type') 05926 CALL mpalloc(nfd,length,'file line (in steering)') 05927 CALL mpalloc(lfd,length,'file name length') 05928 CALL mpalloc(ofd,length,'file option') 05929 length=lenFileNames 05930 CALL mpalloc(tfd,length,'file name') 05931 nline=0 05932 i=1 05933 ioff=0 05934 DO 05935 READ(10,102,IOSTAT=ierrf) text ! read steering file 05936 IF (ierrf < 0) EXIT ! eof 05937 nline=nline+1 05938 IF (nline == vecFileInfo(1,i)) THEN 05939 nfd(i)=vecFileInfo(1,i) 05940 mfd(i)=vecFileInfo(2,i) 05941 ia=vecFileInfo(3,i)-1 05942 lfd(i)=vecFileInfo(4,i)-ia ! length file name 05943 FORALL (k=1:lfd(i)) tfd(ioff+k)=text(ia+k:ia+k) 05944 ! tfd(i)=text(vecFileInfo(3,i):vecFileInfo(4,i)) ! file name 05945 ioff=ioff+lfd(i) 05946 ofd(i)=1.0 ! option for file 05947 IF (vecFileInfo(5,i) > 0) THEN 05948 CALL ratext(text(vecFileInfo(5,i)+4:vecFileInfo(6,i)),nums,dnum) ! translate text to DP numbers 05949 IF (nums > 0) ofd(i)=SNGL(dnum(1)) 05950 END IF 05951 i=i+1 05952 IF (i > nfiles) EXIT 05953 ENDIF 05954 ENDDO 05955 CALL mpdealloc(vecfileInfo) 05956 REWIND 10 05957 ! additional info for binary files 05958 length=nfiles; rows=2 05959 CALL mpalloc(ifd,length,'integrated record numbers (=offset)') 05960 CALL mpalloc(jfd,length,'number of accepted records') 05961 CALL mpalloc(kfd,rows,length,'number of records in file, file order') 05962 CALL mpalloc(dfd,length,'ndf sum') 05963 CALL mpalloc(xfd,length,'max. record size') 05964 CALL mpalloc(wfd,length,'file weight') 05965 CALL mpalloc(cfd,length,'chi2 sum') 05966 ! 05967 WRITE(*,*) '-------------------------' 05968 WRITE(*,*) ' ' 05969 05970 ! print table of files --------------------------------------------- 05971 05972 IF (mprint > 1) THEN 05973 WRITE(*,*) 'Table of files:' 05974 WRITE(*,*) '---------------' 05975 END IF 05976 WRITE(8,*) ' ' 05977 WRITE(8,*) 'Text and data files:' 05978 ioff=0 05979 DO i=1,nfiles 05980 FORALL (k=1:lfd(i)) fname(k:k)=tfd(ioff+k) 05981 ! fname=tfd(i)(1:lfd(i)) 05982 IF (mprint > -1) WRITE(*,103) i,bite(mfd(i)),fname(1:lfd(i)) 05983 WRITE(8,103) i,bite(mfd(i)),fname(1:lfd(i)) 05984 ioff=ioff+lfd(i) 05985 END DO 05986 IF (mprint > 1) THEN 05987 WRITE(*,*) '---------------' 05988 WRITE(*,*) ' ' 05989 END IF 05990 05991 ! open the binary (data) files on unit 11, 12, ... 05992 05993 iosum=0 05994 nfilf=0 05995 nfilb=0 05996 nfilw=0 05997 ioff=0 05998 DO i=1,nfiles ! Fortran files 05999 IF(mfd(i) == 3) THEN 06000 FORALL (k=1:lfd(i)) fname(k:k)=tfd(ioff+k) 06001 ! fname=tfd(i)(1:lfd(i)) 06002 WRITE(*,*) 'Opening Fortran file ',10+nfilf+1, ' ',fname(1:lfd(i)) 06003 OPEN(10+nfilf+1,FILE=fname(1:lfd(i)),IOSTAT=ios, FORM='UNFORMATTED') 06004 IF(ios /= 0) THEN 06005 WRITE(*,*) 'Open error for file ',fname(1:lfd(i)) 06006 iosum=iosum+1 06007 ELSE 06008 nfilf=nfilf+1 06009 nfilb=nfilb+1 06010 wfd(nfilb)=ofd(i) 06011 END IF 06012 END IF 06013 ioff=ioff+lfd(i) 06014 END DO 06015 06016 ! open the binary C files 06017 06018 nfilc=-1 06019 ioff=0 06020 DO i=1,nfiles ! Cfiles 06021 IF(mfd(i) == 1) THEN 06022 #ifdef READ_C_FILES 06023 IF(nfilc < 0) CALL initc(nfiles) ! uncommented by GF 06024 IF(nfilc < 0) nfilc=0 06025 FORALL (k=1:lfd(i)) fname(k:k)=tfd(ioff+k) 06026 ! fname=tfd(i)(1:lfd(i)) 06027 WRITE(*,*) 'Opening C file ',nfilc+1, ': ',fname(1:lfd(i)) ! by GF 06028 CALL openc(fname(1:lfd(i)),ios) 06029 IF(ios /= 0) THEN 06030 WRITE(*,*) 'Open error ',ios,' for file ',fname(1:lfd(i)) 06031 iosum=iosum+1 ! typo fixed by GF 06032 ELSE 06033 nfilc=nfilc+1 06034 nfilb=nfilb+1 06035 wfd(nfilb)=ofd(i) 06036 END IF 06037 #else 06038 WRITE(*,*) 'Opening of C-files not supported.' 06039 ! GF add 06040 iosum=iosum+1 06041 ! GF add end 06042 #endif 06043 END IF 06044 ioff=ioff+lfd(i) 06045 END DO 06046 06047 DO k=1,nfilb 06048 kfd(1,k)=0 ! reset record counters 06049 kfd(2,k)=k ! set file number 06050 ifd(k)=0 ! reset integrated record numbers 06051 xfd(k)=0 ! reset max record size 06052 END DO 06053 06054 IF(iosum /= 0) THEN 06055 STOP 'FILETC: open error ' 06056 END IF 06057 IF(nfilb == 0) THEN 06058 STOP 'FILETC: no binary files ' 06059 END IF 06060 WRITE(*,*) nfilb,' binary files opened' ! corrected by GF 06061 101 FORMAT(i3,2X,a) 06062 102 FORMAT(a) 06063 103 FORMAT(i3,2X,a14,3X,a) 06064 ! CALL mend 06065 RETURN 06066 END SUBROUTINE filetc 06067 06118 06119 SUBROUTINE filetx ! --------------------------------------------------- 06120 USE mpmod 06121 06122 IMPLICIT NONE 06123 INTEGER :: i 06124 INTEGER :: ia 06125 INTEGER :: ib 06126 INTEGER :: ierrf 06127 INTEGER :: ioff 06128 INTEGER :: ios 06129 INTEGER :: iosum 06130 INTEGER :: k 06131 INTEGER :: mat 06132 INTEGER :: nab 06133 INTEGER :: nfiln 06134 INTEGER :: nline 06135 INTEGER :: nlinmx 06136 INTEGER :: npat 06137 INTEGER :: ntext 06138 INTEGER :: matint 06139 06140 ! CALL MSTART('FILETX') 06141 06142 CHARACTER (LEN=1024) :: text 06143 CHARACTER (LEN=1024) :: fname 06144 06145 WRITE(*,*) ' ' 06146 WRITE(*,*) 'Processing text files ...' 06147 WRITE(*,*) ' ' 06148 06149 iosum=0 06150 ioff=0 06151 DO i=0,nfiles 06152 IF(i == 0) THEN 06153 WRITE(*,*) 'File ',filnam(1:nfnam) 06154 nlinmx=100 06155 ELSE 06156 nlinmx=10 06157 ia=ioff 06158 ioff=ioff+lfd(i) 06159 IF(mfd(i) /= 2) CYCLE ! exclude binary files 06160 FORALL (k=1:lfd(i)) fname(k:k)=tfd(ia+k) 06161 WRITE(*,*) 'File ',fname(1:lfd(i)) 06162 IF (mprint > 1) WRITE(*,*) ' ' 06163 OPEN(10,FILE=fname(1:lfd(i)),IOSTAT=ios,FORM='FORMATTED') 06164 IF(ios /= 0) THEN 06165 WRITE(*,*) 'Open error for file ',fname(1:lfd(i)) 06166 iosum=iosum+1 06167 CYCLE 06168 END IF 06169 END IF 06170 06171 nline=0 06172 nfiln=1 06173 ! read text file 06174 DO 06175 READ(10,102,IOSTAT=ierrf) text 06176 IF (ierrf < 0) THEN 06177 text=' ' 06178 CALL intext(text,nline) 06179 WRITE(*,*) ' end-of-file after',nline,' text lines' 06180 EXIT ! eof 06181 ENDIF 06182 nline=nline+1 06183 IF(nline <= nlinmx.AND.mprint > 1) THEN ! print first 10 lines of every text fiLE 06184 CALL rltext(text,ia,ib,nab) 06185 nab=MAX(1,nab) 06186 WRITE(*,101) nline,text(1:nab) 06187 IF(nline == nlinmx) WRITE(*,*) ' ...' 06188 END IF 06189 06190 CALL rltext(text,ia,ib,nab) ! test content 'end' 06191 IF(ib == ia+2) THEN 06192 mat=matint(text(ia:ib),'end',npat,ntext) 06193 IF(mat == 3) THEN 06194 text=' ' 06195 CALL intext(text,nline) 06196 WRITE(*,*) ' end-statement after',nline,' text lines' 06197 EXIT 06198 END IF 06199 END IF 06200 06201 IF(i == 0) THEN ! first text file - exclude lines with file names 06202 IF(nfiln <= nfiles.AND.nline == nfd(nfiln)) THEN 06203 nfiln=nfiln+1 06204 text=' ' 06205 ! WRITE(*,*) 'line is excluded ',TEXT(1:10) 06206 END IF 06207 END IF 06208 ! WRITE(*,*) TEXT(1:40),' < interprete text' 06209 CALL intext(text,nline) ! interprete text 06210 END DO 06211 WRITE(*,*) ' ' 06212 REWIND 10 06213 CLOSE(UNIT=10) 06214 END DO 06215 06216 IF(iosum /= 0) THEN 06217 STOP 'FILETX: open error(s) in text files ' 06218 END IF 06219 06220 WRITE(*,*) '... end of text file processing.' 06221 WRITE(*,*) ' ' 06222 06223 IF(lunkno /= 0) THEN 06224 WRITE(*,*) ' ' 06225 WRITE(*,*) lunkno,' unknown keywords in steering files, ', & 06226 'or file non-existing,' 06227 WRITE(*,*) ' see above!' 06228 WRITE(*,*) '------------> stop' 06229 WRITE(*,*) ' ' 06230 STOP 06231 END IF 06232 06233 ! check methods 06234 06235 IF(metsol == 0) THEN ! if undefined 06236 IF(matsto == 0) THEN ! if undefined 06237 ! METSOL=1 ! default is matrix inversion 06238 ! MATSTO=1 ! default is symmetric matrix 06239 ELSE IF(matsto == 1) THEN ! if symmetric 06240 metsol=3 ! MINRES 06241 ELSE IF(matsto == 2) THEN ! if sparse 06242 metsol=3 ! MINRES 06243 END IF 06244 ELSE IF(metsol == 1) THEN ! if inversion 06245 matsto=1 ! 06246 ELSE IF(metsol == 2) THEN ! if diagonalization 06247 matsto=1 06248 ELSE IF(metsol == 3) THEN ! if MINRES 06249 ! MATSTO=2 or 1 06250 ELSE IF(metsol == 4) THEN ! if GMRES 06251 ! MATSTO=2 or 1 06252 ELSE 06253 WRITE(*,*) 'MINRES forced with sparse matrix!' 06254 WRITE(*,*) ' ' 06255 WRITE(*,*) 'MINRES forced with sparse matrix!' 06256 WRITE(*,*) ' ' 06257 WRITE(*,*) 'MINRES forced with sparse matrix!' 06258 metsol=3 ! forced 06259 matsto=2 ! forced 06260 END IF 06261 IF(matsto > 2) THEN 06262 WRITE(*,*) 'MINRES forced with sparse matrix!' 06263 WRITE(*,*) ' ' 06264 WRITE(*,*) 'MINRES forced with sparse matrix!' 06265 WRITE(*,*) ' ' 06266 WRITE(*,*) 'MINRES forced with sparse matrix!' 06267 metsol=3 ! forced 06268 matsto=2 ! forced 06269 END IF 06270 06271 ! print information about methods and matrix storage modes 06272 06273 WRITE(*,*) ' ' 06274 WRITE(*,*) 'Solution method and matrix-storage mode:' 06275 IF(metsol == 1) THEN 06276 WRITE(*,*) ' METSOL = 1: matrix inversion' 06277 ELSE IF(metsol == 2) THEN 06278 WRITE(*,*) ' METSOL = 2: diagonalization' 06279 ELSE IF(metsol == 3) THEN 06280 WRITE(*,*) ' METSOL = 3: MINRES' 06281 ELSE IF(metsol == 4) THEN 06282 WRITE(*,*) ' METSOL = 4: GMRES (-> MINRES)' 06283 06284 END IF 06285 06286 WRITE(*,*) ' with',mitera,' iterations' 06287 06288 IF(matsto == 1) THEN 06289 WRITE(*,*) ' MATSTO = 1: symmetric matrix, ', '(n*n+n)/2 elements' 06290 ELSE IF(matsto == 2) THEN 06291 WRITE(*,*) ' MATSTO = 2: sparse matrix' 06292 END IF 06293 IF(mbandw /= 0) THEN 06294 WRITE(*,*) ' and band matrix, width',mbandw 06295 END IF 06296 06297 06298 06299 IF(chicut /= 0.0) THEN 06300 WRITE(*,*) 'Chi square cut equiv 3 st.dev applied ...' 06301 WRITE(*,*) ' in first iteration with factor',chicut 06302 WRITE(*,*) ' in second iteration with factor',chirem 06303 WRITE(*,*) ' (reduced by sqrt in next iterations)' 06304 END IF 06305 06306 IF(lhuber /= 0) THEN 06307 WRITE(*,*) ' Down-weighting of outliers in', lhuber,' iterations' 06308 WRITE(*,*) ' Cut on downweight fraction',dwcut 06309 END IF 06310 06311 CALL mend 06312 06313 101 FORMAT(i3,2X,a) 06314 102 FORMAT(a) 06315 END SUBROUTINE filetx 06316 06326 06327 INTEGER FUNCTION nufile(fname) 06328 06329 IMPLICIT NONE 06330 INTEGER :: ios 06331 INTEGER :: l1 06332 INTEGER :: ll 06333 INTEGER :: nm 06334 INTEGER :: npat 06335 INTEGER :: ntext 06336 INTEGER :: nuprae 06337 INTEGER :: matint 06338 06339 CHARACTER (LEN=*), INTENT(INOUT) :: fname 06340 LOGICAL :: ex 06341 SAVE 06342 ! ... 06343 nufile=0 06344 IF(fname(1:5) == 'rfio:') nuprae=1 06345 IF(fname(1:5) == 'dcap:') nuprae=2 06346 IF(fname(1:5) == 'root:') nuprae=3 06347 IF(nuprae == 0) THEN 06348 INQUIRE(FILE=fname,IOSTAT=ios,EXIST=ex) 06349 IF(ios /= 0) nufile=-ABS(ios) 06350 IF(ios /= 0) RETURN 06351 ELSE IF(nuprae == 1) THEN ! rfio: 06352 ll=LEN(fname) 06353 fname=fname(6:ll) 06354 ex=.TRUE. 06355 nufile=1 06356 RETURN 06357 ELSE 06358 ex=.TRUE. ! assume file existence 06359 END IF 06360 IF(ex) THEN 06361 nufile=1 ! binary 06362 ll=LEN(fname) 06363 l1=MAX(1,ll-3) 06364 nm=matint('xt',fname(l1:ll),npat,ntext) 06365 IF(nm == 2) nufile=2 ! text 06366 IF(nm < 2) THEN 06367 nm=matint('tx',fname(l1:ll),npat,ntext) 06368 IF(nm == 2) nufile=2 ! text 06369 END IF 06370 END IF 06371 END FUNCTION nufile 06372 06380 SUBROUTINE intext(text,nline) 06381 USE mpmod 06382 USE mptext 06383 06384 IMPLICIT NONE 06385 INTEGER :: i 06386 INTEGER :: ia 06387 INTEGER :: ib 06388 INTEGER :: icount 06389 INTEGER :: ier 06390 INTEGER :: iomp 06391 INTEGER :: k 06392 INTEGER :: kkey 06393 INTEGER :: label 06394 INTEGER :: lkey 06395 INTEGER :: mat 06396 INTEGER :: miter 06397 INTEGER :: mxcnt 06398 INTEGER :: nab 06399 INTEGER :: nkey 06400 INTEGER :: nkeys 06401 INTEGER :: nl 06402 INTEGER :: nmeth 06403 INTEGER :: npat 06404 INTEGER :: ntext 06405 INTEGER :: nums 06406 INTEGER :: matint 06407 06408 CHARACTER (LEN=*), INTENT(IN) :: text 06409 INTEGER, INTENT(IN) :: nline 06410 06411 PARAMETER (nkeys=9,nmeth=4) 06412 CHARACTER (LEN=16) :: methxt(nmeth) 06413 CHARACTER (LEN=16) :: keylst(nkeys) 06414 CHARACTER (LEN=32) :: keywrd 06415 CHARACTER (LEN=32) :: keystx 06416 DOUBLE PRECISION :: dnum(100) 06417 REAL :: plvs(3) ! vector array: real and ... 06418 INTEGER :: lpvs(3) ! ... integer 06419 EQUIVALENCE (plvs(1),lpvs(1)) 06420 06421 INTERFACE 06422 SUBROUTINE addItem(length,list,label,value) 06423 USE mpmod 06424 INTEGER, INTENT(IN OUT) :: length 06425 TYPE(listItem), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list 06426 INTEGER, INTENT(IN) :: label 06427 REAL, INTENT(IN) :: value 06428 END SUBROUTINE addItem 06429 END INTERFACE 06430 06431 DATA keylst/'unknown','parameter','constraint','wconstraint', & 06432 'measurement', 'method', & 06433 'mestimate', 'atleast','option'/ 06434 06435 !add number of iterations 06436 ! wconstraint like constraint 06437 ! measured r sigma label factor ...(more) 06438 06439 SAVE 06440 DATA methxt/'diagonalization','inversion','fullMINRES', 'sparseMINRES'/ 06441 DATA lkey/-1/ ! last keyword 06442 06443 ! ... 06444 nkey=-1 ! new keyword 06445 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area 06446 IF(nab == 0) GOTO 10 06447 CALL ratext(text(1:nab),nums,dnum) ! translate text to DP numbers 06448 06449 IF(nums /= 0) nkey=0 06450 IF(keyb /= 0) THEN 06451 keywrd=text(keya:keyb) ! text is TEXT(KEYA)...TEXT(KEYB) 06452 ! WRITE(*,*) 'Keyword is ',KEYWRD 06453 06454 ! compare keywords 06455 06456 DO nkey=2,nkeys-1 ! loop over all pede keywords 06457 keystx=keylst(nkey) ! copy NKEY.th pede keyword 06458 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06459 IF(mat >= ntext-ntext/5) GO TO 10 06460 END DO 06461 06462 ! more comparisons 06463 06464 keystx='print' 06465 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06466 ! WRITE(*,*) KEYSTX,MAT,NTEXT 06467 ! IF(MAT.GE.NTEXT) THEN 06468 IF(mat >= (npat-npat/5)) THEN 06469 ! IF(MAT.GE.(NTEXT+NTEXT+3)/3) THEN 06470 mprint=1 06471 IF(nums > 0) mprint=IDNINT(dnum(1)) 06472 RETURN 06473 END IF 06474 06475 keystx='debug' 06476 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06477 IF(mat >= (npat-npat/5)) THEN 06478 ! IF(MAT.GE.(NTEXT+NTEXT+3)/3) THEN 06479 mdebug=3 06480 ! GF IF(NUMS.GT.0) MPRINT=DNUM(1) 06481 IF(nums > 0) mdebug=IDNINT(dnum(1)) 06482 IF(nums > 1) mdebg2=IDNINT(dnum(2)) 06483 RETURN 06484 END IF 06485 06486 keystx='entries' 06487 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06488 IF(mat >= (npat-npat/5)) THEN 06489 ! IF(MAT.GE.(NTEXT+NTEXT+3)/3) THEN 06490 mreqen=0 06491 IF(nums > 0) mreqen=IDNINT(dnum(1)) 06492 IF (mreqen <= 0) mreqen=1 06493 RETURN 06494 END IF 06495 06496 keystx='printrecord' 06497 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06498 IF(mat >= (npat-npat/5)) THEN 06499 IF(nums > 0) nrecpr=IDNINT(dnum(1)) 06500 IF(nums > 1) nrecp2=IDNINT(dnum(2)) 06501 RETURN 06502 END IF 06503 06504 keystx='maxrecord' 06505 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06506 IF(mat >= (npat-npat/5)) THEN 06507 IF (nums > 0.AND.dnum(1) > 0.) mxrec=IDNINT(dnum(1)) 06508 RETURN 06509 END IF 06510 06511 keystx='cache' 06512 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06513 IF(mat >= (npat-npat/5)) THEN 06514 IF (nums > 0.AND.dnum(1) >= 0.) ncache=IDNINT(dnum(1)) ! cache size, <0 keeps default 06515 IF (nums == 2.AND.dnum(2) > 0..AND.dnum(2) <= 1.0) & ! read cache fill level 06516 fcache(1)=SNGL(dnum(2)) 06517 IF (nums >= 4) THEN ! explicit cache splitting 06518 DO k=1,3 06519 fcache(k)=SNGL(dnum(k+1)) 06520 END DO 06521 END IF 06522 RETURN 06523 END IF 06524 06525 keystx='chisqcut' 06526 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06527 IF(mat >= (npat-npat/5)) THEN 06528 IF(nums == 0) THEN ! always 3-sigma cut 06529 chicut=1.0 06530 chirem=1.0 06531 ELSE 06532 chicut=SNGL(dnum(1)) 06533 IF(chicut < 1.0) chicut=-1.0 06534 IF(nums == 1) THEN 06535 chirem=1.0 ! 3-sigma cut, if not specified 06536 ELSE 06537 chirem=SNGL(dnum(2)) 06538 IF(chirem < 1.0) chirem=1.0 06539 IF(chicut >= 1.0) chirem=MIN(chirem,chicut) 06540 END IF 06541 END IF 06542 RETURN 06543 END IF 06544 06545 ! GF added: 06546 keystx='hugecut' 06547 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06548 IF(mat >= (npat-npat/5)) THEN 06549 IF(nums > 0) chhuge=SNGL(dnum(1)) 06550 IF(chhuge < 1.0) chhuge=1.0 ! at least (!!) 3-sigma 06551 RETURN 06552 END IF 06553 ! GF added end 06554 06555 keystx='localfit' 06556 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06557 IF(mat >= (npat-npat/5)) THEN 06558 IF(nums > 0) lfitnp=IDNINT(dnum(1)) 06559 IF(nums > 1) lfitbb=IDNINT(dnum(2)) 06560 RETURN 06561 END IF 06562 06563 keystx='regularization' 06564 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06565 IF(mat >= (npat-npat/5)) THEN 06566 nregul=1 06567 regula=SNGL(dnum(1)) 06568 IF(nums >= 2) regpre=SNGL(dnum(2)) 06569 RETURN 06570 END IF 06571 06572 keystx='regularisation' 06573 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06574 IF(mat >= (npat-npat/5)) THEN 06575 nregul=1 06576 regula=SNGL(dnum(1)) 06577 IF(nums >= 2) regpre=SNGL(dnum(2)) 06578 RETURN 06579 END IF 06580 06581 keystx='presigma' 06582 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06583 IF(mat >= (npat-npat/5)) THEN 06584 regpre=SNGL(dnum(1)) 06585 RETURN 06586 END IF 06587 06588 keystx='matiter' 06589 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06590 IF(mat >= (npat-npat/5)) THEN 06591 matrit=IDNINT(dnum(1)) 06592 RETURN 06593 END IF 06594 06595 keystx='matmoni' 06596 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06597 IF(mat >= (npat-npat/5)) THEN 06598 matmon=-1 06599 IF (nums > 0.AND.dnum(1) > 0.) matmon=IDNINT(dnum(1)) 06600 RETURN 06601 END IF 06602 06603 keystx='bandwidth' 06604 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06605 ! IF(MAT.GE.(NTEXT+NTEXT+3)/3) THEN 06606 IF(mat >= (npat-npat/5)) THEN 06607 IF(nums > 0) mbandw=IDNINT(dnum(1)) 06608 IF(mbandw < 0) mbandw=-1 06609 RETURN 06610 END IF 06611 06612 ! KEYSTX='outlierrejection' 06613 ! MAT=MATINT(TEXT(KEYA:KEYB),KEYSTX,NPAT,NTEXT) ! comparison 06614 ! WRITE(*,*) KEYSTX,MAT,(NTEXT+NTEXT)/3 06615 ! IF(MAT.GE.(NTEXT+NTEXT+NTEXT-2)/3) THEN 06616 ! IF(MAT.GE.(NPAT-NPAT/5)) THEN 06617 ! CHDFRJ=DNUM(1) 06618 ! IF(CHDFRJ.LT.3.0) CHDFRJ=100.0 06619 ! RETURN 06620 ! END IF 06621 06622 ! KEYSTX='outliersuppression' 06623 ! MAT=MATINT(TEXT(KEYA:KEYB),KEYSTX,NPAT,NTEXT) ! comparison 06624 ! WRITE(*,*) KEYSTX,MAT,(NTEXT+NTEXT)/3 06625 ! IF(MAT.GE.(NTEXT+NTEXT+NTEXT-2)/3) THEN 06626 ! IF(MAT.GE.(NPAT-NPAT/5)) THEN 06627 ! LHUBER=DNUM(1) 06628 ! IF(LHUBER.LE.2) LHUBER=2 ! at least 2 Huber iterations 06629 ! RETURN 06630 ! END IF 06631 06632 keystx='outlierdownweighting' 06633 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06634 ! WRITE(*,*) KEYSTX,MAT,(NTEXT+NTEXT)/3 06635 ! IF(MAT.GE.(NTEXT+NTEXT+NTEXT-2)/3) THEN 06636 IF(mat >= (npat-npat/5)) THEN 06637 lhuber=IDNINT(dnum(1)) 06638 IF(lhuber > 0.AND.lhuber <= 2) lhuber=2 ! at least 2 Huber iterations (if any) 06639 RETURN 06640 END IF 06641 06642 keystx='dwfractioncut' 06643 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06644 IF(mat >= (npat-npat/5)) THEN 06645 dwcut=SNGL(dnum(1)) 06646 IF(dwcut > 0.5) dwcut=0.5 06647 RETURN 06648 END IF 06649 06650 keystx='pullrange' 06651 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06652 IF(mat >= (npat-npat/5)) THEN 06653 prange=ABS(SNGL(dnum(1))) 06654 RETURN 06655 END IF 06656 06657 keystx='subito' 06658 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06659 IF(mat >= (npat-npat/5)) THEN 06660 isubit=1 06661 RETURN 06662 END IF 06663 06664 keystx='force' 06665 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06666 IF(mat >= (npat-npat/5)) THEN 06667 iforce=1 06668 RETURN 06669 END IF 06670 06671 keystx='memorydebug' 06672 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06673 IF(mat >= (npat-npat/5)) THEN 06674 memdbg=1 06675 IF (nums > 0.AND.dnum(1) > 0.0) memdbg=IDNINT(dnum(1)) 06676 RETURN 06677 END IF 06678 06679 keystx='globalcorr' 06680 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06681 IF(mat >= (npat-npat/5)) THEN 06682 igcorr=1 06683 RETURN 06684 END IF 06685 06686 keystx='threads' 06687 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06688 IF(mat >= (npat-npat/5)) THEN 06689 iomp=0 06690 !$ IOMP=1 06691 !$ IF (IOMP.GT.0) THEN 06692 !$ IF (NUMS.GE.1.AND.DNUM(1).GT.0.) MTHRD =IDNINT(DNUM(1)) 06693 !$ IF (NUMS.GE.2) THEN 06694 !$ MTHRDR=MTHRD 06695 !$ IF (DNUM(2).GT.0.) MTHRDR=IDNINT(DNUM(2)) 06696 !$ ENDIF 06697 !$ ELSE 06698 WRITE(*,*) 'WARNING: multithreading not available' 06699 !$ ENDIF 06700 RETURN 06701 END IF 06702 06703 keystx='compress' 06704 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06705 IF(mat >= (npat-npat/5)) THEN 06706 mcmprs=1 06707 RETURN 06708 END IF 06709 06710 keystx='errlabels' 06711 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06712 IF(mat >= (npat-npat/5).AND.mnrsel < 100) THEN 06713 nl=MIN(nums,100-mnrsel) 06714 DO k=1,nl 06715 lbmnrs(mnrsel+k)=IDNINT(dnum(k)) 06716 END DO 06717 mnrsel=mnrsel+nl 06718 RETURN 06719 END IF 06720 06721 keystx='pairentries' 06722 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06723 IF(mat >= (npat-npat/5)) THEN 06724 ! This option could be implemented to get rid of parameter pairs 06725 ! that have very few entries - to save matrix memory size. 06726 IF (nums > 0.AND.dnum(1) > 0.0) THEN 06727 mreqpe=IDNINT(dnum(1)) 06728 IF (nums >= 2.AND.dnum(2) >= dnum(1)) mhispe=IDNINT(dnum(2)) 06729 IF (nums >= 3.AND.dnum(3) > 0.0) msngpe=IDNINT(dnum(3)) 06730 icount=MAX(msngpe+1,mhispe) 06731 icount=MAX(mreqpe,icount) 06732 numbit=1 ! number of bits needed to count up to ICOUNT 06733 mxcnt=2 06734 DO k=1,30 06735 IF (icount >= mxcnt) THEN 06736 numbit=numbit+1 06737 mxcnt=mxcnt*2 06738 END IF 06739 END DO 06740 END IF 06741 RETURN 06742 END IF 06743 06744 keystx='wolfe' 06745 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06746 IF(mat >= (npat-npat/5)) THEN 06747 wolfc1=SNGL(dnum(1)) 06748 wolfc2=SNGL(dnum(2)) 06749 RETURN 06750 END IF 06751 06752 ! GF added: 06753 ! convergence tolerance for minres: 06754 keystx='mrestol' 06755 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06756 IF(mat >= (npat-npat/5)) THEN 06757 IF(nums > 0) THEN 06758 IF (dnum(1) < 1.0D-10.OR.dnum(1) > 1.0D-04) THEN 06759 WRITE(*,*) 'ERROR: need 1.0D-10 <= MRESTL ', & 06760 '<= 1.0D-04, but get ', dnum(1) 06761 ELSE 06762 mrestl=IDNINT(dnum(1)) 06763 END IF 06764 END IF 06765 RETURN 06766 END IF 06767 ! GF added end 06768 06769 keystx='nofeasiblestart' 06770 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06771 IF(mat >= (npat-npat/5)) THEN 06772 nofeas=1 ! do not make parameters feasible at start 06773 RETURN 06774 END IF 06775 06776 keystx='histprint' 06777 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06778 IF(mat >= ntext-ntext/10) THEN 06779 ! IF(MAT.GE.(NPAT-NPAT/5)) THEN 06780 nhistp=1 ! print histograms 06781 RETURN 06782 END IF 06783 06784 keystx='fortranfiles' 06785 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison 06786 IF(mat >= ntext-ntext/10) RETURN 06787 06788 keystx='Cfiles' 06789 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison 06790 IF(mat >= ntext-ntext/10) RETURN 06791 06792 keystx=keylst(1) 06793 nkey=1 ! unknown keyword 06794 IF(nums /= 0) nkey=0 06795 06796 WRITE(*,*) ' ' 06797 WRITE(*,*) '**************************************************' 06798 WRITE(*,*) ' ' 06799 WRITE(*,*) 'Unknown keyword(s): ',text(1:MIN(nab,50)) 06800 WRITE(*,*) ' ' 06801 WRITE(*,*) '**************************************************' 06802 WRITE(*,*) ' ' 06803 lunkno=lunkno+1 06804 06805 END IF 06806 ! result: NKEY = -1 blank 06807 ! NKEY = 0 numerical data, no text keyword or unknown 06808 ! NKEY > 0 keyword NKEY from list, keyword = KEYSTX 06809 06810 06811 ! content/lastcontent 06812 ! ------------------- 06813 ! blank -1 06814 ! data 0 06815 ! keyword 06816 ! unknown 1 06817 ! parameter 2 06818 ! constraint 3 06819 ! method 4 06820 ! atleast 5 06821 ! option 6 06822 ! cut 7 06823 06824 10 IF(nkey > 0) THEN ! new keyword 06825 lkey=nkey 06826 IF(lkey == 2) THEN ! parameter 06827 IF(nums == 3) THEN 06828 lpvs(1)=IDNINT(dnum(1)) ! label 06829 plvs(2)=SNGL(dnum(2)) ! start value 06830 plvs(3)=SNGL(dnum(3)) ! pre-sigma 06831 IF(lpvs(1) /= 0) THEN 06832 ! CALL megvec('7',plvs,3,0) ! always 3 words 06833 CALL addItem(lenParameters,listParameters,lpvs(1),plvs(2)) 06834 CALL addItem(lenPreSigmas,listPresigmas,lpvs(1),plvs(3)) 06835 ELSE 06836 WRITE(*,*) 'Line',nline,' error, label=',lpvs(1) 06837 END IF 06838 ELSE IF(nums /= 0) THEN 06839 kkey=1 ! switch to "unknown" ? 06840 WRITE(*,*) 'Wrong text in line',nline 06841 WRITE(*,*) 'Status: new parameter' 06842 WRITE(*,*) '> ',text(1:nab) 06843 END IF 06844 ELSE IF(lkey == 3.OR.lkey == 4) THEN ! constraint 06845 ! WRITE(*,*) 'Keyword is constraint!',NUMS,' numerical data' 06846 IF(nums >= 1.AND.nums <= 2) THEN ! start constraint 06847 ! WRITE(*,*) 'NUMs is ',NUMS 06848 lpvs(1)=0 06849 plvs(2)=SNGL(dnum(1)) ! r = r.h.s. value 06850 ! CALL megvec('8',plvs,2,0) 06851 CALL addItem(lenConstraints,listConstraints,lpvs(1),plvs(2)) 06852 ! WRITE(*,*) 'LPVS PLVS ',LPVS,PLVS 06853 lpvs(1)=-1 ! constraint 06854 IF(lkey == 4) lpvs(1)=-2 ! wconstraint (weighted) 06855 plvs(2)=0.0 06856 ! WRITE(*,*) 'LPVS PLVS ',LPVS,PLVS 06857 IF(nums == 2) plvs(2)=SNGL(dnum(2)) ! sigma 06858 ! CALL megvec('8',plvs,2,0) 06859 CALL addItem(lenConstraints,listConstraints,lpvs(1),plvs(2)) 06860 ! WRITE(*,*) 'LPVS PLVS ',LPVS,PLVS 06861 ELSE 06862 kkey=1 ! switch to "unknown" 06863 WRITE(*,*) 'Wrong text in line',nline 06864 WRITE(*,*) 'Status: new keyword (w)constraint' 06865 WRITE(*,*) '> ',text(1:nab) 06866 END IF 06867 ELSE IF(lkey == 5) THEN ! measurement 06868 IF(nums == 2) THEN ! start measurement 06869 lpvs(1)=0 06870 plvs(2)=SNGL(dnum(1)) ! r = r.h.s. value 06871 ! CALL megvec('9',plvs,2,0) 06872 CALL addItem(lenMeasurements,listMeasurements,lpvs(1),plvs(2)) 06873 lpvs(1)=-1 ! constraint 06874 plvs(2)=SNGL(dnum(2)) ! sigma 06875 ! CALL megvec('9',plvs,2,0) 06876 CALL addItem(lenMeasurements,listMeasurements,lpvs(1),plvs(2)) 06877 ELSE 06878 kkey=1 ! switch to "unknown" 06879 WRITE(*,*) 'Wrong text in line',nline 06880 WRITE(*,*) 'Status: new keyword measurement' 06881 WRITE(*,*) '> ',text(1:nab) 06882 END IF 06883 06884 ELSE IF(lkey == 6) THEN ! method 06885 miter=mitera 06886 IF(nums >= 1) miter=IDNINT(dnum(1)) 06887 IF(miter >= 1) mitera=miter 06888 dflim=SNGL(dnum(2)) 06889 lkey=0 06890 DO i=1,nmeth 06891 keystx=methxt(i) 06892 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison 06893 IF(mat >= ntext-ntext/5) THEN 06894 IF(i == 1) THEN ! diagonalization 06895 metsol=2 06896 matsto=1 06897 ELSE IF(i == 2) THEN ! inversion 06898 metsol=1 06899 matsto=1 06900 ELSE IF(i == 3) THEN ! fullMINRES 06901 metsol=3 06902 matsto=1 06903 ! METSOL=4 !!! 06904 ELSE IF(i == 4) THEN ! sparseMINRES 06905 ! METSOL=4 06906 metsol=3 06907 matsto=2 06908 06909 END IF 06910 END IF 06911 END DO 06912 END IF 06913 ELSE IF(nkey == 0) THEN ! data for continuation 06914 IF(lkey == 2) THEN ! parameter 06915 IF(nums >= 3) THEN ! store data from this line 06916 lpvs(1)=IDNINT(dnum(1)) ! label 06917 plvs(2)=SNGL(dnum(2)) ! start value 06918 plvs(3)=SNGL(dnum(3)) ! pre-sigma 06919 IF(lpvs(1) /= 0) THEN 06920 ! CALL megvec('7',plvs,3,0) ! always 3 words 06921 CALL addItem(lenParameters,listParameters,lpvs(1),plvs(2)) 06922 CALL addItem(lenPreSigmas,listPresigmas,lpvs(1),plvs(3)) 06923 ELSE 06924 WRITE(*,*) 'Line',nline,' error, label=',lpvs(1) 06925 END IF 06926 ELSE IF(nums > 1.AND.nums < 3) THEN 06927 kkey=1 ! switch to "unknown" ? 06928 WRITE(*,*) 'Wrong text in line',nline 06929 WRITE(*,*) 'Status continuation parameter' 06930 WRITE(*,*) '> ',text(1:nab) 06931 END IF 06932 06933 ELSE IF(lkey == 3.OR.lkey == 4) THEN ! (w)constraint 06934 ier=0 06935 DO i=1,nums,2 06936 label=IDNINT(dnum(i)) 06937 IF(label <= 0) ier=1 06938 END DO 06939 IF(MOD(nums,2) /= 0) ier=1 ! reject odd number 06940 IF(ier == 0) THEN 06941 DO i=1,nums,2 06942 lpvs(1)=IDNINT(dnum(i)) ! label 06943 plvs(2)=SNGL(dnum(i+1)) ! factor 06944 ! CALL megvec('8',plvs,2,0) 06945 CALL addItem(lenConstraints,listConstraints,lpvs(1),plvs(2)) 06946 END DO 06947 ELSE 06948 kkey=0 06949 WRITE(*,*) 'Wrong text in line',nline 06950 WRITE(*,*) 'Status continuation (w)constraint' 06951 WRITE(*,*) '> ',text(1:nab) 06952 END IF 06953 06954 ELSE IF(lkey == 5) THEN ! measurement 06955 ! WRITE(*,*) 'continuation < ',NUMS 06956 ier=0 06957 DO i=1,nums,2 06958 label=IDNINT(dnum(i)) 06959 IF(label <= 0) ier=1 06960 END DO 06961 IF(MOD(nums,2) /= 0) ier=1 ! reject odd number 06962 ! WRITE(*,*) 'IER NUMS ',IER,NUMS 06963 IF(ier == 0) THEN 06964 DO i=1,nums,2 06965 lpvs(1)=IDNINT(dnum(i)) ! label 06966 plvs(2)=SNGL(dnum(i+1)) ! factor 06967 ! CALL megvec('9',plvs,2,0) 06968 CALL addItem(lenMeasurements,listMeasurements,lpvs(1),plvs(2)) 06969 END DO 06970 ELSE 06971 kkey=0 06972 WRITE(*,*) 'Wrong text in line',nline 06973 WRITE(*,*) 'Status continuation measurement' 06974 WRITE(*,*) '> ',text(1:nab) 06975 END IF 06976 06977 END IF 06978 END IF 06979 END SUBROUTINE intext 06980 06988 SUBROUTINE addItem(length,list,label,value) 06989 USE mpdalc 06990 06991 INTEGER, INTENT(IN OUT) :: length 06992 TYPE(listItem), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list 06993 INTEGER, INTENT(IN) :: label 06994 REAL, INTENT(IN) :: value 06995 06996 INTEGER(kind=large) :: newSize 06997 INTEGER(kind=large) :: oldSize 06998 TYPE(listItem), DIMENSION(:), ALLOCATABLE :: tempList 06999 07000 IF (label > 0.AND.value == 0.) RETURN ! skip zero for valid labels 07001 IF (length == 0 ) THEN ! initial list with size = 100 07002 newSize = 100 07003 CALL mpalloc(list,newSize,' list ') 07004 ENDIF 07005 oldSize=size(list,kind=large) 07006 IF (length >= oldSize) THEN ! increase sizeby 20% + 100 07007 newSize = oldSize + oldSize/5 + 100 07008 CALL mpalloc(tempList,oldSize,' temp. list ') 07009 tempList=list 07010 CALL mpdealloc(list) 07011 CALL mpalloc(list,newSize,' list ') 07012 list(1:oldSize)=tempList(1:oldSize) 07013 CALL mpdealloc(tempList) 07014 ENDIF 07015 ! add to end of list 07016 length=length+1 07017 list(length)%label=label 07018 list(length)%value=value 07019 07020 END SUBROUTINE addItem 07021 07023 SUBROUTINE mstart(text) 07024 USE mpmod, ONLY: textl 07025 07026 IMPLICIT NONE 07027 INTEGER :: i 07028 INTEGER :: ka 07029 INTEGER :: kb 07030 INTEGER :: l 07031 CHARACTER (LEN=*), INTENT(IN) :: text 07032 CHARACTER (LEN=16) :: textc 07033 SAVE 07034 ! ... 07035 DO i=1,74 07036 textl(i:i)='_' 07037 END DO 07038 l=LEN(text) 07039 ka=(74-l)/2 07040 kb=ka+l-1 07041 textl(ka:kb)=text(1:l) 07042 WRITE(*,*) ' ' 07043 WRITE(*,*) textl 07044 WRITE(*,*) ' ' 07045 textc=text(1:l)//'-end' 07046 07047 DO i=1,74 07048 textl(i:i)='_' 07049 END DO 07050 l=l+4 07051 ka=(74-l)/2 07052 kb=ka+l-1 07053 textl(ka:kb)=textc(1:l) 07054 RETURN 07055 END SUBROUTINE mstart 07056 07058 SUBROUTINE mend 07059 USE mpmod, ONLY: textl 07060 07061 IMPLICIT NONE 07062 WRITE(*,*) ' ' 07063 WRITE(*,*) textl 07064 CALL petime 07065 WRITE(*,*) ' ' 07066 END SUBROUTINE mend 07067 07074 07075 SUBROUTINE mvopen(lun,fname) 07076 IMPLICIT NONE 07077 INTEGER :: l 07078 INTEGER, INTENT(IN) :: lun 07079 CHARACTER (LEN=*), INTENT(IN) :: fname 07080 CHARACTER (LEN=33) :: nafile 07081 CHARACTER (LEN=33) :: nbfile 07082 LOGICAL :: ex 07083 SAVE 07084 ! ... 07085 l=LEN(fname) 07086 IF(l > 32) STOP 'File name too long ' 07087 nafile=fname 07088 nafile(l+1:l+1)='~' 07089 07090 INQUIRE(FILE=nafile(1:l),EXIST=ex) 07091 IF(ex) THEN 07092 INQUIRE(FILE=nafile(1:l+1),EXIST=ex) 07093 IF(ex) THEN 07094 CALL system('rm '//nafile) 07095 END IF 07096 nbfile=nafile 07097 nafile(l+1:l+1)=' ' 07098 CALL system('mv '//nafile//nbfile) 07099 END IF 07100 OPEN(UNIT=lun,FILE=fname) 07101 END SUBROUTINE mvopen 07102 07106 07107 SUBROUTINE petime 07108 IMPLICIT NONE 07109 REAL :: ta(2) 07110 REAL :: rst 07111 REAL :: delta 07112 REAL :: rstp 07113 REAL :: secnd1 07114 REAL :: secnd2 07115 INTEGER :: ncount 07116 INTEGER :: nhour1 07117 INTEGER :: minut1 07118 INTEGER :: nsecd1 07119 INTEGER :: nhour2 07120 INTEGER :: minut2 07121 INTEGER :: nsecd2 07122 07123 SAVE 07124 DATA ncount/0/ 07125 ! ... 07126 ncount=ncount+1 07127 CALL etime(ta,rst) 07128 IF(ncount > 1) THEN 07129 delta=rst 07130 nsecd1=INT(delta) ! -> integer 07131 nhour1=nsecd1/3600 07132 minut1=nsecd1/60-60*nhour1 07133 secnd1=delta-60*(minut1+60*nhour1) 07134 delta=rst-rstp 07135 nsecd2=INT(delta) ! -> integer 07136 nhour2=nsecd2/3600 07137 minut2=nsecd2/60-60*nhour2 07138 secnd2=delta-60*(minut2+60*nhour2) 07139 WRITE(*,101) nhour1,minut1,secnd1, nhour2,minut2,secnd2 07140 END IF 07141 07142 rstp=rst 07143 RETURN 07144 101 FORMAT(i4,' h',i3,' min',f5.1,' sec total',18X,'elapsed', & 07145 i4,' h',i3,' min',f5.1,' sec') 07146 END SUBROUTINE petime ! print 07147 07148 ! ----- accurate summation ----(from mpnum) --------------------------------- 07149 07153 07154 SUBROUTINE addsum(add) 07155 USE mpmod 07156 07157 IMPLICIT NONE 07158 DOUBLE PRECISION:: add 07159 INTEGER::nadd 07160 ! ... 07161 nadd=INT(add) ! convert to integer 07162 accurateNsum=accurateNsum+nadd ! sum integer 07163 accurateDsum=accurateDsum+(add-dfloat(nadd)) ! sum remainder 07164 IF(accurateDsum > 16.0D0) THEN ! + - 16 07165 accurateDsum=accurateDsum-16.0D0 07166 accurateNsum=accurateNsum+16 07167 END IF 07168 IF(accurateNsum > nexp20) THEN ! if > 2^20: + - 2^20 07169 accurateNexp=accurateNexp+1 07170 accurateNsum=accurateNsum-nexp20 07171 END IF 07172 RETURN 07173 END SUBROUTINE addsum 07174 07178 07179 SUBROUTINE getsum(asum) 07180 USE mpmod 07181 07182 IMPLICIT NONE 07183 DOUBLE PRECISION, INTENT(OUT) ::asum 07184 asum=(accurateDsum+dfloat(accurateNsum))+dfloat(accurateNexp)*dfloat(nexp20) 07185 accurateDsum=0.0D0 07186 accurateNsum=0 07187 accurateNexp=0 07188 RETURN 07189 END SUBROUTINE getsum 07190