*! Author(s) : Michael J Grayling *! Date : 31 Jan 2019 *! Version : 0.9 /* Version history: 31/01/19 v0.9 Initial version complete. */ /* To do list: - Add option for plotting. */ program define des_dtl, rclass version 15.0 syntax , [Kv(numlist) ALPha(real 0.05) Beta(real 0.2) DELta(real 0.5) /// delta0(real 0) sd(real 1) RATio(real 1) NO_sample_size /// n_start(integer 1) n_stop(integer -1)] preserve ///// Check input variables //////////////////////////////////////////////////// local lenkv:list sizeof kv if (`lenkv' == 1) { di "{error}The number of experimental treatments in each stage (kv) must be a" di " numlist of length greater than 1." exit(198) } else if (`lenkv' > 0) { local kviold:word 1 of `kv' if ((`kviold' <= 1) | (mod(`kviold', 1) != 0)) { di "{error}The number of experimental treatments in each stage (kv) must be" di " a strictly monotonically decreasing numlist of length greater than 1, " di "containing only positive integers, with final element equal to 1." exit(198) } forvalues i = 2/`lenkv' { local kvinew:word `i' of `kv' if ((`kvinew' <= 0) | (`kvinew' >= `kviold') | (mod(`kvinew', 1) != 0)) { di "{error}The number of experimental treatments in each stage (kv) must " di "be a strictly monotonically decreasing numlist of length greater than" di " 1, containing only positive integers, with final element equal to 1." exit(198) } local kviold `kvinew' } if (`kviold' != 1) { di "{error}The number of experimental treatments in each stage (kv) must be" di " a strictly monotonically decreasing numlist of length greater than 1, " di "containing only positive integers, with final element equal to 1." exit(198) } } if ((`alpha' <= 0) | (`alpha' >= 1)) { di "{error}The desired familywise error-rate (alpha) must be a real strictly " di "between 0 and 1." exit(198) } if ((`beta' <= 0) | (`beta' >= 1)) { di "{error}The desired type-II error-rate (beta) must be a real strictly " di "between 0 and 1." exit(198) } if (`delta' <= 0) { di "{error}The interesting treatment effect (delta) must be a real strictly" di " greater than 0." exit(198) } if (`sd' <= 0) { di "{error}The assumed value of the standard deviation of the responses (sd) " di "must be a real strictly greater than 0." exit(198) } if (`ratio' <= 0) { di "{error}The allocation ratio between the experimental arms and the control" di "arm (ratio) must be a real strictly greater than 0." exit(198) } if (`n_start' < 1) { di "{error}The starting value in the search for the required stage-wise group" di " size (n_start) must be an integer greater than or equal to 1." exit(198) } if ((`n_stop' != -1) & (`n_stop' < `n_start')) { di "{error}The stopping value in the search for the required stage-wise group" di " size (n_stop) must either be equal to -1 or be an integer greater than " di "or equal to n_start." exit(198) } if (`delta0' >= `delta') { di "WARNING: The uninteresting treatment effect (delta0) should in general be" di "strictly smaller than the interesting treatment effect (delta)." } if ("`no_sample_size'" != "") { if (`beta' != 0.2) { di "WARNING: beta has been changed from default but this will have no " di "effect given the choice of no_sample_size." } if (`delta' != 0.5) { di "WARNING: delta has been changed from default but this will have no " di "effect given the choice of no_sample_size." } if (`delta0' != 0) { di "WARNING: delta0 has been changed from default but this will have no " di "effect given the choice of no_sample_size." } if ("`separate'" != "") { di "WARNING: separate has been changed from default but this will have no " di "effect given the choice of no_sample_size." } if (`n_start' != 1) { di "WARNING: n_start has been changed from default but this will have no " di "effect given the choice of no_sample_size." } if (`n_stop' != -1) { di "WARNING: n_stop has been changed from default but this will have no " di "effect given the choice of no_sample_size." } } ///// Perform main computations //////////////////////////////////////////////// if (`lenkv' > 0) { local matakv "" foreach i of local kv { if "`matakv'" == "" local matakv "`i'" else local matakv "`matakv',`i'" } mat kv = (`matakv') } else { mat kv = (3, 1) } mata: des_dtl_void(`alpha', `beta', `delta', `delta0', `sd', `ratio', /// "`no_sample_size'", `n_start', `n_stop') ///// Output /////////////////////////////////////////////////////////////////// return scalar N = opchar[1, 3] return scalar P_LFC = opchar[1, 2] return scalar P_HG = opchar[1, 1] return scalar n = n[1, 1] return scalar u = u[1, 1] restore end ///// Mata ///////////////////////////////////////////////////////////////////// mata: void des_dtl_void(real scalar alpha, real scalar beta, real scalar delta, real scalar delta0, real scalar sd, real scalar ratio, string no_sample_size, real scalar n_start, real scalar n_stop) { Kv = st_matrix("kv") J = length(Kv) printf("{txt}{dup 43:{c -}}\n") printf("{inp}%g{txt}-stage {inp}%g{txt}-experimental treatment DTL design", J, Kv[1]) printf("\n{dup 43:{c -}}\n") printf("The hypotheses to be tested will be:\n\n") if (Kv[1] == 1) { printf(" H1: τ{inp}1{txt} = μ1 - μ0 ≤ 0.\n\n") } else if (Kv[1] == 2) { printf(" Hk: τk = μk - μ0 ≤ 0, k = 1, {inp}2{txt}.\n\n") } else if (Kv[1] == 3) { printf(" Hk: τk = μk - μ0 ≤ 0, k = 1, 2, {inp}3{txt}.\n\n") } else { printf(" Hk: τk = μk - μ0 ≤ 0, k = 1, ..., {inp}%g{txt}.\n\n", Kv[1]) } printf("The stopping boundaries will be determined to control the ") printf("familywise error-rate\nunder the global null hypothesis, HG, ") printf("given by:\n\n") if (Kv[1] == 1) { printf(" HG: τ{inp}1{txt} = 0.\n\n") } else if (Kv[1] == 2) { printf(" HG: τ1 = τ{inp}2{txt} = 0.\n\n") } else if (Kv[1] == 3) { printf(" HG: τ1 = τ2 = τ{inp}3{txt} = 0.\n\n") } else { printf(" HG: τ1 = ... = τ{inp}%g{txt} = 0.\n\n", Kv[1]) } printf("Specifically, if P_HA() is the power function for rejecting any null") printf(" hypothesis,\nthe stopping boundaries will be chosen such that:\n\n") printf(" P_HA(HG) ≤ α = {inp}%g{txt}.\n\n", alpha) if (no_sample_size == "") { printf("The required sample size will be determined to control the type-II") printf(" error-rate\nunder the least favourable configuration, LFC, given ") printf("by:\n\n") if (Kv[1] == 1) { printf(" LFC: τ{inp}1{txt} = δ = %g.\n\n", delta) } else if (Kv[1] == 2) { printf(" LFC: τ1 = δ = {inp}%g{txt}, τ{inp}2{txt} = δ0 = ", delta) printf("{inp}%g{txt}.\n\n", delta0) } else if (Kv[1] == 3) { printf(" LFC: τ1 = δ = {inp}%g{txt}, τ2 = τ{inp}3{txt} = δ0 = ", delta) printf("{inp}%g{txt}.\n\n", delta0) } else { printf(" LFC: τ1 = δ = {inp}%g{txt}, τ2 = ... = τ{inp}%g{txt} = ", delta, Kv[1]) printf("δ0 = {inp}%g{txt}.\n\n", delta0) } printf("Specifically, if P_H1() is the power function for rejecting H1, ") printf("the sample size\nwill be chosen such that:\n\n") printf(" P_H1(LFC) ≥ 1 - β = 1 - {inp}%g{txt}.\n\n", beta) } else { printf("The required sample size will not be determined.\n\n") } printf("The stage-wise allocation ratio between the (remaining) experimental") printf(" arms and\nthe shared control arm, ratio, will be: {inp}%g{txt}.\n\n", ratio) printf("The number of experimental treatments present in stages 1 through ") printf("{inp}%g{txt} will be:\n\n", J) for (j = 1; j <= J; j++) { if (j == 1) { printf("{inp}(%g, ", Kv[j]) } else if ((j > 1) & (j < J)) { printf("%g, ", Kv[j]) } else { printf("%g){txt}.\n\n", Kv[j]) } } printf("Now determining the final-stage rejection boundary.\n\n") JK = J*Kv[1] Lambda = J(JK, JK, 0) add = ratio/(ratio + 1) minus = 1 - add I_K = I(Kv[1]) Lambda_j = J(Kv[1], Kv[1], add) + I_K*minus for (j = 1; j <= J; j++) { index_range = (1 + (j - 1)*Kv[1])::(j*Kv[1]) Lambda[index_range, index_range] = Lambda_j } for (j1 = 1; j1 <= J; j1++) { for (j2 = 1; j2 <= j1 - 1; j2++) { range_j1 = (1 + (j1 - 1)*Kv[1])::(j1*Kv[1]) range_j2 = (1 + (j2 - 1)*Kv[1])::(j2*Kv[1]) Lambda[range_j2, range_j1] = Lambda[range_j1, range_j2] = sqrt(j2/j1)*Lambda_j } } rej = lowertriangle(J(Kv[J], Kv[J], 1), .) outcomes = (J(Kv[J], 1, (1::Kv[1])'), rej, J(Kv[J], 2, 0)) conditions = sum(Kv[1::(J - 1)]) - (J - 1) + Kv[J] + (Kv[J] > 1)*(Kv[J] - 1) A = J(conditions, JK, 0) counter = 1 for (j = 1; j <= J - 1; j++) { dropped = Kv[j]::(Kv[j + 1] + 1) if (length(dropped) > 1) { for (cond = 1; cond <= Kv[j] - Kv[j + 1] - 1; cond++) { A[counter, Kv[1]*(j - 1) + which_condition(outcomes[1, 1::Kv[1]], "e", dropped[cond + 1])] = 1 A[counter, Kv[1]*(j - 1) + which_condition(outcomes[1, 1::Kv[1]], "e", dropped[cond])] = -1 counter = counter + 1 } } continued = Kv[j + 1]::1 for (cond = 1; cond <= Kv[j + 1]; cond++) { A[counter, Kv[1]*(j - 1) + which_condition(outcomes[1, 1::Kv[1]], "e", continued[cond])] = 1 A[counter, Kv[1]*(j - 1) + which_condition(outcomes[1, 1::Kv[1]], "e", dropped[length(dropped)])] = -1 counter = counter + 1 } } if (Kv[J] > 1) { for (cond = 1; cond <= Kv[J] - 1; cond++) { A[counter, Kv[1]*(J - 1) + which_condition(outcomes[1, 1::Kv[1]], "e", Kv[J] - cond)] = 1 A[counter, Kv[1]*(J - 1) + which_condition(outcomes[1, 1::Kv[1]], "e", Kv[J] - cond + 1)] = -1 counter = counter + 1 } } for (k = 1; k <= Kv[J]; k++) { A[counter, (J - 1)*Kv[1] + which_condition(outcomes[1, 1::Kv[1]], "e", k)] = 1 counter = counter + 1 } means_HG = lowers = J(conditions, 1, 0) means_LFC = A*(vec(J(J, 1, (delta \ J(Kv[1] - 1, 1, delta0)))):* sqrt(vec(J(1, Kv[1], (1/(sd^2 + sd^2/ratio))*(1::J))'))) Lambda = A*Lambda*(A') uppers = J(conditions, 1, .) u = brent_root_u(Kv, alpha, J, outcomes, lowers', uppers', means_HG', Lambda, conditions)[1] printf("Final-stage rejection boundary, u, determined to be: ") printf("{res}%g{txt}.\n\n", round(u, 0.01)) if (no_sample_size == "") { printf("Now determining the required sample size.\n\n") if (n_stop = -1) { q = invmvnormal_mata(1 - alpha, J(1, Kv[1], 0), Lambda_j, "lower", 100, 1e-4, "pmvnormal", 12, 1000)[1] n_stop = ceil((sd*(q*sqrt(1 + 1/ratio) + invnormal(1 - beta)*sqrt(1 + 1/ratio))/delta)^2) while (mod(ratio*n_stop, 1) != 0) { n_stop = n_stop + 1 } if (n_stop < n_start) { printf("{err}Computed value of n_stop is smaller than the specified ") printf("value of n_start.\n") exit(198) } } power_check = 0 n = n_start while (mod(ratio*n, 1) != 0) { n = n + 1 } while ((power_check == 0) & (n <= n_stop)) { power_check = (dtl_find_n(n, Kv, beta, J, outcomes, lowers, uppers, means_LFC, Lambda, conditions, u) < 0) n = n + 1 while (mod(ratio*n, 1) != 0) { n = n + 1 } } if (n > n_stop) { printf("{err}The group size was limited by n_stop. Consider increasing") printf(" its value and re-running des_mams.") exit(198) } if (n == n_start) { printf("WARNING: The required power was met with n_start. Considering ") printf("decreasing its value and re-running des_dtl.") } n = n - 1 while (mod(ratio*n, 1) != 0) { n = n - 1 } printf("Required stage-wise group size in the control arm, n, determined ") printf("to be: {res}%g{txt}.\n\n", n) opchar = (dtl_opchar(n, Kv, J, outcomes, lowers, uppers, means_HG, means_LFC, Lambda, conditions, u), n*(J + sum(Kv))) printf("The operating characteristics of the design are:\n\n") printf(" r() | Variable\n") printf(" {dup 5:{c -}} {dup 8:{c -}}\n") printf(" P_HG | P_HA(HG) = {res}%g{txt},\n", round(opchar[1], .001)) printf(" P_LFC | P_H1(LFC) = {res}%g{txt},\n", round(opchar[2], .001)) printf(" N | N = {res}%g{txt}.\n", opchar[3]) } else { n = . opchar = J(1, 3, .) } st_matrix("n", n) st_matrix("u", u) st_matrix("opchar", opchar) } real colvector brent_root_u(real vector Kv, real scalar alpha, real scalar J, real matrix outcomes, real vector lowers, real vector uppers, real vector means_HG, real matrix Lambda, real scalar conditions) { max_iter = 100 half_tol = 5e-5 a = 0 b = 5 fa = dtl_find_u(a, Kv, alpha, J, outcomes, lowers, uppers, means_HG, Lambda, conditions) fb = dtl_find_u(b, Kv, alpha, J, outcomes, lowers, uppers, means_HG, Lambda, conditions) if (((fa > 0) & (fb > 0)) | ((fa < 0) & (fb < 0))) { return((. \ . \ 2 \ 0)) } c = b fc = fb for (iter = 1; iter <= max_iter; iter++) { if (((fb > 0) & (fc > 0)) | ((fb < 0) & (fc < 0))) { c = a fc = fa d = b - a e = d } if (abs(fc) < abs(fb)) { a = b b = c c = a fa = fb fb = fc fc = fa } tol1 = 6e-8*abs(b) + half_tol xm = 0.5*(c - b) if ((abs(xm) <= tol1) | (fb == 0)) { return((b \ fb \ 0 \ iter)) } if ((abs(e) >= tol1) & (abs(fa) > abs(fb))) { s = fb/fa if (a == c) { p = 2*xm*s q = 1 - s } else { q = fa/fc r = fb/fc p = s*(2*xm*q*(q - r) - (b - a)*(r - 1)) q = (q - 1)*(r - 1)*(s - 1) } if (p > 0) { q = -q } p = abs(p) if (2*p < min((3*xm*q - abs(tol1*q), abs(e*q)))) { e = d d = p/q } else { e = d = xm } } else { e = d = xm } a = b fa = fb if (abs(d) > tol1) { b = b + d } else { b = b + tol1*sign(xm) } fb = dtl_find_u(b, Kv, alpha, J, outcomes, lowers, uppers, means_HG, Lambda, conditions) } return((b \ fb \ 1 \ max_iter)) } real scalar dtl_find_u(real scalar u, real vector Kv, real scalar alpha, real scalar J, real matrix outcomes, real vector lowers, real vector uppers, real vector means_HG, real matrix Lambda, real scalar conditions) { Lambda_old = Lambda for (i = 1; i <= Kv[J]; i++) { lowers_i = lowers uppers_i = uppers for (k = 1; k <= Kv[J]; k++) { if (outcomes[i, Kv[1] + k] == 1) { lowers_i[conditions - Kv[J] + k] = u } else { lowers_i[conditions - Kv[J] + k] = . uppers_i[conditions - Kv[J] + k] = u } } outcomes[i, Kv[1] + Kv[J] + 1] = pmvnormal_mata(lowers_i, uppers_i, means_HG, Lambda[1::conditions, 1::conditions], 12, 1000, 3)[1] Lambda = Lambda_old } return(alpha - factorial(Kv[1])*sum(outcomes[, Kv[1] + Kv[J] + 1])) } real scalar dtl_find_n(real scalar n, real vector Kv, real scalar beta, real scalar J, real matrix outcomes, real matrix lowers, real matrix uppers, real vector means_LFC, real matrix Lambda, real scalar conditions, real scalar u) { Lambda_old = Lambda for (i = 1; i <= Kv[J]; i++) { lowers_i = lowers uppers_i = uppers for (k = 1; k <= Kv[J]; k++) { if (outcomes[i, Kv[1] + k] == 1) { lowers_i[conditions - Kv[J] + k] = u } else { lowers_i[conditions - Kv[J] + k] = . uppers_i[conditions - Kv[J] + k] = u } } outcomes[i, Kv[1] + Kv[J] + 2] = pmvnormal_mata(lowers_i, uppers_i, sqrt(n)*means_LFC, Lambda[1::conditions, 1::conditions], 12, 1000, 3)[1] Lambda = Lambda_old } return((1 - beta) - factorial(Kv[1] - 1)*sum(outcomes[, Kv[1] + Kv[J] + 2])) } real vector dtl_opchar(real scalar n, real vector Kv, real scalar J, real matrix outcomes, real matrix lowers, real matrix uppers, real vector means_HG, real vector means_LFC, real matrix Lambda, real scalar conditions, real scalar u) { Lambda_old = Lambda for (i = 1; i <= Kv[J]; i++) { lowers_i = lowers uppers_i = uppers for (k = 1; k <= Kv[J]; k++) { if (outcomes[i, Kv[1] + k] == 1) { lowers_i[conditions - Kv[J] + k] = u } else { lowers_i[conditions - Kv[J] + k] = . uppers_i[conditions - Kv[J] + k] = u } } lowers_i_old = lowers_i uppers_i_old = uppers_i Lambda = Lambda_old outcomes[i, Kv[1] + Kv[J] + 1] = pmvnormal_mata(lowers_i, uppers_i, means_HG, Lambda[1::conditions, 1::conditions], 12, 1000, 3)[1] Lambda = Lambda_old lowers_i = lowers_i_old uppers_i = uppers_i_old outcomes[i, Kv[1] + Kv[J] + 2] = pmvnormal_mata(lowers_i, uppers_i, sqrt(n)*means_LFC, Lambda[1::conditions, 1::conditions], 12, 1000, 3)[1] } Lambda = Lambda_old return((factorial(Kv[1])*sum(outcomes[, Kv[1] + Kv[J] + 1]), factorial(Kv[1] - 1)*sum(outcomes[, Kv[1] + Kv[J] + 2]))) } real colvector invmvnormal_mata(real scalar p, real vector mean, real matrix Sigma, string tail, real scalar max_iter, real scalar tolerance, string integrator, real scalar shifts, real scalar samples) { if ((p == 0) | (p == 1)) { return((. \ 0 \ 0 \ 0 \ 0)) } else { if (rows(Sigma) == 1) { if (tail == "upper") { p = 1 - p } else if (tail == "both") { p = 0.5 + 0.5*p } return((invnormal(p) + mean \ 0 \ 0 \ 0 \ 0)) } else { if (tail == "both") { a = 10^-6 } else { a = -10 } b = 10 fa = invmvnormal_mata_int(a, p, mean, Sigma, tail, integrator, shifts, samples) if (fa == 0) { return((a \ 0 \ 0 \ 0 \ 0)) } fb = invmvnormal_mata_int(b, p, mean, Sigma, tail, integrator, shifts, samples) if (fb == 0) { return((b \ 0 \ 0 \ 0 \ 0)) } if (tail == "both") { while ((fa > 0) & (a >= 10^-20)) { a = a/2 fa = invmvnormal_mata_int(a, p, mean, Sigma, tail, integrator, shifts, samples) } while ((fb < 0) & (b <= 10^6)) { b = 2*b fb = invmvnormal_mata_int(b, p, mean, Sigma, tail, integrator, shifts, samples) } } else { while ((((fa > 0) & (fb > 0)) | ((fa < 0) & (fb < 0))) & (a >= -10^6)) { a = 2*a b = 2*b fa = invmvnormal_mata_int(a, p, mean, Sigma, tail, integrator, shifts, samples) fb = invmvnormal_mata_int(b, p, mean, Sigma, tail, integrator, shifts, samples) } } if (fa == 0) { return((a \ 0 \ 0 \ 0 \ 0)) } else if (fb == 0) { return((b \ 0 \ 0 \ 0 \ 0)) } else if (((fa < 0) & (fb > 0)) | ((fa > 0) & (fb < 0))) { half_tol = 0.5*tolerance c = b fc = fb for (iter = 1; iter <= max_iter; iter++) { if (((fb > 0) & (fc > 0)) | ((fb < 0) & (fc < 0))) { c = a fc = fa d = b - a e = d } if (abs(fc) < abs(fb)) { a = b b = c c = a fa = fb fb = fc fc = fa } tol1 = 6e-8*abs(b) + half_tol xm = 0.5*(c - b) if ((abs(xm) <= tol1) | (fb == 0)) { return((b \ abs(0.5*(b - a)) \ 0 \ fb \ iter)) } if ((abs(e) >= tol1) & (abs(fa) > abs(fb))) { s = fb/fa if (a == c) { pi = 2*xm*s q = 1 - s } else { q = fa/fc r = fb/fc pi = s*(2*xm*q*(q - r) - (b - a)*(r - 1)) q = (q - 1)*(r - 1)*(s - 1) } if (pi > 0) { q = -q } pi = abs(pi) if (2*pi < min((3*xm*q - abs(tol1*q), abs(e*q)))) { e = d d = pi/q } else { e = d = xm } } else { e = d = xm } a = b fa = fb if (abs(d) > tol1) { b = b + d } else { b = b + tol1*sign(xm) } fb = invmvnormal_mata_int(b, p, mean, Sigma, tail, integrator, shifts, samples) } return((b \ abs(0.5*(b - a)) \ 1 \ fb \ iter)) } else { return((. \ . \ 2 \ . \ .)) } } } } real scalar invmvnormal_mata_int(real scalar q, real scalar p, real vector mean, real matrix Sigma, string tail, string integrator, real scalar shifts, real scalar samples) { k = rows(Sigma) if (tail == "lower") { a = J(1, k, .) b = J(1, k, q) } else if (tail == "upper") { a = J(1, k, q) b = J(1, k, .) } else { a = J(1, k, -q) b = J(1, k, q) } if (integrator != "mvnormal") { return(pmvnormal_mata(a, b, mean, Sigma[1::k, 1::k], shifts, samples, 3)[1] - p) } else { for (i = 1; i <= k; i++) { if (a[i] == .) { a[i] = -8e307 } if (b[i] == .) { b[i] = 8e307 } } return(mvnormalcv(a, b, mean, vech(Sigma)') - p) } } real colvector pmvnormal_mata(real vector lower, real vector upper, real vector mean, real matrix Sigma, real scalar shifts, real scalar samples, real scalar alpha) { k = rows(Sigma) if (k == 1) { if ((lower == .) & (upper == .)) { I = 1 } else if ((lower != .) & (upper == .)) { I = 1 - normal((lower - mean)/sqrt(Sigma)) } else if ((lower == .) & (upper != .)) { I = normal((upper - mean)/sqrt(Sigma)) } else { sqrt_Sigma = sqrt(Sigma) I = normal((upper - mean)/sqrt_Sigma) - normal((lower - mean)/sqrt_Sigma) } E = 0 } else if (k == 2) { if (lower[1] == .) lower[1] = -8e307 if (lower[2] == .) lower[2] = -8e307 if (upper[1] == .) upper[1] = 8e307 if (upper[2] == .) upper[2] = 8e307 sqrt_Sigma = sqrt((Sigma[1, 1], Sigma[2, 2])) a = (lower - mean):/(sqrt_Sigma[1], sqrt_Sigma[2]) b = (upper - mean):/(sqrt_Sigma[1], sqrt_Sigma[2]) r = Sigma[1, 2]/(sqrt_Sigma[1]*sqrt_Sigma[2]) I = binormal(b[1], b[2], r) + binormal(a[1], a[2], r) - binormal(b[1], a[2], r) - binormal(a[1], b[2], r) E = 0 } else { a = lower - mean b = upper - mean C = J(k, k, 0) zero_k_min_2 = J(1, k - 2, 0) zero_k_min_1 = (zero_k_min_2, 0) y = zero_k_min_1 atilde = (a[1], zero_k_min_2) btilde = (b[1], zero_k_min_2) sqrt_Sigma11 = sqrt(Sigma[1, 1]) args = J(1, k, 1) for (j = 1; j <= k; j++) { if ((a[j] != .) & (b[j] != .)) { args[j] = normal(b[j]/sqrt_Sigma11) - normal(a[j]/sqrt_Sigma11) } else if ((a[j] == .) & (b[j] != .)) { args[j] = normal(b[j]/sqrt_Sigma11) } else if ((b[j] == .) & (a[j] != .)) { args[j] = 1 - normal(a[j]/sqrt_Sigma11) } } ii = ww = . minindex(args, 1, ii, ww) if (ii[1] != 1) { tempa = a tempb = b tempa[1] = a[ii[1]] tempa[ii[1]] = a[1] a = tempa tempb[1] = b[ii[1]] tempb[ii[1]] = b[1] b = tempb tempSigma = Sigma tempSigma[1, ] = Sigma[ii[1], ] tempSigma[ii[1], ] = Sigma[1, ] Sigma = tempSigma Sigma[, 1] = tempSigma[, ii[1]] Sigma[, ii[1]] = tempSigma[, 1] C[1, 1] = sqrt(Sigma[1, 1]) C[2::k, 1] = Sigma[2::k, 1]/C[1, 1] } else { C[, 1] = (sqrt_Sigma11 \ Sigma[2::k, 1]/sqrt_Sigma11) } if (atilde[1] != btilde[1]) { y[1] = (normalden(atilde[1]) - normalden(btilde[1]))/ (normal(btilde[1]) - normal(atilde[1])) } for (i = 2; i <= k - 1; i++) { args = J(1, k - i + 1, 1) i_vec = 1::(i - 1) for (j = 1; j <= k - i + 1; j++) { s = j + i - 1 if ((a[s] != .) & (b[s] != .)) { Cy = sum(C[s, i_vec]:*y[i_vec]) denom = sqrt(Sigma[s, s] - sum(C[s, i_vec]:^2)) args[j] = normal((b[s] - Cy)/denom) - normal((a[s] - Cy)/denom) } else if ((a[s] == .) & (b[s] != .)) { args[j] = normal((b[s] - sum(C[s, i_vec]:*y[i_vec]))/ sqrt(Sigma[s, s] - sum(C[s, i_vec]:^2))) } else if ((b[s] == .) & (a[s] != .)) { args[j] = 1 - normal((a[s] - sum(C[s, i_vec]:*y[i_vec]))/ sqrt(Sigma[s, s] - sum(C[s, i_vec]:^2))) } } ii = ww = . minindex(args, 1, ii, ww) m = i - 1 + ii[1] if (i != m) { tempa = a tempb = b tempa[i] = a[m] tempa[m] = a[i] a = tempa tempb[i] = b[m] tempb[m] = b[i] b = tempb tempSigma = Sigma tempSigma[i, ] = Sigma[m, ] tempSigma[m, ] = Sigma[i, ] Sigma = tempSigma Sigma[, i] = tempSigma[, m] Sigma[, m] = tempSigma[, i] tempC = C tempC[i, ] = C[m, ] tempC[m, ] = C[i, ] C = tempC C[, i] = tempC[, m] C[, m] = tempC[, i] } C[i, i] = sqrt(Sigma[i, i] - sum(C[i, i_vec]:^2)) i_vec2 = (i + 1)::k C[i_vec2, i] = (Sigma[i_vec2, i] - rowsum(J(k - i, 1, C[i, i_vec]):*C[i_vec2, i_vec]))/ C[i, i] Cy = sum(C[i, i_vec]:*y[i_vec]) atilde[i] = (a[i] - Cy)/C[i, i] btilde[i] = (b[i] - Cy)/C[i, i] if (atilde[i] != btilde[i]) { y[i] = (normalden(atilde[i]) - normalden(btilde[i]))/ (normal(btilde[i]) - normal(atilde[i])) } } C[k, k] = sqrt(Sigma[k, k] - sum(C[k, 1::(k - 1)]:^2)) I = V = 0 if (a[1] != .) { d = J(samples, 1, (normal(a[1]/C[1, 1]), J(1, k - 1, 0))) } else { d = J(samples, k, 0) } if (b[1] != .) { e = J(samples, 1, (normal(b[1]/C[1, 1]), J(1, k - 1, 1))) } else { e = J(samples, 1, J(1, k, 1)) } f = (e[, 1] - d[, 1], J(samples, k - 1, 0)) y = J(samples, k - 1, 0) Delta = runiform(shifts, k - 1) samples_sqrt_primes = (1::samples)*sqrt((2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541)[1::(k - 1)]) Ii = J(1, shifts, 0) for (i = 1; i <= shifts; i++) { for (l = 2; l <= k; l++) { l_vec = 1::(l - 1) y[, l - 1] = invnormal(d[, l - 1] + abs(2*mod(samples_sqrt_primes[, l - 1] :+ Delta[i, l - 1], 1) :- 1):* (e[, l - 1] - d[, l - 1])) if ((a[l] != .) & (b[l] != .)) { Cy = rowsum(J(samples, 1, C[l, l_vec]):*y[, l_vec]) d[, l] = normal((a[l] :- Cy)/C[l, l]) e[, l] = normal((b[l] :- Cy)/C[l, l]) f[, l] = (e[, l] :- d[, l]):*f[, l - 1] } else if ((a[l] != .) & (b[l] == .)) { d[, l] = normal((a[l] :- rowsum(J(samples, 1, C[l, l_vec]):*y[, l_vec]))/C[l, l]) f[, l] = (1 :- d[, l]):*f[, l - 1] } else if ((a[l] == .) & (b[l] != .)) { e[, l] = normal((b[l] :- rowsum(J(samples, 1, C[l, l_vec]):*y[, l_vec]))/C[l, l]) f[, l] = e[, l]:*f[, l - 1] } else { f[, l] = f[, l - 1] } } for (j = 1; j <= samples; j++) { Ii[i] = Ii[i] + (f[j, k] - Ii[i])/j } del = (Ii[i] - I)/i I = I + del V = (i - 2)*V/i + del^2 E = alpha*sqrt(V) } } return((I \ E)) } function which_condition(real vector check, string type, real scalar value) { match = . for (i = 1; i <= length(check); i++) { if (type == "ge") { if (check[i] >= value) { match = (match, i) } } else if (type == "g") { if (check[i] > value) { match = (match, i) } } else if (type == "le") { if (check[i] <= value) { match = (match, i) } } else if (type == "l") { if (check[i] < value) { match = (match, i) } } else if (type == "e") { if (check[i] == value) { match = (match, i) } } } if (length(match) > 1) { match = match[2::length(match)] if (rows(check) > 1) { return(match') } else { return(match) } } else { return(J(0, 0, .)) } } end