competitive/math/
berlekamp_massey.rs1use super::{One, Zero};
2use std::{
3 mem::swap,
4 ops::{Add, Div, Mul, Sub},
5};
6
7pub fn berlekamp_massey<T>(a: &[T]) -> Vec<T>
8where
9 T: Zero
10 + One
11 + Clone
12 + PartialEq
13 + Add<Output = T>
14 + Sub<Output = T>
15 + Mul<Output = T>
16 + Div<Output = T>,
17{
18 let n = a.len();
19 let mut b = Vec::with_capacity(n + 1);
20 let mut c = Vec::with_capacity(n + 1);
21 let mut tmp = Vec::with_capacity(n + 1);
22 b.push(T::one());
23 c.push(T::one());
24 let mut y = T::one();
25 for k in 1..=n {
26 let clen = c.len();
27 let mut x = T::zero();
28 for (c, a) in c.iter().zip(&a[k - clen..]) {
29 x = x + c.clone() * a.clone();
30 }
31 b.push(T::zero());
32 let blen = b.len();
33 if x.is_zero() {
34 continue;
35 }
36 let freq = x.clone() / y.clone();
37 if clen < blen {
38 swap(&mut c, &mut tmp);
39 c.clear();
40 c.resize_with(blen - clen, T::zero);
41 c.extend(tmp.iter().cloned());
42 for (c, b) in c.iter_mut().rev().zip(b.iter().rev()) {
43 *c = c.clone() - freq.clone() * b.clone();
44 }
45 swap(&mut b, &mut tmp);
46 y = x;
47 } else {
48 for (c, b) in c.iter_mut().rev().zip(b.iter().rev()) {
49 *c = c.clone() - freq.clone() * b.clone();
50 }
51 }
52 }
53 c.reverse();
54 c
55}