mod constant_sequence;
mod power_sequence;
mod recurrent;
use std::ops::{Mul, Div};
use crate::local_num::{LocalOne, LocalZero};
use constant_sequence::ConstantSequence;
use power_sequence::PowerSequence;
use super::Sequence;
pub fn constant<T>(term: T) -> impl Clone + Sequence<Term=T>
where T: Clone {
ConstantSequence::new(term)
}
pub fn linear<T>(term: T) -> impl Clone + Sequence<Term=T>
where T: Clone + LocalZero {
let zero = term.local_zero();
constant(term).term_scan(zero, |ongoing, t| {
let out = ongoing.clone();
*ongoing = ongoing.clone() + t;
out
})
}
pub fn power<T>(coefficient: T, term: T, power: u32) -> impl Clone + Sequence<Term=T>
where T: Clone + LocalOne {
PowerSequence::new(coefficient, term, power)
}
pub fn geometric_progression<T>(term: T) -> impl Clone + Sequence<Term=T>
where T: Clone + LocalOne {
PowerSequence::new(term.local_one(), term, 1)
}
pub fn exponential_progression<T>(x: T) -> impl Clone + Sequence<Term=T>
where T: Clone + LocalZero + LocalOne + Mul<Output = T> + Div<Output = T> {
let zero = x.local_zero();
let one = x.local_one();
let denom = linear(one.clone()).skip(1);
let numer = constant(x);
numer.term_compose(denom, (zero.clone(), zero.clone()), |n, d| n / d).term_scan(one, |acc, t| {
let out = acc.clone();
*acc = acc.clone() * t;
out
})
}
pub fn lucas(initial_values: (u32, u32)) -> impl Clone + Sequence<Term=u32> {
recurrent::Lucas::new(initial_values)
}
pub fn fibonacci() -> impl Clone + Sequence<Term=u32> {
recurrent::Lucas::fibonacci()
}
pub fn collatz(starting_element: u32) -> impl Clone + Sequence<Term=u32> {
recurrent::Collatz::new(starting_element)
}
pub fn thue_morse(starting_element: u32) -> impl Clone + Sequence<Term=u32> {
recurrent::ThueMorse::new(starting_element)
}
#[cfg(test)]
mod test;