*! Date : 13 Jan 2012 *! Version : 1.09 *! Author : Adrian Mander *! Email : adrian.mander@mrc-bsu.cam.ac.uk *! The Simon two stage design written for Stata 11.0 with Mata /* Example commands simon2stage, p0(0.1) p1(0.3)admiss eff minn(33) simon2stage, p0(0.1) p1(0.3) beta(0.15) admiss eff minn(33) simon2stage, p0(0.1) p1(0.5) beta(0.15) admiss eff maxn(14) minn(7) simon2stage, p0(0.1) p1(0.5) beta(0.15) admiss maxn(14) minn(7) */ /* 09/06/09 v1.00 The command is born 18/11/09 v1.02 The command is extended to Mata and stopping for efficacy 25/11/09 v1.03 checking some weird results that meant stopping for efficacy was worse! 1/ 2/10 v1.04 Added the return list and added the A&B matrices to the Mata code 11/ 5/10 v1.05 BUG FIX - returned a1 11/11/10 v1.06 Added the option to find the delta-minimax 3/12/10 v1.07 Added admissible design code 19/ 5/11 v1.08 Going to add in the vectorised version to benefit from MATA MP 13/ 1/12 v1.09 Bug on output */ pr simon2stage, rclass version 11.0 syntax [,p0(real 0.1) p1(real 0.4) alpha(real 0.05) beta(real 0.2) MINN(real 1) MAXN(real 35) /* */ OPTIMAL OPTP(real -1) DIsplay(int 200000) EFF NOISE DELTAminimax ADMISS FAST] /******************************************************************** * Argument checking * Although we are now just going to look for the optp * The default optimal probability is set as p0 if there are errors ********************************************************************/ if "`optp'"=="-1" { local optp `p0' local optptxt "p0" } else if `optp'<0 { local optp `p0' local optptxt "p0" } else if `optp'>1 { local optp `p0' local optptxt "p0" } local optptxt: di %4.2f `optp' if `minn'>`maxn' { di "{err} Warning: minn() value should be less than maxn() value" local maxn `minn' } local startmin `minn' if "`deltaminimax'"~="" & "`eff'"=="" { di "{err} Warning: the deltaminimax design is the minimax design when not stopping for efficacy" di "to use the deltaminimax option you must specify the eff option as well" exit(198) } /****************************************************************** * The admissible design if statement ******************************************************************/ if "`admiss'"=="" { /****************************************************************** * This does the optimal or minimax without stopping for efficacy ******************************************************************/ if "`eff'"=="" mata: s2s(`p0', `p1', `optp', `alpha', `beta', `minn', `maxn', "`optimal'", "`noise'", `display') /**************************************************************** * Mata command does the optimal or minimax OR deltaminimax ****************************************************************/ else mata: a2s(`p0', `p1', `optp', `alpha', `beta', `minn', `maxn', "`optimal'", "`noise'", `display', "`deltaminimax'") } else{ if "`fast'"=="" { di di "{err} NOTE: The admiss() option may take a long time" if "`eff'"=="" mata: admisss2s(`p0', `p1', `optp', `alpha', `beta', `minn', `maxn', "`optimal'", "`noise'", `display') else mata: admissa2s(`p0', `p1', `optp', `alpha', `beta', `minn', `maxn', "`optimal'", "`noise'", `display') } else { if "`eff'"=="" mata: vecadmisss2s(`p0', `p1', `optp', `alpha', `beta', `minn', `maxn', "`optimal'", "`noise'", `display') else mata: vecadmissa2s(`p0', `p1', `optp', `alpha', `beta', `minn', `maxn', "`optimal'", "`noise'", `display') } } /******************************************************* * Create the scatter plot from the admissible designs *******************************************************/ if "`admiss'"~="" { cap clear qui svmat grid if "`eff'"=="" qui gen d = "{"+string(grid3)+"/"+string(grid4)+" "+string(grid5)+"/"+string(grid6)+"}" else qui gen d = "{("+string(grid3)+" "+string(grid4)+")/"+string(grid5)+" "+string(grid6)+"/"+string(grid7)+"}" lab var grid1 "q0" lab var grid2 "q1" rename grid1 g1 rename grid2 g2 preserve sort d qui by d:keep if _n==1 forv i=1/`=_N' { local tmp = d[`i'] local leg `"`leg'lab(`i' "`tmp'") "' local g `"`g'(scatter g1 g2 if d=="`tmp'",ms(s) msize(*.75))"' } restore di "NOTE: Just about to create plot of the admissible designs" twoway `g', legend(on cols(1) `leg' ring(0) pos(2)) aspect(1) title(Admissible designs) subtitle("n {&isin}[`minn',`maxn']") /* */ note("({&alpha},{&beta},p0,p1)=(`alpha',`beta',`p0',`p1')") } /************************************************************* * Return the values EN and PET for H0, H1 and Hopt * The A matrix is created at the end of the Mata functions *************************************************************/ if "`admiss'"=="" { return local EN0 = A[1,1] return local EN1 = A[1,2] return local ENo = A[1,3] return local PET0 = A[2,1] return local PET1 = A[2,2] return local PETo = A[2,3] return local r1 = B[1,1] return local n1 = B[1,2] return local r = B[1,3] return local n = B[1,4] if "`eff'"~="" return local a1 = B[1,5] } end /******************************** * Start of MATA commands * ********************************/ mata: /******************************** * The minimum of two numbers ********************************/ real mymin(real scalar a, real scalar b) { if (a=p0\n") printf("{txt}where p0 is {res}%g{txt} and p1 is {res}%g\n\n", p0, p1) printf("{txt}The study is stopped if there are <= r1 responders out of the first n1 participants\n") printf("The null hypothesis is rejected if there are >r responders out of n participants\n") printf("{txt}R(p) is the probability of concluding there is no evidence of a treatment effect\n") printf("PET(p) is the probability of early termination\n") printf("EN(p) is the expected sample size\n\n") printf("{txt}NOTE: this program searches many designs and can take a while to find the best design\n") printf("An occassional design is displayed with The current best design is always displayed\n\n") if (optimal=="") printf("{txt}This algorithm is searching for the {res}minimax {txt}design\n") else printf("{txt}This algorithm is searching for the Optimal design i.e smallest {res}EN(%g)\n", po) printf("{txt}Design {col 17}R(p0) {col 26} R(p1) {col 36}PET(%g){col 46}EN(%g)\n",po, po) currentmin = 10000000000 found = 0 /*************************************** * Check what we are optimising ***************************************/ if (optimal=="optimal") minimax=0 else minimax = 1 n=minn count=1 while(!found) { while(n<=maxn) { for(r=0; r<=n; r++) { for(n1=1; n1<= mymin(n,currentmin); n1++) { for(r1=0; r1<= mymin(r,n1); r1++) { sum0 =0 sum1 =0 sumo =0 for(x=r1+1;x<=mymin(r,n1);x++) { sum0 = sum0+binomialp(n1,x,p0)*binomial(n-n1,r-x,p0) sum1 = sum1+binomialp(n1,x,p1)*binomial(n-n1,r-x,p1) sumo = sumo+binomialp(n1,x,po)*binomial(n-n1,r-x,po) } Rp0 = binomial(n1,r1,p0)+sum0 PETp0 = binomial(n1,r1,p0) ENp0 = PETp0*n1+(1-PETp0)*n Rp1 = binomial(n1,r1,p1)+sum1 PETp1 = binomial(n1,r1,p1) ENp1 = PETp1*n1+(1-PETp1)*n Rpo = binomial(n1,r1,po)+sumo PETpo = binomial(n1,r1,po) ENpo = PETpo*n1+(1-PETpo)*n if ((ENpo= 1-alpha) & (Rp1 <= beta)) { currentmin=ENpo found = 1 printf("{txt} %g/%g %g/%g {res} {col 17}%5.3f {col 26}%5.3f {col 36}%5.3f {col 46}%7.3f {txt}(Best design so far)\n" , r1, n1, r, n, Rp0, Rp1, PETpo, ENpo) mr1=r1 mr=r mn1=n1 mn=n men0 = ENp0 mpetp0 = PETp0 men1 = ENp1 mpetp1 = PETp1 meno = ENpo mpetpo = PETpo mpe1 = Rp0 mpe2 = Rp1 } if (mod(count,display)==0 & count>1) printf("{txt}%g/%g %g/%g {res} {col 17}%5.3f {col 26}%5.3f {col 36}%5.3f {col 46}%7.3f \n", r1, n1, r, n, Rp0, Rp1, PETpo, ENpo) count++ } } } if ((found) & (minimax)) { printf("\n{txt} The minimax design is {res}%g/%g %g/%g\n", mr1, mn1, mr, mn) printf("{txt} Expected sample size is {res} %7.3f\n", meno) printf("{txt} Probability of early termination {res} %5.3f\n", mpetpo) printf("{txt} Probability of type 1 error {res} %5.3f\n", 1-mpe1) printf("{txt} Probability of type 2 error {res} %5.3f\n", mpe2) n=maxn+1 } n++ } if (!found) { minn=maxn maxn++ printf("{err}Increasing n by 1 to %g\n", maxn) displayflush() } } if ((found) & !(minimax)) { printf("\n{txt}The optimal design at p={res}%g{txt} (%g<= n <= %g) {res}%g/%g %g/%g\n", po, minn, maxn, mr1, mn1, mr, mn) printf("{txt} Expected sample size is {res} %7.3f\n", meno) printf("{txt} Probability of early termination {res} %5.3f\n", mpetpo) printf("{txt} Probability of type 1 error {res} %5.3f\n", 1-mpe1) printf("{txt} Probability of type 2 error {res} %5.3f\n", mpe2) } /* Print everything for the best design*/ if (noise=="noise") { printf("\n{txt}EN(p0)= {res}%7.3f\n", men0) printf("{txt}EN(p1)= {res}%7.3f\n", men1) printf("{txt}EN(po)= {res}%7.3f\n", meno) printf("{txt}PET(p0)= {res}%7.3f\n", mpetp0) printf("{txt}PET(p1)= {res}%7.3f\n", mpetp1) printf("{txt}PET(po)= {res}%7.3f\n", mpetpo) } /********************************************************** * Create matrices of results and then pass back to Stata * and then eventually return **********************************************************/ results = ( men0, men1, meno \ mpetp0, mpetp1, mpetpo ) design = (mr1, mn1, mr, mn) st_matrix("A", results) st_matrix("B", design) }/*END of s2s function!*/ /******************************************************** * The ade 2 stage design stopping for efficacy ********************************************************/ void a2s(p0, p1, po, alpha, beta, minn, maxn, optimal, noise, display, deltaminimax) { printf("\n{txt}Simon's Two Stage Design with stopping for Efficacy\n") printf("{dup 51:{c -}}\n") printf("A design is indexed by five values {res}(r1 a1)/n1 r/n\n") printf("{txt}Type I error ={res} %g\n", alpha) printf("{txt}Power ={res} %g\n", 1-beta) printf("{txt}H0: p = p0\n") printf("{txt}H1: p = p1 >=p0\n") printf("{txt}where p0 is {res}%g{txt} and p1 is {res}%g\n\n", p0, p1) printf("{txt}The study is stopped for futility if there are <= r1 responders out of the first n1 participants\n") printf("{txt}The study is stopped for efficacy if there are >a1 responders out of the first n1 participants\n") printf("The null hypothesis is rejected if there are >r responders out of n participants\n") printf("{txt}R(p) is the probability of concluding there is no evidence of a treatment effect\n") printf("PET(p) is the probability of early termination\n") printf("EN(p) is the expected sample size\n\n") printf("{txt}NOTE: this program searches many designs and can take a while to find the best design\n") printf("An occassional design is displayed with The current best design is always displayed\n\n") if (deltaminimax~="") printf("{txt}This algorithm is searching for the {res}delta-minimax {txt}design\n") if ((optimal=="")&(deltaminimax=="")) printf("{txt}This algorithm is searching for the {res}minimax {txt}design\n") else printf("{txt}This algorithm is searching for the Optimal design i.e smallest {res}EN(%g)\n", po) printf("{txt}Design {col 17}R(p0) {col 26} R(p1) {col 36}PET(%g){col 46}EN(%g)\n",po, po) /********************************************************* * Set the smallest expected sample size as a big number * and state we haven't found the best design *********************************************************/ currentmin = 10000000000 found = 0 /***************************************** * Check what we are optimising *****************************************/ if (optimal=="optimal") minimax=0 else minimax = 1 n=minn count=1 while(!found) { /**************************** * loop through every design ****************************/ while(n<=maxn) { for(r=0; r<=n; r++) { for(n1=1; n1<= mymin(n,currentmin); n1++) { for(r1=0; r1<= mymin(r,n1); r1++) { for(r2=r1; r2<= n1; r2++) { /*NOTE: It is possible to have r2>r &r2<=n1 but weird design*/ /**************************************** * Work out the reject H0 probabilities ****************************************/ sum0 =0 sum1 =0 sumo =0 for(x=r1+1;x<=mymin(r2,n1);x++) { sum0 = sum0+binomialp(n1,x,p0)*binomial(n-n1,r-x,p0) sum1 = sum1+binomialp(n1,x,p1)*binomial(n-n1,r-x,p1) sumo = sumo+binomialp(n1,x,po)*binomial(n-n1,r-x,po) } /************************* * THE PETs have changed *************************/ Rp0 = binomial(n1,r1,p0)+sum0 PETp0 = 1-binomial(n1,r2,p0)+binomial(n1,r1,p0) ENp0 = PETp0*n1+(1-PETp0)*n Rp1 = binomial(n1,r1,p1)+sum1 PETp1 = 1-binomial(n1,r2,p1)+binomial(n1,r1,p1) ENp1 = PETp1*n1+(1-PETp1)*n Rpo = binomial(n1,r1,po)+sumo PETpo = 1-binomial(n1,r2,po)+binomial(n1,r1,po) ENpo = PETpo*n1+(1-PETpo)*n EMAXpsi = ( ( (factorial(n1-r2-1))*factorial(r2) )/( factorial(r1)*factorial(n1-r1-1) ) )^(1/(r2-r1)) EMAXp = EMAXpsi/(1+EMAXpsi) PETmax= 1- binomial(n1,r2,EMAXp) + binomial(n1,r1,EMAXp) ENmax = n-(n-n1)*PETmax if (deltaminimax~="") { if ((ENmax= 1-alpha) & (Rp1 <= beta)) { currentmin=ENmax found = 1 printf("{txt}(%g %g)/%g %g/%g {res} {col 17}%5.3f {col 26}%5.3f {col 36}%5.3f {col 46}%7.3f {txt}(Best design so far)\n" , r1, r2, n1, r, n, Rp0, Rp1, PETmax, ENmax) mr1=r1 mr2=r2 mr=r mn1=n1 mn=n men0 = ENp0 mpetp0 = PETp0 men1 = ENp1 mpetp1 = PETp1 meno = ENpo mpetpo = PETpo mpe1 = Rp0 mpe2 = Rp1 } } else { if ((ENpo= 1-alpha) & (Rp1 <= beta)) { currentmin=ENpo found = 1 printf("{txt}(%g %g)/%g %g/%g {res} {col 17}%5.3f {col 26}%5.3f {col 36}%5.3f {col 46}%7.3f {txt}(Best design so far)\n" , r1, r2, n1, r, n, Rp0, Rp1, PETpo, ENpo) mr1=r1 mr2=r2 mr=r mn1=n1 mn=n men0 = ENp0 mpetp0 = PETp0 men1 = ENp1 mpetp1 = PETp1 meno = ENpo mpetpo = PETpo mpe1 = Rp0 mpe2 = Rp1 } } if (mod(count,display)==0 & count>1 ) printf("{txt}(%g %g)/%g %g/%g {res} {col 17}%5.3f {col 26}%5.3f {col 36}%5.3f {col 46}%7.3f \n", r1, r2, n1, r, n, Rp0, Rp1, PETpo, ENpo) count++ } /*r2 loop*/ } /*r1 loop */ } /*n1 loop*/ } /*r loop*/ if ((found) & (minimax)) { printf("\n{txt} The minimax design is {res}(%g %g)/%g %g/%g\n", mr1, mr2, mn1, mr, mn) printf("{txt} Expected sample size is {res} %7.3f\n", meno) printf("{txt} Probability of early termination {res} %5.3f\n", mpetpo) printf("{txt} Probability of type 1 error {res} %5.3f\n", 1-mpe1) printf("{txt} Probability of type 2 error {res} %5.3f\n", mpe2) n=maxn+1 } n++ } /* n loop */ if (!found) { minn=maxn maxn++ printf("{err}Increasing n by 1 to %g\n", maxn) displayflush() } } if ((found) & !(minimax)) { printf("\n{txt}The optimal design at p={res}%g{txt} (%g<= n <= %g) {res}(%g %g)/%g %g/%g\n", po, minn, maxn, mr1, mr2, mn1, mr, mn) printf("{txt} Expected sample size is {res} %7.3f\n", meno) printf("{txt} Probability of early termination {res} %5.3f\n", mpetpo) printf("{txt} Probability of type 1 error {res} %5.3f\n", 1-mpe1) printf("{txt} Probability of type 2 error {res} %5.3f\n", mpe2) } /*Print everything for the best design*/ if (noise=="noise") { printf("\n{txt}EN(p0)= {res}%7.3f\n", men0) printf("{txt}EN(p1)= {res}%7.3f\n", men1) printf("{txt}EN(po)= {res}%7.3f\n", meno) printf("{txt}PET(p0)= {res}%7.3f\n", mpetp0) printf("{txt}PET(p1)= {res}%7.3f\n", mpetp1) printf("{txt}PET(po)= {res}%7.3f\n", mpetpo) } /********************************************************** * Create matrices of results and then pass back to Stata * and then eventually return **********************************************************/ results = ( men0, men1, meno \ mpetp0, mpetp1, mpetpo ) design = (mr1, mn1, mr, mn, mr2) st_matrix("A", results) st_matrix("B", design) }/*END of a2s() function!*/ /******************************************************** * The admiss 2 stage design stopping for efficacy ********************************************************/ void admissa2s(p0, p1, po, alpha, beta, minn, maxn, optimal, noise, display) { printf("\n{txt}Simon's Two Stage Design with stopping for Efficacy\n") printf("{dup 51:{c -}}\n") printf("A design is indexed by five values {res}(r1 a1)/n1 r/n\n") printf("{txt}Type I error ={res} %g\n", alpha) printf("{txt}Power ={res} %g\n", 1-beta) printf("{txt}H0: p = p0\n") printf("{txt}H1: p = p1 >=p0\n") printf("{txt}where p0 is {res}%g{txt} and p1 is {res}%g\n\n", p0, p1) printf("{txt}The study is stopped for futility if there are <= r1 responders out of the first n1 participants\n") printf("{txt}The study is stopped for efficacy if there are >a1 responders out of the first n1 participants\n") printf("The null hypothesis is rejected if there are >r responders out of n participants\n\n") printf("{txt}This algorithm is searching for the set of {res}admissible {txt}designs\n\n") found=0 n=minn count=1 while(!found) { /***************************** * loop through EVERY design *****************************/ while(n<=maxn) { for(r=0; r<=n; r++) { for(n1=1; n1<= n; n1++) { for(r1=0; r1<= mymin(r,n1); r1++) { for(r2=r1; r2<= n1; r2++) { /*NOTE: It is possible to have r2>r &r2<=n1 but weird design*/ /**************************************** * Work out the reject H0 probabilities ****************************************/ sum0 =0 sum1 =0 for(x=r1+1;x<=mymin(r2,n1);x++) { sum0 = sum0+binomialp(n1,x,p0)*binomial(n-n1,r-x,p0) sum1 = sum1+binomialp(n1,x,p1)*binomial(n-n1,r-x,p1) } /************************* * THE PETs have changed *************************/ Rp0 = binomial(n1,r1,p0)+sum0 PETp0 = 1-binomial(n1,r2,p0)+binomial(n1,r1,p0) ENp0 = PETp0*n1+(1-PETp0)*n Rp1 = binomial(n1,r1,p1)+sum1 PETp1 = 1-binomial(n1,r2,p1)+binomial(n1,r1,p1) ENp1 = PETp1*n1+(1-PETp1)*n if ((Rp0 >= 1-alpha) & (Rp1 <= beta)) { /* First design then set up the admissible designs matrix */ if (!found) { admissible = (r1, r2, n1, r, n, ENp0, ENp1) found = 1 } /* If second design then first check it isn't dominated by another admissible design */ else { test = (r1, r2, n1, r, n, ENp0, ENp1) domin =0 for (i=1;i<=rows(admissible);i++) { if ((test[5]>=admissible[i,5])&(test[6]>admissible[i,6])&(test[7]>admissible[i,7])) domin=1 } /* If it isn't dominated then add it to the admissible design matrix BUT NEED to check whether it dominates another design so a little tricky */ if (!domin) { keep=NULL for (i=1;i<=rows(admissible);i++) { if (!((test[5]<=admissible[i,5])&(test[6]1 ) printf("Still searching [until n=%3.0f..] found {res}%2.0f {txt}potential designs (current n=%3.0f n1=%3.0f)\n", maxn, rows(admissible), n, n1) count++ } /*r2 loop*/ } /*r1 loop */ } /*n1 loop*/ } /*r loop*/ n++ } /* n loop */ if (!found) { minn=maxn maxn++ printf("{err}MAXN too low .. Increasing n by 1 to %g\n", maxn) displayflush() } } /********************************************************** * Need to then go through a grid of values to find the * admissible designs **********************************************************/ printf("\nNOTE: Creating the matrix that contains the admissible designs\n") grid=NULL gstep = 0.0075 i=0 do { if (i==0) j=gstep else j=0 do { sum = (1-i-j):*admissible[,5]+i:*admissible[,6]+j:*admissible[,7] minindex(sum,1,a,b) if (grid==NULL) grid = i,j, admissible[a,], sum[a] else grid = grid \ (i,j, admissible[a,], sum[a]) j=j+gstep } while (i+j<=1) i=i+gstep } while (i<=1) /********************************************************** * Create matrices of results and then pass back to Stata * and then eventually return **********************************************************/ st_matrix("grid", grid) st_matrix("admissible", admissible) }/*END of admiss2s() function!*/ /******************************************************** * All the calculations needed for the binomial sums ********************************************************/ void admisss2s(p0, p1, po, alpha, beta, minn, maxn, optimal, noise , display) { printf("\n{txt}Simon's Two Stage Design\n") printf("{dup 24:{c -}}\n") printf("A design is indexed by four values {res} r1/n1 r/n \n") printf("{txt}Type I error ={res} %g\n", alpha) printf("{txt}Power ={res} %g\n", 1-beta) printf("{txt}H0: p = p0\n") printf("{txt}H1: p = p1 >=p0\n") printf("{txt}where p0 is {res}%g{txt} and p1 is {res}%g\n\n", p0, p1) printf("{txt}The study is stopped if there are <= r1 responders out of the first n1 participants\n") printf("The null hypothesis is rejected if there are >r responders out of n participants\n") printf("{txt}This algorithm is searching for the {res}admissible {txt}designs\n") found = 0 n=minn count=1 while(!found) { while(n<=maxn) { for(r=0; r<=n; r++) { for(n1=1; n1<= n; n1++) { for(r1=0; r1<= mymin(r,n1); r1++) { sum0 =0 sum1 =0 for(x=r1+1;x<=mymin(r,n1);x++) { sum0 = sum0+binomialp(n1,x,p0)*binomial(n-n1,r-x,p0) sum1 = sum1+binomialp(n1,x,p1)*binomial(n-n1,r-x,p1) } Rp0 = binomial(n1,r1,p0)+sum0 PETp0 = binomial(n1,r1,p0) ENp0 = PETp0*n1+(1-PETp0)*n Rp1 = binomial(n1,r1,p1)+sum1 PETp1 = binomial(n1,r1,p1) ENp1 = PETp1*n1+(1-PETp1)*n if ((Rp0 >= 1-alpha) & (Rp1 <= beta)) { /* First design then set up the admissible designs matrix */ if (!found) { admissible = (r1, n1, r, n, ENp0, ENp1) found = 1 } /* If second design then first check it isn't dominated by another admissible design */ else { test = (r1, n1, r, n, ENp0, ENp1) domin =0 for (i=1;i<=rows(admissible);i++) { if ((test[4]>=admissible[i,4])&(test[5]>admissible[i,5])&(test[6]>admissible[i,6])) domin=1 } /* If it isn't dominated then add it to the admissible design matrix BUT NEED to check whether it dominates another design so a little tricky */ if (!domin) { keep=NULL for (i=1;i<=rows(admissible);i++) { if (!((test[4]<=admissible[i,4])&(test[5]1 ) printf("Still searching [until n=%3.0f..] found {res}%2.0f {txt}potential designs (current n=%3.0f n1=%3.0f)\n", maxn, rows(admissible), n, n1) count++ } } } n++ } if (!found) { minn=maxn maxn++ printf("{err}MAXN() too low! increasing n by 1 to %g\n", maxn) displayflush() } } /********************************************************** * Need to then go through a grid of values to find the * admissible designs **********************************************************/ printf("\nNOTE: Creating the matrix that contains the admissible designs\n") grid=NULL gstep = 0.0075 i=0 do { if (i==0) j=gstep else j=0 do { sum = (1-i-j):*admissible[,4]+i:*admissible[,5]+j:*admissible[,6] minindex(sum,1,a,b) if (grid==NULL) grid = i,j, admissible[a,], sum[a] else grid = grid \ (i,j, admissible[a,], sum[a]) j=j+gstep } while (i+j<=1) i=i+gstep } while (i<=1) /********************************************************** * Create matrices of results and then pass back to Stata * and then eventually return **********************************************************/ st_matrix("grid", grid) st_matrix("admissible", admissible) }/*END of admisss2s function!*/ /******************************************************** * All the calculations needed for the binomial sums ********************************************************/ void vecadmisss2s(p0, p1, po, alpha, beta, minn, maxn, optimal, noise , display) { printf("\n{txt}Simon's Two Stage Design\n") printf("{dup 24:{c -}}\n") printf("A design is indexed by four values {res} r1/n1 r/n \n") printf("{txt}Type I error ={res} %g\n", alpha) printf("{txt}Power ={res} %g\n", 1-beta) printf("{txt}H0: p = p0\n") printf("{txt}H1: p = p1 >=p0\n") printf("{txt}where p0 is {res}%g{txt} and p1 is {res}%g\n\n", p0, p1) printf("{txt}The study is stopped if there are <= r1 responders out of the first n1 participants\n") printf("The null hypothesis is rejected if there are >r responders out of n participants\n") printf("{txt}This algorithm is searching for the {res}admissible {txt}designs\n") /******************************************************* * Now to create a loop vector of all possibilities *******************************************************/ nd = maxn*maxn*maxn*maxn loop = (0::nd-1) n1=mod(loop,maxn+1) loop = (loop:-mod(loop,maxn+1) ) :/ (maxn+1) r1=mod(loop,maxn+1) loop = (loop:-mod(loop,maxn+1) ) :/ (maxn+1) n2=mod(loop,maxn+1) loop = (loop:-mod(loop,maxn+1) ) :/ (maxn+1) r2=mod(loop,maxn+1) loop = (loop:-mod(loop,maxn+1) ) :/ (maxn+1) r=r1+r2 n=n1+n2 design = r1, n1, r, n, r2, n2 design design = select(design, n1= 1-alpha) & (Rp1 <= beta)) { /* First design then set up the admissible designs matrix */ if (!found) { admissible = (r1, n1, r, n, ENp0, ENp1) found = 1 } /* If second design then first check it isn't dominated by another admissible design */ else { test = (r1, n1, r, n, ENp0, ENp1) domin =0 for (i=1;i<=rows(admissible);i++) { if ((test[4]>=admissible[i,4])&(test[5]>admissible[i,5])&(test[6]>admissible[i,6])) domin=1 } /* If it isn't dominated then add it to the admissible design matrix BUT NEED to check whether it dominates another design so a little tricky */ if (!domin) { keep=NULL for (i=1;i<=rows(admissible);i++) { if (!((test[4]<=admissible[i,4])&(test[5]1 ) printf("Still searching [until n=%3.0f..] found {res}%2.0f {txt}potential designs (current n=%3.0f n1=%3.0f)\n", maxn, rows(admissible), n, n1) count++ } } } n++ } if (!found) { minn=maxn maxn++ printf("{err}MAXN() too low! increasing n by 1 to %g\n", maxn) displayflush() } } /********************************************************** * Need to then go through a grid of values to find the * admissible designs **********************************************************/ printf("\nNOTE: Creating the matrix that contains the admissible designs\n") grid=NULL gstep = 0.0075 i=0 do { if (i==0) j=gstep else j=0 do { sum = (1-i-j):*admissible[,4]+i:*admissible[,5]+j:*admissible[,6] minindex(sum,1,a,b) if (grid==NULL) grid = i,j, admissible[a,], sum[a] else grid = grid \ (i,j, admissible[a,], sum[a]) j=j+gstep } while (i+j<=1) i=i+gstep } while (i<=1) /********************************************************** * Create matrices of results and then pass back to Stata * and then eventually return **********************************************************/ st_matrix("grid", grid) st_matrix("admissible", admissible) }/*END of vecadmisss2s function!*/ end /* this is the END OF MATA!*/