Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

genfit.f

Go to the documentation of this file.
00001 
00002 c
00003 c       Copyright (c) 1986,1987,1988,1989,1990,1991,1992,1993,
00004 c       by Steve McMillan, Drexel University, Philadelphia, PA.
00005 c
00006 c       All rights reserved.
00007 c
00008 c       Redistribution and use in source and binary forms are permitted
00009 c       provided that the above copyright notice and this paragraph are
00010 c       duplicated in all such forms and that any documentation,
00011 c       advertising materials, and other materials related to such
00012 c       distribution and use acknowledge that the software was developed
00013 c       by the author named above.
00014 c
00015 c       THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
00016 c       IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00017 c       WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00018 c
00019 
00020         subroutine genfit(input,istart,nin,x,y,z,n,nz,iprompt,*)
00021         save
00022 c
00023 c       Perform a general least-squares fit to y(x).
00024 c
00025         character*(*) input
00026 c
00027         parameter (MMAX = 21)
00028         dimension x(1),y(1),z(1),a(MMAX)
00029 c
00030         external poly,trig
00031 c
00032 c       Equal weights for all points if nz <= 0.
00033 c       Otherwise, specify the weights in the z array...
00034 c
00035         nw = nz
00036         if (nz.le.0) nw = 1
00037 c
00038 c       Determine the array ranges.  Note that the arrays MUST be sorted
00039 c       in x for this to work.
00040 c
00041         call sort3(n,x,y,z)
00042 c
00043 10      if (istart.gt.nin) then
00044             i1 = 1
00045             nn = n
00046             ma = 2
00047         else
00048             ma = 1
00049             x1 = -1.e20
00050             x2 = 1.e20
00051             call readrq(input(istart:nin),3,
00052      &                  xma,x1,x2,dum,*1001)
00053             ma = nint(xma)
00054             if (ma.le.0) ma = 1
00055 c
00056             ma = ma + 1
00057             if (ma.gt.MMAX) then
00058                 if (iprompt.eq.1) then
00059                     call devoff
00060                     write(6,*)' Must specify order <= ',MMAX-1
00061                     go to 1001
00062                 end if
00063             end if
00064 c
00065             i1=0
00066             do 150 i=1,n
00067                 if (x(i).gt.x1.and.i1.eq.0) i1=i
00068                 if (x(i).gt.x2) go to 160
00069 150         continue
00070             i = n+1
00071 160         i1 = max(1,i1)
00072             nn = i-i1
00073             if (nn.le.1) then
00074                 write(6,*)'No points in specified range.'
00075                 go to 1001
00076             end if
00077         end if
00078 c
00079 c       Note: Input ma is the order of the polynomial fit (<=20).
00080 c             Internal ma is one greater than this number.
00081 c
00082 c       Rescale the x and y data to lie in [-1,1], to reduce the effects of
00083 c       finite-precision arithmetic.  This appears to do a better job than 
00084 c       scaling to [0,1].
00085 c
00086         call minmax(x,n,xmin,xmax)
00087         xscale = 2./(xmax - xmin)
00088         xref = .5*(xmin+xmax)
00089 c
00090         call minmax(y,n,ymin,ymax)
00091         yscale = 2./(ymax - ymin)
00092         yref = .5*(ymin+ymax)
00093 c
00094         do 200 i=1,n
00095             x(i) = (x(i) - xref)*xscale
00096             y(i) = (y(i) - yref)*yscale
00097 200     continue
00098 c
00099         xscale = 1./xscale
00100         yscale = 1./yscale
00101 c
00102         x1 = x(i1)
00103         x2 = x(i1+nn-1)
00104 c
00105 c       Use an intermediate C routine to allocate workspace space.
00106 c       (Pointers are NOT standard FORTRAN yet!)
00107 c
00108         if (input(2:2).eq.'t') then
00109             call cfit(x(i1),y(i1),z(i1),nn,a,ma,trig,nw,chisq,iret)
00110         else
00111             call cfit(x(i1),y(i1),z(i1),nn,a,ma,poly,nw,chisq,iret)
00112         end if
00113 c
00114 c       Print out some basic data on the fit obtained.
00115 c
00116         if (iprompt.eq.1) then
00117             call devoff
00118             write(6,250)(a(i),i=1,ma)
00119 250         format(' Coefficients: ',1p,5e11.3,:/(15x,5e11.3))
00120             write(6,*)' Chisq = ',chisq
00121         end if
00122 c
00123         if (input(3:3).eq.'p') then
00124 c
00125 c           Plot the fit.
00126 c
00127             call uplotin(x1*xscale+xref,
00128      &                   afunc(x1,a,ma,input(2:2))*yscale+yref,3)
00129 c
00130             do 300 i=1,n
00131 300         if (x(i).gt.x1.and.x(i).le.x2)
00132      &          call uplotin(x(i)*xscale+xref,
00133      &                       afunc(x(i),a,ma,input(2:2))*yscale+yref,2)
00134         end if
00135 c
00136 c       Unscale x and y before returning.
00137 c
00138         do 350 i=1,n
00139             x(i) = xscale*x(i) + xref
00140             y(i) = yscale*y(i) + yref
00141 350     continue
00142 c
00143         return
00144 1001    return 1
00145 c
00146         end
00147 
00148 
00149         function afunc(x,a,ma,which)
00150         save
00151 c
00152         parameter (MMAX = 21)
00153         dimension a(ma),f(MMAX)
00154         character*1 which
00155 c
00156         if (which.eq.'t') then
00157             call trig(x,f,ma)
00158         else
00159             call poly(x,f,ma)
00160         end if
00161 c
00162         sum = 0.
00163         do 10 i=1,ma
00164 10      sum = sum + a(i)*f(i)
00165 c
00166         afunc = sum
00167 c
00168         return
00169         end

Generated at Sun Feb 24 09:57:01 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001