use symplex::prelude::*;
#[test]
fn faulhaber_sum_k_1_to_10() {
let ctx = Context::new();
let k = ctx.symbol("k");
let s = Ex::symbolic_sum(&k, &k, &ctx.int(1), &ctx.int(10));
let result = s.eval();
assert_eq!(format!("{result}"), "55");
}
#[test]
fn faulhaber_sum_k_sq_1_to_10() {
let ctx = Context::new();
let k = ctx.symbol("k");
let body = k.powi(2);
let s = Ex::symbolic_sum(&body, &k, &ctx.int(1), &ctx.int(10));
let result = s.eval();
assert_eq!(format!("{result}"), "385");
}
#[test]
fn faulhaber_sum_k_cube_1_to_10() {
let ctx = Context::new();
let k = ctx.symbol("k");
let body = k.powi(3);
let s = Ex::symbolic_sum(&body, &k, &ctx.int(1), &ctx.int(10));
let result = s.eval();
assert_eq!(format!("{result}"), "3025");
}
#[test]
fn faulhaber_sum_k_4_1_to_10() {
let ctx = Context::new();
let k = ctx.symbol("k");
let body = k.powi(4);
let s = Ex::symbolic_sum(&body, &k, &ctx.int(1), &ctx.int(10));
let result = s.eval();
assert_eq!(format!("{result}"), "25333");
}
#[test]
fn geometric_sum_2_pow_k_0_to_9() {
let ctx = Context::new();
let k = ctx.symbol("k");
let body = ctx.int(2).pow(&k);
let s = Ex::symbolic_sum(&body, &k, &ctx.int(0), &ctx.int(9));
let result = s.eval();
assert_eq!(format!("{result}"), "1023");
}
#[test]
fn constant_sum_5_from_1_to_10() {
let ctx = Context::new();
let k = ctx.symbol("k");
let body = ctx.int(5);
let s = Ex::symbolic_sum(&body, &k, &ctx.int(1), &ctx.int(10));
let result = s.eval();
assert_eq!(format!("{result}"), "50");
}
#[test]
fn symbolic_sum_k_1_to_n_gives_closed_form() {
let ctx = Context::new();
let k = ctx.symbol("k");
let n = ctx.symbol("n");
let s = Ex::symbolic_sum(&k, &k, &ctx.int(1), &n);
let closed = s.closed_form_sum();
let evaluated = closed.subs(&n, &ctx.int(10)).eval();
assert_eq!(format!("{evaluated}"), "55");
}
#[test]
fn symbolic_constant_sum_to_n() {
let ctx = Context::new();
let k = ctx.symbol("k");
let n = ctx.symbol("n");
let body = ctx.int(3);
let s = Ex::symbolic_sum(&body, &k, &ctx.int(1), &n);
let closed = s.closed_form_sum();
let evaluated = closed.subs(&n, &ctx.int(10)).eval();
assert_eq!(format!("{evaluated}"), "30");
}
#[test]
fn convergence_p_series_k_sq_converges() {
let ctx = Context::new();
let k = ctx.symbol("k");
let body = k.powi(-2);
assert_eq!(body.is_convergent(&k), Some(true));
}
#[test]
fn convergence_harmonic_diverges() {
let ctx = Context::new();
let k = ctx.symbol("k");
let body = k.powi(-1);
assert_eq!(body.is_convergent(&k), Some(false));
}
#[test]
fn convergence_geometric_half_converges() {
let ctx = Context::new();
let k = ctx.symbol("k");
let half = ctx.rational(1, 2);
let body = half.pow(&k);
assert_eq!(body.is_convergent(&k), Some(true));
}
#[test]
fn convergence_geometric_2_diverges() {
let ctx = Context::new();
let k = ctx.symbol("k");
let body = ctx.int(2).pow(&k);
assert_eq!(body.is_convergent(&k), Some(false));
}
#[test]
fn gamma_positive_integer_still_works() {
let ctx = Context::new();
let result = ctx.int(5).gamma().eval();
assert_eq!(format!("{result}"), "24");
}
#[test]
fn gamma_half_integer_still_works() {
let ctx = Context::new();
let result = ctx.rational(1, 2).gamma().eval();
assert_eq!(format!("{result}"), "sqrt(pi)");
}
#[test]
fn gamma_recurrence_7_over_3() {
let ctx = Context::new();
let result = ctx.rational(7, 3).gamma().eval();
let display = format!("{result}");
assert!(
display.contains("Gamma(1/3)") || display.contains("gamma(1/3)"),
"Expected Gamma(1/3) in result, got: {display}"
);
}
#[test]
fn gamma_recurrence_5_over_3() {
let ctx = Context::new();
let result = ctx.rational(5, 3).gamma().eval();
let display = format!("{result}");
assert!(
display.contains("Gamma(2/3)") || display.contains("gamma(2/3)"),
"Expected Gamma(2/3) in result, got: {display}"
);
}