rem TITLE: Clopper-Pearson mid-P confidence interval calculator
rem AUTHOR: André GILLIBERT (August 2017)
rem LICENSE: Creative Commons CC0
rem REFERENCE ARTICLE: DOI:10.2307/2348891
rem USAGE 1: Open & run the script in MYSTAT >= 12 or SYSTAT >= 12 to get an interactive calculator
rem USAGE 2:
rem Remove the interactive part of the script (delimited by comments)
rem And then, use the cpmidp_onesided and cpmidp_twosided functions
rem Their syntax is described in the interactive part

function cpmidpq(x,n,target)
{
prec=1e-8/n
xlower=0
xupper=1
flower=1-target
fupper=-target

while ((xupper - xlower) > prec)
	xmid = (xlower+xupper)/2
	fmid = NCF(x,n,xmid)-0.5*NDF(x,n,xmid)-target
	
	sgn=(fmid*flower) > 0

	xlower = xmid*sgn + xlower*(1-sgn)
	flower = fmid*sgn + flower*(1-sgn)
	xupper = xmid*(1-sgn) + xupper*sgn
	fupper = fmid*(1-sgn) + fupper*sgn
endwhile
return (xlower + xupper)/2
}

function cpmidp_onesided(x,n,conflvl)
{
cl = cpmidpq(x,n,1-conflvl)
lcl = cl*(x<>0)
ucl = cl*(x<>n)+(x=n)
cl  = ucl*(conflvl>0.5) + lcl*(conflvl<=0.5)
return cl
}

function cpmidp_twosided(x,n,conf)
{
lcl2 = cpmidp_onesided(x,n,0.5-conf/2)
ucl2 = cpmidp_onesided(x,n,0.5+conf/2)

PRINT lcl2, ucl2
PRINT "Two-sided Clopper-Pearson mid-P confidence interval"
PRINT cat$("Confidence level: ", str$(conf))
PRINT cat$("Lower confidence limit: ", str$(lcl2))
PRINT cat$("Upper confidence limit: ", str$(ucl2))
return 0
}

rem ###### Start of interactive part ######

print "This script computes the Clopper-Pearson mid-P confidence interval of a binomial proportion"
print "You may use this script non-interactively !"
print "The key function is cpmidp_onesided(successes, trials, confidence_level)"
print "Example 1:"
print "lower = cpmidp_onesided(3,100,0.025)"
print "upper = cpmidp_onesided(3,100,0.975)"
print "print lower, upper"
print "The cpmidp_twosided function displays results but returns 0"
print "Example 2:"
print "x=cpmidp_twosided(3,100,0.95)"

FORMAT 12, 5
token &successes / type=integer, prompt='How many successes in the sample?'
token &trials / type=integer, prompt='How many trials in the sample?'
token &conflevel / type=number, prompt='Confidence level (e.g. 0.95)?'
dropit=cpmidp_twosided(&successes, &trials, &conflevel)
rem ###### End of interactive part ######
