[go: up one dir, main page]

File: fitfun.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 (212 lines) | stat: -rw-r--r-- 8,101 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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
       subroutine fitfun(mf, nx, xvar, fvec, 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:  feffit fitting function for lmdif1 minimization 
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      fvec     output vector to be minimized        [out]
c      iend     information tag                      [out]
       implicit none
       include 'consts.h'
       include 'arrays.h'
       include 'keywrd.h'
       include 'fft.h'
       include 'fefdat.h'
       include 'pthpar.h'
       include 'feffit.h'
c local variables
       integer    nx, mf, iend, i,  id, isp, nx1, iter
       integer    jfit, nqdata, nfit1, nkpar, npaths
       integer    iupath(mpaths), inxx, ixx, joff, jqw
       integer   ier, iff_eval_dp
       double precision xvar(nx), fvec(mf), xolow, xohigh, bvalue
       double precision getsca, xspl(mtknot), bx, qx, sum, tmpval
       double precision xsum, sumsqr
       character  arg*2 
       integer    isarg, ilen, istrln, j, nmx
       external   bvalue, getsca,  istrln, iff_eval_dp, sumsqr
       save
c
       nkpar = 0
       id    = 1
       if (nx.ne.nvarys) iend = 1
       if (mf.ne.mfit)   iend = 2
       nx1 = nx - nbkg(id)
cc       print*, 'FITFUN N_vars:',nx,mf,nfdats
       do 20 i = 1, nx
          scalar(i) = xvar(i)
 20    continue
       call synvar
cc       print*, 'VARS ', xvar(1), xvar(2), xvar(3), xvar(4)
       if (final) rfact_total = zero
c
c  sum function to minimize over data sets
c   jfit is the counter (through all the data sets)
c   for the total number of fitting points

       jfit = 0
       do 3000 id = 1, nfdats
          nqdata = min(maxpts, max(2, nqfit(id)) + 10)
          if (ifft(id).eq.1) then
             xolow  = rmin(id)
             xohigh = rmax(id)
          else
             xolow  = qmin(id)
             xohigh = qmax(id)
          endif
          do 200 i = 1, nfit(id)*nqwfs(id)
             thifit(i)   = zero
 200      continue
c  re-initialize array for theoretical chi(k)
c  by assigning this to the background function
          do 300 i = 1, nqdata
             thiq(i, id) = zero
             thiqr(i, id) = zero
 300      continue
c
c sum over paths for theory chi for this data set
          npaths = 0
          do 400 i = 1, mpaths
             iupath(i) = 0
             if (iulist(i,id).ne.0) then
                npaths = npaths + 1
                iupath(npaths) = iulist(i,id)
             end if
 400      continue 
          call sum_paths(id, iupath, npaths, nqdata,
     $         thiqr(1,id), thiq(1,id))
c
c if refining background, include that here
          if ( bkgfit(id))  then
             do 450 isp = 1, nbkg(id)
                write(tmpstr, '(a,i2.2,a,i2.2)') 'bkg',id,'_',isp
                xspl(isp) = getsca(tmpstr,0)
cc                print*, 'FITFUN i ' , isp, xspl(isp)
 450         continue
             do 470 i = 1, nqdata
                qx = qgrid*(i-1)
                thiq(i, id) = thiq(i, id) + 
     $               bvalue(qknot(1,id), xspl, nbkg(id),korder,qx,0)
 470         continue 
          end if
c
c subtract data from theory
          do 500 i = 1, nqdata
             thiq(i,id) = thiq(i,id)-chiq(i,id)
 500      continue 
c
c loop over k-weights for multiple k-weights
c    top down, so that the first k-weight listed is done last
c
          do 1000 jqw = nqwfs(id), 1, -1
             qweigh(id) = qwfs(jqw,id)

c   take fft of theory(+bkg) - data
c   note: imag part of theory chi(k) compares to real part of data!!!
c   see ff2chi as well
             call fitfft(thiq(1,id), maxpts, maxfft, wfftc, qgrid,
     $            qwindo(1,id), qwfs(jqw,id), rwindo(1,id), one,
     $            ifft(id),modeft(id),xolow,xohigh, nfit1, thifit)

             if (nfit1.ne.nfit(id)) then
                call warn(3,' fitfun fitfft failed internal test.')
                iend = -10
             end if
c
c  evaluate the contribution to fvec for this data set.  weight scales
c  chi-square properly to the number of independent points. this is
c  important for error analysis (if chi-square is to increase by one,
c  it  must be scaled correctly.), but only in the final pass, when
c  chi-square and r-factors will be calculated.
c             print*, 'fitfun ', jfit, jqw, id,
c     $            weight(jqw, id), nfit(id), thifit(1), thifit(2)
             do 700 i =  1, nfit(id)
                fvec(jfit+i) = (thifit(i))/weight(jqw,id)
 700         continue

             jfit = jfit + nfit(id)

c construct r-factor
             if (final) then 
                call fitfft(chiq(1,id), maxpts, maxfft, wfftc, qgrid,
     $               qwindo(1,id), qwfs(jqw,id), rwindo(1,id), one, 
     $               ifft(id),modeft(id),xolow,xohigh, nfit1, chifit)
                if (nfit1.ne.nfit(id)) then
                   call warn(3,' fitfun fitfft failed internal test.')
                   iend = -10
                end if

                sum        = zero
                rfactr(id) = zero
                do 800 i = 1, nfit(id)
                   sum        = sum        + chifit(i)*chifit(i)
                   rfactr(id) = rfactr(id) + thifit(i)*thifit(i)
 800            continue
                if (sum.le.tiny) sum = tiny
                rfactr(id)  =  rfactr(id) / (sum * nqwfs(id))
                rfact_total = rfact_total + rfactr(id) 
cc                print*, ' final ', sum, rfactr(id), id, rfact_total
             end if
c
c  restraints
             if (nrestraint(id).ge.1) then
cc                print*, ' RESTRAINT ', nrestraint(id), id, jfit
                do 900 i =  1, nrestraint(id)
                   if ( (restraint(i,id) .ne. undef).and.
     $                  (restraint(i,id) .ne. '')) then 
                      ier    = iff_eval_dp(restraint(i,id),tmpval)
                      if (ier.eq.0) then
                         jfit   = jfit + 1
                         fvec(jfit) = tmpval
cc                         print*, ' t: ', tmpval, jfit, ier
                      endif
                   endif
 900            continue
             endif
 1000     continue   ! end loop over k-weights
cc          print*, ' end of ndata loop  ', id, nfit(id), jfit
 3000  continue      ! end loop over data sets

       if (final) rfact_total = rfact_total / max(1,nfdats)

c
c execute user-defined macro
       iter  =  int(getsca('&fit_iteration',0))
       if (iter.gt.itera) then
          itera = iter
          xsum = sumsqr(fvec,jfit)
cc          print*, ' iteration ', iter, mf,mfit,jfit,nfdats, xsum
          if (ifit_mac.gt.0) then
             call iff_macro_do(ifit_mac, fit_m_arg, 0,.false.)
          end if

       end if
       return
c end subroutine fitfun
       end