pub fn wrapping_geom_series<T, N>(r: T, n: N) -> Twhere
T: PrimInt + Unsigned + ConstOne + ConstZero + WrappingMul + WrappingAdd + WrappingSub + AddAssign + MulAssign,
N: PrimInt + Unsigned + ConstOne + ConstZero + BitAnd,Expand description
Calculate geometric series
That is, calculate the geometric series:
1 + r + r^2 + r^3 + … r^(n-1)
summed to n terms, with the natural modulo of the unsigned integer
type T (ie, with wrapping).
It makes use of the fact that the series can pair up terms:
(1 + r) + (1 + r) r^2 + (1 + r) r^4 + … + (1 + r) (r^2)^(n/2-1) + [ r^(n-1) if n is odd ] (1 + r) (1 + r^2 + r^4 + … + (r^2)^(n/2-1)) + [ r^(n-1) if n is odd ]
Which can easily be calculated by recursion, with time order O(log n), and
stack depth O(log n). However that stack depth isn’t good, so a
non-recursive implementation is preferable.
This implementation is by a loop, not recursion, with time order
O(log n) and stack depth O(1).
use simplerandom::maths::wrapping_geom_series;
let result = wrapping_geom_series(12345_u32, 1500000_u32);
assert_eq!(result, 57634016_u32);