SignalFree Median
SignalFree Median
*
Program SignalFree
c
c *** does the minimum and implements Tom Melvin's signal free method
c
parameter(mxy=5000,mxs=3000)
parameter(iu10=10,iu11=11,iu12=12)
real*4 x(mxy,mxs),y(mxy),f(mxy),sfind(mxy,mxs)
real*4 crn1(mxy,2),crn2(mxy,2),crn3(mxy,2)
real*4 ybar(mxy,3),rxm(mxy,7),runr(mxy,5)
real*8 tol
integer iopt,irob
integer idate(mxs,3),nss(mxy),ls(mxy)
character filnam*40,fil1*60,itrdb(3)*88,ident(mxs)*8,id*8
ccc character tit*85,xlab*20,ylab*20,annot1*35,annot2*35
character itrun,melvin,switch,reset,hpfilt,itol,cproc,cdat*10,frm*20
character cook,cset,cmed
c
c *** open data file to process
c
call blank(filnam)
write(*,'(/1x,''Tree-ring data file name (/ to exit)'',t50,''==> '',$)')
read(*,'(a)')filnam
if(filnam(1:1).eq.'/')stop
open(iu10,file=filnam,status='old')
c
c *** first read in the data
c
ncrns=0
do i=1,mxy
do j=1,mxs
x(i,j)=-9.99
sfind(i,j)=-9.99
enddo
enddo
call trread(x,y,nc,idate,ident,itrdb,iu10,mxy,mxs)
close(iu10)
ifmny=idate(nc+1,1)
ilmxy=idate(nc+1,2)
maxn=ilmxy-ifmny+1
write(*,'(/t30,'' NS IFY ILY NYR'')')
write(*,'(1x,''Total series read in:'',t30,4i6,'' Years total time span'')')
* nc,ifmny,ilmxy,maxn
c
c *** get unique character string for output files
c
ll=len(filnam)
jj=0
do j=1,ll
jj=ll-j+1
if(filnam(jj:jj).ne.' ')goto 1
enddo
1 ll=jj
do j=1,ll
jj=j
if(filnam(j:j).eq.'.')then
jj=j-1
goto 2
endif
enddo
2 ll=jj
c
c *** now find the minimum, lower hinge, median, upper hinge, and maximum segment
lengths
c
3 do j=1,nc
f(j)=idate(j,3)
enddo
call mfs(f,nc,xmedseg,hhseg,hlseg,fsdseg,rmnseg,rmxseg)
mnseg=int(rmnseg)
mlseg=int(hlseg)
medseg=int(xmedseg)
mhseg=int(hhseg)
mxseg=int(rmxseg)
nsegmin=0
nseghl=0
nsegmed=0
nseghh=0
nsegmax=0
do j=1,nc
nyrs=idate(j,3)
if(nyrs.eq.mnseg)nsegmin=nsegmin+1
if(nyrs.ge.mlseg)nseghl=nseghl+1
if(nyrs.ge.medseg)nsegmed=nsegmed+1
if(nyrs.ge.mhseg)nseghh=nseghh+1
if(nyrs.eq.mxseg)nsegmax=nsegmax+1
enddo
write(*,'(/1x,''ORIGINAL DATA SET'',t30,'' MIN 25% MED 75% MAX'')')
write(*,'(1x,''Segment length
statistics:'',t30,5i6)')mnseg,mlseg,medseg,mhseg,mxseg
write(*,'(1x,''Series .ge. segment
length:'',t30,5i6)')nsegmin,nseghl,nsegmed,nseghh,nsegmax
c
c *** process all the data or censor by segment length or starting year
c
4 cproc=' '
write(*,'(/1x,''Series processing options (/ to exit):''/
* 1x,''All series processed as read in'',t39,''<1>''/
* 1x,''Minimum segment length series'',t40,''2''/
* 1x,''Series on or before starting year'',t40,''3''/
* 1x,''Series over common period only'',t40,''4'',t50,''==> '',$)')
read(*,'(a)')cproc
if(cproc.eq.'/')stop
if(cproc.eq.' ')cproc='1'
c
c *** censor the data by chosen method and save it in Tucson raw ring width format
c
if(cproc.ne.'1')then
if(cproc.eq.'2')then
5 mnsl=0
write(*,'(/1x,''Enter the minimum segment length'',t50,''==> '',$)')
read(*,*,err=5)mnsl
call cenbyseg(mnsl,x,nc,idate,ident,mxy,mxs)
icen1=mnsl
icen2=0
elseif(cproc.eq.'3')then
6 mxsy=0
write(*,'(/1x,''Enter the maximum starting year'',t50,''==> '',$)')
read(*,*,err=6)mxsy
call cenbyify(mxsy,x,nc,idate,ident,mxy,mxs)
icen1=mxsy
icen2=0
elseif(cproc.eq.'4')then
7 ifc=0
ilc=0
write(*,'(/1x,''Enter the common start year'',t50,''==> '',$)')
read(*,*,err=7)ifc
write(*,'(1x,''Enter the common end year'',t50,''==> '',$)')
read(*,*,err=7)ilc
call cenbycom(ifc,ilc,x,nc,idate,ident,mxy,mxs)
icen1=ifc
icen2=ilc
else
goto 4
endif
call savcen(cproc,icen1,icen2,x,y,nc,idate,ident,itrdb,filnam,iu11,mxy,mxs)
endif
c
c *** now find the minimum, lower hinge, median, upper hinge, and maximum segment
lengths
c
if(cproc.ne.'1')then
do j=1,nc
f(j)=idate(j,3)
enddo
call mfs(f,nc,xmedseg,hhseg,hlseg,fsdseg,rmnseg,rmxseg)
mnseg=int(rmnseg)
mlseg=int(hlseg)
medseg=int(xmedseg)
mhseg=int(hhseg)
mxseg=int(rmxseg)
nsegmin=0
nseghl=0
nsegmed=0
nseghh=0
nsegmax=0
do j=1,nc
nyrs=idate(j,3)
if(nyrs.eq.mnseg)nsegmin=nsegmin+1
if(nyrs.ge.mlseg)nseghl=nseghl+1
if(nyrs.ge.medseg)nsegmed=nsegmed+1
if(nyrs.ge.mhseg)nseghh=nseghh+1
if(nyrs.eq.mxseg)nsegmax=nsegmax+1
enddo
write(*,'(/1x,''CENSORED DATA SET'',t30,'' MIN 25% MED 75%
MAX'')')
write(*,'(1x,''Segment length
statistics:'',t30,5i6)')mnseg,mlseg,medseg,mhseg,mxseg
write(*,'(1x,''Series .ge. segment
length:'',t30,5i6)')nsegmin,nseghl,nsegmed,nseghh,nsegmax
endif
c
c *** get curve fit option
c
10 call blank(cdat)
write(*,'(/1x,''Curve fit options:''/
* 1x,''Spline pct N filter (variable) .le. -10''/
* 1x,''Friedman variable span smoother'',t40,''-5''/
ccc * 1x,''Age-dependent spline smoothing'',t40,''-3''/
ccc * 1x,''Regional curve detrending (RCS)'',t40,''-2''/
* 1x,''Neg Expon/linear any slope'',t40,''<1>''/
* 1x,''Neg Expon/linear neg slope'',t41,''2''/
* 1x,''Linear regression any slope'',t41,''3''/
* 1x,''Linear regression neg slope'',t41,''4''/
* 1x,''Horizontal line through mean'',t41,''5''/
* 1x,''Median segment length spline'',t41,''9''/
* 1x,''Spline filter in years (fixed) .ge. 10''/
* 1x,''Opt 1 is default, hit <RET> if you want it'',t50,''==> '',$)')
read(*,'(a)')cdat
if(cdat(1:1).eq.'/')stop
if(cdat(1:1).eq.' ')cdat(1:1)='1'
call intfrm(cdat,frm)
read(cdat,frm,err=10)iopt
if(iopt.eq.9)iopt=medseg
if(iopt.eq.-5)then
write(*,'(/1x,''Enter tweeter alpha 0-9'',t50,''==> '',$)')
read(*,*,err=10)alpha
if(alpha.lt.0.or.alpha.gt.9)then
write(*,'(/1x,''Friedman alpha not in admissible 0-9 range'')')
goto 10
endif
endif
c
c *** calculate mean chronology robustly or stupidly not
c
11 call blank(cdat)
write(*,'(/1x,''How to calculate the mean chronology (/ to stop):''/
* 1x,''Non-robust arithmetic mean'',t39,'' 1 ''/
* 1x,''Robust Tukey biweight mean'',t39,''<2>''/
* 1x,''Robust is default, hit <RET> if you want it'',t50,''==> '',
$)')
read(*,'(a)')cdat
if(cdat(1:1).eq.'/')stop
if(cdat(1:1).eq.' ')cdat(1:1)='2'
if(cdat(1:1).eq.'1')then
irob=1
elseif(cdat(1:1).eq.'2')then
irob=2
else
write(*,'(/1x,''Mean index choice not admissible'')')
goto 11
endif
c
c *** get running RBAR window width for performing running RBAR variance
stabilization
c
12 call blank(cdat)
write(*,'(/1x,''Enter running RBAR window width for variance''/
* 1x,''stabilization. Must be .ge. 25 years and odd.''/
* 1x,''Default window width is 51 years, 0 to skip'',t50,''==> '',
$)')
read(*,'(a)')cdat
if(cdat(1:1).eq.'/')stop
if(cdat(1:1).eq.' ')cdat(1:2)='51'
call intfrm(cdat,frm)
read(cdat,frm,err=12)nsg
if(nsg.eq.0)then
write(*,'(/1x,''Running RBAR variance stabilization skipped'')')
elseif(nsg.gt.0.and.nsg.lt.25)then
write(*,'(/1x,''Running RBAR window width must be .ge. 25'')')
goto 12
elseif(mod(nsg,2).eq.0)then
nsg=nsg+1
write(*,'(/1x,''Running RBAR window width increased to make it odd:
'',i5)')nsg
endif
c
itrun='n'
c write(*,'(/1x,''Truncate curve fitting to same end year?''/
c * 1x,''Curve is extrapolated to end. So y/<n>'',t50,''==> '',$)')
c read(*,'(a)')itrun
c if(itrun.eq.' ')itrun='n'
c if(itrun.eq.'Y')itrun='y'
c if(itrun.eq.'N')itrun='n'
c if(itrun.eq.'y')then
c write(*,'(1x,''Enter the fixed end year of fitting period'',t50,''==> '',
$)')
c read(*,*)itrunyr
c endif
c
c irev1=' '
c write(*,'(/1x,''Review the curve fits? y/<n>'',t50,''==> '',$)')
c read(*,'(a)')irev1
c if(irev1.eq.' ')irev1='n'
c if(irev1.eq.'Y')irev1='y'
c if(irev1.eq.'N')irev1='n'
c irev2=irev1
c
13 melvin=' '
switch='n'
reset='y'
hpfilt='y'
tol=0.0001d0
write(*,'(/1x,''Reset MELVIN signal free convergence settings?''/
* 1x,''WARNING: This is a very dangerous thing to do!''/
* 1x,''Enter y/<n> (default is n for NO, / to exit)'',t50,''==> '',
$)')
read(*,'(a)')melvin
if(melvin.eq.'/')stop
if(melvin.eq.' ')melvin='n'
if(melvin.eq.'N')melvin='n'
if(melvin.eq.'Y')melvin='y'
if(melvin.ne.'y'.and.melvin.ne.'n')then
write(*,'(/1x,''Melvin not entered as y or n'')')
goto 13
endif
if(melvin.eq.'y')then
switch=' '
write(*,'(/1x,''Allow hierarchical curve switching? y/<n>'',t50,''==> '',
$)')
read(*,'(a)')switch
if(switch.eq.'/')stop
if(switch.eq.' ')switch='n'
if(switch.eq.'Y')switch='y'
if(switch.eq.'N')switch='n'
c
reset=' '
write(*,'(/1x,''Reset means of signal free series? <y>/n'',t50,''==> '',
$)')
read(*,'(a)')reset
if(reset.eq.'/')stop
if(reset.eq.' ')reset='y'
if(reset.eq.'Y')reset='y'
if(reset.eq.'N')reset='n'
c
hpfilt=' '
write(*,'(/1x,''H-P filter chronology differences? <y>/n'',t50,''==> '',
$)')
read(*,'(a)')hpfilt
if(hpfilt.eq.'/')stop
if(hpfilt.eq.' ')hpfilt='y'
if(hpfilt.eq.'Y')hpfilt='y'
if(hpfilt.eq.'N')hpfilt='n'
14 itol=' '
write(*,'(/1x,''Enter the signal free convergence test''/
* 1x,''based on minimizing the MEAN absolute''/
* 1x,''differences between the current and''/
* 1x,''preceeding chronologies: ''/
* 1x,'' Original Melvin setting 1 0.0005''/
* 1x,'' Current default setting <2> 0.0001''/
* 1x,'' **** Roll Your Own **** 3 X.XXXX'',t50,''==> '',$)')
read(*,'(a)')itol
if(itol.eq.'/')stop
if(itol.eq.'1')then
tol=0.0005d0
elseif(itol.eq.' '.or.itol.eq.'2')then
tol=0.0001d0
elseif(itol.eq.'3')then
write(*,'(/1x,''Okay, enter YOUR convergence test'',t50,''==> '',$)')
read(*,*,err=14)tol
else
goto 14
endif
endif
15 cook=' '
ccc switch='n'
ccc reset='y'
ccc hpfilt='y'
ccc tol=0.0001d0
write(*,'(/1x,''Play with COOK signal free convergence tweaks?''/
* 1x,''Try to converge faster and more reliabliably?''/
* 1x,''Enter y/<n> (default is n for NO, / to exit)'',t50,''==> '',
$)')
read(*,'(a)')cook
if(cook.eq.'/')stop
if(cook.eq.' ')cook='n'
if(cook.eq.'N')cook='n'
if(cook.eq.'Y')cook='y'
if(cook.ne.'y'.and.cook.ne.'n')then
write(*,'(/1x,''Cook not entered as y or n'')')
goto 15
endif
if(cook.eq.'n')then
cset='n'
cmed='n'
elseif(cook.eq.'y')then
write(*,'(/1x,''Set chronology mean to 1.0 each time? y/<n>'',t50,''==> '',
$)')
read(*,'(a)')cset
if(cset.eq.'/')stop
if(cset.eq.' ')cset='n'
if(cset.eq.'Y')cset='y'
if(cset.eq.'N')cset='n'
write(*,'(/1x,''Minimize the MEDIAN absolute differences''/
* 1x,''between the signal free chronologies? y/<n>'',t50,''==> '',
$)')
read(*,'(a)')cmed
if(cmed.eq.'/')stop
if(cmed.eq.' ')cmed='n'
if(cmed.eq.'Y')cmed='y'
if(cmed.eq.'N')cmed='n'
endif
parameter(mxlen=5000,mxser=3000,maxit=100,iu29=29,iu30=30,iu31=31,iu32=32,iu33=33)
real*4
x(mxy,mxs),y(mxy),f(mxy),sfind(mxy,mxs),crn1(mxy,2),crn2(mxy,2),crn3(mxy,2)
real*4
crnsav(mxlen),xbar(mxser),segmn(mxlen),segsd(mxlen),agemn(mxlen),agesd(mxlen)
real*4
test1(maxit),test2(maxit),test3(maxit),test4(maxit),wrk1(mxlen),wrk2(mxlen)
real*4 ybar(mxy,3),rxm(mxy,7),runr(mxy,5),savit(mxlen,maxit),ones(mxlen)
real*8 test,tol,testd,testdd
integer idate(mxs,3),nss(mxy),iopt1(mxser,maxit+2),ls(mxy)
character
ident(mxs)*8,tit*60,xlab*20,ylab*20,annot1*35,annot2*35,hpfilt,line*410,reset,switc
h
character star1,star2,star3,star4,itrdb(3)*88,id*8,istab,filnam*40,fil1*60
character cset,cmed
c
if(nsg.eq.0)then
istab='n'
else
istab='y'
endif
c
c *** get chronologiy length info
c
ifmny=idate(nc+1,1)
ilmxy=idate(nc+1,2)
maxn=ilmxy-ifmny+1
c
c *** calculate the average segment length over all years
c
do j=1,nc
ify=idate(j,1)
ily=idate(j,2)
n=ily-ify+1
ish=ify-ifmny
do i=1,n
ii=i+ish
sfind(ii,j)=float(n)
enddo
enddo
call robsum(sfind,maxn,nc,segmn,segsd,nss,1,mxy,mxs)
c
c *** calculate the average tree age over all years
c
do j=1,nc
ify=idate(j,1)
ily=idate(j,2)
n=ily-ify+1
ish=ify-ifmny
do i=1,n
ii=i+ish
sfind(ii,j)=float(i)
enddo
enddo
call robsum(sfind,maxn,nc,agemn,agesd,nss,1,mxy,mxs)
c
c *** plot out mean segment length and mean tree age
c
call blank(tit)
tit(1:37)='Mean Segment Length And Mean Tree Age'
call blank(xlab)
xlab(1:5)='Years'
call blank(ylab)
ylab(1:5)='Years'
call blank(annot1)
annot1(1:20)=' Mean Segment Length'
call blank(annot2)
annot2(1:20)='Mean Approx Tree Age'
do i=1,maxn
f(i)=0.0
enddo
call plot1(mxy,segmn,agemn,maxn,ifmny,xlab,ylab,tit,f,annot1,annot2)
c
c *** do the initial detrending based on iopt curve fitting option
c
c
c *** get unique character string for output files
c
ll=len(filnam)
jj=0
do j=1,ll
jj=ll-j+1
if(filnam(jj:jj).ne.' ')goto 1
enddo
1 ll=jj
do j=1,ll
jj=j
if(filnam(j:j).eq.'.')then
jj=j-1
goto 2
endif
enddo
2 ll=jj
call blank(fil1)
fil1(1:40)=filnam(1:40)
fil1(ll+1:ll+15)='_OrigCurves.txt'
open(iu31,file=fil1,status='unknown')
close(iu31,status='delete')
open(iu31,file=fil1,status='unknown')
fil1(ll+1:ll+16)='_OrigIndices.txt'
open(iu32,file=fil1,status='unknown')
close(iu32,status='delete')
open(iu32,file=fil1,status='unknown')
do j=1,nc
ify=idate(j,1)
ily=idate(j,2)
ily1=ily
n=ily-ify+1
n1=n
do i=1,n
y(i)=x(i,j)
enddo
call mnsd(y,n,xm,sd)
xbar(j)=xm
iopt1(j,1)=iopt
iopt1(j,2)=iopt
call curvefits(y,f,ify,n,n1,tit,iopt1(j,2),alpha,mxy,mxs)
do i=1,n
wrk2(i)=y(i)/f(i)
sfind(i,j)=y(i)/f(i)
enddo
call trrw(ident(j),ify,n,f,nss,ifl,iu31,iuo,'mw',tit,'stdcrv',mxy,itrdb)
call trrw(ident(j),ify,n,wrk2,nss,ifl,iu32,iuo,'mw',tit,'stdind',mxy,itrdb)
enddo
close(iu31)
close(iu32)
c
c *** align the data by calendar year now
c
do j=1,nc
ify=idate(j,1)
ily=idate(j,2)
n=ily-ify+1
ish=ify-ifmny
if(ish.gt.0)then
do i=1,n
ii=n-i+1
x(ii+ish,j)=x(ii,j)
sfind(ii+ish,j)=sfind(ii,j)
enddo
do i=1,ish
x(i,j)=-9.99
sfind(i,j)=-9.99
enddo
endif
enddo
c
c *** calculate the initial mean chronology
c
call robsum(sfind,maxn,nc,crn1(1,1),crn1(1,2),nss,irob,mxy,mxs)
call mnsd(crn1(1,1),maxn,xmstd1,sdstd1)
do i=1,maxn
ybar(i,1)=crn1(i,1) !runcor bit added 01/03/11
runr(i,1)=float(nss(i))
enddo
nss1=0
do i=1,maxn
if(nss(i).eq.1)then
nss1=nss1+1
else
goto 5
endif
enddo
5 write(*,'(/1x,''nss1 skip first number of years: '',i3)')nss1
if(nss1.gt.0)then
do j=1,nc
ify=idate(j,1)
ily=idate(j,2)
n=ily-ify+1
if(ify.eq.ifmny)then
ncset=j
nreset=n-nss1
write(*,'(/1x,i4,2x,a8,2x,5i6)')ncset,ident(j),ify,ily,n,nss1,nreset
do i=1,nreset
ii=i+nss1
y(i)=x(ii,j)
enddo
call mnsd(y,nreset,xm1,sd)
write(*,'(/1x,''full and truncated means: '',2f8.4)')xbar(j),xm1
xbar(j)=xm1
endif
enddo
else
nreset=maxn
endif
call mnsd(crn1(nss1+1,1),nreset,xm,sd)
do i=1,maxn
cccccccccccccccc - New
if(cset.eq.'y')crn1(i,1)=crn1(i,1)-xm+1.0
cccccccccccccccc - New
crn2(i,1)=crn1(i,1)
crnsav(i)=crn1(i,1)
enddo
c
c *** perform running rbar variance stabilization on original standard indices
c
if(istab.eq.'y')then
write(*,'(/1x,''Perform standard indices running rbar calculations'')')
nlp=nsg-1
call blank(fil1)
fil1(1:40)=filnam(1:40)
fil1(ll+1:ll+13)='_Std_RBAR.txt'
open(iu33,file=fil1,status='unknown')
call runbar(sfind,ybar,idate,nc,rxm,runr,ncnt,nsg,nlp,mxy,mxs,iu33)
close(iu33)
call blank(tit)
tit(1:45)='Standard Indices Running Average Correlations'
call blank(xlab)
xlab='Years'
call blank(ylab)
ylab='Correlations'
call blank(annot1)
annot1(1:14)='Running RBAR ('
if(nsg.lt.100)then
write(annot1(15:16),'(i2)')nsg
annot1(17:21)=' Yrs)'
else
write(annot1(15:17),'(i3)')nsg
annot1(18:22)=' Yrs)'
endif
call blank(annot2)
annot2(1:20)='Constant Sample RBAR'
ones(1)=-999.9
call
plot1(mxy,runr(1,2),runr(1,4),maxn,ifmny,xlab,ylab,tit,ones,annot1,annot2)
do i=1,maxn
crn3(i,1)=ybar(i,3)
enddo
call mnsd(crn1(1,1),maxn,xmstd1,sdstd1)
call mnsd(crn3(1,1),maxn,xmstd2,sdstd2)
do i=1,maxn
datum1=crn1(i,1)-xmstd1+1.0
crn1(i,1)=datum1
datum2=crn3(i,1)-xmstd2+1.0
crn3(i,1)=datum2
ones(i)=1.0
enddo
call blank(tit)
tit(1:53)='Original vs. Running RBAR Stabilized Standard Indices'
call blank(annot1)
annot1(1:23)='Original STD Chronology'
call blank(annot2)
annot2(1:21)='Stable STD Chronology'
call
plot1(mxy,crn1(1,1),crn3(1,1),maxn,ifmny,xlab,ylab,tit,ones,annot1,annot2)
endif
c
c *** do the signal free iterations
c
iter=0
small=9999.0
smooth1=9999.0
smooth2=9999.0
big=9999.0
write(*,'(/38x,''Mean ABS Median ABS FSpread ABS Maxx ABS'')')
10 continue
iter=iter+1
call blank(fil1)
fil1(1:40)=filnam(1:40)
fil1(ll+1:ll+18)='_SigFreeRawdat.txt'
open(iu30,file=fil1,status='unknown')
close(iu30,status='delete')
open(iu30,file=fil1,status='unknown')
call blank(fil1)
fil1(1:40)=filnam(1:40)
fil1(ll+1:ll+18)='_SigFreeCurves.txt'
open(iu31,file=fil1,status='unknown')
close(iu31,status='delete')
open(iu31,file=fil1,status='unknown')
call blank(fil1)
fil1(1:40)=filnam(1:40)
fil1(ll+1:ll+19)='_SigFreeIndices.txt'
open(iu32,file=fil1,status='unknown')
close(iu32,status='delete')
open(iu32,file=fil1,status='unknown')
do j=1,nc
ify=idate(j,1)
ily=idate(j,2)
ily1=idate(j,3)
n=ily-ify+1
n1=ily1-ify+1
iskp=ify-ifmny
do i=1,n
ii=i+iskp
if(nss(ii).gt.1)then
y(i)=x(ii,j)/crn2(ii,1)
else
y(i)=x(ii,j)
endif
enddo
if(reset.eq.'y')then
if(nss1.gt.0.and.j.eq.ncset)then
call mnsd(y(nss1+1),nreset,xm1,sd)
do i=1,nreset
y(nss1+i)=y(nss1+i)/xm1*xbar(j)
enddo
else
call mnsd(y,n,xm1,sd)
do i=1,n
y(i)=y(i)/xm1*xbar(j)
enddo
endif
endif
iopt1(j,iter+2)=iopt
call curvefits(y,f,ify,n,n1,id,iopt1(j,iter+2),alpha,mxy,mxs)
if(switch.eq.'n'.and.iter.ge.5)then
ccc if(switch.eq.'n'.and.iter.ge.1)then
if((iopt1(j,iter+2).ne.iopt1(j,iter+1)).or.(iopt1(j,iter+1).eq.5))then
if(iopt.eq.1.or.opt.eq.2)then
iopt1(j,iter+2)=-66
else
iopt1(j,iter+2)=5
endif
call curvefits(y,f,ify,n,n1,id,iopt1(j,iter+2),alpha,mxy,mxs)
endif
endif
ccc if(switch.eq.'n'.and.iter.ge.1)then
ccc if((iopt1(j,iter+2).ne.iopt1(j,iter+1)).or.(iopt1(j,iter+1).eq.5))then
ccc iopt1(j,iter+2)=5
ccc call curvefits(y,f,ify,n,n1,id,iopt1(j,iter+2),alpha,mxy,mxs)
ccc endif
ccc endif
do i=1,n
ii=i+iskp
wrk1(i)=y(i)
y(i)=x(ii,j)
sfind(ii,j)=y(i)/f(i)
wrk2(i)=y(i)/f(i)
enddo
call trrw(ident(j),ify,n,wrk1,nss,ifl,iu30,iuo,'mw',tit,'ssfraw',mxy,itrdb)
call trrw(ident(j),ify,n,f,nss,ifl,iu31,iuo,'mw',tit,'ssfcur',mxy,itrdb)
call trrw(ident(j),ify,n,wrk2,nss,ifl,iu32,iuo,'mw',tit,'ssfind',mxy,itrdb)
enddo
close(iu30)
close(iu31)
close(iu32)
c
c *** now calculate the signal free mean chronology
c
call robsum(sfind,maxn,nc,crn2(1,1),crn2(1,2),nss,irob,mxy,mxs)
call mnsd(crn2(1,1),maxn,xmstd1,sdstd1)
do i=1,maxn
ybar(i,1)=crn2(i,1) !runcor bit added 01/03/11
enddo
call mnsd(crn2(nss1+1,1),nreset,xm,sd)
cccccccccccccccc - New
if(cset.eq.'y')then
do i=1,maxn
crn2(i,1)=crn2(i,1)-xm+1.0
enddo
endif
cccccccccccccccc - New
do i=1,maxn
y(i)=crnsav(i)-crn2(i,1)
savit(i,iter)=y(i)
enddo
c
c *** high-pass filter the differences according to Tom's average segment length
spline smoothing
c
if(hpfilt.eq.'y')then
do i=1,maxn-2
ls(i)=segmn(i+1)
enddo
call spline2(maxn,y,f,ls)
do i=1,maxn
y(i)=y(i)-f(i)
enddo
endif
c
c *** compute the convergence statistics - use Tom's average absolute difference
criterion
c
do i=1,maxn
f(i)=abs(y(i))
enddo
test=0.0d0
testd=0.0d0
testdd=0.0d0
maxn1=0
do i=1,maxn
if(nss(i).gt.1)then
maxn1=maxn1+1
f(maxn1)=f(i)
test=test+dabs(y(i))
if(i.gt.1)then
testd=testd+dabs(y(i)-y(i-1))
endif
if(i.gt.2)then
testdd=testdd+dabs(y(i)-2.0*y(i-1)+y(i-2))
endif
endif
enddo
test=test/dfloat(maxn1)
if(test.lt.small)then
small=test
star1='*'
else
star1=' '
endif
call mfs(f,maxn1,xmed,hh,hl,fsd,rmn,rmx)
testd=xmed
ccc testd=testd/dfloat(maxn1-1)
if(testd.lt.smooth1)then
smooth1=testd
star2='*'
else
star2=' '
endif
testdd=fsd
ccc testdd=testdd/dfloat(maxn1-2)
if(testdd.lt.smooth2)then
smooth2=testdd
star3='*'
else
star3=' '
endif
ccc call qcksrt(maxn1,f)
ccc testb=f(maxn1)
testb=rmx
if(testb.lt.big)then
big=testb
star4='*'
else
star4=' '
endif
if(cmed.eq.'n')test1(iter)=test
if(cmed.eq.'y')test1(iter)=testd
test2(iter)=testd
test3(iter)=testdd
test4(iter)=testb
write(*,'(1x,''Iter '',i3,'' Convergence criteria: '',f13.8,a,3(f14.8,a))')
* iter,test,star1,testd,star2,testdd,star3,testb,star4
c
c *** test for convergence now using the user-supplied mean absolute difference
threshold
c *** but use the mean first-difference of the absolute differences as an
additional test
c
if(cmed.eq.'y')test=testd
if(test.le.tol)then
ccc if(testd.le.tol)then
goto 20
elseif(iter.eq.maxit)then
goto 20
cccccccccccccccc - New
elseif(iter.gt.6.and.(test1(iter).gt.test1(iter-1)))then
ccc elseif(iter.gt.6.and.(test2(iter).gt.test2(iter-1)))then
write(*,'(/1x,''WARNING: Convergence tests are not monotonic decreasing,
iter: '',i3)')iter
do i=1,maxn
crn2(i,1)=crnsav(i)
enddo
iter=iter-1
goto 20
cccccccccccccccc - New
elseif(test.gt.tol)then
ccc elseif(testd.gt.tol)then
do i=1,maxn
crnsav(i)=crn2(i,1)
enddo
goto 10
endif
c
c *** plot out the original and signal free chronologies
c
20 write(*,'(/1x,''Final iteration for signal free: '',i2)')iter
call blank(tit)
if(irob.eq.1)then
tit(1:41)='Original & Signal Free Chronology, Iter ='
write(tit(42:44),'(i3)')iter
elseif(irob.eq.2)then
tit(1:48)='Robust Original & Signal Free Chronology, Iter ='
write(tit(49:51),'(i3)')iter
endif
call blank(ylab)
ylab(1:7)='Indices'
call blank(annot1)
annot1(1:23)='Original STD Chronology'
call blank(annot2)
annot2(1:21)='Signal Free STD Chron'
call mnsd(crn2(1,1),maxn,xmstd1,sdstd1)
do i=1,maxn
crn2(i,1)=crn2(i,1)-xmstd1+1.0
f(i)=1.0
enddo
call plot1(mxy,crn1(1,1),crn2(1,1),maxn,ifmny,xlab,ylab,tit,f,annot1,annot2)
c
c *** perform running rbar variance stabilization on signal free indices
c
if(istab.eq.'y')then
write(*,'(/1x,''Perform signal free indices running rbar calculations'')')
call blank(fil1)
fil1(1:40)=filnam(1:40)
fil1(ll+1:ll+13)='_Ssf_RBAR.txt'
open(iu33,file=fil1,status='unknown')
call runbar(sfind,ybar,idate,nc,rxm,runr,ncnt,nsg,nlp,mxy,mxs,iu33)
close(iu33)
call blank(tit)
tit(1:40)='Signal Free Indices Running Correlations'
call blank(xlab)
xlab='Years'
call blank(ylab)
ylab='Correlations'
call blank(annot1)
annot1(1:14)='Running RBAR ('
if(nsg.lt.100)then
write(annot1(15:16),'(i2)')nsg
annot1(17:21)=' Yrs)'
else
write(annot1(15:17),'(i3)')nsg
annot1(18:22)=' Yrs)'
endif
call blank(annot2)
annot2(1:20)='Constant Sample RBAR'
ones(1)=-999.9
call
plot1(mxy,runr(1,2),runr(1,4),maxn,ifmny,xlab,ylab,tit,ones,annot1,annot2)
do i=1,maxn
crn3(i,2)=ybar(i,3)
enddo
call mnsd(crn2(1,1),maxn,xmstd1,sdstd1)
call mnsd(crn3(1,2),maxn,xmstd2,sdstd2)
do i=1,maxn
crn2(i,1)=crn2(i,1)-xmstd1+1.0
crn3(i,2)=crn3(i,2)-xmstd2+1.0
ones(i)=1.0
enddo
call blank(tit)
tit(1:56)='Original vs. Running RBAR Stabilized Signal Free Indices'
call blank(annot1)
annot1(1:20)='Orig Signal Free STD'
call blank(annot2)
annot2(1:22)='Stable Signal Free STD'
call
plot1(mxy,crn2(1,1),crn3(1,2),maxn,ifmny,xlab,ylab,tit,ones,annot1,annot2)
endif
c
c *** plot out the mean abs and mean dabs convergence statistics
c
call blank(tit)
tit(1:40)='Iteration Convergence Statistics, Iter ='
write(tit(41:43),'(i3)')iter
call blank(xlab)
xlab(1:10)='Iterations'
call blank(ylab)
ylab(1:17)='Differences'
call blank(annot1)
annot1(1:19)=' Mean ABS Diff Test'
call blank(annot2)
annot2(1:20)='Median ABS Diff Test'
do i=1,maxn
f(i)=0.0
enddo
call plot1(maxit,test1,test2,iter,1,xlab,ylab,tit,f,annot1,annot2)
c
c *** plot out the successive signal free iteration differences
c
call blank(tit)
tit(1:51)='Signal Free Chronology Iteration Differences'
call blank(xlab)
xlab(1:5)='Years'
call blank(ylab)
ylab(1:17)='Differences'
call blank(annot1)
annot1(1:20)=' First Iteration'
call blank(annot2)
annot2(1:19)=' Final Iteration'
do j=2,iter
jj=iter-j+1
rj=j-1
do i=1,maxn
ccc savit(i,jj)=savit(i,jj)-(rj*0.10)
savit(i,jj)=savit(i,jj)-(rj*0.10)
enddo
enddo
call spaghetti(savit,maxn,iter,ifmny,xlab,ylab,tit,annot1,annot2,mxlen,maxit)
c
c *** print out the curve fit options as a function of signal free iteration
c
write(*,'(/1x,''SIGNAL FREE DETRENDING OPTIONS BY ITERATION:'')')
write(*,'(3x,''NC IDENT'',4x,'' 0 0'',100i5)')(j,j=1,iter)
call blank(line)
do i=1,iter+2
ii=(i-1)*5+1
iii=ii+4
line(ii:iii)=' ---'
enddo
write(*,'(3x,''-- -----'',4x,a)')line
do j=1,nc
write(*,'(i5,2x,a,102i5)')j,ident(j),(iopt1(j,k),k=1,iter+2)
enddo
ccc close(iu29)
return
end
*sbr curvefits
*
subroutine curvefits(y,f,iyr,n,n1,id,iopt,alpha,mxy,mxs)
parameter(mxlen=10000,epsi=0.000001)
real*4 y(mxy),f(mxy),eq(7)
real*4 wrk(mxlen),w(mxlen),sc(mxlen,7),tmp(mxlen)
character id*8
c
c *** negative exponential curve
c
iopt1=iopt
if(iopt.eq.1.or.iopt.eq.2)then
do j=1,7
eq(j)=0.0
enddo
call curve(n,n1,y,f,eq)
if(eq(2).le.epsi.or.eq(5).lt.epsi)then
ccc if(eq(2).le.0.or.eq(5).lt.0)then
if(iopt.eq.1)iopt=3
if(iopt.eq.2)iopt=4
do j=1,7
eq(j)=0.0
enddo
call trend(n,n1,y,f,eq(3),eq(5))
endif
if(eq(3).gt.epsi.and.iopt1.eq.2)then
ccc if(eq(3).gt.0.and.iopt1.eq.2)then
iopt=5
call xmean(y,f,n,n1)
endif
c
c *** linear regression curve
c
elseif(iopt.eq.3.or.iopt.eq.4)then
do j=1,7
eq(j)=0.0
enddo
call trend(n,n1,y,f,eq(3),eq(5))
if(iopt.eq.4.and.eq(3).gt.0)then
iopt=5
call xmean(y,f,n,n1)
endif
c
c *** horizontal line through the mean
c
elseif(iopt.eq.5)then
call xmean(y,f,n,n1)
c
c *** Friedman variable span smoother
c
elseif(iopt.eq.-5)then
do i=1,n
wrk(i)=float(i)
w(i)=1.0
enddo
span=0.0
if(n1.lt.40)span=0.3
iper=1
call supsmu(n1,wrk,y,w,iper,span,alpha,f,sc)
if(n.gt.n1)then
do i=1,n1
tmp(i)=y(i)
enddo
iext=n-n1
do i=1,iext
ii=i+n1
ccc f(ii)=f(n1)
tmp(ii)=f(n1)
enddo
call supsmu(n,wrk,tmp,w,iper,span,alpha,f,sc)
endif
c
c *** cubic smoothing spline smoothing
c
elseif(abs(iopt).ge.8)then
if(iopt.eq.8)then
ls=iopt
call spline1(n1,y,f,ls)
c if(n.eq.n1)then
c minspl=n
c do i=2,n
c ii=n-i+1
c iii=n-i
c dif=f(ii)-f(iii)
c if(dif.le.0)then
c minspl=n-ii
c goto 10
c endif
c enddo
c 10 if(minspl.lt.n)then
c do i=minspl,n
c f(i)=f(minspl-1)
c enddo
c endif
c endif
elseif(iopt.ge.10)then
ls=iopt
call spline1(n1,y,f,ls)
elseif(iopt.le.-10)then
rn1=n1
ropt=float(abs(iopt))/100.
ls=ropt*rn1
call spline1(n1,y,f,ls)
endif
if(n.gt.n1)then
do i=1,n1
tmp(i)=y(i)
enddo
iext=n-n1
do i=1,iext
ii=i+n1
ccc f(ii)=f(n1)
tmp(ii)=f(n1)
enddo
call spline1(n,tmp,f,ls)
endif
endif
do i=1,n
if(f(i).lt.0.02)then
f(i)=0.02
endif
enddo
ier=0
do i=1,n
if(f(i).lt.0.02)then
ier=1
goto 90
endif
enddo
90 if(ier.eq.1)then
iopt=5
call xmean(y,f,n,n1)
return
endif
do i=1,n
if(f(i).lt.0.02)then
f(i)=0.02
endif
enddo
c ier=0
c do i=1,n
c if(f(i).le.0.02)then
c ier=ier+1
c goto 90
c endif
c enddo
c 90 if(ier.gt.0)then
c if(ier.eq.1)iopt=-66
c if(ier.eq.2)iopt=-50
c if(ier.eq.3)iopt=-33
c if(ier.eq.4)iopt=5
c rn1=n1
c ropt=float(abs(iopt))/100.
c ls=ropt*rn1
c if(iopt.lt.4)then
c call spline1(n1,y,f,ls)
c else
c call xmean(y,f,n,n1)
c endif
c
c do i=1,n
c if(f(i).le.0.02)then
c ier=ier+1
c goto 90
c endif
c enddo
nm2=n-2
if(ls.eq.9)then
ls1=20
else
ls1=ls
endif
ccc rn23=dfloat(n)*2.d0/3.d0
rn23=dfloat(n)
do i=1,nm2
if(ls.eq.9)then
v=dfloat(ls1)+i-1
if(v.gt.rn23)v=rn23
else
v=dfloat(ls1)
endif
arg=(2.d0*pi)/v
p(i)=(6.d0*(dcos(arg)-1.d0)**2.d0)/(dcos(arg)+2.d0)
enddo
do 1 i=1,nm2
do 1 j=1,3
a(i,j)=c1(j)+p(i)*c2(j)
1 a(i,4)=dble(y(i))+c1(4)*dble(y(i+1))+dble(y(i+2))
a(1,1)=c2(1)
a(1,2)=c2(1)
a(2,1)=c2(1)
nc=2
* begin ludapb
rn=dble(1.d0/(dfloat(nm2)*16.d0))
d1=1.d0
d2=0.d0
ncp1=nc+1
if(nc .ne. 0)then
* initialize zero elements
do 5 i=1,nc
do 5 j=i,nc
k=ncp1-j
5 a(i,k)=0.d0
* 'i' is row index of element being computed
* 'j' is column index of element being computed
* 'l' is row index of previously computed vector
* being used to compute inner product
* 'm' is column index
endif
do 60 i=1,nm2
imncp1=i-ncp1
i1=max0(1,1-imncp1)
do 60 j=i1,ncp1
l=imncp1+j
i2=ncp1-j
sum=a(i,j)
jm1=j-1
if(jm1 .gt. 0)then
do 25 k=1,jm1
m=i2+k
25 sum=sum-a(i,k)*a(l,m)
endif
if(j .eq. ncp1)then
if(a(i,j)+sum*rn .le. a(i,j))then
f(1)=-9999.
write(*,'(''>> sbr spline: matrix not positive definite'')')
return
endif
a(i,j)=1.d0/dsqrt(sum)
* update determinant
d1=d1*sum
35 if(dabs(d1) .gt. 1.d0)then
d1=d1*.0625d0
d2=d2+4.d0
goto 35
endif
47 if(dabs(d1) .le. .0625d0)then
d1=d1*16.d0
d2=d2-4.d0
goto 47
else
goto 60
endif
endif
a(i,j)=sum*a(l,ncp1)
60 continue
* end ludapb / begin luelpb
* solution ly = b
nc1=nc+1
iw=0
l=0
do 15 i=1,nm2
sum=a(i,4)
if(nc .gt. 0)then
if(iw .ne. 0)then
l=l+1
if(l .gt. nc) l=nc
k=nc1-l
kl=i-l
do 45 j=k,nc
sum=sum-a(kl,4)*a(i,j)
45 kl=kl+1
else
if(sum .ne. 0.d0)iw=1
endif
endif
15 a(i,4)=sum*a(i,nc1)
* solution ux = y
a(nm2,4)=a(nm2,4)*a(nm2,nc1)
n1=nm2+1
do 30 i=2,nm2
k=n1-i
sum=a(k,4)
if(nc .gt. 0)then
kl=k+1
k1=min0(nm2,k+nc)
l=1
do 50 j=kl,k1
sum=sum-a(j,4)*a(j,nc1-l)
50 l=l+1
endif
30 a(k,4)=sum*a(k,nc1)
* end luelpb
do 2 i=3,nm2
2 f(i)=a(i-2,4)+c1(4)*a(i-1,4)+a(i,4)
f(1)=a(1,4)
f(2)=c1(4)*a(1,4)+a(2,4)
f(n-1)=a(nm2-1,4)+c1(4)*a(nm2,4)
f(n)=a(nm2,4)
do 3 i=1,n
3 f(i)=y(i)-f(i)
return
end
*sbr spline2: fits cubic spline curve to time series
*
* derived from imsl library routines by edward r cook,
* lamont-doherty geological observatory, and modified by
* richard l holmes, tree-ring laboratory, university of arizona.
*
* modified by r l holmes 10 jun 1988
* modified by e r cook to full double precision 4 apr 1991
*
********************************************************************
*
* calculates a cubic spline function to filter a time series.
* 'stiffness' of spline is specified by parameter 'ls'
*
* parameters:
*
* n: number of values in time series
* y: time series array to be modeled
* f: array of cubic spline function values computed
* p: value computed in this routine, used to calculate spline
* ls: stiffness (50% frequency response) of spline
* a: working array of dimension (n,4)
*
********************************************************************
*
subroutine spline2(n,y,f,ls)
parameter(mxy=10000)
implicit real*8 (a-h,o-z)
integer ls(mxy)
dimension a(mxy,4),c1(4),c2(3),p(mxy)
real*4 y(n),f(n)
data c1 /1.d0,-4.d0,6.d0,-2.d0/
data c2 /0.d0,.33333333333333d0,1.33333333333333d0/
data pct,pi / .50d0, 3.1415926535897935d0 /
if(n .lt. 4)then
f(1)=-9998.
return
endif
if(n.gt.mxy)then
write(*,'(/t2,''*** series too long for spline subroutine ***''/
* t2,'' *** enlarge mxy parameter in subroutine ***''/)')
stop
endif
nm2=n-2
do i=1,nm2
v=dfloat(ls(i))
arg=(2.d0*pi)/v
p(i)=(6.d0*(dcos(arg)-1.d0)**2.d0)/(dcos(arg)+2.d0)
enddo
do 1 i=1,nm2
do 1 j=1,3
a(i,j)=c1(j)+p(i)*c2(j)
1 a(i,4)=dble(y(i))+c1(4)*dble(y(i+1))+dble(y(i+2))
a(1,1)=c2(1)
a(1,2)=c2(1)
a(2,1)=c2(1)
nc=2
* begin ludapb
rn=dble(1.d0/(dfloat(nm2)*16.d0))
d1=1.d0
d2=0.d0
ncp1=nc+1
if(nc .ne. 0)then
* initialize zero elements
do 5 i=1,nc
do 5 j=i,nc
k=ncp1-j
5 a(i,k)=0.d0
* 'i' is row index of element being computed
* 'j' is column index of element being computed
* 'l' is row index of previously computed vector
* being used to compute inner product
* 'm' is column index
endif
do 60 i=1,nm2
imncp1=i-ncp1
i1=max0(1,1-imncp1)
do 60 j=i1,ncp1
l=imncp1+j
i2=ncp1-j
sum=a(i,j)
jm1=j-1
if(jm1 .gt. 0)then
do 25 k=1,jm1
m=i2+k
25 sum=sum-a(i,k)*a(l,m)
endif
if(j .eq. ncp1)then
if(a(i,j)+sum*rn .le. a(i,j))then
f(1)=-9999.
write(*,'(''>> sbr spline: matrix not positive definite'')')
return
endif
a(i,j)=1.d0/dsqrt(sum)
* update determinant
d1=d1*sum
35 if(dabs(d1) .gt. 1.d0)then
d1=d1*.0625d0
d2=d2+4.d0
goto 35
endif
47 if(dabs(d1) .le. .0625d0)then
d1=d1*16.d0
d2=d2-4.d0
goto 47
else
goto 60
endif
endif
a(i,j)=sum*a(l,ncp1)
60 continue
* end ludapb / begin luelpb
* solution ly = b
nc1=nc+1
iw=0
l=0
do 15 i=1,nm2
sum=a(i,4)
if(nc .gt. 0)then
if(iw .ne. 0)then
l=l+1
if(l .gt. nc) l=nc
k=nc1-l
kl=i-l
do 45 j=k,nc
sum=sum-a(kl,4)*a(i,j)
45 kl=kl+1
else
if(sum .ne. 0.d0)iw=1
endif
endif
15 a(i,4)=sum*a(i,nc1)
* solution ux = y
a(nm2,4)=a(nm2,4)*a(nm2,nc1)
n1=nm2+1
do 30 i=2,nm2
k=n1-i
sum=a(k,4)
if(nc .gt. 0)then
kl=k+1
k1=min0(nm2,k+nc)
l=1
do 50 j=kl,k1
sum=sum-a(j,4)*a(j,nc1-l)
50 l=l+1
endif
30 a(k,4)=sum*a(k,nc1)
* end luelpb
do 2 i=3,nm2
2 f(i)=a(i-2,4)+c1(4)*a(i-1,4)+a(i,4)
f(1)=a(1,4)
f(2)=c1(4)*a(1,4)+a(2,4)
f(n-1)=a(nm2-1,4)+c1(4)*a(nm2,4)
f(n)=a(nm2,4)
do 3 i=1,n
3 f(i)=y(i)-f(i)
return
end
*sbr robsum
*
subroutine robsum(x,n,nc,crnmn,crnsd,nss,iopt,mxy,mxs)
parameter(maxnum=1000)
real*4 x(mxy,mxs),crnmn(mxy),crnsd(mxy),wrk(maxnum),datum
integer nss(mxy),iopt
if(nc.le.3)iopt=2
do i=1,n
n1=0
do j=1,nc
datum=0.0
datum=x(i,j)
if(datum.ne.-9.99)then
n1=n1+1
wrk(n1)=datum
endif
enddo
if(n1.eq.1)then
xm=wrk(1)
sd=0.0
elseif(n1.gt.1.and.n1.lt.6)then
if(iopt.eq.1)then
call mnsd(wrk,n1,xm,sd)
elseif(iopt.eq.2)then
call mdian1 (wrk,n1,xmed)
call xmad(wrk,n1,xmed,xmadm)
xm=xmed
sd=3.0*xmadm/2.0
endif
elseif(n1.ge.6)then
if(iopt.eq.1)then
call mnsd(wrk,n1,xm,sd)
elseif(iopt.eq.2)then
call xbiwt(wrk,n1,xlbiwt,xsbiwt,xlbiwt1,xsbiwt1)
xm=xlbiwt
sd=xsbiwt
endif
endif
crnmn(i)=xm
crnsd(i)=sd
nss(i)=n1
enddo
return
end
*sbr mnsd
*
subroutine mnsd(x,n,xm,sd)
real*4 x(n),xm,sd,sq,sm,rn
xm=0.0
sd=0.0
c
c *** compute the mean and standard deviation of the data
c
sq=0.0
sm=0.0
do 10 i=1,n
sm=sm+x(i)
10 continue
rn=n
xm=sm/rn
do 15 i=1,n
sq=sq+(x(i)-xm)**2
15 continue
sd=sqrt(sq/(rn-1.0))
return
end
c-----------------------------------------------------------------------------
SUBROUTINE XBIWT (XDATA,N,XLBIWT,XSBIWT,XLBIWT1,XSBIWT1)
c-----------------------------------------------------------------------------
c
c The subroutine XBIWT provides an estimator of the location and
c scale of the data set XDATA. The scale uses the Biweight function
c in the general formula of "A-estimators." This formula is given
c on page of 416 in UREDA (formula 4). The BIWEIGHT scale estimate
c is returned as the value XSBIWT. The BIWEIGHT function is given
c by:
c
c u((1-u*u)**2) abs(u) <= 1
c f(u) =
c 0 abs(u) > 1
c
c where u is defined by
c
c u = (XDATA(I) - M) / c*MAD .
c
c M, MAD, and c are the median, the median absolute deviation from
c the median, and the tuning constant respectively. The tuning
c constant is a parameter which is chosen depending on the sample
c size and the specific function being used for the scale estimate.
c (See page 417 in UREDA). Here we take c = 9.0.
c
c The biweght location is found using the formula:
c
c T = M + (sums)
c
c where M is the sample median and sums are
c as given on page 421 in UREDA
c
c the tuning constant c is set to 6.0 for calculation
c of the location as reccommended by Tukey ()
c
c NOTE that the biweight is meant to be an iterated estimator, but one
c commonly only takes the first step of the iteration. Here we report
c both the one-step estimators (XLBIWT1, XSBIWT1) and the preferred
c fully iterated versions (XLBIWT, XSBIWT).
c
c****************************************************************************
parameter(iii=10000)
implicit real*4 (a-h,o-z)
dimension xdata(n),u1(iii),u2(iii),xlb(11),xsb(11)
data zero,d6,d1,d5,d9/0.0,6.0,1.0,5.0,9.0/
CALL MDIAN1(XDATA,N,XM)
CALL XMAD(XDATA,N,XM,XMADM)
c1 = d6
c2 = d9
do i = 1,n
u1(i) = (xdata(i) - xm)/(c1*xmadm)
u2(i) = (xdata(i) - xm)/(c2*xmadm)
enddo
s1 = zero
s2 = zero
s3 = zero
s4 = zero
do i = 1,n
if (abs(u2(i)) .lt. d1) then
s1 = s1+(((xdata(i)-xm)**2)*(d1-(u2(i)*u2(i)))**4)
s2 = s2+((d1-u2(i)*u2(i))*(d1-(d5*u2(i)*u2(i))))
endif
if (abs(u1(i)) .lt. d1) then
s3 = s3+(xdata(i)-xm)*(d1-u1(i)*u1(i))**2
s4 = s4+(d1-u1(i)*u1(i))**2
endif
enddo
c--- here are the one-step estimators
xlbiwt1 = xm+s3/s4
xsbiwt1 = float(n)/(float(n-1))**0.5*s1**0.5/abs(s2)
c--- now obtain the fully-iterated versions
c--- solve for new estimates of u1 and u2
xlb(1) = xlbiwt1
xsb(1) = xsbiwt1
do j = 2,11 !assuming 10 iterations is sufficient
xmm = xlb(j-1)
do i = 1,n
u1(i) = (xdata(i) - xmm)/(c1*xmadm)
u2(i) = (xdata(i) - xmm)/(c2*xmadm)
enddo
s1 = zero
s2 = zero
s3 = zero
s4 = zero
do i = 1,n
if (abs(u2(i)) .lt. d1) then
s1 = s1+(((xdata(i)-xmm)**2)*(d1-(u2(i)*u2(i)))**4)
s2 = s2+((d1-u2(i)*u2(i))*(d1-(d5*u2(i)*u2(i))))
endif
if (abs(u1(i)) .lt. d1) then
s3 = s3+(xdata(i)-xmm)*(d1-u1(i)*u1(i))**2
s4 = s4+(d1-u1(i)*u1(i))**2
endif
enddo
xlb(j) = xlb(j-1)+s3/s4
xsb(j) = float(n)/(float(n-1))**0.5*s1**0.5/abs(s2)
enddo
xlbiwt = xlb(11)
xsbiwt = xsb(11)
20 continue
return
end
c-----------------------------------------------------------------------------
SUBROUTINE XMAD (XDATA,N,XMED,XMADM)
c-----------------------------------------------------------------------------
c
c The XMAD subroutine calculates the Median Absolute Deviation from
c the sample median. The median, M , is subtracted from each
c ORDERED statistic and then the absolute value is taken. This new
c set of of statistics is then resorted so that they are ORDERED
c statistics. The MAD is then defined to be the median of this
c new set of statistics and is returned as XMADM. The MAD can
c be defined:
c
c XMADM = median{ abs(x(i) - M) }
c
c where the x(i) are the values passed in the array XDATA, and
c the median, M, is passed in the array XLETTER. The set of stats
c in the brackets is assumed to be resorted. For more information
c see page 408 in UREDA.
c
c****************************************************************************
parameter(iii=10000)
implicit real*4 (a-h,o-z)
dimension xdata2(iii),xdata(n)
data dhalf,n1,n2/0.5,1,2/
do i = 1,n
xdata2(i) = abs(xdata(i) - xmed)
enddo
call qcksrt(n,xdata2)
ccc call sort(n,xdata2)
if (float(n)/float(n2) - int(n/n2) .eq. 0) then
i1 = n/n2
i2 = n/n2 + n1
xmadm = dhalf*(xdata2(i1) + xdata2(i2))
else
i1 = int(n/n2) + n1
xmadm = xdata2(i1)
endif
return
end
c------------------------------------------------------------------------------
SUBROUTINE MDIAN1 (X,N,XMED)
c------------------------------------------------------------------------------
c
c Taken from Numerical Recipes, page 460.
c Given an array X of N numbers, returns their median value XMED, and
c the array is sorted low to high
c
c*******************************************************************************
real x(n)
call qcksrt(n,x)
ccc call sort(n,x)
n2=n/2
if (2*n2.eq.n) then
xmed=0.5*(x(n2)+x(n2+1))
else
xmed=x(n2+1)
endif
return
end
*sbr mfs
*
* computes the median, hinges, and fourth-spread of n observations
*
* inputs:
*
* x = input series, returned in ranked form
* n = number of observations in series x
*
* outputs:
*
* xmed = median of series x
* hh = high hinge
* hl = low hinge
* fsd = fourth-spread
* rmn = minimum value
* rmx = maximum value
*
* subroutines required: sort
*
subroutine mfs(x,n,xmed,hh,hl,fsd,rmn,rmx)
real*4 x(n)
integer temp1,temp2,j,k !pjk
*
* rank the observations
call qcksrt(n,x)
rmn=x(1)
rmx=x(n)
k=n
j=(k/2)+1
temp1=n+1-j
xmed=(x(j)+x(temp1))/2.0
*
* calculate the high (hh) and low (hl) hinges
* for computing the fourth-spread (fsd)
k=(k+1)/2
j=(k/2)+1
temp1=k+1-j
hl=(x(j)+x(temp1))/2.0
temp1=n-k+j
temp2=n+1-j
hh=(x(temp1)+x(temp2))/2.0
*
* the fourth-spread
fsd=hh-hl
return
end
*sbr qcksrt
*
subroutine qcksrt(n,arr)
parameter (m=7,nstack=10000,fm=7875.,fa=211.,fc=1663.
* ,fmi=1.2698413e-4)
dimension arr(n),istack(nstack)
jstack=0
l=1
ir=n
fx=0.
10 if(ir-l.lt.m)then
do 13 j=l+1,ir
a=arr(j)
do 11 i=j-1,1,-1
if(arr(i).le.a)go to 12
arr(i+1)=arr(i)
11 continue
i=0
12 arr(i+1)=a
13 continue
if(jstack.eq.0)return
ir=istack(jstack)
l=istack(jstack-1)
jstack=jstack-2
else
i=l
j=ir
fx=mod(fx*fa+fc,fm)
iq=l+(ir-l+1)*(fx*fmi)
a=arr(iq)
arr(iq)=arr(l)
20 continue
21 if(j.gt.0)then
if(a.lt.arr(j))then
j=j-1
go to 21
endif
endif
if(j.le.i)then
arr(i)=a
go to 30
endif
arr(i)=arr(j)
i=i+1
22 if(i.le.n)then
if(a.gt.arr(i))then
i=i+1
go to 22
endif
endif
if(j.le.i)then
arr(j)=a
i=j
go to 30
endif
arr(j)=arr(i)
j=j-1
go to 20
30 jstack=jstack+2
if(jstack.gt.nstack)pause 'nstack must be made larger.'
if(ir-i.ge.i-l)then
istack(jstack)=ir
istack(jstack-1)=i+1
ir=i-1
else
istack(jstack)=i-1
istack(jstack-1)=l
l=i+1
endif
endif
go to 10
end
*sbr cenbyseg - censor by minimum segment length - mnsl
*
subroutine cenbyseg(mnsl,x,nc,idate,ident,mxy,mxs)
real*4 x(mxy,mxs)
integer idate(mxs,3)
character ident(mxs)*8
maxn=idate(nc+1,2)-idate(nc+1,1)+1
nc1=0
ifmny1=9999
ilmxy1=-9999
c
c *** find those series .ge. minimum segment legnth and save
c
do j=1,nc
nyrs=idate(j,3)
if(nyrs.ge.mnsl)then
nc1=nc1+1
idate(nc1,1)=idate(j,1)
idate(nc1,2)=idate(j,2)
idate(nc1,3)=idate(j,3)
ident(nc1)=ident(j)
if(idate(nc1,1).lt.ifmny1)ifmny1=idate(nc1,1)
if(idate(nc1,2).gt.ilmxy1)ilmxy1=idate(nc1,2)
do i=1,maxn
x(i,nc1)=x(i,j)
enddo
endif
enddo
maxn1=ilmxy1-ifmny1+1
idate(nc1+1,1)=ifmny1
idate(nc1+1,2)=ilmxy1
idate(nc1+1,3)=maxn1
if(maxn1.lt.maxn)then
ndif=maxn-maxn1
write(*,'(/1x,''Total chronology length shortened: '',i6,'' years'')')ndif
c do i=1,maxn1
c do j=1,nc
c x(i,j)=x(i+ndif,j)
c enddo
c enddo
endif
c
c *** dummy out the data matrix with missing values to account for removed series
c
do j=nc1+1,nc
do i=1,maxn
x(i,j)=-9.99
enddo
call blank(ident(j))
enddo
c
c *** final results
c
write(*,'(/t30,'' NS IFY ILY NYR'')')
write(*,'(1x,''Min segment length series:'',t30,4i6,'' Years total time
span'')')
* nc1,ifmny1,ilmxy1,maxn1
nc=nc1
return
end
*sbr cenbyify - censor by maximum starting year - mxsy
*
subroutine cenbyify(mxsy,x,nc,idate,ident,mxy,mxs)
real*4 x(mxy,mxs)
integer idate(mxs,3)
character ident(mxs)*8
maxn=idate(nc+1,2)-idate(nc+1,1)+1
nc1=0
ifmny1=9999
ilmxy1=-9999
c
c *** find those series .le. minimum starting year and save
c
do j=1,nc
ify=idate(j,1)
if(ify.le.mxsy)then
nc1=nc1+1
idate(nc1,1)=idate(j,1)
idate(nc1,2)=idate(j,2)
idate(nc1,3)=idate(j,3)
ident(nc1)=ident(j)
if(idate(nc1,1).lt.ifmny1)ifmny1=idate(nc1,1)
if(idate(nc1,2).gt.ilmxy1)ilmxy1=idate(nc1,2)
do i=1,maxn
x(i,nc1)=x(i,j)
enddo
endif
enddo
maxn1=ilmxy1-ifmny1+1
idate(nc1+1,1)=ifmny1
idate(nc1+1,2)=ilmxy1
idate(nc1+1,3)=maxn1
if(maxn1.lt.maxn)then
ndif=maxn-maxn1
write(*,'(/1x,''Total chronology length shortened: '',i6,'' years'')')ndif
c do i=1,maxn1
c do j=1,nc
c x(i,j)=x(i+ndif,j)
c enddo
c enddo
endif
c
c *** dummy out the data matrix with missing values to account for removed series
c
do j=nc1+1,nc
do i=1,maxn
x(i,j)=-9.99
enddo
call blank(ident(j))
enddo
c
c *** final results
c
write(*,'(/t30,'' NS IFY ILY NYR'')')
write(*,'(1x,''Max starting year series:'',t30,4i6,'' Years total time
span'')')
* nc1,ifmny1,ilmxy1,maxn1
nc=nc1
return
end
*sbr cenbycom - censor by common period - ifc, ilc
*
subroutine cenbycom(ifc,ilc,x,nc,idate,ident,mxy,mxs)
real*4 x(mxy,mxs)
integer idate(mxs,3),ifc,ilc,nc
character ident(mxs)*8
maxn=idate(nc+1,2)-idate(nc+1,1)+1
nc1=0
nyc=ilc-ifc+1
ifmny1=ifc
ilmxy1=ilc
maxn1=ilmxy1-ifmny1+1
c
c *** find those series with data in the common period - ifc, ilc
c
do j=1,nc
ify=idate(j,1)
ily=idate(j,2)
if(ify.le.ifc.and.ily.ge.ilc)then
nc1=nc1+1
idate(nc1,1)=idate(j,1)
idate(nc1,2)=idate(j,2)
idate(nc1,3)=idate(j,2)-idate(j,1)+1
ident(nc1)=ident(j)
do i=1,maxn
x(i,nc1)=x(i,j)
enddo
endif
enddo
idate(nc1+1,1)=ifc
idate(nc1+1,2)=ilc
idate(nc1+1,3)=nyc
c
c *** shorten the length of retained series to the common interval only
c
write(*,'(/1x,''Total chronology length shortened: '',i6,'' years'')')maxn-
nyc
do j=1,nc1
ify=idate(j,1)
ily=idate(j,2)
ndif=ifc-ify
do i=1,nyc
x(i,j)=x(i+ndif,j)
enddo
do i=1,ndif
x(i+nyc,j)=-9.99
enddo
idate(j,1)=ifc
idate(j,2)=ilc
idate(j,3)=nyc
enddo
c
c *** dummy out the data matrix with missing values to account for removed series
c
do j=nc1+1,nc
do i=1,maxn
x(i,j)=-9.99
enddo
call blank(ident(j))
enddo
c
c *** final results
c
write(*,'(/t30,'' NS IFY ILY NYR'')')
write(*,'(1x,''Max starting year series:'',t30,4i6,'' Years total time
span'')')
* nc1,ifc,ilc,nyc
nc=nc1
return
end
*sbr savcen - save the censored data in Tucson raw ringwidth format
*
subroutine
savcen(cproc,icen1,icen2,x,y,nc,idate,ident,itrdb,filnam,iu11,mxy,mxs)
real*4 x(mxy,mxs),y(mxy)
integer idate(mxs,3),icen1,icen2,nc
character cproc,filnam*40,fil1*50,ident(mxs)*8,id*8,itrdb(3)*88,tag*3
c
c *** parse the input file name for creating the output file name
c
ll=len(filnam)
jj=0
do j=1,ll
jj=ll-j+1
if(filnam(jj:jj).ne.' ')goto 1
enddo
1 ll=jj
do j=1,ll
jj=j
if(filnam(j:j).eq.'.')then
jj=j-1
goto 2
endif
enddo
2 ll=jj
c
c *** create the unique output file name for the censored data type
c
call blank(fil1)
fil1(1:40)=filnam(1:40)
if(cproc.eq.'2')then
if(icen1.lt.100)then
fil1(ll+1:ll+12)='_mnsl= .txt'
write(fil1(ll+7:ll+8),'(i2)')icen1
elseif(icen1.ge.100.and.icen1.lt.1000)then
fil1(ll+1:ll+13)='_mnsl= .txt'
write(fil1(ll+7:ll+9),'(i3)')icen1
elseif(icen1.ge.1000)then
fil1(ll+1:ll+14)='_mnsl= .txt'
write(fil1(ll+7:ll+10),'(i4)')icen1
endif
elseif(cproc.eq.'3')then
fil1(ll+1:ll+14)='_mxsy= .txt'
write(fil1(ll+7:ll+10),'(i4)')icen1
elseif(cproc.eq.'4')then
fil1(ll+1:ll+19)='_comm= - .txt'
write(fil1(ll+7:ll+10),'(i4)')icen1
write(fil1(ll+12:ll+15),'(i4)')icen2
endif
call blank(tag)
if(cproc.eq.'2')tag='mnsl'
if(cproc.eq.'3')tag='mxsy'
if(cproc.eq.'4')tag='comm'
open(iu11,file=fil1,status='unknown')
write(*,'(/1x,''File for censored data created: '',a)')fil1
do j=1,3
if(cproc.eq.'2')itrdb(j)(85:88)='MNSL'
if(cproc.eq.'3')itrdb(j)(85:88)='MXSY'
if(cproc.eq.'4')itrdb(j)(85:88)='COMM'
write(iu11,'(a)')itrdb(j)
enddo
c
c *** write the censored data to the file in Tucson ring width format
c
do j=1,nc
call blank(id)
id=ident(j)
ify=idate(j,1)
nyr=idate(j,3)
do i=1,nyr
y(i)=x(i,j)
enddo
call trrw(id,ify,nyr,y,nss,ifl,iu11,iuo,'mw',tit,tag,mxy,itrdb)
enddo
close(iu11)
return
end
*sbr arpad
*
subroutine arpad(x,n,y,np,ls,mxy)
real*4 x(mxy),y(mxy)
real*8 arps(500),wk1(5000),wk2(5000),wkm(500)
c
c *** extend the series off both ends with prediction error filter
c *** forecasts and hindcasts of length ls-1 (i.e. # of lags)
c
lstest=0.67*n
if(lstest.lt.ls)ls=lstest
next=ls
np=n+2*next
do i=1,mxy
y(i)=0.0
enddo
call mnsd(x,n,xm,sd)
do i=1,n
ii=i+next
y(ii)=x(i)-xm
enddo
iopt=0
ip=next
call memcof(y(next+1),n,ip,pm,arps,wk1,wk2,wkm)
call extend(y,n,next,arps,ip,iopt)
do i=1,np
y(i)=y(i)+xm
enddo
return
end
*sbr memcof
*
subroutine memcof(data,n,m,pm,cof,wk1,wk2,wkm)
implicit real*8 (a-h,o-z)
real*4 data(1)
real*8 cof(1),wk1(1),wk2(1),wkm(1)
data zero/0.0d0/,one/1.0d0/,two/2.0d0/
rn=n
p=zero
do 11 j=1,n
p=p+dble(data(j))*dble(data(j))
11 continue
pm=p/rn
wk1(1)=dble(data(1))
wk2(n-1)=dble(data(n))
do 12 j=2,n-1
wk1(j)=dble(data(j))
wk2(j-1)=dble(data(j))
12 continue
do 17 k=1,m
pneum=zero
denom=zero
do 13 j=1,n-k
pneum=pneum+wk1(j)*wk2(j)
denom=denom+wk1(j)**2+wk2(j)**2
13 continue
cof(k)=two*pneum/denom
pm=pm*(one-cof(k)**2)
if(k.ne.1)then
do 14 i=1,k-1
cof(i)=wkm(i)-cof(k)*wkm(k-i)
14 continue
endif
if(k.eq.m)return
do 15 i=1,k
wkm(i)=cof(i)
15 continue
do 16 j=1,n-k-1
wk1(j)=wk1(j)-wkm(k)*wk2(j)
wk2(j)=wk2(j+1)-wkm(k)*wk1(j+1)
16 continue
17 continue
pause 'never get here'
end
*sbr extend
*
c
c *** uses prediction error filter or autogregressive coefficients
c *** to extrapolate a time series off either or both ends into
c *** never-never-land. are you listening, peter pan or tinkerbell?
c
c *** it can be used to pad the ends of time series before applying
c *** digital filters, provide starting values for autoregressive
c *** modeling or prewhitening, and simply forecast or hindcast a
c *** time series into the past for future for whatever purpose.
c
c y time series of length n
c n number of observations
c ncast number of forecasts and/or hindcasts
c phi prediction error filter coefficients
c ip order of prediction error filter
c iopt option for forecasts and hindcasts
c -1 hindcasts only
c 0 forecasts and hindcasts
c 1 forecasts only
c
c *** a cautionary note:
c *** this routine assumes that room is available on either
c *** end of array y to put the forecasts and/or hindcasts.
c *** thus, if hindcasts are to be made, you must have moved
c *** the observations in y foreward to make room for the ncast
c *** hindcasts. if forecasts are to be made, array y must be
c *** dimensioned long enough to hold the ncast forecasts.
c *** thus, y must be dimensioned to hold n+ncast values and,
c *** perhaps, n+2*ncast elements long in the main program,
c *** depending on the way the subroutine is used.
c
subroutine extend(y,n,ncast,arps,ip,iopt)
real*4 y(1)
real*8 arps(1),pf,pb,zero
data zero/0.0d0/
ccc write(2,'(10f8.4)')(arps(j),j=1,ip) !debug
do 15 i=1,ncast
pf=zero
pb=zero
nf=ncast+n+i
nb=ncast+1-i
do 10 j=1,ip
if(iopt.eq.0.or.iopt.eq.+1)pf=pf+arps(j)*dble(y(nf-j))
if(iopt.eq.0.or.iopt.eq.-1)pb=pb+arps(j)*dble(y(nb+j))
10 continue
y(nf)=sngl(pf)
y(nb)=sngl(pb)
ccc write(2,'(1x,2i5,f9.5,i4,f9.5)')i,nb,y(nb),nf,y(nf) !debug
15 continue
return
end
*sbr plot1
*
subroutine plot1(nmax,wrk,sp,ny,iy,xlab,ylab,tit,rline,annot1,annot2)
c
c write(winu9,'(/13x,''COLOR TABLE
______________________________________________'')')
c write(winu9,'(13x,''White(0) Red(1) Yellow(2) Green(3) Aquamarine(4)
Pink(5) '')')
c write(winu9,'(13x,''Wheat(6) Grey(7) Browm(8) Blue(9) BlueViolet(10)'')')
c write(winu9,'(13x,''Cyan(11) Turquoise(12) Magenta(13) Salmon(14)
Black(15)'')')
c
write(winu9,'(13x,''___________________________________________________________'',/
)')
c
c
c argument
integer nmax,ny,iy
dimension sp(nmax),wrk(nmax),rline(nmax)
character tit*60,xlab*20,ylab*20,annot1*35,annot2*35
c local
integer p,red,green,blue
real*4 x(10000),mny,mxy,mx,mnx
logical bg
c
mny=100000.0;mxy=-100000.0
red=255;green=255;blue=255
bg=.false.
c
do p=1,ny
if(wrk(p).gt.mxy)mxy=wrk(p)
if(sp(p).gt.mxy)mxy=sp(p)
if(wrk(p).lt.mny)mny=wrk(p)
if(sp(p).lt.mny)mny=sp(p)
x(p)=iy+p-1
enddo
irange=mxy-mny
mxy=mxy+irange/10
mny=mny-irange/10
c
mnx=iy;mx=iy+ny-1
ccc write(*,*)mxy,mny
ccc write(*,*)mx,mnx
c
call plsdev('Mac1')
c
c set background color
c
if(.not.bg)then
call plscol0(0,255,255,255) !change default color map
black>white
call plscol0(15,0,0,0) !change default color map
white>black
call plscolbg(red,green,blue) !change background color if other
than white is desired
elseif(bg)then
call plscol0(15,255,255,255) !change default color map
white>black
call plscol0(0,0,0,0) !change default color map
black>white
call plscolbg(red,green,blue) !change background color if other
than white is desired
endif
c
c initialize plplot
c
call plinit()
c
c set lable color
c
call plcol(15) !color box and lables
c set curve width
call plwid(2)
c
c define the viewport one column by one rows
c
call plssub(1,1)
ccc call plenv(mnx,mx,mny,mxy,0,2)
call plenv(mnx,mx,mny,mxy,0,0)
if(rline(1).ne.-999.9)then
call plline(ny,x,rline) !plot rline
endif
call plfont(1)
ccc call pllab(xlab,ylab,tit)
call plcol(9)
ccc call plmtex('b',-27.0,0.05,0.0,annot2)
call plmtex('b',-32.5,0.55,0.0,annot2)
c
c *** end plotting
c
call plend()
return
end
*sbr runbar
*
subroutine runbar(x,ybar,idate,nc,rxm,runr,ncnt,nsg,nlp,mxy,mxs,iu33)
c
c x - input - real matrix of input series being averaged
c ybar - input - real matrix containing a copy of the unstabilized series
(*,1)
c output - running rbar (runr) variance stabilized series, based on
unsmoothed
c (*,2) and spline smoothed (*,3) runr series
c idate - input - array of start and end years of input series
c nc - input - number of input series being averaged
c runr - output - real array containing sample sizes, running rbars, effective
sample sizes
c nsg - input - running rbar window length, must be odd - incremented by one
if not
c nlp - input - overlap of running rbar window
c mxy - input - maximum number of observations - from calling program
c mxs - input - maximum number of series - from calling program
c
parameter(maxlen=1000000)
real*4 x(mxy,mxs),ybar(mxy,3),rxm(mxy,7),runr(mxy,5),wrk1(maxlen)
integer idate(mxs,3)
nseg=0
ncnt=0
ifmn=idate(nc+1,1)
ilmx=idate(nc+1,2)
n=ilmx-ifmn+1
if(mod(nsg,2).eq.0)then
nsg=nsg+1
nlp=nsg-1
endif
nsgd2=nsg/2
write(*,'(/1x,''Running RBAR window length: '',t37,i5/
* 1x,''Running RBAR window overlap: '',t37,i5)')nsg,nlp
do i=1,n,nsg-nlp
nseg=nseg+1
iskp=(nseg-1)*nsg-(nseg-1)*nlp
ifskp=ifmn+iskp
ilskp=ifskp+nsg-1
iyr=ifskp+nsg/2
if(ilskp.le.ilmx)then
call
rrbar(x,wrk1,idate,nc,ifskp,ilskp,nr,ave,sdev,see,nsg,mxy,mxs,maxlen)
if(ave.ne.-99.9)then
ncnt=ncnt+1
if(ncnt.eq.1)then
ndif1=iyr-idate(nc+1,1)
endif
rxm(ncnt,1)=iyr
rxm(ncnt,2)=nr
rxm(ncnt,3)=ave
rxm(ncnt,4)=sdev
rxm(ncnt,5)=see
runr(ncnt+ndif1,2)=ave
rncores=0.0
do j=1,nsg
j1=ifskp-idate(nc+1,1)+j
do k=1,nc
if(x(j1,k).ne.-9.99)rncores=rncores+1.0
enddo
enddo
rncores=rncores/float(nsg)
rxm(ncnt,6)=ave/(ave+(1.0-ave)/rncores)
rxm(ncnt,7)=rncores
endif
endif
enddo
write(*,'(1x,''Running RBAR segments calculated: '',t37,i5)')ncnt
c
c *** pad the ends with values equal to the first and last running RBAR values
c
do i=1,ndif1
runr(i,2)=runr(ndif1+1,2)
enddo
ndif2=n-ncnt-ndif1
do i=1,ndif2
runr(i+ndif1+ncnt,2)=runr(ndif1+ncnt,2)
enddo
c
c *** calculate the mean running RBARs for periods of constant sample size
c
icnt=1
jcnt=0
kcnt=0
do i=2,n
num1=runr(i-1,1)
num2=runr(i,1)
if(num2.eq.num1)then
icnt=icnt+1
else
jcnt=jcnt+1
kcnt=icnt
ccc write(*,'(1x,''jcnt,kcnt: '',2i5)')jcnt,kcnt
wrk1(jcnt)=kcnt
icnt=icnt+1
endif
if(i.eq.n)then
jcnt=jcnt+1
kcnt=n
ccc write(*,'(1x,''jcnt,kcnt: '',2i5)')jcnt,kcnt
wrk1(jcnt)=kcnt
endif
enddo
do i=1,jcnt
sum=0.0
if(i.eq.1)then
kcnt1=1
else
kcnt1=wrk1(i-1)+1
endif
kcnt2=wrk1(i)
rcnt=0.0
do j=kcnt1,kcnt2
rcnt=rcnt+1.0
sum=sum+runr(j,2)
enddo
sum=sum/rcnt
do j=kcnt1,kcnt2
runr(j,4)=sum
enddo
enddo
c
c *** do the running rbar variance stabilization now
c
call mnsd(ybar(1,1),n,xm,sd)
do i=1,n
runr(i,3)=runr(i,1)/(1.0+(runr(i,1)-1.0)*runr(i,2))
runr(i,5)=runr(i,1)/(1.0+(runr(i,1)-1.0)*runr(i,4))
iyr=ify+i-1
datum=ybar(i,1)-xm
ybar(i,2)=datum*sqrt(runr(i,2)*runr(i,3))+xm
ybar(i,3)=datum*sqrt(runr(i,4)*runr(i,5))+xm
enddo
ifmn=idate(nc+1,1)
write(iu33,'('' YEAR NC RBAR1 NEFF1 RBAR2 NEFF2'')')
do i=1,n
iyr=ifmn+i-1
ncores=runr(i,1)
write(iu33,'(i5,i7,4f8.3)')iyr,ncores,(runr(i,j),j=2,5)
enddo
return
end
*sbr rrbar
*
subroutine
rrbar(x,wrk1,idate,nc,ifskp,ilskp,nr,ave,sdev,see,nsg,mxy,mxs,maxlen)
real*4 x(mxy,mxs),wrk1(maxlen)
real*8 x1,x2,dr,rn
integer idate(mxs,3)
ifyf=idate(nc+1,1)
nr=0
x1=0.d0
x2=0.d0
do 20 i=1,nc-1
ify1=idate(i,1)
ily1=idate(i,2)
do 10 j=i+1,nc
ify2=idate(j,1)
ily2=idate(j,2)
ifmx=max0(ify1,ify2)
ilmn=min0(ily1,ily2)
if(ifmx.gt.ifskp)then
goto 10
endif
ist=ifskp-ifyf+1
nmin=ilmn-ifskp+1
if(nmin.gt.nsg)nmin=nsg
if(nmin.eq.nsg)then
call pearsn(x(ist,i),x(ist,j),nmin,r,a,b)
if(r.gt.0)then
nr=nr+1
wrk1(nr)=r
dr=r
x1=x1+dr
x2=x2+dr*dr
endif
endif
10 continue
20 continue
if(nr.lt.3)then
ave=-99.9
sdev=-99.9
see=-99.9
return
ccc elseif(nr.eq.1)then
ccc ave=r
ccc sdev=0.0
ccc see=0.0
ccc return
else
rn=dble(nr)
ave=x1/rn
sdev=dsqrt((x2-rn*ave*ave)/(rn-1.d0))
endif
rnr=nr
see=sdev/sqrt(rnr)
rnc=nc
pap=(rnr/(rnc*(rnc-1.0)/2.0))*100.0
return
end
*sbr pearsn -- pearson product-moment correlation coefficient
*
subroutine pearsn(x,y,n,r,a,b)
real*4 x(n),y(n)
ax=0.
ay=0.
do j=1,n
ax=ax+x(j)
ay=ay+y(j)
enddo
ax=ax/n
ay=ay/n
sxx=0.
syy=0.
sxy=0.
do j=1,n
xt=x(j)-ax
yt=y(j)-ay
sxx=sxx+xt**2
syy=syy+yt**2
sxy=sxy+xt*yt
enddo
sgy=sqrt(syy/(n-1.))
sgx=sqrt(sxx/(n-1.))
yxr=sgy/sgx
r=sxy/sqrt(sxx*syy)
b=yxr*r
a=ay-b*ax
return
end
*sbr intfrm
*
subroutine intfrm(datum,frm)
character datum*(*),frm*(*)
l=len(datum)
ll=0
nb=0
do 5 i=1,l
if(datum(i:i).ne.' ')then
nb=i-1
goto 10
endif
5 continue
10 do 15 i=1,l
if(datum(i:i).ne.' ')ll=ll+1
15 continue
if(nb.gt.0)then
do 20 i=1,ll
j=i+nb
datum(i:i)=datum(j:j)
20 continue
do 25 i=ll+1,l
datum(i:i)=' '
25 continue
endif
call blank(frm)
frm(1:2)='(i'
if(ll.lt.10)then
write(frm(3:3),'(i1)')ll
frm(4:4)=')'
else
write(frm(3:4),'(i2)')ll
frm(5:5)=')'
endif
return
end