fitnesstools/
lib.rs

1//! Fitnesstools is a library of math utitilites in fitness such as
2//!
3//! - **Powerlifting ratings** — Common rating normalizing formulas such as Wilks, DOTS(Not implemented)
4//!
5//! - **1rm estimators** — Not implemented
6//!
7//! - **Set difficulty rating / Equivalent RPE** — Not implemented
8
9pub enum Gender {
10    Male,
11    Female,
12}
13
14/// Compute the wilks coefficient for a lifter, using the original formula
15///
16/// <https://en.wikipedia.org/wiki/Wilks_coefficient>
17///
18/// ```
19/// use fitnesstools::{wilks, Gender};
20/// let wilks_coefficient = wilks(Gender::Male, 80.0);
21///
22/// assert_eq!(wilks_coefficient, 0.6826985901683169);
23/// ```
24pub fn wilks(gender: Gender, bodyweight: f64) -> f64 {
25    500.0 / poly5(wilks_constants(gender), bodyweight)
26}
27
28/// Compute the wilks coefficient for a lifter, using the updated 2020 formula
29///
30/// <https://en.wikipedia.org/wiki/Wilks_coefficient>
31///
32/// ```
33/// use fitnesstools::{wilks2020, Gender};
34/// let wilks_coefficient = wilks2020(Gender::Male, 80.0);
35///
36/// assert_eq!(wilks_coefficient, 0.8192383082019803);
37/// ```
38pub fn wilks2020(gender: Gender, bodyweight: f64) -> f64 {
39    600.0 / poly5(wilks_constants(gender), bodyweight)
40}
41
42fn wilks_constants(gender: Gender) -> [f64; 6] {
43    match gender {
44        Gender::Male => [
45            -216.0475144,
46            16.2606339,
47            -0.002388645,
48            -0.00113732,
49            7.01863 * 10_f64.powi(-6),
50            -1.291 * 10_f64.powi(-8),
51        ],
52        Gender::Female => [
53            594.31747775582,
54            -27.23842536447,
55            0.82112226871,
56            -0.00930733913,
57            4.731582 * 10_f64.powi(-5),
58            -9.054 * 10_f64.powi(-8),
59        ],
60    }
61}
62fn wilks2020_constants(gender: Gender) -> [f64; 6] {
63    match gender {
64        Gender::Male => [
65            47.46178854,
66            8.472061379,
67            0.07369410346,
68            -0.001395833811,
69            7.07665973070743 * 10_f64.powi(-6),
70            -1.20804336482315 * 10_f64.powi(-8),
71        ],
72        Gender::Female => [
73            -125.4255398,
74            13.71219419,
75            -0.03307250631,
76            -0.001050400051,
77            9.38773881462799 * 10_f64.powi(-5),
78            -2.3334613884954 * 10_f64.powi(-8),
79        ],
80    }
81}
82fn poly5(coefficients: [f64; 6], x: f64) -> f64 {
83    coefficients
84        .iter()
85        .enumerate()
86        .fold(0.0, |acc, (idx, val)| acc + val * x.powi(idx as i32))
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92
93    #[test]
94    fn test_poly5() {
95        assert_eq!(poly5([1.0, 0.0, 0.0, 0.0, 0.0, 0.0], 80.0), 1.0);
96        assert_eq!(poly5([1.0, 1.0, 0.0, 0.0, 0.0, 0.0], 80.0), 81.0);
97        assert_eq!(poly5([1.0, 1.0, 1.0, 0.0, 0.0, 0.0], 80.0), 6481.0);
98    }
99
100    #[test]
101    fn test_wilks() {
102        assert_eq!(wilks(Gender::Male, 80.0), 0.6826985901683169);
103    }
104
105    #[test]
106    fn test_wilks2020() {
107        assert_eq!(wilks2020(Gender::Male, 80.0), 0.8192383082019803);
108    }
109}