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