From 2c0959689bd956be3801a121d8439b7c6e0953a3 Mon Sep 17 00:00:00 2001 From: Andrey Hristov Date: Mon, 2 May 2005 12:29:38 +0000 Subject: [PATCH] add possibility to calculate the standard deviation and the variance on a sample - the formulae are slightly different. --- ext/standard/math.c | 22 +++++++++++++++------- ext/standard/tests/math/math_std_dev.phpt | 7 ++++++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/ext/standard/math.c b/ext/standard/math.c index 3e27103e3c..3aa845fd67 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -1183,11 +1183,14 @@ PHP_FUNCTION(fmod) /* }}} */ -static long double php_population_variance(zval *arr) +static long double php_population_variance(zval *arr, zend_bool sample) { double mean, sum = 0.0, vr = 0.0; zval **entry; HashPosition pos; + int elements_num; + + elements_num = zend_hash_num_elements(Z_ARRVAL_P(arr)); zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos); while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&entry, &pos) == SUCCESS) { @@ -1195,7 +1198,7 @@ static long double php_population_variance(zval *arr) sum += Z_DVAL_PP(entry); zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos); } - mean = sum / zend_hash_num_elements(Z_ARRVAL_P(arr)); + mean = sum / elements_num; zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos); while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&entry, &pos) == SUCCESS) { @@ -1205,7 +1208,10 @@ static long double php_population_variance(zval *arr) vr += d*d; zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos); } - return (vr / zend_hash_num_elements(Z_ARRVAL_P(arr))); + if (sample) { + --elements_num; + } + return (vr / elements_num); } /* {{{ proto float math_variance(array a) @@ -1213,15 +1219,16 @@ static long double php_population_variance(zval *arr) PHP_FUNCTION(math_variance) { zval *arr; + zend_bool sample = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &arr, &sample) == FAILURE) { return; } if (zend_hash_num_elements(Z_ARRVAL_P(arr)) == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The array has zero elements"); RETURN_FALSE; } - RETURN_DOUBLE(php_population_variance(arr)); + RETURN_DOUBLE(php_population_variance(arr, sample)); } /* }}} */ @@ -1231,15 +1238,16 @@ PHP_FUNCTION(math_variance) PHP_FUNCTION(math_std_dev) { zval *arr; + zend_bool sample = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &arr, &sample) == FAILURE) { return; } if (zend_hash_num_elements(Z_ARRVAL_P(arr)) == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The array has zero elements"); RETURN_FALSE; } - RETURN_DOUBLE(sqrt(php_population_variance(arr))); + RETURN_DOUBLE(sqrt(php_population_variance(arr, sample))); } /* }}} */ diff --git a/ext/standard/tests/math/math_std_dev.phpt b/ext/standard/tests/math/math_std_dev.phpt index 6c9f9694ac..a0d8fce6d7 100644 --- a/ext/standard/tests/math/math_std_dev.phpt +++ b/ext/standard/tests/math/math_std_dev.phpt @@ -6,14 +6,19 @@ $a=array(4, 1, 7); $dev=math_std_dev($a); var_dump(sprintf("%2.9f", $dev)); var_dump(math_std_dev(array())); +$a=array(5,7,8,10,10); +var_dump(math_std_dev($a,1)); echo "---Variance---\n"; $a=array(5,7,8,10,10); var_dump(math_variance($a)); +var_dump(math_variance($a, true)); ?> --EXPECTF-- string(11) "2.449489743" Warning: math_std_dev(): The array has zero elements in %s on line %d bool(false) +float(2.1213203435596) ---Variance--- -float(3.6) \ No newline at end of file +float(3.6) +float(4.5) \ No newline at end of file -- 2.40.0