V3FIT
svdfit.f
1  SUBROUTINE svdfit(nfitin,nlo,cutin,a0,x,y,m,b)
2  USE precision
3  IMPLICIT NONE
4  REAL(rprec) b(*), cutin
5  REAL(rprec) ,DIMENSION(*)::a0
6  REAL(rprec) , POINTER :: yvals
7  REAL(rprec) , DIMENSION(m) :: x,y,w
8  REAL(rprec) , DIMENSION(:,:), ALLOCATABLE ::
9  . amatrix, vv ,uu, wwd
10  REAL(rprec) , DIMENSION(:,:), ALLOCATABLE :: asave
11  REAL(rprec) , DIMENSION(:) , ALLOCATABLE :: ww
12  REAL(rprec) , DIMENSION(:) , ALLOCATABLE :: ys,xs
13  REAL(rprec) , DIMENSION(:), ALLOCATABLE, SAVE :: apar,apar2
14  INTEGER , DIMENSION(:) , ALLOCATABLE :: pwr
15  INTEGER :: m, n=8, mp=9, ipos=0 ! m rows > n columns
16  INTEGER :: nmax, nmin, i, j, nlo, nfitin
17  LOGICAL :: first=.true.
18  REAL(rprec) :: cutoff=3e-8
19 
20 ! mp = 9 is number of PARAMETER vectors SAVEd
21 ! n=8 is the polynomial order !10 or 9 result in core dump
22  IF(first)then
23  first=.false.
24  nmax=nfitin
25  nmin=0
26  ENDIF !first
27  IF(nfitin.eq.0)nfitin=nmax-2
28  IF(cutin.eq.0.)cutin=cutoff
29  n=nfitin;cutoff=cutin
30  IF(.not.ALLOCATED(amatrix)) ALLOCATE(amatrix(m,n-nlo))
31  IF(.not.ALLOCATED(uu)) ALLOCATE(uu(m,n-nlo))
32  IF(.not.ALLOCATED(pwr)) ALLOCATE(pwr(n-nlo))
33  IF(.not.ALLOCATED(apar)) ALLOCATE(apar(n))
34  IF(.not.ALLOCATED(apar2)) ALLOCATE(apar2(n-nlo))
35  IF(.not.ALLOCATED(wwd)) ALLOCATE(wwd(n-nlo,n-nlo))
36  IF(.not.ALLOCATED(ww)) ALLOCATE(ww(n-nlo))
37  IF(.not.ALLOCATED(vv)) ALLOCATE(vv(n-nlo,n-nlo))
38  DO i=1,n-nlo
39  pwr(i)=i-1+nlo
40  ENDdo
41  IF(nlo.ge.1)y(1:SIZE(y))=y(1:SIZE(y))-a0(1)
42 ! make amatrix
43  DO i=1,m
44  DO j=1,n-nlo
45  IF(x(i).eq.0.) THEN
46  amatrix(i,j)=0.
47  ELSE
48  amatrix(i,j)=x(i)**pwr(j)
49  ENDIF
50  ENDdo
51  ENDdo
52  uu=amatrix
53  CALL svdcmp(uu,m,n-nlo,m,n-nlo,ww,vv) ! m rows > n columns
54  DO i=1,n-nlo
55  DO j=1,n-nlo
56  wwd(i,j)=0 ! reset after matmul
57  ENDdo
58  ENDdo
59  DO i=1,n-nlo
60  wwd(i,i)=1/ww(i)
61  ENDdo
62  DO i= 1,SIZE(ww)
63  IF(ww(i)/maxval(ww) .lt. cutoff) wwd(i,i)=0
64  ENDdo
65  apar=0.
66  apar2=matmul(vv,matmul(wwd,matmul(transpose(uu),y)))
67  apar(nlo+1:n)=apar2(1:n-nlo)
68  IF(nlo.ne.0)apar(1:nlo)=a0(1:nlo)
69  IF(nlo.ge.1)y(1:SIZE(y))=y(1:SIZE(y))+a0(1)
70  b(1:n)=apar(1:n)
71  DEALLOCATE(amatrix)
72  DEALLOCATE(uu)
73  DEALLOCATE(pwr)
74  DEALLOCATE(apar)
75  DEALLOCATE(apar2)
76  DEALLOCATE(wwd)
77  DEALLOCATE(ww)
78  DEALLOCATE(vv)
79  RETURN
80  END SUBROUTINE svdfit