*! 1.0.0 Ariel Linden 12Sep2025 program define power_arima_itsa, rclass version 11 syntax , Ntime(integer) /// EFFect(numlist) /// [ TRperiod(string) /// TYPE(string) /// ACorr(real 0) /// ALPha(real 0.05) /// ONESIDed /// KNOWnmean /// RAW /// FORmat(string) ] * set the default treatment period to the halfway point in the time series if "`trperiod'" == "" { local trperiod = ceil(`ntime' / 2) } * set default type to "step" if "`type'" == "" { local type step } local first = 1 // flag for first effect (to create matrix) tempname sigma_stat effect_raw i11 i12 i22 se_effect det lambda zcrit power results foreach e of local effect { * stationary SD (sigma) scalar `sigma_stat' = 1/sqrt(1 - `acorr'^2) * effect scaling if "`raw'" != "" { scalar `effect_raw' = `e' } else { scalar `effect_raw' = `e' * `sigma_stat' } * information matrix entries for AR1 (from Table 1) scalar `i11' = `ntime' * (1 - `acorr')^2 scalar `i12' = 0 scalar `i22' = 0 if "`type'" == "step" { scalar `i12' = (`ntime' - `trperiod') * (1 - `acorr')^2 + 1 - `acorr' scalar `i22' = (`ntime' - `trperiod') * (1 - `acorr')^2 + 1 } else if "`type'" == "pulse" { scalar `i12' = 1 - `acorr'^2 scalar `i22' = 1 - `acorr'^2 } else if "`type'" == "ramp" { scalar `i12' = (1 + `ntime' - `trperiod') * (1 - `acorr') * (2 + `ntime' - `trperiod' - (`ntime' - `trperiod')*`acorr') / 2 scalar `i22' = (1 + `ntime' - `trperiod') * /// (6 + 7*`ntime' + 2*`ntime'^2 - 7*`trperiod' - 4*`ntime'*`trperiod' + 2*`trperiod'^2 /// - 8*`ntime'*`acorr' - 4*`ntime'^2*`acorr' + 8*`trperiod'*`acorr' + 8*`ntime'*`trperiod'*`acorr' /// - 4*`trperiod'^2*`acorr' + `ntime'*`acorr'^2 + 2*`ntime'^2*`acorr'^2 - `trperiod'*`acorr'^2 /// - 4*`ntime'*`trperiod'*`acorr'^2 + 2*`trperiod'^2*`acorr'^2) / 6 } else { di as err "unknown type: `type' (use step/pulse/ramp)" exit 198 } * standard error if "`knownmean'" != "" { scalar `se_effect' = sqrt(1 / `i22') } else { scalar `det' = `i11' * `i22' - `i12'^2 if `det' <= 0 { di as err "nonpositive determinant in information matrix; check inputs" exit 199 } scalar `se_effect' = sqrt(`i11' / `det') } * noncentrality and `power' scalar `lambda' = `effect_raw' / `se_effect' if "`onesided'" != "" { scalar `zcrit' = invnormal(1 - `alpha') scalar `power' = 1 - normal(`zcrit' - `lambda') } else { scalar `zcrit' = invnormal(1 - `alpha'/2) scalar `power' = normal(-`zcrit' - `lambda') + (1 - normal(`zcrit' - `lambda')) } * append to `results' matrix if `first' { matrix `results' = (`e', `=`power'') // first row local first = 0 } else { matrix `results' = `results' \ (`e', `=`power'') // subsequent rows } } // end foreach effect * formatting for titles, headers and values in `results' table if "`onesided'" != "" { local side One-sided } else { local side Two-sided } local plevel = `alpha' * 100 if "`format'" != "" { confirm numeric format `format' } else local format %-6.3f if "`raw'" != "" { local std unstandardardized } else { local std standardardized } if "`knownmean'" != "" { local mean known } else { local mean estimated } matrix colnames `results' = Effect Power di _n di as txt "Statistical power computation for a {bf:`type'} intervention with AR(1) Error" di as txt "`side' test at `plevel'% level" di _n di as txt "Length of time series = " `ntime' di as txt "Observation number corresponding to the start of the intervention = " `trperiod' di as txt "Lag-one autocorrelation coefficient = " %4.2f `acorr' di as txt "Pre-intervention mean is `mean' di as txt "Effect size is `std' * results table matlist `results', border(top bottom) format(`format') tindent(0) aligncolnames(center) twidth(8) names(columns) * return matrix return matrix table = `results' end