[go: up one dir, main page]

File: fitfft.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 (148 lines) | stat: -rw-r--r-- 5,829 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
       subroutine fitfft(chiq, mpts, mfft, wfftc, qgrid,
     $      qwin, qweigh, rwin, rweigh, ifft, mode, xlow, xhigh,
     $      nout, chifit)
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    calculate a fft of a function to be minimized in either r or
c    backtransformed k-space to use as a fitting function, as in 
c    ifeffit.  calls routine xafsft which uses the routine cfftf.
c
c    ** cffti must be called prior to this routine **
c
c inputs:
c   chiq    array containing chi(q), on grid with spacing qgrid, 
c           and first point at chi(q = 0.).
c   mpts    dimension of chiq, qwin, and rwin
c   mfft    number of points to use for fft 
c   wfftc   work array for fft initialized by cffti, which must
c           be called prior to this routine.
c   qgrid   grid size for chiq.
c   qwin    q-space fft window array 
c   qweigh  q-weight in  k->r fft.
c   rwin    r-space fft window array
c   rweigh  r-weight in  r->q fft.
c   ifft    integer flag for number of fft's to do:
c             0    chifit is in original k-space 
c             1    chifit is in r-space 
c             2    chifit is in back-transformed k-space 
c   mode    integer flag for output mode for complex data:
c             0    real/imag pair  (default)
c             1    real/mag  pair
c   xlow    low-x range for output chifit (either r or k)
c   xhigh   high-x range for output chifit (either r or k)
c   nout    number of points in output : useful length of chifit
c outputs:
c   chifit  real array representation of the complex result from 
c           0, 1, or 2 fft of the input chi(k).
c           output between xlow and xhigh in real-imag pairs
c           (if ifft=0, all imag parts are 0.) 
c
c mxmpts is the largest expected value for mpts
c
        implicit none
        integer   mpts, mfft, ifft, nout, mxmpts, nfft, i, ipos,jft,mode
        double precision  pi, zero, xlow, xhigh, xgrid
        parameter (mxmpts = 4096, zero=0.d0, pi = 3.141592653589793d0)
        double precision chiq(mpts), chifit(mpts),qwin(mpts),rwin(mpts)
        double precision qweigh, rweigh, qgrid, rgrid, q, pha
        double precision  wfftc(*)
        complex*16  cchiq(mxmpts), tmpft(mxmpts), coni
        parameter (coni=(0d0,1d0))

c  check that ifft is valid
       if ((ifft.lt.0).or.(ifft.ge.3)) then 
          call warn(3,'fitfft: ifft out of range.')
          return
       endif
cc       if (mxmpts.ne.mfft) then 
cc          call echo('fitfft warning: weird number of points')
cc          print*, mxmpts, mfft
cc       endif

c
c  nfft will be the actual length of the fft arrays. 
c  it is expected that nfft = mfft, but just in case...
       nfft   =  min(mxmpts, min(mfft, mpts) )
       rgrid  =  pi / (qgrid * nfft)
c
c  copy input data into complex data array.
       do 130 i = 1, nfft
          cchiq(i) = dcmplx(chiq(i), zero)
 130   continue
c
c  do ifft (= 0, 1, 2)  number of fourier transforms
c  ifft: 
c     0   just get k-weighted chi(k)
c     1   k->r
c     2   k->r then r->q

       jft = 1
       if (ifft.eq.0) jft = 0

       xgrid = qgrid
       if (ifft.eq.1) xgrid = rgrid

       call xafsft(nfft,cchiq,qwin,qgrid,qweigh,wfftc, jft, tmpft)

       if (ifft.eq.2) then
          call xafsft(nfft,tmpft,rwin,rgrid,rweigh,wfftc,-1, cchiq)
          call fftout(mxmpts,mode,cchiq,qgrid,xlow,xhigh,
     $         nout,mpts,chifit)
       else
          call fftout(mxmpts,mode,tmpft,xgrid,xlow,xhigh,
     $         nout,mpts,chifit)
       endif
cc       if (ifft.eq.0) nout = nout/2
       return
c  end subroutine fitfft
       end

       subroutine fftout(mpts, mode, xdat, dx, xlo, xhi,nout,npts,xout)
c convert complex data xdat to a real array, using only
c that part of the complex array between [xlow, xhi].
c mode=0 : return real/imag pair
c mode=1 : return real/mag pair

       integer  mpts, npts, nout, nmin, npairs, i, mode
       complex*16  xdat(mpts)
       double precision xout(npts), dx, dxi, xlo, xhi, small, tiny
       double precision dxxr, dxxi
       parameter (tiny = 1.d-9, small = 1.d-2)
c
       dxi    = 1 / max(tiny, dx)
       nmin   = max(0, int(xlo * dxi + small ))
       npairs = max(1, int(xhi * dxi + small )) - nmin + 1
       nout   = min(npts, 2 * npairs)
       do 50 i= 1, npairs
          dxxr = dble (xdat( nmin + i ))
          dxxi = dimag(xdat( nmin + i ))
          xout(2*i-1) = dxxr
          if (mode.eq.1) then
             dxxi = dxxr*dxxr + dxxi*dxxi
          endif
          xout(2*i  ) = dxxi
 50    continue
       return
c end subroutine fftout
       end