1use std;
4
5use collect_slice::CollectSlice;
6
7pub type P25Codeword = Codeword<P25Field>;
9
10#[derive(Copy, Clone, Debug)]
13pub struct P25Field;
14
15impl GaloisField for P25Field {
16 fn size() -> usize {
17 63
18 }
19 fn valid_codeword(bits: u8) -> bool {
20 bits >> 6 == 0
21 }
22
23 fn codeword(pow: usize) -> u8 {
24 const CODEWORDS: [u8; 63] = [
27 0b000001, 0b000010, 0b000100, 0b001000, 0b010000, 0b100000, 0b000011, 0b000110,
28 0b001100, 0b011000, 0b110000, 0b100011, 0b000101, 0b001010, 0b010100, 0b101000,
29 0b010011, 0b100110, 0b001111, 0b011110, 0b111100, 0b111011, 0b110101, 0b101001,
30 0b010001, 0b100010, 0b000111, 0b001110, 0b011100, 0b111000, 0b110011, 0b100101,
31 0b001001, 0b010010, 0b100100, 0b001011, 0b010110, 0b101100, 0b011011, 0b110110,
32 0b101111, 0b011101, 0b111010, 0b110111, 0b101101, 0b011001, 0b110010, 0b100111,
33 0b001101, 0b011010, 0b110100, 0b101011, 0b010101, 0b101010, 0b010111, 0b101110,
34 0b011111, 0b111110, 0b111111, 0b111101, 0b111001, 0b110001, 0b100001,
35 ];
36
37 CODEWORDS[pow]
38 }
39
40 fn power(codeword: usize) -> usize {
41 const POWERS: [usize; 63] = [
42 0, 1, 6, 2, 12, 7, 26, 3, 32, 13, 35, 8, 48, 27, 18, 4, 24, 33, 16, 14, 52, 36, 54, 9,
43 45, 49, 38, 28, 41, 19, 56, 5, 62, 25, 11, 34, 31, 17, 47, 15, 23, 53, 51, 37, 44, 55,
44 40, 10, 61, 46, 30, 50, 22, 39, 43, 29, 60, 42, 21, 20, 59, 57, 58,
45 ];
46
47 POWERS[codeword]
48 }
49}
50
51pub trait GaloisField {
53 fn size() -> usize;
55 fn valid_codeword(bits: u8) -> bool;
57 fn codeword(pow: usize) -> u8;
59 fn power(codeword: usize) -> usize;
61
62 fn codeword_modded(pow: usize) -> u8 {
65 Self::codeword(pow % Self::size())
66 }
67}
68
69#[derive(Copy, Clone)]
71pub struct Codeword<F: GaloisField> {
72 field: std::marker::PhantomData<F>,
73 bits: u8,
74}
75
76impl<F: GaloisField> Codeword<F> {
77 pub fn new(bits: u8) -> Codeword<F> {
80 assert!(F::valid_codeword(bits));
81
82 Codeword {
83 field: std::marker::PhantomData,
84 bits: bits,
85 }
86 }
87
88 pub fn for_power(power: usize) -> Codeword<F> {
91 Codeword::new(F::codeword_modded(power))
92 }
93
94 pub fn bits(&self) -> u8 {
96 self.bits
97 }
98
99 pub fn zero(&self) -> bool {
101 self.bits == 0
102 }
103
104 pub fn power(&self) -> Option<usize> {
107 if self.zero() {
108 None
109 } else {
110 Some(F::power(self.bits as usize - 1))
112 }
113 }
114
115 pub fn invert(self) -> Codeword<F> {
118 match self.power() {
119 Some(p) => Codeword::for_power(F::size() - p),
120 None => panic!("invert zero"),
121 }
122 }
123
124 pub fn pow(&self, pow: usize) -> Codeword<F> {
127 match self.power() {
128 Some(p) => Codeword::for_power(p * pow),
129 None => Codeword::default(),
130 }
131 }
132}
133
134impl<F: GaloisField> Default for Codeword<F> {
135 fn default() -> Self {
137 Codeword::new(0)
138 }
139}
140
141impl<F: GaloisField> std::ops::Add for Codeword<F> {
143 type Output = Codeword<F>;
144
145 fn add(self, rhs: Codeword<F>) -> Self::Output {
146 Codeword::new(self.bits ^ rhs.bits)
147 }
148}
149
150impl<F: GaloisField> std::ops::Sub for Codeword<F> {
152 type Output = Codeword<F>;
153
154 fn sub(self, rhs: Codeword<F>) -> Self::Output {
155 self + rhs
156 }
157}
158
159impl<F: GaloisField> std::ops::Mul for Codeword<F> {
161 type Output = Codeword<F>;
162
163 fn mul(self, rhs: Codeword<F>) -> Self::Output {
164 match (self.power(), rhs.power()) {
165 (Some(p), Some(q)) => Codeword::for_power(p + q),
166 _ => Codeword::default(),
167 }
168 }
169}
170
171impl<F: GaloisField> std::ops::Div for Codeword<F> {
173 type Output = Codeword<F>;
174
175 fn div(self, rhs: Codeword<F>) -> Self::Output {
176 match (self.power(), rhs.power()) {
177 (Some(p), Some(q)) => Codeword::for_power(F::size() + p - q),
179 (None, Some(_)) => Codeword::default(),
180 (_, None) => panic!("divide by zero"),
181 }
182 }
183}
184
185impl<F: GaloisField> std::cmp::PartialEq for Codeword<F> {
187 fn eq(&self, other: &Self) -> bool {
188 self.bits == other.bits
189 }
190}
191
192impl<F: GaloisField> std::cmp::Eq for Codeword<F> {}
193
194impl<F: GaloisField> std::cmp::PartialEq<u8> for Codeword<F> {
196 fn eq(&self, other: &u8) -> bool {
197 self.bits == *other
198 }
199}
200
201impl<F: GaloisField> std::fmt::Debug for Codeword<F> {
202 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
203 match self.power() {
204 Some(p) => write!(fmt, "Codeword::for_power({})", p),
205 None => write!(fmt, "Codeword::default()"),
206 }
207 }
208}
209
210pub trait PolynomialCoefs:
212 Default + Copy + Clone + std::ops::Deref<Target = [P25Codeword]> + std::ops::DerefMut
213{
214 fn distance() -> usize;
216
217 fn errors() -> usize {
219 Self::distance() / 2
222 }
223
224 fn syndromes() -> usize {
226 2 * Self::errors()
227 }
228
229 fn validate(&self) {
231 assert!(Self::distance() % 2 == 1);
233 assert!(self.len() > Self::syndromes());
236 }
237}
238
239macro_rules! impl_polynomial_coefs {
243 ($name:ident, $dist:expr) => {
244 impl_polynomial_coefs!($name, $dist, $dist + 1);
245 };
246 ($name:ident, $dist:expr, $len:expr) => {
247 #[derive(Copy)]
248 struct $name([P25Codeword; $len]);
249
250 impl PolynomialCoefs for $name {
251 fn distance() -> usize {
252 $dist
253 }
254 }
255
256 impl Default for $name {
257 fn default() -> Self {
258 $name([P25Codeword::default(); $len])
259 }
260 }
261
262 impl Clone for $name {
263 fn clone(&self) -> Self {
264 let mut coefs = [P25Codeword::default(); $len];
265 coefs.copy_from_slice(&self.0[..]);
266 $name(coefs)
267 }
268 }
269
270 impl std::ops::Deref for $name {
271 type Target = [P25Codeword];
272 fn deref(&self) -> &Self::Target {
273 &self.0[..]
274 }
275 }
276
277 impl std::ops::DerefMut for $name {
278 fn deref_mut(&mut self) -> &mut Self::Target {
279 &mut self.0[..]
280 }
281 }
282 };
283}
284
285#[derive(Copy, Clone)]
287pub struct Polynomial<P: PolynomialCoefs> {
288 coefs: P,
291 start: usize,
294}
295
296impl<P: PolynomialCoefs> Polynomial<P> {
297 pub fn new<T: Iterator<Item = P25Codeword>>(mut init: T) -> Self {
303 let mut coefs = P::default();
305 init.collect_slice_exhaust(&mut coefs[..]);
306
307 Self::with_coefs(coefs)
308 }
309
310 pub fn unit_power(n: usize) -> Self {
312 let mut coefs = P::default();
313 coefs[n] = Codeword::for_power(0);
314
315 Self::with_coefs(coefs)
316 }
317
318 fn with_coefs(coefs: P) -> Self {
320 Polynomial { coefs, start: 0 }
321 }
322
323 pub fn constant(&self) -> P25Codeword {
325 self.coefs[self.start]
326 }
327
328 pub fn degree(&self) -> Option<usize> {
333 for (deg, coef) in self.coefs.iter().enumerate().rev() {
334 if !coef.zero() {
335 return Some(deg - self.start);
337 }
338 }
339
340 None
341 }
342
343 pub fn shift(mut self) -> Polynomial<P> {
348 assert!(self.constant().zero());
349
350 self.coefs[self.start] = P25Codeword::default();
351 self.start += 1;
352 self
353 }
354
355 fn get(&self, idx: usize) -> P25Codeword {
358 match self.coefs.get(idx) {
359 Some(&c) => c,
360 None => P25Codeword::default(),
361 }
362 }
363
364 pub fn coef(&self, i: usize) -> P25Codeword {
368 self.get(self.start + i)
369 }
370
371 pub fn eval(&self, x: P25Codeword) -> P25Codeword {
373 self.iter()
376 .rev()
377 .fold(P25Codeword::default(), |s, &coef| s * x + coef)
378 }
379
380 pub fn truncate(mut self, deg: usize) -> Polynomial<P> {
384 for i in (self.start + deg + 1)..self.coefs.len() {
385 self.coefs[i] = P25Codeword::default();
386 }
387
388 self
389 }
390
391 pub fn deriv(mut self) -> Polynomial<P> {
393 for i in self.start..self.coefs.len() {
394 self.coefs[i] = if (i - self.start) % 2 == 0 {
395 self.get(i + 1)
396 } else {
397 P25Codeword::default()
398 };
399 }
400
401 self
402 }
403}
404
405impl<P: PolynomialCoefs> Default for Polynomial<P> {
406 fn default() -> Self {
408 Polynomial::new(std::iter::empty())
409 }
410}
411
412impl<P: PolynomialCoefs> std::ops::Deref for Polynomial<P> {
415 type Target = [P25Codeword];
416 fn deref(&self) -> &Self::Target {
417 &self.coefs[self.start..]
418 }
419}
420
421impl<P: PolynomialCoefs> std::ops::DerefMut for Polynomial<P> {
422 fn deref_mut(&mut self) -> &mut Self::Target {
423 &mut self.coefs[self.start..]
424 }
425}
426
427impl<P: PolynomialCoefs> std::ops::Add for Polynomial<P> {
429 type Output = Polynomial<P>;
430
431 fn add(mut self, rhs: Polynomial<P>) -> Self::Output {
432 for i in 0..self.coefs.len() {
436 self.coefs[i] = self.coef(i) + rhs.coef(i);
437 }
438
439 self.start = 0;
440 self
441 }
442}
443
444impl<P: PolynomialCoefs> std::ops::Mul<P25Codeword> for Polynomial<P> {
446 type Output = Polynomial<P>;
447
448 fn mul(mut self, rhs: P25Codeword) -> Self::Output {
449 for coef in self.coefs.iter_mut() {
450 *coef = *coef * rhs;
451 }
452
453 self
454 }
455}
456
457impl<P: PolynomialCoefs> std::ops::Mul<Polynomial<P>> for Polynomial<P> {
463 type Output = Polynomial<P>;
464
465 fn mul(self, rhs: Polynomial<P>) -> Self::Output {
466 let mut out = Polynomial::<P>::default();
467
468 for (i, &coef) in self.iter().enumerate() {
469 for (j, &mult) in rhs.iter().enumerate() {
470 if let Some(c) = out.coefs.get_mut(i + j) {
471 *c = *c + coef * mult
472 }
473 }
474 }
475
476 out
477 }
478}
479
480impl<P: PolynomialCoefs> std::fmt::Debug for Polynomial<P> {
481 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
482 write!(fmt, "Polynomial({:?})", &self.coefs[..])
483 }
484}
485
486#[cfg(test)]
487mod test {
488 use super::*;
489 use std;
490
491 impl_polynomial_coefs!(TestCoefs, 23);
492 type TestPolynomial = Polynomial<TestCoefs>;
493
494 impl_polynomial_coefs!(ShortCoefs, 5);
495 type ShortPolynomial = Polynomial<ShortCoefs>;
496
497 #[test]
498 fn test_coefs() {
499 assert_eq!(TestCoefs::errors(), 11);
500 assert_eq!(TestCoefs::syndromes(), 22);
501 }
502
503 #[test]
504 fn test_for_power() {
505 assert!(P25Codeword::for_power(0) == 0b000001);
506 assert!(P25Codeword::for_power(62) == 0b100001);
507 assert!(P25Codeword::for_power(63) == 0b000001);
508 }
509
510 #[test]
511 fn test_add_sub() {
512 assert!((P25Codeword::new(0b100000) + P25Codeword::new(0b010000)) == 0b110000);
513 assert!((P25Codeword::new(0b100000) - P25Codeword::new(0b010000)) == 0b110000);
514 assert!((P25Codeword::new(0b100001) + P25Codeword::new(0b100001)) == 0b000000);
515 assert!((P25Codeword::new(0b100001) - P25Codeword::new(0b100001)) == 0b000000);
516 assert!((P25Codeword::new(0b100001) + P25Codeword::new(0b110100)) == 0b010101);
517 assert!((P25Codeword::new(0b100001) - P25Codeword::new(0b110100)) == 0b010101);
518 }
519
520 #[test]
521 fn test_mul() {
522 assert!((P25Codeword::new(0b000110) * P25Codeword::new(0b000101)) == 0b011110);
523 assert!((P25Codeword::new(0b000000) * P25Codeword::new(0b000101)) == 0b000000);
524 assert!((P25Codeword::new(0b000110) * P25Codeword::new(0b000000)) == 0b000000);
525 assert!((P25Codeword::new(0b000000) * P25Codeword::new(0b000000)) == 0b000000);
526 assert!((P25Codeword::new(0b100001) * P25Codeword::new(0b000001)) == 0b100001);
527 assert!((P25Codeword::new(0b100001) * P25Codeword::new(0b000010)) == 0b000001);
528 assert!((P25Codeword::new(0b110011) * P25Codeword::new(0b110011)) == 0b111001);
529 assert!((P25Codeword::new(0b101111) * P25Codeword::new(0b101111)) == 0b100110);
530 }
531
532 #[test]
533 fn test_div() {
534 assert!((P25Codeword::new(0b001000) / P25Codeword::new(0b000101)) == 0b010111);
535 assert!((P25Codeword::new(0b000000) / P25Codeword::new(0b101000)) == 0b000000);
536 assert!((P25Codeword::new(0b011110) / P25Codeword::new(0b000001)) == 0b011110);
537 assert!((P25Codeword::new(0b011110) / P25Codeword::new(0b011110)) == 0b000001);
538 }
539
540 #[test]
541 fn test_cmp() {
542 assert!(P25Codeword::new(0b000000) == P25Codeword::new(0b000000));
543 }
544
545 #[test]
546 fn test_pow() {
547 assert_eq!(P25Codeword::for_power(0).pow(10).power().unwrap(), 0);
548 assert_eq!(P25Codeword::for_power(1).pow(10).power().unwrap(), 10);
549 assert_eq!(P25Codeword::for_power(62).pow(10).power().unwrap(), 53);
550 assert!(P25Codeword::default().pow(20).power().is_none());
551 }
552
553 #[test]
554 fn test_eval() {
555 let p = TestPolynomial::new((0..3).map(|_| P25Codeword::for_power(0)));
556 assert!(p.eval(P25Codeword::for_power(1)) == 0b000111);
557
558 let p = TestPolynomial::new((0..2).map(|_| P25Codeword::for_power(0)));
559 assert_eq!(p.eval(P25Codeword::for_power(1)), 0b000011);
560
561 let p = TestPolynomial::new(
562 [
563 P25Codeword::default(),
564 P25Codeword::default(),
565 P25Codeword::default(),
566 P25Codeword::for_power(0),
567 ]
568 .iter()
569 .cloned(),
570 );
571 assert_eq!(p.eval(P25Codeword::for_power(3)), 0b011000);
572
573 let p = TestPolynomial::new(
574 [
575 P25Codeword::default(),
576 P25Codeword::for_power(0),
577 P25Codeword::default(),
578 P25Codeword::for_power(0),
579 ]
580 .iter()
581 .cloned(),
582 );
583 assert_eq!(p.eval(P25Codeword::for_power(3)), 0b010000);
584
585 let p = TestPolynomial::new(
586 [
587 P25Codeword::default(),
588 P25Codeword::default(),
589 P25Codeword::default(),
590 P25Codeword::default(),
591 P25Codeword::default(),
592 P25Codeword::default(),
593 P25Codeword::default(),
594 P25Codeword::default(),
595 P25Codeword::default(),
596 P25Codeword::default(),
597 P25Codeword::default(),
598 P25Codeword::default(),
599 P25Codeword::default(),
600 P25Codeword::default(),
601 P25Codeword::default(),
602 P25Codeword::default(),
603 P25Codeword::default(),
604 P25Codeword::default(),
605 P25Codeword::default(),
606 P25Codeword::default(),
607 P25Codeword::default(),
608 P25Codeword::default(),
609 P25Codeword::default(),
610 P25Codeword::for_power(5),
611 ]
612 .iter()
613 .cloned(),
614 );
615 assert_eq!(p.eval(P25Codeword::for_power(4)), 0b100100);
616
617 let p = TestPolynomial::new(
618 [
619 P25Codeword::for_power(12),
620 P25Codeword::default(),
621 P25Codeword::default(),
622 P25Codeword::default(),
623 P25Codeword::default(),
624 P25Codeword::default(),
625 P25Codeword::default(),
626 P25Codeword::default(),
627 P25Codeword::default(),
628 P25Codeword::default(),
629 P25Codeword::default(),
630 P25Codeword::default(),
631 P25Codeword::default(),
632 P25Codeword::default(),
633 P25Codeword::default(),
634 P25Codeword::default(),
635 P25Codeword::default(),
636 P25Codeword::default(),
637 P25Codeword::default(),
638 P25Codeword::default(),
639 P25Codeword::default(),
640 P25Codeword::default(),
641 P25Codeword::default(),
642 P25Codeword::for_power(5),
643 ]
644 .iter()
645 .cloned(),
646 );
647 assert_eq!(p.eval(P25Codeword::for_power(4)), 0b100001);
648
649 let p = TestPolynomial::new(
650 [
651 P25Codeword::for_power(0),
652 P25Codeword::for_power(0),
653 P25Codeword::for_power(0),
654 P25Codeword::for_power(0),
655 P25Codeword::for_power(0),
656 P25Codeword::for_power(0),
657 P25Codeword::for_power(0),
658 P25Codeword::for_power(0),
659 P25Codeword::for_power(0),
660 P25Codeword::for_power(0),
661 P25Codeword::for_power(0),
662 P25Codeword::for_power(0),
663 P25Codeword::for_power(0),
664 P25Codeword::for_power(0),
665 P25Codeword::for_power(0),
666 P25Codeword::for_power(0),
667 P25Codeword::for_power(0),
668 P25Codeword::for_power(0),
669 P25Codeword::for_power(0),
670 P25Codeword::for_power(0),
671 P25Codeword::for_power(0),
672 P25Codeword::for_power(0),
673 P25Codeword::for_power(0),
674 P25Codeword::for_power(0),
675 ]
676 .iter()
677 .cloned(),
678 );
679 assert!(p.eval(P25Codeword::for_power(0)).zero());
680 }
681
682 #[test]
683 fn test_truncate() {
684 let p = TestPolynomial::new((0..5).map(|_| P25Codeword::for_power(0)));
685
686 assert_eq!(p.degree().unwrap(), 4);
687 assert_eq!(p.coefs[4].power().unwrap(), 0);
688 assert!(p.coefs[5].power().is_none());
689
690 let p = p.truncate(2);
691 assert_eq!(p.degree().unwrap(), 2);
692 assert_eq!(p.coefs[2].power().unwrap(), 0);
693 assert!(p.coefs[3].power().is_none());
694 }
695
696 #[test]
697 fn test_polynomial() {
698 let p = TestPolynomial::new((0..23).map(P25Codeword::for_power));
699
700 assert!(p.degree().unwrap() == 22);
701 assert!(p.constant() == P25Codeword::for_power(0));
702
703 let p = TestPolynomial::new((1..23).map(P25Codeword::for_power));
704 assert!(p.degree().unwrap() == 21);
705 assert!(p.constant() == P25Codeword::for_power(1));
706
707 let q = p * P25Codeword::for_power(0);
708 assert!(q.degree().unwrap() == 21);
709 assert!(q.constant() == P25Codeword::for_power(1));
710
711 let q = p * P25Codeword::for_power(2);
712 assert!(q.degree().unwrap() == 21);
713 assert!(q.constant() == P25Codeword::for_power(3));
714
715 let q = p + p;
716 assert!(q.constant().zero());
717
718 for coef in q.iter() {
719 assert!(coef.zero());
720 }
721
722 let p = TestPolynomial::new((4..27).map(P25Codeword::for_power));
723
724 let q = TestPolynomial::new((4..26).map(P25Codeword::for_power));
725
726 let r = p + q;
727
728 assert!(r.coefs[0].zero());
729 assert!(r.coefs[1].zero());
730 assert!(r.coefs[2].zero());
731 assert!(r.coefs[3].zero());
732 assert!(r.coefs[4].zero());
733 assert!(!r.coefs[22].zero());
734
735 let p = TestPolynomial::new((0..2).map(|_| P25Codeword::for_power(0)));
736
737 let q = TestPolynomial::new((0..4).map(|_| P25Codeword::for_power(1)));
738
739 let r = p + q;
740
741 assert!(r.coef(0) == P25Codeword::for_power(6));
742 }
743
744 #[test]
745 fn test_poly_mul() {
746 let p = TestPolynomial::new((0..2).map(|_| P25Codeword::for_power(0)));
747
748 let q = p;
749 let r = p * q;
750
751 assert_eq!(r.coef(0).power().unwrap(), 0);
752 assert!(r.coef(1).power().is_none());
753 assert_eq!(r.coef(2).power().unwrap(), 0);
754
755 let p = TestPolynomial::new((0..3).map(P25Codeword::for_power));
756 let q = TestPolynomial::new(
757 [P25Codeword::default(), P25Codeword::for_power(0)]
758 .iter()
759 .cloned(),
760 );
761 let r = p * q;
762
763 assert!(r.coef(0).power().is_none());
764 assert_eq!(r.coef(1).power().unwrap(), 0);
765 assert_eq!(r.coef(2).power().unwrap(), 1);
766 assert_eq!(r.coef(3).power().unwrap(), 2);
767 }
768
769 #[test]
770 fn test_deriv() {
771 let p = TestPolynomial::new(
772 [
773 P25Codeword::for_power(0),
774 P25Codeword::for_power(3),
775 P25Codeword::for_power(58),
776 ]
777 .into_iter(),
778 );
779
780 let q = p.deriv();
781
782 assert!(q.coefs[0] == P25Codeword::for_power(3));
783 assert!(q.coefs[1] == P25Codeword::default());
784 assert!(q.coefs[2] == P25Codeword::default());
785
786 let p = TestPolynomial::new(
787 [
788 P25Codeword::default(),
789 P25Codeword::for_power(5),
790 P25Codeword::for_power(3),
791 P25Codeword::for_power(58),
792 ]
793 .into_iter(),
794 );
795
796 let q = p.shift().deriv();
797
798 assert!(q.coef(0) == P25Codeword::for_power(3));
799 assert!(q.coef(1) == P25Codeword::default());
800 assert!(q.coef(2) == P25Codeword::default());
801
802 let p = TestPolynomial::new(
803 [
804 P25Codeword::for_power(0),
805 P25Codeword::for_power(5),
806 P25Codeword::for_power(3),
807 P25Codeword::for_power(58),
808 ]
809 .into_iter(),
810 )
811 .deriv();
812
813 assert!(p.coef(0) == P25Codeword::for_power(5));
814 assert!(p.coef(1) == P25Codeword::default());
815 assert!(p.coef(2) == P25Codeword::for_power(58));
816 assert!(p.coef(3) == P25Codeword::default());
817 assert!(p.coef(4) == P25Codeword::default());
818
819 let p = TestPolynomial::new(
820 [
821 P25Codeword::for_power(0),
822 P25Codeword::for_power(5),
823 P25Codeword::for_power(3),
824 P25Codeword::for_power(58),
825 P25Codeword::for_power(43),
826 ]
827 .into_iter(),
828 )
829 .deriv();
830
831 assert!(p.coef(0) == P25Codeword::for_power(5));
832 assert!(p.coef(1) == P25Codeword::default());
833 assert!(p.coef(2) == P25Codeword::for_power(58));
834 assert!(p.coef(3) == P25Codeword::default());
835 assert!(p.coef(4) == P25Codeword::default());
836 assert!(p.coef(5) == P25Codeword::default());
837
838 let p = TestPolynomial::new(
839 [
840 P25Codeword::for_power(0),
841 P25Codeword::for_power(5),
842 P25Codeword::for_power(3),
843 P25Codeword::for_power(58),
844 P25Codeword::for_power(43),
845 P25Codeword::for_power(15),
846 ]
847 .into_iter(),
848 )
849 .deriv();
850
851 assert!(p.coef(0) == P25Codeword::for_power(5));
852 assert!(p.coef(1) == P25Codeword::default());
853 assert!(p.coef(2) == P25Codeword::for_power(58));
854 assert!(p.coef(3) == P25Codeword::default());
855 assert!(p.coef(4) == P25Codeword::for_power(15));
856 assert!(p.coef(5) == P25Codeword::default());
857
858 let p = ShortPolynomial::new(
859 [
860 P25Codeword::for_power(0),
861 P25Codeword::for_power(5),
862 P25Codeword::for_power(3),
863 P25Codeword::for_power(58),
864 P25Codeword::for_power(43),
865 ]
866 .into_iter(),
867 )
868 .deriv();
869
870 assert!(p.coef(0) == P25Codeword::for_power(5));
871 assert!(p.coef(1) == P25Codeword::default());
872 assert!(p.coef(2) == P25Codeword::for_power(58));
873 assert!(p.coef(3) == P25Codeword::default());
874 assert!(p.coef(4) == P25Codeword::default());
875
876 let p = TestPolynomial::new(
877 [
878 P25Codeword::for_power(0),
879 P25Codeword::for_power(5),
880 P25Codeword::for_power(3),
881 P25Codeword::for_power(58),
882 P25Codeword::for_power(43),
883 P25Codeword::for_power(15),
884 P25Codeword::for_power(5),
885 P25Codeword::for_power(3),
886 P25Codeword::for_power(58),
887 P25Codeword::for_power(43),
888 P25Codeword::for_power(15),
889 P25Codeword::for_power(5),
890 P25Codeword::for_power(3),
891 P25Codeword::for_power(58),
892 P25Codeword::for_power(43),
893 P25Codeword::for_power(15),
894 P25Codeword::for_power(5),
895 P25Codeword::for_power(3),
896 P25Codeword::for_power(58),
897 P25Codeword::for_power(43),
898 P25Codeword::for_power(15),
899 P25Codeword::for_power(5),
900 P25Codeword::for_power(3),
901 P25Codeword::for_power(58),
902 ]
903 .into_iter(),
904 )
905 .deriv();
906
907 assert!(p.coef(0) == P25Codeword::for_power(5));
908 assert!(p.coef(1) == P25Codeword::default());
909 assert!(p.coef(2) == P25Codeword::for_power(58));
910 assert!(p.coef(3) == P25Codeword::default());
911 assert!(p.coef(4) == P25Codeword::for_power(15));
912 assert!(p.coef(5) == P25Codeword::default());
913 assert!(p.coef(6) == P25Codeword::for_power(3));
914 assert!(p.coef(7) == P25Codeword::default());
915 assert!(p.coef(8) == P25Codeword::for_power(43));
916 assert!(p.coef(9) == P25Codeword::default());
917 assert!(p.coef(10) == P25Codeword::for_power(5));
918 assert!(p.coef(11) == P25Codeword::default());
919 assert!(p.coef(12) == P25Codeword::for_power(58));
920 assert!(p.coef(13) == P25Codeword::default());
921 assert!(p.coef(14) == P25Codeword::for_power(15));
922 assert!(p.coef(15) == P25Codeword::default());
923 assert!(p.coef(16) == P25Codeword::for_power(3));
924 assert!(p.coef(17) == P25Codeword::default());
925 assert!(p.coef(18) == P25Codeword::for_power(43));
926 assert!(p.coef(19) == P25Codeword::default());
927 assert!(p.coef(20) == P25Codeword::for_power(5));
928 assert!(p.coef(21) == P25Codeword::default());
929 assert!(p.coef(22) == P25Codeword::for_power(58));
930 assert!(p.coef(23) == P25Codeword::default());
931 assert!(p.coef(24) == P25Codeword::default());
932 }
933
934 #[test]
935 fn test_unit_power() {
936 let p = TestPolynomial::unit_power(0);
937 assert_eq!(p[0], Codeword::for_power(0));
938 assert_eq!(p.degree().unwrap(), 0);
939
940 let p = TestPolynomial::unit_power(2);
941 assert_eq!(p[0], Codeword::default());
942 assert_eq!(p[1], Codeword::default());
943 assert_eq!(p[2], Codeword::for_power(0));
944 assert_eq!(p.degree().unwrap(), 2);
945
946 let p = TestPolynomial::unit_power(10);
947 assert_eq!(p[0], Codeword::default());
948 assert_eq!(p[1], Codeword::default());
949 assert_eq!(p[2], Codeword::default());
950 assert_eq!(p[3], Codeword::default());
951 assert_eq!(p[4], Codeword::default());
952 assert_eq!(p[5], Codeword::default());
953 assert_eq!(p[6], Codeword::default());
954 assert_eq!(p[7], Codeword::default());
955 assert_eq!(p[8], Codeword::default());
956 assert_eq!(p[9], Codeword::default());
957 assert_eq!(p[10], Codeword::for_power(0));
958 assert_eq!(p.degree().unwrap(), 10);
959 }
960}