rs_stats/prob/std_err.rs
1//! # Standard Error Calculation
2//!
3//! This module implements the standard error calculation, which measures
4//! the precision of the sample mean as an estimate of the population mean.
5//!
6//! ## Mathematical Definition
7//! The standard error is defined as:
8//!
9//! SE = σ / √n
10//!
11//! where:
12//! - σ is the sample standard deviation
13//! - n is the sample size
14//!
15//! ## Key Properties
16//! - Decreases as sample size increases
17//! - Measures the variability of the sample mean
18//! - Used in confidence intervals and hypothesis testing
19
20use crate::error::StatsResult;
21use crate::prob::std_dev;
22use num_traits::ToPrimitive;
23
24/// Calculate the standard error of a dataset
25///
26/// The standard error quantifies the uncertainty in the sample mean
27/// as an estimate of the population mean.
28///
29/// # Arguments
30/// * `data` - A slice of numeric values implementing `ToPrimitive`
31///
32/// # Returns
33/// * `StatsResult<f64>` - The standard error, or an error if the input is invalid
34///
35/// # Errors
36/// Returns `StatsError::EmptyData` if the input slice is empty.
37/// Returns `StatsError::ConversionError` if any value cannot be converted to f64.
38///
39/// # Examples
40/// ```
41/// use rs_stats::prob::std_err;
42///
43/// // Calculate standard error for a dataset
44/// let data = [1.0, 2.0, 3.0, 4.0, 5.0];
45/// let se = std_err(&data)?;
46/// assert!((se - 0.632455532).abs() < 1e-9);
47///
48/// // Handle empty input
49/// let empty_data: &[f64] = &[];
50/// assert!(std_err(empty_data).is_err());
51/// # Ok::<(), rs_stats::StatsError>(())
52/// ```
53#[inline]
54pub fn std_err<T>(data: &[T]) -> StatsResult<f64>
55where
56 T: ToPrimitive + std::fmt::Debug,
57{
58 std_dev(data).map(|std| std / (data.len() as f64).sqrt())
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 const EPSILON: f64 = 1e-9;
66
67 #[test]
68 fn test_std_err_integers() {
69 // Dataset: [1, 2, 3, 4, 5]
70 // Standard deviation of [1, 2, 3, 4, 5] is 1.414213562 (approx)
71 // Standard error should be std_dev / sqrt(n) = 1.414213562 / sqrt(5) = 0.632455532 (approx)
72 let data = vec![1, 2, 3, 4, 5];
73 let result = std_err(&data).unwrap();
74 let expected = 0.632455532; // Calculated value of the standard error
75 assert!(
76 (result - expected).abs() < EPSILON,
77 "Standard error should be approximately 0.632455532"
78 );
79 }
80
81 #[test]
82 fn test_std_err_floats() {
83 // Dataset: [1.0, 2.0, 3.0, 4.0, 5.0]
84 // Standard deviation of [1.0, 2.0, 3.0, 4.0, 5.0] is the same as for integers
85 let data = vec![1.0, 2.0, 3.0, 4.0, 5.0];
86 let result = std_err(&data).unwrap();
87 let expected = 0.632455532;
88 assert!(
89 (result - expected).abs() < EPSILON,
90 "Standard error for floats should be approximately 0.632455532"
91 );
92 }
93
94 #[test]
95 fn test_std_err_single_element() {
96 // Dataset with only one element: [5]
97 // Standard deviation is 0, and thus standard error should also be 0
98 let data = vec![5];
99 let result = std_err(&data).unwrap();
100 let expected = 0.0;
101 assert_eq!(
102 result, expected,
103 "Standard error for a single element should be 0.0"
104 );
105 }
106
107 #[test]
108 fn test_std_err_empty() {
109 // Empty dataset: []
110 // There should be no standard error, result should be an error
111 let data: Vec<i32> = vec![];
112 let result = std_err(&data);
113 assert!(result.is_err());
114 assert!(matches!(
115 result.unwrap_err(),
116 crate::error::StatsError::EmptyData { .. }
117 ));
118 }
119}