*! version 1.1.0 2026-04-27

Title

mht_cost_estimate -- Estimate cost function parameters for study-specific MHT calibration

Syntax

mht_cost_estimate costvar armsvar sizevar [if] [in],
alphabar(#) [options]

Important: sizevar should contain the per-arm (per-subgroup)
sample size, matching the paper's parameterization. If your size variable
is the total sample size across all arms, pass option totalsize so
the command converts internally before estimation.

Quick start

Estimate Cobb-Douglas cost parameters from data on project costs, arms, and size:

. mht_cost_estimate cost arms sample_size, alphabar(0.05) robust

Add controls and display the implied critical-value table:

. mht_cost_estimate cost arms sample_size, alphabar(0.05) ///

controls(ptype2 ptype3) robust table

Linear (fixed-cost-share) decomposition:

. mht_cost_estimate cost arms sample_size, alphabar(0.05) model(linear_share) robust table

Use the estimated parameters in mht_test or mht_est:

. local b = e(beta)

. local i = e(iota)

. mht_test pval, alphabar(0.05) model(cobbdouglas) beta(`b') iota(`i')

Description

mht_cost_estimate estimates the parameters of the research cost function
from project-level data on costs, the number of treatment arms (or hypotheses),
and sample sizes. The estimated parameters can be passed back to
mht_test or mht_est for study-specific calibration of the
optimal MHT threshold.

Two cost-function parameterizations are supported:

Cobb-Douglas (default; Table 2 / Appendix A in the paper):
log(C) = const + beta*log(|J|) + iota*log(n). Estimated via OLS on the
log-linearized equation. Used in the J-PAL calibration.

Linear (model(linear_share); Section 6.1):
C = c_f + c_v * |J| * n. Estimated via OLS to decompose fixed and variable
costs; reports the implied fixed-cost share c_f / E[C].

The command also tests four restrictions on the Cobb-Douglas parameters:
beta=0 (Bonferroni appropriate), beta=1 (no adjustment needed), iota=0
(costs invariant to n), and iota=1 (costs proportional to n).

Note on regression output: the command creates named log variables
(log_costvar, log_armsvar, log_sizevar) so that
the regression output displays meaningful variable names rather than Stata
tempvar identifiers. These variables are dropped automatically at the end.

Options

Required

costvar, armsvar, sizevar are the three input variables: project
cost, number of treatment arms (or hypotheses), and sample size.

alphabar(#) benchmark single-hypothesis size, in (0,1).

Model selection

model(string) cobbdouglas (default) or linear_share.

Regression

controls(varlist) additional control variables included in the cost regression.

robust use robust (Huber-White) standard errors.

cluster(varname) cluster standard errors by varname.

Sample size convention

totalsize indicates that sizevar contains the total sample
size (n_total = J x n_bar) rather than the per-arm sample size n_bar. When
specified, the command auto-converts: log(n_bar) = log(n_total / arms).
Without this option, sizevar is assumed to be per-arm. The command
prints a one-line note in either case so the user is reminded which
convention is in effect.

Why this matters. The paper's Cobb-Douglas formula uses the per-arm
elasticity. If you regress log(C) on log(arms) and log(n_total), the
coefficient on log(arms) becomes (beta - iota) instead of beta because
log(n_total) = log(arms) + log(n_bar). Passing totalsize avoids
this bias.

Output

table display a table of implied optimal critical values for |J|=1..9 and
several n/m ratios, computed using the estimated parameters.

Examples

Setup: simulate a Cobb-Douglas cost dataset

. clear

. set seed 12345

. set obs 500

. gen arms = ceil(runiform() * 5)

. gen sample_size = ceil(500 + runiform() * 4500)

. gen cost = exp(10 + 0.2*ln(arms) + 0.15*ln(sample_size) + rnormal(0, 0.4))

Cobb-Douglas estimation

. mht_cost_estimate cost arms sample_size, alphabar(0.05) table robust

With controls for project type

. gen ptype = ceil(runiform() * 3)

. tabulate ptype, gen(ptype_)

. mht_cost_estimate cost arms sample_size, alphabar(0.05) ///

controls(ptype_2 ptype_3) robust table

Linear (fixed-cost-share) model

. mht_cost_estimate cost arms sample_size, alphabar(0.05) model(linear_share) robust table

Feed estimated parameters into mht_test

. quietly mht_cost_estimate cost arms sample_size, alphabar(0.05) robust

. local b = e(beta)

. local i = e(iota)

. mht_test mypvals, alphabar(0.05) model(cobbdouglas) beta(`b') iota(`i')

Stored results

mht_cost_estimate stores the following in e():

Cobb-Douglas (model = cobbdouglas):

Scalars

e(beta) estimated elasticity wrt arms

e(iota) estimated elasticity wrt sample size

e(beta_se) standard error of beta

e(iota_se) standard error of iota

e(p_beta0) p-value for H0: beta = 0

e(p_beta1) p-value for H0: beta = 1

e(p_iota0) p-value for H0: iota = 0

e(p_iota1) p-value for H0: iota = 1

e(alpha_bar) benchmark alpha (input)

e(N) number of observations used

Macros

e(model) cobbdouglas

Linear (model = linear_share):

Scalars

e(c_f) estimated fixed cost

e(c_v) estimated variable cost per (J*n) unit

e(cf_share) fixed cost share c_f / E[C]

e(mean_J) mean number of arms

e(alpha_bar) benchmark alpha (input)

e(N) number of observations used

Macros

e(model) linear_share

References

Viviano, D., K. Wuthrich, and P. Niehaus (2026).
A model of multiple hypothesis testing. arXiv:2104.13367v10.

Also see

Online: mht_critical, mht_test, mht_est, mht_table