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}