mathhook_core/calculus/derivatives/chain_rule.rs
1//! Chain rule implementation for function derivatives
2
3use crate::calculus::derivatives::Derivative;
4use crate::core::{Expression, Symbol};
5use crate::functions::intelligence::get_universal_registry;
6use crate::simplify::Simplify;
7
8/// Chain rule implementation for function derivatives
9pub struct ChainRule;
10
11impl ChainRule {
12 /// Handle derivative of function expressions using chain rule
13 ///
14 /// # Examples
15 ///
16 /// ```rust
17 /// use mathhook_core::simplify::Simplify;
18 /// use mathhook_core::{Expression, symbol};
19 /// use mathhook_core::calculus::derivatives::Derivative;
20 ///
21 /// let x = symbol!(x);
22 /// let expr = Expression::function("sin", vec![Expression::symbol(x.clone())]);
23 /// let result = expr.derivative(x.clone());
24 /// ```
25 pub fn handle_function(name: &str, args: &[Expression], variable: Symbol) -> Expression {
26 if args.len() != 1 {
27 return Expression::derivative(Expression::function(name, args.to_vec()), variable, 1);
28 }
29
30 Self::apply(name, &args[0], variable)
31 }
32
33 /// Apply chain rule for function derivatives
34 ///
35 /// # Examples
36 ///
37 /// ```rust
38 /// use mathhook_core::{Expression, symbol};
39 /// use mathhook_core::calculus::derivatives::ChainRule;
40 ///
41 /// let x = symbol!(x);
42 /// let arg = Expression::pow(Expression::symbol(x.clone()), Expression::integer(2));
43 /// let result = ChainRule::apply("sin", &arg, x.clone());
44 /// ```
45 pub fn apply(function_name: &str, arg: &Expression, variable: Symbol) -> Expression {
46 let arg_derivative = arg.derivative(variable.clone());
47 let function_derivative = FunctionDerivatives::get(function_name, arg, variable);
48
49 Expression::mul(vec![function_derivative, arg_derivative]).simplify()
50 }
51}
52
53/// Function derivative lookup
54pub struct FunctionDerivatives;
55
56impl FunctionDerivatives {
57 /// Get the derivative of a specific function using UniversalFunctionRegistry
58 ///
59 /// # Examples
60 ///
61 /// ```rust
62 /// use mathhook_core::{Expression, symbol};
63 /// use mathhook_core::calculus::derivatives::FunctionDerivatives;
64 ///
65 /// let x = symbol!(x);
66 /// let arg = Expression::symbol(x.clone());
67 /// let result = FunctionDerivatives::get("sin", &arg, x.clone());
68 /// ```
69 pub fn get(name: &str, arg: &Expression, variable: Symbol) -> Expression {
70 let registry = get_universal_registry();
71
72 if let Some(props) = registry.get_properties(name) {
73 if let Some(deriv_expr) = props.get_derivative_expression(arg) {
74 return deriv_expr;
75 }
76 }
77
78 Expression::derivative(Expression::function(name, vec![arg.clone()]), variable, 1)
79 }
80}