Hello. Thanks for your reply.
Sorry, I meant to say that I need to plot the smoothed spectrum and its confidence bands with fractions of pi on the horizontal axis, as the procedure @spectrum does.
I tried to add the boostrapping part of @bootspectrum to @spectrum, and adding some changes:
- plotting without log scale
- plotting the spectrum and confidence bands in the (0, pi) range
Below I enclose the code for this modified version of @spectrum. It does run, but the confidence band looks very wide.
I'm not sure whether what I did is right, if you could check it I would be very grateful
Regards.
Code:
- Code: Select all
*
*
* @spectrum3( options ) series start end
* Computes and optionally graphs the estimated spectrum of a series.
*
* Options:
* ORDINATES=Number of ordinates [depends upon length,seasonal]
* WINDOW=[FLAT]/TENT/QUADRATIC
* WIDTH=Window width [depends upon ordinates]
* TAPER=TRAPEZOIDAL/COSINE/[NONE]
* WTAPER=Taper width [.25 of length]
* [GRAPH]/NOGRAPH
* HEADER=Header for high-resolution graph
* FOOTER=Footer for high-resolution graph
* [LOGSCALE]/NOLOGSCALE Graph spectrum in log scale or not.
* PERIODOGRAM/[NOPERIODOGRAM]
* SPECTRUM=series for [0,pi] spectrum (0 frequency at entry 1)
* FREQ= frequencies [0,pi] (0 frequency at entry 1)
*
* Revision schedule
* 04/1992 COMPUTE HALF added
* 10/1999 Update to Version 5.00
* 08/2003 Add LOGSCALE and PERIODOGRAM options
* 06/2007 Add FOOTER option
* 07/2007 Add WINDOW=QUADRATIC
*
procedure spectrum3 series start end
type series series
type integer start end
option integer ordinate ;* Number of ordinates
option choice window 1 flat tent quadratic ;* Window type
option integer width ;* Window width
option choice taper 3 trap cosine none ;* Taper type
option real wtaper ;* Taper width (fraction)
option switch graph 1
option string header
option string footer
option switch logscale 1
option switch periodogram 0
option series *spectrum
option series *freq
local integer nobs startl endl freqord half
local series spect frequencies
if .not.%defined(series) {
DISPLAY "Syntax: @SPECTRUM3 series start end"
return
}
*
* Determine the range of SERIES to use
*
inquire(series=series) startl<<start endl<<end
compute nobs=endl-startl+1
*********************************
* <<nwidth>> is the window width to be used in estimation.
* <<nwidthboot>> is the window width to be used to standardize the
* periodogram for bootstrapping. These can be different.
*
compute nwidth=9
compute nwidthboot=9
*********************************
*
* Determine the ordinates. If the user provides a number, use it. If
* not, use the number of observations, if the user has requested the
* periodogram, or the recommended number, if a more general spectral
* density estimate is requested.
*
if %defined(ordinate)
compute freqord=ordinate
else if periodogram
compute freqord=nobs
else
compute freqord=%freqsize(nobs)
compute half = freqord/2+1
frequency 5 freqord
*
* Transfer the series to the frequency domain - shift it to begin at
* entry 1
*
rtoc startl endl 1
# series
# 1
*
* If TAPER is requested, taper the transferred part of series 1
*
if taper<>3
{
taper(type=taper,fraction=wtaper) 1 1 nobs
}
else
{
compute %scaletap=nobs
compute %kappa =1.0
}
fft 1
cmult(scale=1./(2.*%pi*%scaletap)) 1 1
if periodogram
cset 2 = %z(t,1)
else
window(type=window,width=width) 1 / 2
ctor 1 half
# 2
# spect
if %defined(spectrum)
set spectrum 1 half = spect
if .not.graph
return
*********************************************************************
* Get the smoothed estimate with the width for bootstrapping to complex
* series 5.
*
window(type=tent,width=nwidthboot) 1 / 5
compute nboot=1000
*
* The reshuffled periodogram needs to be symmetrical, so we only use
* half the ordinates. Because the 0 ordinate in the periodogram is
* forceably zero (as a result of de-meaning), we also leave that out.
*
compute nshuffle=freqord/2+1
*
* We need to bootstrap the periodogram divided by the estimated
* spectral density using the width <<nwidthboot>>.
*
set source = %real(%z(t,1))/%real(%z(t,5))
*
set sumsqr 1 freqord = 0.0
*
do draw=1,nboot
*
* Draw a set of standardized periodogram ordinates. Normalize to mean
* one and symmetrize.
*
boot shuffle 2 nshuffle
cset 3 1 nshuffle = %if(t==1,0.0,source(shuffle(t)))
sstats(mean) 2 nshuffle %real(%z(t,3))>>shufflesum
cset 3 1 nshuffle = %z(t,3)/shufflesum
@cseriessymm 3
*
* Recolor it by the standardizing spectral estimate.
*
cset 3 = %z(t,3)*%z(t,5)
*
* Smooth using the desired width.
*
window(type=tent,width=nwidth) 3 / 4
*
* Get sample statistics with respect to log ratio to the original
* spectral density estimate.
*
set sumsqr 1 freqord = sumsqr+log(%real(%z(t,4))/%real(%z(t,2)))^2
end do draw
set lower 1 half = spect-2.0*sqrt(sumsqr/nboot)
set upper 1 half = spect+2.0*sqrt(sumsqr/nboot)
*******************************************************************
set frequencies 1 half = (t-1.0)/half
if logscale {
scatter(style=lines,header=header,footer=footer,hlabel="Fractions of pi",vlog=10.0) 1
# frequencies spect 1 half
}
else {
scatter(style=lines,header=header,footer="Confidence bands using bootstrap",hlabel="Fractions of pi") 3
# frequencies spect 1 half
# frequencies lower 1 half
# frequencies upper 1 half
}
if %defined(freq)
set freq 1 half = frequencies
if .not.graph
return
end spectrum3