[go: up one dir, main page]

File: splfun.f

package info (click to toggle)
ifeffit 2%3A1.2.11d-9.1
  • links: PTS
  • area: contrib
  • in suites: jessie, jessie-kfreebsd
  • size: 12,444 kB
  • ctags: 6,492
  • sloc: fortran: 35,441; ansic: 8,454; makefile: 4,815; python: 3,274; perl: 3,146; sh: 2,721; ada: 1,003; tcl: 95
file content (160 lines) | stat: -rw-r--r-- 6,439 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
       subroutine splfun(mf,nx,xv,ffit,iend)
c
c//////////////////////////////////////////////////////////////////////
c Copyright (c) 1997--2000 Matthew Newville, The University of Chicago
c Copyright (c) 1992--1996 Matthew Newville, University of Washington
c
c Permission to use and redistribute the source code or binary forms of
c this software and its documentation, with or without modification is
c hereby granted provided that the above notice of copyright, these
c terms of use, and the disclaimer of warranty below appear in the
c source code and documentation, and that none of the names of The
c University of Chicago, The University of Washington, or the authors
c appear in advertising or endorsement of works derived from this
c software without specific prior written permission from all parties.
c
c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
c EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
c MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
c IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
c CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
c TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
c SOFTWARE OR THE USE OR OTHER DEALINGS IN THIS SOFTWARE.
c//////////////////////////////////////////////////////////////////////
c
c purpose:  evaluate spline function for lmdif1 minimization a la autobk
c
c arguments:
c      mf       number of points in ffit                [in]
c      nx       number of points in xv                  [in]
c      xv       vector of variables                     [in]
c      ffit     output vector to be minimized           [out]
c      iend     information tag                         [out]
c
c notes:
c   1. see subroutine lmdif1
c   1. see subroutine spline 
c   2. this evaluates the difference between the fft of theory and 
c      post-background-subtraction chi data for changing b-spline
c      coefficients, e0, and possibly multi-electron stuff.
c   3. based on/related to suroutine autnls from autobk
c
c see documentation and code comments for more details
c
c requires  include files:  consts.h, spline.h, fft.h
c           qintrp, lintrp, fitfft, bvalue, sumsqr
c
       implicit none
       include 'consts.h'
       include 'spline.h'
       include 'fft.h'
c
c local variables
       integer   nx, mf, iend, nvtmp, i, nrpts, ifit, j
       integer   nqmin, nqmax, nmaxx, ipos, nofx
       double precision   small, half, widmin
       parameter (half = 0.5d0, small = 1.d-10, widmin = 0.5d0)
       double precision xv(nx), ffit(mf), qtmp(maxpts), tmpfit(maxpts)
       double precision chiq(maxpts), qtt, e0t, bvalue
       double precision resid, tresid, sumsqr, t, fclamp
       external  bvalue, sumsqr,nofx
       save
c
       if (nx.ne.nautbk) iend = 1
       if (theory.and.(mf.ne.nr1st)) iend = 2
       if (.not.theory.and.(mf.ne.nrbkg))  iend = 3
       ifit   = 0
       nvtmp  = nx
       e0t    = e0
cc       print*, 'SPLFUN ', mf, nrbkg, nx, nsplin
cc       print*, xv
c
c  unwrap list of possible variables:
c     the last on the list from autnls is the first off
       if (theory.and.eevary) then
          thebkg = xv(nvtmp)
          de0    = xv(nvtmp)
          nvtmp  = nvtmp - 2
       end if
       if (nvtmp.ne.nsplin) iend = 3
c
c  e0 shift to temporary q-array for interpolation, evaluate the spline 
c  and calculate chi(E).
c         if normalizing by the functional form of the 
c        spline, make sure you're not dividing by zero.  
       e0t   = e0 + de0
cc       print*, ' splfun:  ', mf, e0, e0t, de0, nxmu
       do 200 i = 1, nxmu
          qtmp(i)   =  sqrt(etok * abs(endat(i)-e0t) )
          if (endat(i).lt.e0t)   qtmp(i) = - qtmp(i)
          if ( (endat(i).le.emax).and.(endat(i).ge.emin) ) then
             spldat(i)=bvalue(eknot,xv,nsplin,korder,endat(i),0)
             chie(i)   = ( xmudat(i) - spldat(i) ) / step
             if (funnrm)
     $            chie(i) = ( xmudat(i) /max(spldat(i), small)) - one
          else
             chie(i)   = zero
          end if
 200   continue
c  get qmax and qmin
       nqmin = int( sqrt( etok* abs(emin - e0t) ) / qgrid )
       nqmax = int( sqrt( etok* abs(emax - e0t) ) / qgrid )
       if ((emin.lt.e0t).or.(nqmin.lt.1))     nqmin = 1
c  interpolate chiq to q grid, evaluate data chi(k) [chiq]
       nmaxx  = min(maxpts, nqmax + 20)
       ipos   = 1
       call grid_interp(qtmp, chie, nxmu, zero, qgrid, nmaxx, chiq)
c
c get real and imaginary parts of the fft of chiq, put them in tmpfit
       call fitfft(chiq, maxpts, maxfft, wfftc, qgrid,
     $      splwin, splqw, spldat, one, 1, 0, zero, r1st,
     $      nrpts, tmpfit)
c
       if (theory.and.(.not.thefix))
     $      thebkg = sumsqr(tmpfit(nrbkg),nr1st) / thessq
       do 550 i = 1, nrbkg
          ffit(i) = tmpfit(i) - splfit(i) * thebkg
 550   continue
       ifit = nrbkg
       if (theory.and.eevary) then
          do 560 i = nrbkg+1, nr1st
             ffit(i) = (tmpfit(i) - splfit(i)*thebkg) / 10.0
 560      continue 
          ifit = nr1st
       endif
c
c clamp first 4 chie() data points towards zero
       tresid = sumsqr(ffit,ifit)
cc       print*, 'end of splfun ' ,  tresid
       if (clamp(1)) then
          j = max(1,nofx(emin,endat,nxmu))
c
c scale clamp strength to residual, so that clamp strength is
c roughly 'percent importance' in fit.
c note '1+int(tresid)' here. this is to assure the scale is
c not zero, but also should make the scale factor settle down
c to a single number so that it does not affect the fitting
c time too much.
          fclamp = sclamp(1)*(1+int(tresid*100.d0)/nrbkg)/nclamp
          do 620 i = 1, nclamp
             ffit(i+ifit) = chie(i+j-1) * fclamp
cc             print*, i, ffit(i+ifit)
 620      continue 
          ifit = ifit + nclamp
       endif
c clamp last 4 chie() data points towards zero
       if (clamp(2)) then
          j = min(nxmu,max(1,nofx(emax,endat,nxmu)))
          fclamp = sclamp(2)*(1+int(tresid*100.d0)/nrbkg)/nclamp
c          print*, ' splfun clamp 2 at j=',j, endat(j),
c     $         emax, sclamp(2), fclamp
          do 630 i = 1, nclamp
             ffit(i+ifit) = chie(j + 1 - i) * fclamp
 630      continue 
          ifit = ifit + nclamp
       endif
cc       t= sumsqr(ffit,ifit)
cc       print*, 'end of splfun ' ,  tresid, t, ifit, nrbkg
       return
c end subroutine splfun
       end