mod basic;
pub mod by_parts;
pub mod educational;
mod function_integrals;
pub mod numerical;
pub mod rational;
pub mod risch;
pub mod strategy;
pub mod substitution;
pub mod table;
pub mod trigonometric;
pub use basic::BasicIntegrals;
pub use by_parts::IntegrationByParts;
pub use educational::{
explain_constant_rule, explain_definite_integral, explain_integration_by_parts,
explain_power_rule, explain_sum_rule, explain_u_substitution,
};
pub use function_integrals::FunctionIntegrals;
pub use numerical::{
AdaptiveSimpson, GaussianQuadrature, IntegrationConfig, IntegrationResult, NumericalIntegrator,
RombergIntegration,
};
pub use rational::{integrate_rational, is_rational_function};
pub use substitution::try_substitution;
pub use trigonometric::try_trigonometric_integration;
use crate::core::{Expression, Symbol};
use crate::error::MathError;
use std::collections::HashMap;
use strategy::integrate_with_strategy;
pub trait Integration {
fn integrate(&self, variable: Symbol, depth: usize) -> Expression;
fn definite_integrate(
&self,
variable: Symbol,
lower: Expression,
upper: Expression,
) -> Result<Expression, MathError>;
}
impl Integration for Expression {
fn integrate(&self, variable: Symbol, depth: usize) -> Expression {
integrate_with_strategy(self, variable, depth)
}
fn definite_integrate(
&self,
variable: Symbol,
lower: Expression,
upper: Expression,
) -> Result<Expression, MathError> {
let antiderivative = self.integrate(variable.clone(), 0);
let mut substitutions = HashMap::new();
substitutions.insert(variable.name().to_string(), upper.clone());
let upper_val = antiderivative.clone().substitute(&substitutions);
substitutions.insert(variable.name().to_string(), lower.clone());
let lower_val = antiderivative.substitute(&substitutions);
Ok(Expression::add(vec![
upper_val,
Expression::mul(vec![Expression::integer(-1), lower_val]),
]))
}
}
pub struct IntegrationMethods;
impl IntegrationMethods {
pub fn by_parts(expr: &Expression, variable: Symbol) -> Result<Expression, MathError> {
IntegrationByParts::integrate(expr, variable.clone(), 0).ok_or_else(|| {
MathError::NotImplemented {
feature: format!("integration by parts for {}", expr),
}
})
}
pub fn substitution(expr: &Expression, variable: Symbol) -> Result<Expression, MathError> {
try_substitution(expr, &variable, 0).ok_or_else(|| MathError::NotImplemented {
feature: format!("u-substitution for {}", expr),
})
}
}