GeneralBrokenLines  Rev:70
 All Classes Files Functions Variables Pages
gblnum.f90
Go to the documentation of this file.
1 !
2 
3 ! Code converted using TO_F90 by Alan Miller
4 ! Date: 2012-03-03 Time: 17:00:00
5 
6 ! C. Kleinwort , DESY-FH1, www.terascale.de
7 ! February 2011, Analysis Centre: Statistics Tools Group
8 
13 
14 !======================================================================
15 
16 ! V. Blobel, Univ. Hamburg
17 ! Numerical subprograms used in MP-II: matrix equations,
18 ! and matrix products, double precision
19 !
20 ! Solution by inversion
21 ! SQMINV
22 !
23 ! Solution by diagonalization
24 ! DEVROT
25 !
26 ! Solution by Cholesky decomposition of bordered band matrix
27 !CHK SQMIBB
28 !
29 ! Matrix/vector products
30 !- DBDOT dot vector product
31 !- DBAXPY multiplication and addition
32 !- DBSVX symmetric matrix vector
33 ! DBGAX general matrix vector
34 ! DBAVAT AVAT product
35 !- DBMPRV print parameter and matrix
36 !CHK DBPRV print matrix
37 
38 !----------------------------------------------------------------------
57 
58 SUBROUTINE sqminv(v,b,n,nrank,diag,next)
59  IMPLICIT NONE
60  INTEGER :: i
61  INTEGER :: ij
62  INTEGER :: j
63  INTEGER :: jj
64  INTEGER :: jk
65  INTEGER :: jl
66  INTEGER :: k
67  INTEGER :: kk
68  INTEGER :: l
69  INTEGER :: last
70  INTEGER :: lk
71  INTEGER :: next0
72 
73  DOUBLE PRECISION, INTENT(IN OUT) :: v(*)
74  DOUBLE PRECISION, INTENT(OUT) :: b(n)
75  INTEGER, INTENT(IN) :: n
76  INTEGER, INTENT(OUT) :: nrank
77  DOUBLE PRECISION, INTENT(OUT) :: diag(n)
78  INTEGER, INTENT(OUT) :: next(n)
79 
80  DOUBLE PRECISION :: vkk
81  DOUBLE PRECISION ::vjk
82 
83  DOUBLE PRECISION, PARAMETER :: eps=1.0d-10
84  ! ..
85  next0=1
86  DO i=1,n
87  next(i)=i+1 ! set "next" pointer
88  diag(i)=abs(v((i*i+i)/2)) ! save abs of diagonal elements
89  END DO
90  next(n)=-1 ! end flag
91 
92  nrank=0
93  loop: DO i=1,n ! start of loop
94  k =0
95  vkk=0.0d0
96 
97  j=next0
98  last=0
99  DO WHILE (j > 0)
100  jj=(j*j+j)/2
101  IF(abs(v(jj)) > max(abs(vkk),eps*diag(j))) THEN
102  vkk=v(jj)
103  k=j
104  l=last
105  END IF
106  last=j
107  j=next(last)
108  END DO
109 
110  IF(k /= 0) THEN ! pivot found
111  kk=(k*k+k)/2
112  IF(l == 0) THEN
113  next0=next(k)
114  ELSE
115  next(l)=next(k)
116  END IF
117  next(k)=0 ! index is used, reset
118  nrank=nrank+1 ! increase rank and ...
119  vkk =1.0/vkk
120  v(kk) =-vkk
121  b(k) =b(k)*vkk
122  jk =kk-k
123  jl =0
124  DO j=1,n ! elimination
125  IF(j == k) THEN
126  jk=kk
127  jl=jl+j
128  ELSE
129  IF(j < k) THEN
130  jk=jk+1
131  ELSE
132  jk=jk+j-1
133  END IF
134  vjk =v(jk)
135  v(jk)=vkk*vjk
136  b(j) =b(j)-b(k)*vjk
137  lk =kk-k
138  DO l=1,j
139  jl=jl+1
140  IF(l == k) THEN
141  lk=kk
142  ELSE
143  IF(l < k) THEN
144  lk=lk+1
145  ELSE
146  lk=lk+l-1
147  END IF
148  v(jl)=v(jl)-v(lk)*vjk
149  END IF
150  END DO
151  END IF
152  END DO
153  ELSE
154  DO k=1,n
155  IF(next(k) /= 0) THEN
156  b(k)=0.0d0 ! clear vector element
157  DO j=1,k
158  IF(next(j) /= 0) v((k*k-k)/2+j)=0.0d0 ! clear matrix row/col
159  END DO
160  END IF
161  END DO
162  exit loop
163  END IF
164  END DO loop ! end of loop
165  DO ij=1,(n*n+n)/2
166  v(ij)=-v(ij) ! finally reverse sign of all matrix elements
167  END DO
168 END SUBROUTINE sqminv
169 
181 
182 SUBROUTINE devrot(n,diag,u,v,work,iwork)
183  IMPLICIT NONE
184 
185  INTEGER, INTENT(IN) :: n
186  DOUBLE PRECISION, INTENT(OUT) :: diag(n)
187  DOUBLE PRECISION, INTENT(OUT) :: u(n,n)
188  DOUBLE PRECISION, INTENT(IN) :: v(*)
189  DOUBLE PRECISION, INTENT(OUT) :: work(n)
190  INTEGER, INTENT(OUT) :: iwork(n)
191 
192  INTEGER, PARAMETER :: itmax=30
193  DOUBLE PRECISION, PARAMETER :: tol=1.0d-16
194  DOUBLE PRECISION, PARAMETER :: eps=1.0d-16
195 
196  DOUBLE PRECISION :: f
197  DOUBLE PRECISION :: g
198  DOUBLE PRECISION :: h
199  DOUBLE PRECISION :: sh
200  DOUBLE PRECISION :: hh
201  DOUBLE PRECISION :: b
202  DOUBLE PRECISION :: p
203  DOUBLE PRECISION :: r
204  DOUBLE PRECISION :: s
205  DOUBLE PRECISION :: c
206  DOUBLE PRECISION :: workd
207 
208  INTEGER :: ij
209  INTEGER :: i
210  INTEGER :: j
211  INTEGER :: k
212  INTEGER :: l
213  INTEGER :: m
214  INTEGER :: ll
215  ! ...
216  ! 1. part: symmetric matrix V reduced to tridiagonal from
217  ij=0
218  DO i=1,n
219  DO j=1,i
220  ij=ij+1
221  u(i,j)=v(ij) ! copy half of symmetric matirx
222  END DO
223  END DO
224 
225  DO i=n,2,-1
226  l=i-2
227  f=u(i,i-1)
228  g=0.0d0
229  IF(l /= 0) THEN
230  DO k=1,l
231  IF(abs(u(i,k)) > tol) g=g+u(i,k)*u(i,k)
232  END DO
233  h=g+f*f
234  END IF
235  IF(g < tol) THEN ! G too small
236  work(i)=f ! skip transformation
237  h =0.0d0
238  ELSE
239  l=l+1
240  sh=sqrt(h)
241  IF(f >= 0.0d0) sh=-sh
242  g=sh
243  work(i)=sh
244  h=h-f*g
245  u(i,i-1)=f-g
246  f=0.0d0
247  DO j=1,l
248  u(j,i)=u(i,j)/h
249  g=0.0d0
250  ! form element of a u
251  DO k=1,j
252  IF(abs(u(j,k)) > tol.AND.abs(u(i,k)) > tol) THEN
253  g=g+u(j,k)*u(i,k)
254  END IF
255  END DO
256  DO k=j+1,l
257  IF(abs(u(k,j)) > tol.AND.abs(u(i,k)) > tol) THEN
258  g=g+u(k,j)*u(i,k)
259  END IF
260  END DO
261  work(j)=g/h
262  f=f+g*u(j,i)
263  END DO
264  ! form k
265  hh=f/(h+h)
266  ! form reduced a
267  DO j=1,l
268  f=u(i,j)
269  work(j)=work(j)-hh*f
270  g=work(j)
271  DO k=1,j
272  u(j,k)=u(j,k)-f*work(k)-g*u(i,k)
273  END DO
274  END DO
275  END IF
276  diag(i)=h
277  END DO
278 
279  diag(1)=0.0d0
280  work(1)=0.0d0
281 
282  ! accumulation of transformation matrices
283  DO i=1,n
284  IF(diag(i) /= 0.0) THEN
285  DO j=1,i-1
286  g=0.0d0
287  DO k=1,i-1
288  g=g+u(i,k)*u(k,j)
289  END DO
290  DO k=1,i-1
291  u(k,j)=u(k,j)-g*u(k,i)
292  END DO
293  END DO
294  END IF
295  diag(i)=u(i,i)
296  u(i,i)=1.0d0
297  DO j=1,i-1
298  u(i,j)=0.0d0
299  u(j,i)=0.0d0
300  END DO
301  END DO
302 
303  ! 2. part: diagonalization of tridiagonal matrix
304  DO i=2,n
305  work(i-1)=work(i)
306  END DO
307  work(n)=0.0d0
308  b=0.0d0
309  f=0.0d0
310 
311  DO l=1,n
312  j=0
313  h=eps*(abs(diag(l))+abs(work(l)))
314  IF(b < h) b=h
315  DO m=l,n
316  IF(abs(work(m)) <= b) go to 10 ! look for small sub-diagonal element
317  END DO
318  m=l
319 10 IF(m == l) go to 30
320  ! next iteration
321 20 IF(j == itmax) THEN
322  WRITE(*,*) 'DEVROT: Iteration limit reached'
323  stop
324  END IF
325  j=j+1
326  g=diag(l)
327  p=(diag(l+1)-g)/(2.0d0*work(l))
328  r=sqrt(1.0d0+p*p)
329  diag(l)=work(l)
330  IF(p < 0.0d0) diag(l)=diag(l)/(p-r)
331  IF(p >= 0.0d0) diag(l)=diag(l)/(p+r)
332  h=g-diag(l)
333  DO i=l+1,n
334  diag(i)=diag(i)-h
335  END DO
336  f=f+h
337  ! QL transformation
338  p=diag(m)
339  c=1.0d0
340  s=0.0d0
341  DO i=m-1,l,-1 ! reverse loop
342  g=c*work(i)
343  h=c*p
344  IF(abs(p) >= abs(work(i))) THEN
345  c=work(i)/p
346  r=sqrt(1.0d0+c*c)
347  work(i+1)=s*p*r
348  s=c/r
349  c=1.0d0/r
350  ELSE
351  c=p/work(i)
352  r=sqrt(1.0d0+c*c)
353  work(i+1)=s*work(i)*r
354  s=1.0d0/r
355  c=c/r
356  END IF
357  p=c*diag(i)-s*g
358  diag(i+1)=h+s*(c*g+s*diag(i))
359  ! form vector
360  DO k=1,n
361  h=u(k,i+1)
362  u(k,i+1)=s*u(k,i)+c*h
363  u(k,i)=c*u(k,i)-s*h
364  END DO
365  END DO
366  work(l)=s*p
367  diag(l)=c*p
368  IF(abs(work(l)) > b) go to 20 ! next iteration
369 30 diag(l)=diag(l)+f
370  END DO
371  DO i=1,n
372  iwork(i)=i
373  END DO
374 
375  m=1
376 40 m=1+3*m ! determine initial increment
377  IF(m <= n) go to 40
378 50 m=m/3
379  DO j=1,n-m ! sort with increment M
380  l=j
381 60 IF(diag(iwork(l+m)) > diag(iwork(l))) THEN ! compare
382  ll=iwork(l+m) ! exchange the two index values
383  iwork(l+m)=iwork(l)
384  iwork(l)=ll
385  l=l-m
386  IF(l > 0) go to 60
387  END IF
388  END DO
389  IF(m > 1) go to 50
390 
391  DO i=1,n
392  IF(iwork(i) /= i) THEN
393  ! move vector from position I to the work area
394  workd=diag(i)
395  DO l=1,n
396  work(l)=u(l,i)
397  END DO
398  k=i
399 70 j=k
400  k=iwork(j)
401  iwork(j)=j
402  IF(k /= i) THEN
403  ! move vector from position K to the (free) position J
404  diag(j)=diag(k)
405  DO l=1,n
406  u(l,j)=u(l,k)
407  END DO
408  go to 70
409  END IF
410  ! move vector from the work area to position J
411  diag(j)=workd
412  DO l=1,n
413  u(l,j)=work(l)
414  END DO
415  END IF
416  END DO
417 END SUBROUTINE devrot
418 
426 
427 SUBROUTINE dbgax(a,x,y,m,n)
428  IMPLICIT NONE
429  INTEGER :: i
430  INTEGER :: ij
431  INTEGER :: j
432 
433  DOUBLE PRECISION, INTENT(IN) :: a(*)
434  DOUBLE PRECISION, INTENT(IN) :: x(*)
435  DOUBLE PRECISION, INTENT(OUT) :: y(*)
436  INTEGER, INTENT(IN) :: m
437  INTEGER, INTENT(IN) :: n
438 
439  ! ...
440  ij=0
441  DO i=1,m
442  y(i)=0.0d0
443  DO j=1,n
444  ij=ij+1
445  y(i)=y(i)+a(ij)*x(j)
446  END DO
447  END DO
448 END SUBROUTINE dbgax
449 
462 
463 SUBROUTINE dbavat(v,a,w,n,m)
464  IMPLICIT NONE
465  INTEGER :: i
466  INTEGER :: ij
467  INTEGER :: ijs
468  INTEGER :: il
469  INTEGER :: j
470  INTEGER :: jk
471  INTEGER :: k
472  INTEGER :: l
473  INTEGER :: lk
474  INTEGER :: lkl
475 
476  DOUBLE PRECISION, INTENT(IN) :: v(*)
477  DOUBLE PRECISION, INTENT(IN) :: a(*)
478  DOUBLE PRECISION, INTENT(OUT) :: w(*)
479  INTEGER, INTENT(IN) :: n
480  INTEGER, INTENT(IN) :: m
481 
482  DOUBLE PRECISION :: cik
483 
484  ! ...
485  DO i=1,(m*m+m)/2
486  w(i)=0.0 ! reset output matrix
487  END DO
488  il=-n
489  ijs=0
490  DO i=1,m ! do I
491  ijs=ijs+i-1 !
492  il=il+n !
493  lkl=0 !
494  DO k=1,n ! do K
495  cik=0.0d0 !
496  lkl=lkl+k-1 !
497  lk=lkl !
498  DO l=1,k ! do L
499  lk=lk+1 ! .
500  cik=cik+a(il+l)*v(lk) ! .
501  END DO ! end do L
502  DO l=k+1,n ! do L
503  lk=lk+l-1 ! .
504  cik=cik+a(il+l)*v(lk) ! .
505  END DO ! end do L
506  jk=k !
507  ij=ijs !
508  DO j=1,i ! do J
509  ij=ij+1 ! .
510  w(ij)=w(ij)+cik*a(jk) ! .
511  jk=jk+n ! .
512  END DO ! end do J
513  END DO ! end do K
514  END DO ! end do I
515 END SUBROUTINE dbavat
516 
517 ! 090817 C. Kleinwort, DESY-FH1
556 
557 SUBROUTINE sqmibb(v,b,n,nbdr,nbnd,inv,nrank)
558 
559  ! Double precision scratch arrays:
560  ! VBND(N*(NBND+1)) = storage of band part
561  ! VBDR(N* NBDR) = storage of border part
562  ! AUX (N* NBDR) = intermediate results
563 
564  ! cost[dot ops] ~= (N-NBDR)*(NBDR+NBND+1)**2 + NBDR**3/3 (leading term, solution only)
565 
566  USE gbltraj, ONLY: maxFitPar, maxBandWidth, maxBorderSize
567  IMPLICIT NONE
568  INTEGER :: i
569  INTEGER :: ib
570  INTEGER :: ij
571  INTEGER :: ioff
572  INTEGER :: ip
573  INTEGER :: ip1
574  INTEGER :: ip2
575  INTEGER :: is
576  INTEGER :: j
577  INTEGER :: j0
578  INTEGER :: jb
579  INTEGER :: joff
580  INTEGER :: mp1
581  INTEGER :: nb1
582  INTEGER :: nmb
583  INTEGER :: npri
584  INTEGER :: nrankb
585 
586  DOUBLE PRECISION, INTENT(IN OUT) :: v(*)
587  DOUBLE PRECISION, INTENT(OUT) :: b(n)
588  INTEGER, INTENT(IN) :: n
589  INTEGER, INTENT(IN) :: nbdr
590  INTEGER, INTENT(IN) :: nbnd
591  INTEGER, INTENT(IN) :: inv
592  INTEGER, INTENT(OUT) :: nrank
593 
594  DOUBLE PRECISION :: vbnd(maxfitpar*(maxbandwidth+1))
595  DOUBLE PRECISION :: vbdr(maxfitpar*maxbordersize)
596  DOUBLE PRECISION :: aux(maxfitpar*maxbordersize)
597  DOUBLE PRECISION :: vbk((maxbordersize*maxbordersize+maxbordersize)/2)
598  DOUBLE PRECISION :: vzru(maxbordersize)
599  DOUBLE PRECISION ::scdiag(maxbordersize)
600  INTEGER :: scflag(maxbordersize)
601 
602  SAVE npri
603  DATA npri / 100 /
604  ! ...
605  nrank=0
606  nb1=nbdr+1
607  mp1=nbnd+1
608  nmb=n-nbdr
609  ! copy band part
610  DO i=nb1,n
611  ip=(i*(i+1))/2
612  is=0
613  DO j=i,min(n,i+nbnd)
614  ip=ip+is
615  is=j
616  ib=j-i+1
617  vbnd(ib+(i-nb1)*mp1)=v(ip)
618  END DO
619  END DO
620  ! copy border part
621  IF (nbdr > 0) THEN
622  ioff=0
623  DO i=1,nbdr
624  ip=(i*(i+1))/2
625  is=0
626  DO j=i,n
627  ip=ip+is
628  is=j
629  vbdr(ioff+j)=v(ip)
630  END DO
631  ioff=ioff+n
632  END DO
633  END IF
634 
635  CALL dbcdec(vbnd,mp1,nmb,aux)
636  ! use? CALL DBFDEC(VBND,MP1,NMB) ! modified decomp., numerically more stable
637  ! CALL DBCPRB(VBND,MP1,NMB)
638  ip=1
639  DO i=1, nmb
640  IF (vbnd(ip) <= 0.0d0) THEN
641  npri=npri-1
642  IF (npri >= 0) THEN
643  IF (vbnd(ip) == 0.0d0) THEN
644  print *, ' SQMIBB matrix singular', n, nbdr, nbnd
645  ELSE
646  print *, ' SQMIBB matrix not positive definite', n, nbdr, nbnd
647  END IF
648  END IF
649  ! return zeros
650  DO ip=1,n
651  b(ip)=0.0d0
652  END DO
653  DO ip=1,(n*n+n)/2
654  v(ip)=0.0d0
655  END DO
656  return
657  END IF
658  ip=ip+mp1
659  END DO
660  nrank=nmb
661 
662  IF (nbdr == 0) THEN ! special case NBDR=0
663 
664  CALL dbcslv(vbnd,mp1,nmb,b,b)
665  IF (inv > 0) THEN
666  IF (inv > 1) THEN
667  CALL dbcinv(vbnd,mp1,nmb,v)
668  ELSE
669  CALL dbcinb(vbnd,mp1,nmb,v)
670  END IF
671  END IF
672 
673  ELSE ! general case NBDR>0
674 
675  ioff=nb1
676  DO ib=1,nbdr
677  ! solve for aux. vectors
678  CALL dbcslv(vbnd,mp1,nmb,vbdr(ioff),aux(ioff))
679  ! zT ru
680  vzru(ib)=b(ib)
681  DO i=0,nmb-1
682  vzru(ib)=vzru(ib)-b(nb1+i)*aux(ioff+i)
683  END DO
684  ioff=ioff+n
685  END DO
686  ! solve for band part only
687  CALL dbcslv(vbnd,mp1,nmb,b(nb1),b(nb1))
688  ! Ck - cT z
689  ip=0
690  ioff=nb1
691  DO ib=1,nbdr
692  joff=nb1
693  DO jb=1,ib
694  ip=ip+1
695  vbk(ip)=v(ip)
696  DO i=0,nmb-1
697  vbk(ip)=vbk(ip)-vbdr(ioff+i)*aux(joff+i)
698  END DO
699  joff=joff+n
700  END DO
701  ioff=ioff+n
702  END DO
703  ! solve border part
704  CALL sqminv(vbk,vzru,nbdr,nrankb,scdiag,scflag)
705  IF (nrankb == nbdr) THEN
706  nrank=nrank+nbdr
707  ELSE
708  npri=npri-1
709  IF (npri >= 0) print *, ' SQMIBB undef border ', n, nbdr, nbnd, nrankb
710  DO ib=1,nbdr
711  vzru(ib)=0.0d0
712  END DO
713  DO ip=(nbdr*nbdr+nbdr)/2,1,-1
714  vbk(ip)=0.0d0
715  END DO
716  END IF
717  ! smoothed data points
718  ioff=nb1
719  DO ib=1, nbdr
720  b(ib) = vzru(ib)
721  DO i=0,nmb-1
722  b(nb1+i)=b(nb1+i)-b(ib)*aux(ioff+i)
723  END DO
724  ioff=ioff+n
725  END DO
726  ! inverse requested ?
727  IF (inv > 0) THEN
728  IF (inv > 1) THEN
729  CALL dbcinv(vbnd,mp1,nmb,v)
730  ELSE
731  CALL dbcinb(vbnd,mp1,nmb,v)
732  END IF
733  ! expand/correct from NMB to N
734  ip1=(nmb*nmb+nmb)/2
735  ip2=(n*n+n)/2
736  DO i=nmb-1,0,-1
737  j0=0
738  IF (inv == 1) j0=max(0,i-nbnd)
739  DO j=i,j0,-1
740  v(ip2)=v(ip1)
741  ioff=nb1
742  DO ib=1,nbdr
743  joff=nb1
744  DO jb=1,nbdr
745  ij=max(ib,jb)
746  ij=(ij*ij-ij)/2+min(ib,jb)
747  v(ip2)=v(ip2)+vbk(ij)*aux(ioff+i)*aux(joff+j)
748  joff=joff+n
749  END DO
750  ioff=ioff+n
751  END DO
752  ip1=ip1-1
753  ip2=ip2-1
754  END DO
755  ip1=ip1-j0
756  ip2=ip2-j0
757 
758  DO ib=nbdr,1,-1
759  v(ip2)=0.0d0
760  joff=nb1
761  DO jb=1,nbdr
762  ij=max(ib,jb)
763  ij=(ij*ij-ij)/2+min(ib,jb)
764  v(ip2)=v(ip2)-vbk(ij)*aux(i+joff)
765  joff=joff+n
766  END DO
767  ip2=ip2-1
768  END DO
769  END DO
770 
771  DO ip=(nbdr*nbdr+nbdr)/2,1,-1
772  v(ip2)=vbk(ip)
773  ip2=ip2-1
774  END DO
775 
776  END IF
777  END IF
778 
779 END SUBROUTINE sqmibb
780 
787 
788 SUBROUTINE dbprv(lun,v,n)
789  IMPLICIT NONE
790  INTEGER :: i
791  INTEGER :: ip
792  INTEGER :: ipe
793  INTEGER :: ipn
794  INTEGER :: ips
795  INTEGER :: k
796 
797  INTEGER, INTENT(IN OUT) :: lun
798  DOUBLE PRECISION, INTENT(IN OUT) :: v(*)
799  INTEGER, INTENT(IN) :: n
800 
801  INTEGER, PARAMETER :: istp=6
802 
803  WRITE(lun,101)
804 
805  DO i=1,n
806  ips=(i*i-i)/2
807  ipe=ips+i
808  ip =ips
809 100 continue
810  ipn=ip+istp
811  WRITE(lun,102), i, ip+1-ips, (v(k),k=ip+1,min(ipn,ipe))
812  IF (ipn < ipe) THEN
813  ip=ipn
814  go to 100
815  END IF
816 END DO
817 return
818 101 format(1x,'--- DBPRV -----------------------------------')
819 102 format(1x,2i3,6g12.4)
820 
821 END SUBROUTINE dbprv