mathhook_core/functions/polynomials/legendre.rs
1//! Legendre Polynomial Intelligence
2//!
3//! Mathematically accurate implementation of Legendre polynomials P_n(x)
4//! with verified recurrence relations, orthogonality properties, and special values.
5
6use crate::core::{Expression, Symbol};
7use crate::functions::properties::*;
8use std::collections::HashMap;
9use std::sync::Arc;
10
11/// Legendre Polynomial Intelligence
12///
13/// Complete mathematical intelligence for Legendre polynomials P_n(x)
14/// with ABSOLUTE MATHEMATICAL ACCURACY verified against literature.
15pub struct LegendreIntelligence {
16 /// Function properties for Legendre polynomials
17 properties: HashMap<String, FunctionProperties>,
18}
19
20impl Default for LegendreIntelligence {
21 fn default() -> Self {
22 Self::new()
23 }
24}
25
26impl LegendreIntelligence {
27 /// Create new Legendre polynomial intelligence system
28 pub fn new() -> Self {
29 let mut intelligence = Self {
30 properties: HashMap::with_capacity(4),
31 };
32
33 intelligence.initialize_legendre_polynomials();
34
35 intelligence
36 }
37
38 /// Get all Legendre polynomial properties
39 pub fn get_properties(&self) -> HashMap<String, FunctionProperties> {
40 self.properties.clone()
41 }
42
43 /// Check if function is a Legendre polynomial
44 pub fn has_function(&self, name: &str) -> bool {
45 self.properties.contains_key(name)
46 }
47
48 /// Initialize Legendre polynomials with ABSOLUTE MATHEMATICAL ACCURACY
49 ///
50 /// ## Mathematical Background
51 /// Legendre polynomials P_n(x) are orthogonal polynomials that arise naturally in:
52 /// - **Physics**: Solutions to Laplace's equation in spherical coordinates
53 /// - **Quantum Mechanics**: Angular part of hydrogen atom wavefunctions
54 /// - **Numerical Analysis**: Gaussian quadrature for high-precision integration
55 /// - **Potential Theory**: Multipole expansions in electrostatics
56 ///
57 /// ## Key Properties (Verified against Abramowitz & Stegun, Chapter 8)
58 /// - **Orthogonality**: ∫₋₁¹ Pₘ(x) Pₙ(x) dx = 2/(2n+1) δₘₙ
59 /// - **Recurrence**: (n+1)P_{n+1}(x) = (2n+1)x Pₙ(x) - n P_{n-1}(x)
60 /// - **Rodrigues Formula**: Pₙ(x) = 1/(2ⁿn!) dⁿ/dxⁿ (x²-1)ⁿ
61 /// - **Generating Function**: 1/√(1-2xt+t²) = Σ Pₙ(x) tⁿ
62 fn initialize_legendre_polynomials(&mut self) {
63 self.properties.insert(
64 "legendre_p".to_owned(),
65 FunctionProperties::Polynomial(Box::new(PolynomialProperties {
66 family: PolynomialFamily::Legendre,
67 // THREE-TERM RECURRENCE RELATION (MATHEMATICALLY VERIFIED)
68 // (n+1)P_{n+1}(x) = (2n+1)x P_n(x) - n P_{n-1}(x)
69 // Normalized form: P_{n+1}(x) = [(2n+1)x P_n(x) - n P_{n-1}(x)]/(n+1)
70 recurrence: ThreeTermRecurrence {
71 // Coefficient of x*P_n(x): (2n+1)/(n+1)
72 alpha_coeff: Expression::function("legendre_alpha", vec![Expression::symbol("n")]),
73
74 // No linear term
75 beta_coeff: Expression::integer(0),
76
77 // Coefficient of P_{n-1}(x): -n/(n+1)
78 gamma_coeff: Expression::function("legendre_gamma", vec![Expression::symbol("n")]),
79
80 // Initial conditions (mathematically verified)
81 // P_0(x) = 1, P_1(x) = x
82 initial_conditions: (Expression::integer(1), Expression::symbol("x")),
83 },
84
85 // Orthogonality properties (mathematically verified)
86 // ∫_{-1}^{1} P_m(x) P_n(x) dx = (2/(2n+1)) δ_{mn}
87 orthogonality: Some(OrthogonalityData {
88 // Weight function: w(x) = 1 (constant)
89 weight_function: Expression::integer(1),
90
91 // Orthogonality interval: [-1, 1]
92 interval: (Expression::integer(-1), Expression::integer(1)),
93
94 // Normalization: ||P_n||² = 2/(2n+1)
95 norm_squared: Expression::function("legendre_norm_squared", vec![Expression::symbol("n")]),
96 }),
97
98 // Rodrigues' formula (mathematically verified)
99 // P_n(x) = (1/2^n n!) d^n/dx^n (x²-1)^n
100 rodrigues_formula: Some(RodriguesFormula {
101 formula: "P_n(x) = (1/2^n n!) d^n/dx^n (x²-1)^n".to_owned(),
102 normalization: Expression::function("legendre_rodrigues_norm", vec![Expression::symbol("n")]),
103 weight_function: Expression::function("legendre_rodrigues_weight", vec![Expression::symbol("n"), Expression::symbol("x")]),
104 }),
105
106 // Generating function (mathematically verified)
107 // 1/√(1-2xt+t²) = Σ_{n=0}^∞ P_n(x) t^n
108 generating_function: Some(GeneratingFunction {
109 function: Expression::function("legendre_generating", vec![Expression::symbol("x"), Expression::symbol("t")]),
110 gf_type: GeneratingFunctionType::Ordinary,
111 }),
112
113 // Special values (mathematically verified)
114 special_values: vec![
115 // P_n(1) = 1 for all n ≥ 0
116 SpecialValue {
117 input: "1".to_owned(),
118 output: Expression::integer(1),
119 latex_explanation: "P_n(1) = 1 \\text{ for all } n \\geq 0".to_owned(),
120 },
121
122 // P_n(-1) = (-1)^n for all n ≥ 0
123 SpecialValue {
124 input: "-1".to_owned(),
125 output: Expression::pow(Expression::integer(-1), Expression::symbol("n")),
126 latex_explanation: "P_n(-1) = (-1)^n \\text{ for all } n \\geq 0".to_owned(),
127 },
128
129 // P_n(0) depends on parity of n
130 SpecialValue {
131 input: "0".to_owned(),
132 output: Expression::function("legendre_zero_value", vec![Expression::symbol("n")]),
133 latex_explanation: "P_n(0) = \\begin{cases} (-1)^{n/2} \\frac{(n-1)!!}{n!!} & \\text{if } n \\text{ even} \\\\ 0 & \\text{if } n \\text{ odd} \\end{cases}".to_owned(),
134 },
135 ],
136
137 // Evaluation method: Recurrence is most stable and efficient
138 evaluation_method: EvaluationMethod::Recurrence,
139
140 // Numerical evaluator using recurrence relation),
141
142 // Symbolic expansion method for intelligence-driven computation
143 symbolic_expander: Some(super::super::properties::special::SymbolicExpander::Custom(
144 super::symbolic::expand_legendre_symbolic
145 )),
146
147 antiderivative_rule: AntiderivativeRule {
148 rule_type: AntiderivativeRuleType::Custom {
149 builder: Arc::new(|var: Symbol| {
150 Expression::integral(
151 Expression::function("legendre_p", vec![Expression::symbol(var.clone())]),
152 var
153 )
154 }),
155 },
156 result_template: "∫P_n(x) dx (symbolic - orthogonal polynomial integration requires specialized techniques)".to_owned(),
157 constant_handling: ConstantOfIntegration::AddConstant,
158 },
159 wolfram_name: None,
160 })),
161 );
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use super::*;
168
169 #[test]
170 fn test_legendre_mathematical_accuracy() {
171 let legendre = LegendreIntelligence::new();
172
173 // Test that Legendre polynomials are recognized
174 assert!(legendre.has_function("legendre_p"));
175
176 // Test mathematical properties
177 let properties = legendre.get_properties();
178 if let Some(FunctionProperties::Polynomial(legendre_props)) = properties.get("legendre_p") {
179 // Verify polynomial family
180 assert_eq!(legendre_props.family, PolynomialFamily::Legendre);
181
182 // Verify initial conditions: P_0 = 1, P_1 = x
183 assert_eq!(
184 legendre_props.recurrence.initial_conditions.0,
185 Expression::integer(1)
186 );
187 assert_eq!(
188 legendre_props.recurrence.initial_conditions.1,
189 Expression::symbol("x")
190 );
191
192 // Verify orthogonality interval [-1, 1]
193 if let Some(ref ortho) = legendre_props.orthogonality {
194 assert_eq!(ortho.interval.0, Expression::integer(-1));
195 assert_eq!(ortho.interval.1, Expression::integer(1));
196 assert_eq!(ortho.weight_function, Expression::integer(1));
197 }
198
199 // Verify special values
200 assert!(!legendre_props.special_values.is_empty());
201
202 // Verify P_n(1) = 1
203 let p_at_1 = legendre_props
204 .special_values
205 .iter()
206 .find(|sv| sv.input == "1")
207 .expect("P_n(1) special value should exist");
208 assert_eq!(p_at_1.output, Expression::integer(1));
209 }
210 }
211
212 #[test]
213 fn test_legendre_recurrence_accuracy() {
214 let legendre = LegendreIntelligence::new();
215 let properties = legendre.get_properties();
216
217 if let Some(FunctionProperties::Polynomial(legendre_props)) = properties.get("legendre_p") {
218 // Verify recurrence relation structure
219 // (n+1)P_{n+1}(x) = (2n+1)x P_n(x) - n P_{n-1}(x)
220
221 // Beta coefficient should be 0 (no constant term)
222 assert_eq!(legendre_props.recurrence.beta_coeff, Expression::integer(0));
223
224 // Evaluation method should be recurrence (most accurate)
225 assert_eq!(
226 legendre_props.evaluation_method,
227 EvaluationMethod::Recurrence
228 );
229 }
230 }
231}