mathhook_core/functions/elementary/
hyperbolic.rs

1//! Hyperbolic Function Intelligence
2//!
3//! Mathematically accurate implementation of hyperbolic and inverse hyperbolic functions
4//! with verified derivatives, special values, and hyperbolic identities.
5
6use crate::core::{Expression, Symbol};
7use crate::functions::properties::*;
8use std::collections::HashMap;
9use std::sync::Arc;
10
11/// Hyperbolic Function Intelligence
12///
13/// Complete mathematical intelligence for hyperbolic and inverse hyperbolic functions
14/// with ABSOLUTE MATHEMATICAL ACCURACY.
15pub struct HyperbolicIntelligence {
16    /// Function properties for hyperbolic functions
17    properties: HashMap<String, FunctionProperties>,
18}
19
20impl Default for HyperbolicIntelligence {
21    fn default() -> Self {
22        Self::new()
23    }
24}
25
26impl HyperbolicIntelligence {
27    /// Create new hyperbolic intelligence system
28    pub fn new() -> Self {
29        let mut intelligence = Self {
30            properties: HashMap::with_capacity(12),
31        };
32
33        intelligence.initialize_sinh_cosh();
34        intelligence.initialize_tanh();
35        intelligence.initialize_extended();
36        intelligence.initialize_inverse();
37
38        intelligence
39    }
40
41    /// Get all hyperbolic function properties
42    pub fn get_properties(&self) -> HashMap<String, FunctionProperties> {
43        self.properties.clone()
44    }
45
46    /// Check if function is hyperbolic
47    pub fn has_function(&self, name: &str) -> bool {
48        self.properties.contains_key(name)
49    }
50
51    /// Initialize sinh and cosh with MATHEMATICAL ACCURACY
52    fn initialize_sinh_cosh(&mut self) {
53        self.properties.insert(
54            "sinh".to_owned(),
55            FunctionProperties::Elementary(Box::new(ElementaryProperties {
56                derivative_rule: Some(DerivativeRule {
57                    rule_type: DerivativeRuleType::SimpleFunctionSubstitution("cosh".to_owned()),
58                    result_template: "cosh(x)".to_owned(),
59                }),
60                antiderivative_rule: Some(AntiderivativeRule {
61                    rule_type: AntiderivativeRuleType::Simple {
62                        antiderivative_fn: "cosh".to_owned(),
63                        coefficient: Expression::integer(1),
64                    },
65                    result_template: "∫sinh(x)dx = cosh(x) + C".to_owned(),
66                    constant_handling: ConstantOfIntegration::AddConstant,
67                }),
68                special_values: vec![SpecialValue {
69                    input: "0".to_owned(),
70                    output: Expression::integer(0),
71                    latex_explanation: "\\sinh(0) = 0".to_owned(),
72                }],
73                identities: Box::new(vec![MathIdentity {
74                    name: "Hyperbolic Identity".to_owned(),
75                    lhs: Expression::function(
76                        "cosh_squared_minus_sinh_squared",
77                        vec![Expression::symbol("x")],
78                    ),
79                    rhs: Expression::integer(1),
80                    conditions: vec!["x ∈ ℝ".to_owned()],
81                }]),
82                domain_range: Box::new(DomainRangeData {
83                    domain: Domain::Real,
84                    range: Range::Real,
85                    singularities: vec![],
86                }),
87                periodicity: None,
88                wolfram_name: None,
89            })),
90        );
91
92        self.properties.insert(
93            "cosh".to_owned(),
94            FunctionProperties::Elementary(Box::new(ElementaryProperties {
95                derivative_rule: Some(DerivativeRule {
96                    rule_type: DerivativeRuleType::SimpleFunctionSubstitution("sinh".to_owned()),
97                    result_template: "sinh(x)".to_owned(),
98                }),
99                antiderivative_rule: Some(AntiderivativeRule {
100                    rule_type: AntiderivativeRuleType::Simple {
101                        antiderivative_fn: "sinh".to_owned(),
102                        coefficient: Expression::integer(1),
103                    },
104                    result_template: "∫cosh(x)dx = sinh(x) + C".to_owned(),
105                    constant_handling: ConstantOfIntegration::AddConstant,
106                }),
107                special_values: vec![SpecialValue {
108                    input: "0".to_owned(),
109                    output: Expression::integer(1),
110                    latex_explanation: "\\cosh(0) = 1".to_owned(),
111                }],
112                identities: Box::new(vec![MathIdentity {
113                    name: "Hyperbolic Identity".to_owned(),
114                    lhs: Expression::function(
115                        "cosh_squared_minus_sinh_squared",
116                        vec![Expression::symbol("x")],
117                    ),
118                    rhs: Expression::integer(1),
119                    conditions: vec!["x ∈ ℝ".to_owned()],
120                }]),
121                domain_range: Box::new(DomainRangeData {
122                    domain: Domain::Real,
123                    range: Range::Unbounded,
124                    singularities: vec![],
125                }),
126                periodicity: None,
127                wolfram_name: None,
128            })),
129        );
130    }
131
132    /// Initialize tanh with MATHEMATICAL ACCURACY
133    fn initialize_tanh(&mut self) {
134        self.properties.insert(
135            "tanh".to_owned(),
136            FunctionProperties::Elementary(Box::new(ElementaryProperties {
137                derivative_rule: Some(DerivativeRule {
138                    rule_type: DerivativeRuleType::Custom {
139                        builder: Arc::new(|arg: &Expression| {
140                            let tanh_arg = Expression::function("tanh", vec![arg.clone()]);
141                            let tanh_squared = Expression::pow(tanh_arg, Expression::integer(2));
142                            Expression::add(vec![
143                                Expression::integer(1),
144                                Expression::mul(vec![Expression::integer(-1), tanh_squared]),
145                            ])
146                        }),
147                    },
148                    result_template: "1 - tanh²(x)".to_owned(),
149                }),
150                antiderivative_rule: Some(AntiderivativeRule {
151                    rule_type: AntiderivativeRuleType::Custom {
152                        builder: Arc::new(|var: Symbol| {
153                            Expression::function(
154                                "ln",
155                                vec![Expression::function("cosh", vec![Expression::symbol(var)])],
156                            )
157                        }),
158                    },
159                    result_template: "∫tanh(x)dx = ln(cosh(x)) + C".to_owned(),
160                    constant_handling: ConstantOfIntegration::AddConstant,
161                }),
162                special_values: vec![SpecialValue {
163                    input: "0".to_owned(),
164                    output: Expression::integer(0),
165                    latex_explanation: "\\tanh(0) = 0".to_owned(),
166                }],
167                identities: Box::new(vec![MathIdentity {
168                    name: "Hyperbolic Tangent Identity".to_owned(),
169                    lhs: Expression::function("tanh", vec![Expression::symbol("x")]),
170                    rhs: Expression::function("sinh_over_cosh", vec![Expression::symbol("x")]),
171                    conditions: vec!["x ∈ ℝ".to_owned()],
172                }]),
173                domain_range: Box::new(DomainRangeData {
174                    domain: Domain::Real,
175                    range: Range::Bounded(Expression::integer(-1), Expression::integer(1)),
176                    singularities: vec![],
177                }),
178                periodicity: None,
179                wolfram_name: None,
180            })),
181        );
182    }
183
184    /// Initialize extended hyperbolic functions (sech, csch, coth)
185    fn initialize_extended(&mut self) {
186        self.properties.insert(
187            "sech".to_owned(),
188            FunctionProperties::Elementary(Box::new(ElementaryProperties {
189                derivative_rule: Some(DerivativeRule {
190                    rule_type: DerivativeRuleType::Custom {
191                        builder: Arc::new(|arg: &Expression| {
192                            let sech_arg = Expression::function("sech", vec![arg.clone()]);
193                            let tanh_arg = Expression::function("tanh", vec![arg.clone()]);
194                            Expression::mul(vec![Expression::integer(-1), sech_arg, tanh_arg])
195                        }),
196                    },
197                    result_template: "-sech(x)·tanh(x)".to_owned(),
198                }),
199                antiderivative_rule: None,
200                special_values: vec![SpecialValue {
201                    input: "0".to_owned(),
202                    output: Expression::integer(1),
203                    latex_explanation: "\\text{sech}(0) = 1".to_owned(),
204                }],
205                identities: Box::new(vec![]),
206                domain_range: Box::new(DomainRangeData {
207                    domain: Domain::Real,
208                    range: Range::Bounded(Expression::integer(0), Expression::integer(1)),
209                    singularities: vec![],
210                }),
211                periodicity: None,
212                wolfram_name: None,
213            })),
214        );
215
216        self.properties.insert(
217            "csch".to_owned(),
218            FunctionProperties::Elementary(Box::new(ElementaryProperties {
219                derivative_rule: Some(DerivativeRule {
220                    rule_type: DerivativeRuleType::Custom {
221                        builder: Arc::new(|arg: &Expression| {
222                            let csch_arg = Expression::function("csch", vec![arg.clone()]);
223                            let coth_arg = Expression::function("coth", vec![arg.clone()]);
224                            Expression::mul(vec![Expression::integer(-1), csch_arg, coth_arg])
225                        }),
226                    },
227                    result_template: "-csch(x)·coth(x)".to_owned(),
228                }),
229                antiderivative_rule: None,
230                special_values: vec![],
231                identities: Box::new(vec![]),
232                domain_range: Box::new(DomainRangeData {
233                    domain: Domain::Real,
234                    range: Range::Real,
235                    singularities: vec![Expression::integer(0)],
236                }),
237                periodicity: None,
238                wolfram_name: None,
239            })),
240        );
241
242        self.properties.insert(
243            "coth".to_owned(),
244            FunctionProperties::Elementary(Box::new(ElementaryProperties {
245                derivative_rule: Some(DerivativeRule {
246                    rule_type: DerivativeRuleType::Custom {
247                        builder: Arc::new(|arg: &Expression| {
248                            let csch_arg = Expression::function("csch", vec![arg.clone()]);
249                            let csch_squared = Expression::pow(csch_arg, Expression::integer(2));
250                            Expression::add(vec![
251                                Expression::integer(1),
252                                Expression::mul(vec![Expression::integer(-1), csch_squared]),
253                            ])
254                        }),
255                    },
256                    result_template: "1 - csch²(x)".to_owned(),
257                }),
258                antiderivative_rule: None,
259                special_values: vec![],
260                identities: Box::new(vec![]),
261                domain_range: Box::new(DomainRangeData {
262                    domain: Domain::Real,
263                    range: Range::Real,
264                    singularities: vec![Expression::integer(0)],
265                }),
266                periodicity: None,
267                wolfram_name: None,
268            })),
269        );
270    }
271
272    /// Initialize inverse hyperbolic functions (asinh, acosh, atanh)
273    fn initialize_inverse(&mut self) {
274        self.properties.insert(
275            "asinh".to_owned(),
276            FunctionProperties::Elementary(Box::new(ElementaryProperties {
277                derivative_rule: Some(DerivativeRule {
278                    rule_type: DerivativeRuleType::Custom {
279                        builder: Arc::new(|arg: &Expression| {
280                            let sqrt_term = Expression::function(
281                                "sqrt",
282                                vec![Expression::add(vec![
283                                    Expression::pow(arg.clone(), Expression::integer(2)),
284                                    Expression::integer(1),
285                                ])],
286                            );
287                            Expression::mul(vec![
288                                Expression::integer(1),
289                                Expression::pow(sqrt_term, Expression::integer(-1)),
290                            ])
291                        }),
292                    },
293                    result_template: "1/√(x²+1)".to_owned(),
294                }),
295                antiderivative_rule: None,
296                special_values: vec![SpecialValue {
297                    input: "0".to_owned(),
298                    output: Expression::integer(0),
299                    latex_explanation: "\\text{asinh}(0) = 0".to_owned(),
300                }],
301                identities: Box::new(vec![]),
302                domain_range: Box::new(DomainRangeData {
303                    domain: Domain::Real,
304                    range: Range::Real,
305                    singularities: vec![],
306                }),
307                periodicity: None,
308                wolfram_name: None,
309            })),
310        );
311
312        self.properties.insert(
313            "acosh".to_owned(),
314            FunctionProperties::Elementary(Box::new(ElementaryProperties {
315                derivative_rule: Some(DerivativeRule {
316                    rule_type: DerivativeRuleType::Custom {
317                        builder: Arc::new(|arg: &Expression| {
318                            let sqrt_term = Expression::function(
319                                "sqrt",
320                                vec![Expression::add(vec![
321                                    Expression::pow(arg.clone(), Expression::integer(2)),
322                                    Expression::integer(-1),
323                                ])],
324                            );
325                            Expression::mul(vec![
326                                Expression::integer(1),
327                                Expression::pow(sqrt_term, Expression::integer(-1)),
328                            ])
329                        }),
330                    },
331                    result_template: "1/√(x²-1)".to_owned(),
332                }),
333                antiderivative_rule: None,
334                special_values: vec![SpecialValue {
335                    input: "1".to_owned(),
336                    output: Expression::integer(0),
337                    latex_explanation: "\\text{acosh}(1) = 0".to_owned(),
338                }],
339                identities: Box::new(vec![]),
340                domain_range: Box::new(DomainRangeData {
341                    domain: Domain::Real,
342                    range: Range::Unbounded,
343                    singularities: vec![],
344                }),
345                periodicity: None,
346                wolfram_name: None,
347            })),
348        );
349
350        self.properties.insert(
351            "atanh".to_owned(),
352            FunctionProperties::Elementary(Box::new(ElementaryProperties {
353                derivative_rule: Some(DerivativeRule {
354                    rule_type: DerivativeRuleType::Custom {
355                        builder: Arc::new(|arg: &Expression| {
356                            let arg_squared = Expression::pow(arg.clone(), Expression::integer(2));
357                            let denominator = Expression::add(vec![
358                                Expression::integer(1),
359                                Expression::mul(vec![Expression::integer(-1), arg_squared]),
360                            ]);
361                            Expression::mul(vec![
362                                Expression::integer(1),
363                                Expression::pow(denominator, Expression::integer(-1)),
364                            ])
365                        }),
366                    },
367                    result_template: "1/(1-x²)".to_owned(),
368                }),
369                antiderivative_rule: None,
370                special_values: vec![SpecialValue {
371                    input: "0".to_owned(),
372                    output: Expression::integer(0),
373                    latex_explanation: "\\text{atanh}(0) = 0".to_owned(),
374                }],
375                identities: Box::new(vec![]),
376                domain_range: Box::new(DomainRangeData {
377                    domain: Domain::Interval(Expression::integer(-1), Expression::integer(1)),
378                    range: Range::Real,
379                    singularities: vec![Expression::integer(-1), Expression::integer(1)],
380                }),
381                periodicity: None,
382                wolfram_name: None,
383            })),
384        );
385    }
386}
387
388#[cfg(test)]
389mod tests {
390    use super::*;
391
392    #[test]
393    fn test_hyperbolic_intelligence() {
394        let hyp = HyperbolicIntelligence::new();
395
396        assert!(hyp.has_function("sinh"));
397        assert!(hyp.has_function("cosh"));
398        assert!(hyp.has_function("tanh"));
399        assert!(hyp.has_function("sech"));
400        assert!(hyp.has_function("csch"));
401        assert!(hyp.has_function("coth"));
402        assert!(hyp.has_function("asinh"));
403        assert!(hyp.has_function("acosh"));
404        assert!(hyp.has_function("atanh"));
405        assert!(!hyp.has_function("sin"));
406
407        let properties = hyp.get_properties();
408        assert_eq!(properties.len(), 9);
409    }
410
411    #[test]
412    fn test_hyperbolic_derivative_rules() {
413        let hyp = HyperbolicIntelligence::new();
414        let properties = hyp.get_properties();
415
416        if let Some(FunctionProperties::Elementary(tanh_props)) = properties.get("tanh") {
417            assert!(tanh_props.derivative_rule.is_some());
418            let deriv = tanh_props.derivative_rule.as_ref().unwrap();
419            assert!(matches!(deriv.rule_type, DerivativeRuleType::Custom { .. }));
420        } else {
421            panic!("tanh properties not found");
422        }
423
424        if let Some(FunctionProperties::Elementary(asinh_props)) = properties.get("asinh") {
425            assert!(asinh_props.derivative_rule.is_some());
426            let deriv = asinh_props.derivative_rule.as_ref().unwrap();
427            assert!(matches!(deriv.rule_type, DerivativeRuleType::Custom { .. }));
428        } else {
429            panic!("asinh properties not found");
430        }
431    }
432}