binius_field/arch/portable/
pairwise_arithmetic.rs1use crate::{
4 arch::PairwiseStrategy,
5 arithmetic_traits::{InvertOrZero, Square, TaggedInvertOrZero, TaggedMul, TaggedSquare},
6 linear_transformation::Transformation,
7 packed::PackedField,
8};
9
10impl<PT: PackedField> TaggedMul<PairwiseStrategy> for PT {
11 #[inline]
12 fn mul(self, b: Self) -> Self {
13 if PT::WIDTH == 1 {
14 self * b
16 } else {
17 Self::from_fn(|i| self.get(i) * b.get(i))
18 }
19 }
20}
21
22impl<PT: PackedField> TaggedSquare<PairwiseStrategy> for PT
23where
24 PT::Scalar: Square,
25{
26 #[inline]
27 fn square(self) -> Self {
28 if PT::WIDTH == 1 {
29 Square::square(self)
31 } else {
32 Self::from_fn(|i| Square::square(self.get(i)))
33 }
34 }
35}
36
37impl<PT: PackedField> TaggedInvertOrZero<PairwiseStrategy> for PT
38where
39 PT::Scalar: InvertOrZero,
40{
41 #[inline]
42 fn invert_or_zero(self) -> Self {
43 if PT::WIDTH == 1 {
44 InvertOrZero::invert_or_zero(self)
46 } else {
47 Self::from_fn(|i| InvertOrZero::invert_or_zero(self.get(i)))
48 }
49 }
50}
51
52pub struct PairwiseTransformation<I> {
54 inner: I,
55}
56
57impl<I> PairwiseTransformation<I> {
58 pub const fn new(inner: I) -> Self {
59 Self { inner }
60 }
61}
62
63impl<IP, OP, IF, OF, I> Transformation<IP, OP> for PairwiseTransformation<I>
64where
65 IP: PackedField<Scalar = IF>,
66 OP: PackedField<Scalar = OF>,
67 I: Transformation<IF, OF>,
68{
69 fn transform(&self, data: &IP) -> OP {
70 OP::from_fn(|i| self.inner.transform(&data.get(i)))
71 }
72}