use crate::core::Expression;
use crate::simplify::Simplify;
#[inline]
#[must_use]
pub fn expand_legendre_symbolic(n: usize) -> Expression {
if n == 0 {
return Expression::integer(1);
}
if n == 1 {
return Expression::symbol("x");
}
let x = Expression::symbol("x");
let mut p_prev = Expression::integer(1);
let mut p_curr = x.clone();
for i in 1..n {
let i_i64 = i as i64;
let alpha_num = 2 * i_i64 + 1;
let alpha_den = i_i64 + 1;
let gamma_num = -i_i64;
let gamma_den = i_i64 + 1;
let term1 = Expression::mul(vec![
Expression::rational(alpha_num, alpha_den),
x.clone(),
p_curr.clone(),
]);
let term2 = Expression::mul(vec![
Expression::rational(gamma_num, gamma_den),
p_prev.clone(),
]);
let p_next = Expression::add(vec![term1, term2]).simplify();
p_prev = p_curr;
p_curr = p_next;
}
p_curr
}
#[inline]
#[must_use]
pub fn expand_hermite_symbolic(n: usize) -> Expression {
if n == 0 {
return Expression::integer(1);
}
if n == 1 {
return Expression::mul(vec![Expression::integer(2), Expression::symbol("x")]);
}
let x = Expression::symbol("x");
let mut p_prev = Expression::integer(1);
let mut p_curr = Expression::mul(vec![Expression::integer(2), x.clone()]);
for i in 1..n {
let i_i64 = i as i64;
let term1 = Expression::mul(vec![Expression::integer(2), x.clone(), p_curr.clone()]);
let term2 = Expression::mul(vec![Expression::integer(-2 * i_i64), p_prev.clone()]);
let p_next = Expression::add(vec![term1, term2]).simplify();
p_prev = p_curr;
p_curr = p_next;
}
p_curr
}
#[inline]
#[must_use]
pub fn expand_laguerre_symbolic(n: usize) -> Expression {
if n == 0 {
return Expression::integer(1);
}
if n == 1 {
return Expression::add(vec![
Expression::integer(1),
Expression::mul(vec![Expression::integer(-1), Expression::symbol("x")]),
]);
}
let x = Expression::symbol("x");
let mut p_prev = Expression::integer(1);
let mut p_curr = Expression::add(vec![
Expression::integer(1),
Expression::mul(vec![Expression::integer(-1), x.clone()]),
]);
for i in 1..n {
let i_i64 = i as i64;
let alpha_num = -1;
let alpha_den = i_i64 + 1;
let beta_num = 2 * i_i64 + 1;
let beta_den = i_i64 + 1;
let gamma_num = -i_i64;
let gamma_den = i_i64 + 1;
let term1 = Expression::mul(vec![
Expression::rational(alpha_num, alpha_den),
x.clone(),
p_curr.clone(),
]);
let term2 = Expression::mul(vec![
Expression::rational(beta_num, beta_den),
p_curr.clone(),
]);
let term3 = Expression::mul(vec![
Expression::rational(gamma_num, gamma_den),
p_prev.clone(),
]);
let p_next = Expression::add(vec![term1, term2, term3]).simplify();
p_prev = p_curr;
p_curr = p_next;
}
p_curr
}
#[inline]
#[must_use]
pub fn expand_chebyshev_first_symbolic(n: usize) -> Expression {
if n == 0 {
return Expression::integer(1);
}
if n == 1 {
return Expression::symbol("x");
}
let x = Expression::symbol("x");
let mut p_prev = Expression::integer(1);
let mut p_curr = x.clone();
for _ in 1..n {
let term1 = Expression::mul(vec![Expression::integer(2), x.clone(), p_curr.clone()]);
let term2 = Expression::mul(vec![Expression::integer(-1), p_prev.clone()]);
let p_next = Expression::add(vec![term1, term2]).simplify();
p_prev = p_curr;
p_curr = p_next;
}
p_curr
}
#[inline]
#[must_use]
pub fn expand_chebyshev_second_symbolic(n: usize) -> Expression {
if n == 0 {
return Expression::integer(1);
}
if n == 1 {
return Expression::mul(vec![Expression::integer(2), Expression::symbol("x")]);
}
let x = Expression::symbol("x");
let mut p_prev = Expression::integer(1);
let mut p_curr = Expression::mul(vec![Expression::integer(2), x.clone()]);
for _ in 1..n {
let term1 = Expression::mul(vec![Expression::integer(2), x.clone(), p_curr.clone()]);
let term2 = Expression::mul(vec![Expression::integer(-1), p_prev.clone()]);
let p_next = Expression::add(vec![term1, term2]).simplify();
p_prev = p_curr;
p_curr = p_next;
}
p_curr
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_legendre_p0_p1() {
let p0 = expand_legendre_symbolic(0);
let p1 = expand_legendre_symbolic(1);
assert_eq!(p0, Expression::integer(1));
assert_eq!(p1, Expression::symbol("x"));
}
#[test]
fn test_hermite_h0_h1() {
let h0 = expand_hermite_symbolic(0);
let h1 = expand_hermite_symbolic(1);
assert_eq!(h0, Expression::integer(1));
assert_eq!(
h1,
Expression::mul(vec![Expression::integer(2), Expression::symbol("x")])
);
}
#[test]
fn test_laguerre_l0_l1() {
let l0 = expand_laguerre_symbolic(0);
let _l1 = expand_laguerre_symbolic(1);
assert_eq!(l0, Expression::integer(1));
}
#[test]
fn test_chebyshev_first_t0_t1() {
let t0 = expand_chebyshev_first_symbolic(0);
let t1 = expand_chebyshev_first_symbolic(1);
assert_eq!(t0, Expression::integer(1));
assert_eq!(t1, Expression::symbol("x"));
}
#[test]
fn test_chebyshev_second_u0_u1() {
let u0 = expand_chebyshev_second_symbolic(0);
let u1 = expand_chebyshev_second_symbolic(1);
assert_eq!(u0, Expression::integer(1));
assert_eq!(
u1,
Expression::mul(vec![Expression::integer(2), Expression::symbol("x")])
);
}
}