(
op: &Operator,
left: &Distribution,
right: &Distribution,
)
| 898 | note = "Part of the unused Statistics V2 framework; see https://github.com/apache/datafusion/pull/22071" |
| 899 | )] |
| 900 | pub fn compute_variance( |
| 901 | op: &Operator, |
| 902 | left: &Distribution, |
| 903 | right: &Distribution, |
| 904 | ) -> Result<ScalarValue> { |
| 905 | let (left_variance, right_variance) = (left.variance()?, right.variance()?); |
| 906 | |
| 907 | match op { |
| 908 | // Note the independence assumption below: |
| 909 | Operator::Plus => return left_variance.add_checked(right_variance), |
| 910 | // Note the independence assumption below: |
| 911 | Operator::Minus => return left_variance.add_checked(right_variance), |
| 912 | // Note the independence assumption below: |
| 913 | Operator::Multiply => { |
| 914 | // For more details, along with an explanation of the formula below, see: |
| 915 | // |
| 916 | // <https://en.wikipedia.org/wiki/Distribution_of_the_product_of_two_random_variables> |
| 917 | let (left_mean, right_mean) = (left.mean()?, right.mean()?); |
| 918 | let left_mean_sq = left_mean.mul_checked(&left_mean)?; |
| 919 | let right_mean_sq = right_mean.mul_checked(&right_mean)?; |
| 920 | let left_sos = left_variance.add_checked(&left_mean_sq)?; |
| 921 | let right_sos = right_variance.add_checked(&right_mean_sq)?; |
| 922 | let pos = left_mean_sq.mul_checked(right_mean_sq)?; |
| 923 | return left_sos.mul_checked(right_sos)?.sub_checked(pos); |
| 924 | } |
| 925 | // TODO: We can calculate the variance for division when we support reciprocals, |
| 926 | // or know the distributions of the operands. For details, see: |
| 927 | // |
| 928 | // <https://en.wikipedia.org/wiki/Algebra_of_random_variables> |
| 929 | // <https://stats.stackexchange.com/questions/185683/distribution-of-ratio-between-two-independent-uniform-random-variables> |
| 930 | // |
| 931 | // Fall back to an unknown variance value for division: |
| 932 | Operator::Divide => {} |
| 933 | // Fall back to an unknown variance value for other cases: |
| 934 | _ => {} |
| 935 | } |
| 936 | let target_type = Distribution::target_type(&[&left_variance, &right_variance])?; |
| 937 | ScalarValue::try_from(target_type) |
| 938 | } |
| 939 | |
| 940 | #[cfg(test)] |
| 941 | mod tests { |
no test coverage detected
searching dependent graphs…