64 return effect_size * std::sqrt(n);
76 return effect_size * std::sqrt((n1 * n2) / (n1 + n2));
132 default:
return "two.sided";
158 const std::string& alternative =
"two.sided")
161 throw std::invalid_argument(
"statcpp::power_t_test_one_sample: sample size must be positive");
163 if (alpha <= 0.0 || alpha >= 1.0) {
164 throw std::invalid_argument(
"statcpp::power_t_test_one_sample: alpha must be in (0, 1)");
169 if (alternative ==
"two.sided") {
174 }
else if (alternative ==
"greater") {
176 return 1.0 -
norm_cdf(z_crit - ncp);
177 }
else if (alternative ==
"less") {
181 throw std::invalid_argument(
"statcpp::power_t_test_one_sample: alternative must be 'two.sided', 'greater', or 'less'");
197 const std::string& alternative =
"two.sided")
199 if (effect_size == 0.0) {
200 throw std::invalid_argument(
"statcpp::sample_size_t_test_one_sample: effect size must be non-zero");
202 if (power <= 0.0 || power >= 1.0) {
203 throw std::invalid_argument(
"statcpp::sample_size_t_test_one_sample: power must be in (0, 1)");
205 if (alpha <= 0.0 || alpha >= 1.0) {
206 throw std::invalid_argument(
"statcpp::sample_size_t_test_one_sample: alpha must be in (0, 1)");
210 double z_alpha, z_beta;
211 if (alternative ==
"two.sided") {
219 double n_approx = std::pow((z_alpha + z_beta) / std::abs(effect_size), 2.0);
222 std::size_t n = std::max(2.0, std::ceil(n_approx));
225 for (
int iter = 0; iter < 100; ++iter) {
227 if (current_power >= power) {
257 const std::string& alternative =
"two.sided")
259 if (n1 == 0 || n2 == 0) {
260 throw std::invalid_argument(
"statcpp::power_t_test_two_sample: sample sizes must be positive");
262 if (alpha <= 0.0 || alpha >= 1.0) {
263 throw std::invalid_argument(
"statcpp::power_t_test_two_sample: alpha must be in (0, 1)");
267 static_cast<double>(n1),
268 static_cast<double>(n2));
270 if (alternative ==
"two.sided") {
273 }
else if (alternative ==
"greater") {
275 return 1.0 -
norm_cdf(z_crit - ncp);
276 }
else if (alternative ==
"less") {
280 throw std::invalid_argument(
"statcpp::power_t_test_two_sample: alternative must be 'two.sided', 'greater', or 'less'");
296 double alpha = 0.05,
double ratio = 1.0,
297 const std::string& alternative =
"two.sided")
299 if (effect_size == 0.0) {
300 throw std::invalid_argument(
"statcpp::sample_size_t_test_two_sample: effect size must be non-zero");
302 if (power <= 0.0 || power >= 1.0) {
303 throw std::invalid_argument(
"statcpp::sample_size_t_test_two_sample: power must be in (0, 1)");
305 if (alpha <= 0.0 || alpha >= 1.0) {
306 throw std::invalid_argument(
"statcpp::sample_size_t_test_two_sample: alpha must be in (0, 1)");
309 throw std::invalid_argument(
"statcpp::sample_size_t_test_two_sample: ratio must be positive");
313 double z_alpha, z_beta;
314 if (alternative ==
"two.sided") {
322 double n1_approx = std::pow((z_alpha + z_beta) / std::abs(effect_size), 2.0) * (1.0 + 1.0 / ratio);
324 std::size_t n1 = std::max(2.0, std::ceil(n1_approx));
325 std::size_t n2 = std::max(2.0, std::ceil(n1 * ratio));
328 for (
int iter = 0; iter < 100; ++iter) {
330 if (current_power >= power) {
334 n2 = std::max(2.0, std::ceil(n1 * ratio));
357 const std::string& alternative =
"two.sided")
359 if (p1 < 0.0 || p1 > 1.0 || p2 < 0.0 || p2 > 1.0) {
360 throw std::invalid_argument(
"statcpp::power_prop_test: proportions must be in [0, 1]");
363 throw std::invalid_argument(
"statcpp::power_prop_test: sample size must be positive");
365 if (alpha <= 0.0 || alpha >= 1.0) {
366 throw std::invalid_argument(
"statcpp::power_prop_test: alpha must be in (0, 1)");
370 double p_pool = (p1 + p2) / 2.0;
371 double se_null = std::sqrt(2.0 * p_pool * (1.0 - p_pool) /
static_cast<double>(n));
374 double se_alt = std::sqrt((p1 * (1.0 - p1) + p2 * (1.0 - p2)) /
static_cast<double>(n));
376 double diff = std::abs(p1 - p2);
378 if (alternative ==
"two.sided") {
380 double boundary = z_crit * se_null;
381 double z_power = (
diff - boundary) / se_alt;
383 }
else if (alternative ==
"greater") {
385 double boundary = z_crit * se_null;
386 double z_power = ((p1 - p2) - boundary) / se_alt;
388 }
else if (alternative ==
"less") {
390 double boundary = z_crit * se_null;
391 double z_power = ((p2 - p1) - boundary) / se_alt;
394 throw std::invalid_argument(
"statcpp::power_prop_test: alternative must be 'two.sided', 'greater', or 'less'");
411 const std::string& alternative =
"two.sided")
413 if (p1 < 0.0 || p1 > 1.0 || p2 < 0.0 || p2 > 1.0) {
414 throw std::invalid_argument(
"statcpp::sample_size_prop_test: proportions must be in [0, 1]");
416 if (std::abs(p1 - p2) < 1e-10) {
417 throw std::invalid_argument(
"statcpp::sample_size_prop_test: proportions must be different");
419 if (power <= 0.0 || power >= 1.0) {
420 throw std::invalid_argument(
"statcpp::sample_size_prop_test: power must be in (0, 1)");
422 if (alpha <= 0.0 || alpha >= 1.0) {
423 throw std::invalid_argument(
"statcpp::sample_size_prop_test: alpha must be in (0, 1)");
426 double z_alpha, z_beta;
427 if (alternative ==
"two.sided") {
434 double p_pooled = (p1 + p2) / 2.0;
435 double diff = std::abs(p1 - p2);
438 double n_approx = (std::pow(z_alpha * std::sqrt(2.0 * p_pooled * (1.0 - p_pooled)) +
439 z_beta * std::sqrt(p1 * (1.0 - p1) + p2 * (1.0 - p2)), 2.0)) /
442 std::size_t n = std::max(2.0, std::ceil(n_approx));
445 for (
int iter = 0; iter < 100; ++iter) {
447 if (current_power >= power) {
471 const std::string& alternative =
"two.sided")
476 result.
alpha = alpha;
492 const std::string& alternative =
"two.sided")
496 result.
power = power;
497 result.
alpha = alpha;
566 double alpha,
double ratio,
Continuous distribution functions.
double noncentrality_parameter_t(double effect_size, double n)
Calculate noncentrality parameter for t-distribution.
double critical_t_two_sided(double alpha, double df)
Calculate critical value for two-sided t-test.
double critical_t_one_sided(double alpha, double df)
Calculate critical value for one-sided t-test.
const char * alternative_to_string(alternative_hypothesis alt)
Convert alternative_hypothesis enum to string.
double critical_z_one_sided(double alpha)
Calculate critical value for one-sided normal test.
double noncentrality_parameter_t_two_sample(double effect_size, double n1, double n2)
Calculate noncentrality parameter for two-sample case.
double critical_z_two_sided(double alpha)
Calculate critical value for two-sided normal test.
alternative_hypothesis
Enumeration representing the type of alternative hypothesis.
@ greater
One-sided test (greater than)
@ two_sided
Two-sided test.
@ less
One-sided test (less than)
power_result power_analysis_t_one_sample(double effect_size, std::size_t n, double alpha=0.05, const std::string &alternative="two.sided")
Power analysis for one-sample t-test (calculate power)
std::size_t sample_size_t_test_one_sample(double effect_size, double power=0.80, double alpha=0.05, const std::string &alternative="two.sided")
Calculate required sample size for one-sample t-test.
double power_t_test_one_sample(double effect_size, std::size_t n, double alpha=0.05, const std::string &alternative="two.sided")
Calculate power for one-sample t-test.
double norm_cdf(double x)
Standard normal CDF.
double norm_quantile(double p)
Standard normal quantile function.
double power_t_test_two_sample(double effect_size, std::size_t n1, std::size_t n2, double alpha=0.05, const std::string &alternative="two.sided")
Calculate power for two-sample t-test.
power_result power_analysis_t_one_sample_n(double effect_size, double power=0.80, double alpha=0.05, const std::string &alternative="two.sided")
Power analysis for one-sample t-test (calculate sample size)
double t_quantile(double p, double df)
t-distribution quantile function (Newton-Raphson method)
std::vector< double > diff(Iterator first, Iterator last, std::size_t order=1)
Difference series (first-order or d-th order differencing)
std::size_t sample_size_prop_test(double p1, double p2, double power=0.80, double alpha=0.05, const std::string &alternative="two.sided")
Calculate required sample size for two-sample proportion test.
std::size_t sample_size_t_test_two_sample(double effect_size, double power=0.80, double alpha=0.05, double ratio=1.0, const std::string &alternative="two.sided")
Calculate required sample size for two-sample t-test (per group)
double power_prop_test(double p1, double p2, std::size_t n, double alpha=0.05, const std::string &alternative="two.sided")
Calculate power for two-sample proportion test.
Parametric test functions.
Special mathematical functions implementation.
double effect_size
Effect size.
double power
Statistical power (1-beta)
double sample_size
Sample size.
double alpha
Significance level.