use crate::core::{Expression, Symbol};
pub fn integrate_sin_cos_power(m: i64, n: i64, var: Symbol) -> Option<Expression> {
let x = Expression::symbol(var.clone());
if m == 1 && n == 0 {
return Some(Expression::mul(vec![
Expression::integer(-1),
Expression::function("cos", vec![x]),
]));
}
if m == 0 && n == 1 {
return Some(Expression::function("sin", vec![x]));
}
if m > 0 && m % 2 == 1 {
return Some(integrate_with_cos_substitution(m, n, var));
}
if n > 0 && n % 2 == 1 {
return Some(integrate_with_sin_substitution(m, n, var));
}
if m >= 0 && n >= 0 && m % 2 == 0 && n % 2 == 0 {
return Some(integrate_with_power_reduction(m, n, var));
}
None
}
fn integrate_with_cos_substitution(m: i64, n: i64, var: Symbol) -> Expression {
let x = Expression::symbol(var.clone());
if m == 1 {
if n == 0 {
return Expression::mul(vec![
Expression::integer(-1),
Expression::function("cos", vec![x]),
]);
} else {
return Expression::mul(vec![
Expression::integer(-1),
Expression::pow(
Expression::function("cos", vec![x]),
Expression::integer(n + 1),
),
Expression::rational(1, n + 1),
]);
}
}
if m == 3 && n == 0 {
return Expression::add(vec![
Expression::mul(vec![
Expression::integer(-1),
Expression::function("cos", vec![x.clone()]),
]),
Expression::mul(vec![
Expression::pow(Expression::function("cos", vec![x]), Expression::integer(3)),
Expression::rational(1, 3),
]),
]);
}
Expression::integral(
Expression::mul(vec![
Expression::pow(
Expression::function("sin", vec![x.clone()]),
Expression::integer(m),
),
Expression::pow(Expression::function("cos", vec![x]), Expression::integer(n)),
]),
var,
)
}
fn integrate_with_sin_substitution(m: i64, n: i64, var: Symbol) -> Expression {
let x = Expression::symbol(var.clone());
if n == 1 {
if m == 0 {
return Expression::function("sin", vec![x]);
} else {
return Expression::mul(vec![
Expression::pow(
Expression::function("sin", vec![x]),
Expression::integer(m + 1),
),
Expression::rational(1, m + 1),
]);
}
}
if n == 3 && m == 0 {
return Expression::add(vec![
Expression::function("sin", vec![x.clone()]),
Expression::mul(vec![
Expression::integer(-1),
Expression::pow(Expression::function("sin", vec![x]), Expression::integer(3)),
Expression::rational(1, 3),
]),
]);
}
Expression::integral(
Expression::mul(vec![
Expression::pow(
Expression::function("sin", vec![x.clone()]),
Expression::integer(m),
),
Expression::pow(Expression::function("cos", vec![x]), Expression::integer(n)),
]),
var,
)
}
fn integrate_with_power_reduction(m: i64, n: i64, var: Symbol) -> Expression {
let x = Expression::symbol(var.clone());
if m == 2 && n == 0 {
return Expression::add(vec![
Expression::mul(vec![Expression::rational(1, 2), x.clone()]),
Expression::mul(vec![
Expression::rational(-1, 4),
Expression::function(
"sin",
vec![Expression::mul(vec![Expression::integer(2), x])],
),
]),
]);
}
if m == 0 && n == 2 {
return Expression::add(vec![
Expression::mul(vec![Expression::rational(1, 2), x.clone()]),
Expression::mul(vec![
Expression::rational(1, 4),
Expression::function(
"sin",
vec![Expression::mul(vec![Expression::integer(2), x])],
),
]),
]);
}
if m == 2 && n == 2 {
return Expression::add(vec![
Expression::mul(vec![Expression::rational(1, 8), x.clone()]),
Expression::mul(vec![
Expression::rational(-1, 32),
Expression::function(
"sin",
vec![Expression::mul(vec![Expression::integer(4), x])],
),
]),
]);
}
Expression::integral(
Expression::mul(vec![
Expression::pow(
Expression::function("sin", vec![x.clone()]),
Expression::integer(m),
),
Expression::pow(Expression::function("cos", vec![x]), Expression::integer(n)),
]),
var,
)
}