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 c------------------------------------------------------------------------
00021 c
00022 c Least-squares fitting routines.
00023 c
00024 c------------------------------------------------------------------------
00025
00026 subroutine lsfit1(x,y,n,w,nw,a,b)
00027 implicit real (a-h,o-z)
00028 save
00029 c
00030 dimension x(1),y(1),w(1)
00031 common/resid/resi
00032 c
00033 c Return least-squares best linear fit to y(x) (n points,
00034 c weighted by w) of the form y = a*x + b, where a is
00035 c specified and b is variable.
00036 c
00037 if(n.le.1)then
00038 b=0.
00039 resi=0.
00040 return
00041 end if
00042 c
00043 s1=0.
00044 s2=0.
00045 do i=1,n
00046 c
00047 if (nw.eq.1) then
00048 ww = w(1)
00049 else
00050 ww = w(i)
00051 end if
00052 c
00053 s1=s1+ww
00054 s2=s2+ww*(y(i)-a*x(i))
00055 end do
00056 b=s2/s1
00057 c
00058 resi=0.
00059 do i=1,n
00060 c
00061 if (nw.eq.1) then
00062 ww = w(1)
00063 else
00064 ww = w(i)
00065 end if
00066 c
00067 resi=resi+ww*(y(i)-a*x(i)-b)**2
00068 end do
00069 resi=sqrt(resi/s1)
00070 c
00071 dy=a*(x(1)-x(n))
00072 if(dy.ne.0.)then
00073 resi=resi/abs(dy)
00074 else
00075 resi=1.
00076 end if
00077 c
00078 end
00079
00080
00081 subroutine lsfit2(x,y,n,w,nw,a,b)
00082 implicit real (a-h,o-z)
00083 save
00084 c
00085 dimension x(1),y(1),w(1)
00086 common/resid/resi
00087 c
00088 c Return least-squares best linear fit to y(x) (n points,
00089 c weighted by w) of the form y = a*x + b, where a and b
00090 c are both variable.
00091 c
00092 if(n.le.1)then
00093 a=0.
00094 b=0.
00095 resi=0.
00096 return
00097 end if
00098 c
00099 c We will used NORMALIZED numbers for the fitting, to avoid
00100 c problems with single-precision roundoff...
00101 c
00102 xo = x(1)
00103 xfac = 1./(x(n) - xo)
00104 yo = y(1)
00105 yfac = 1./(y(n) - yo)
00106 c
00107 s1=0.
00108 sx=0.
00109 sy=0.
00110 sxx=0.
00111 sxy=0.
00112 do i=1,n
00113 c
00114 if (nw.eq.1) then
00115 ww = w(1)
00116 else
00117 ww = w(i)
00118 end if
00119 c
00120 xx = (x(i) - xo)*xfac
00121 yy = (y(i) - yo)*yfac
00122 c
00123 s1=s1+ww
00124 sx=sx+ww*xx
00125 sy=sy+ww*yy
00126 sxx=sxx+ww*xx**2
00127 sxy=sxy+ww*xx*yy
00128 end do
00129 d=sxx*s1-sx**2
00130 c
00131 a=0.
00132 b=0.
00133 if(d.ne.0.)then
00134 d=1./d
00135 a=d*(s1*sxy-sx*sy)
00136 b=d*(sxx*sy-sx*sxy)
00137 end if
00138 c
00139 c Now undo the normalization...
00140 c
00141 b = (b-a*xfac*xo)/yfac + yo
00142 a = a*xfac/yfac
00143 c
00144 resi=0.
00145 do i=1,n
00146 c
00147 if (nw.eq.1) then
00148 ww = w(1)
00149 else
00150 ww = w(i)
00151 end if
00152 c
00153 resi=resi+ww*(y(i)-a*x(i)-b)**2
00154 end do
00155 resi=sqrt(resi/s1)
00156 c
00157 dy=a*(x(1)-x(n))
00158 if(dy.ne.0.)then
00159 resi=resi/abs(dy)
00160 else
00161 resi=1.
00162 end if
00163 c
00164 end