binius_field/arch/portable/
scaled_arithmetic.rs1use std::array;
4
5use bytemuck::{Pod, TransparentWrapper};
6
7use super::packed::PackedPrimitiveType;
8use crate::{
9 BinaryField,
10 arch::ScaledStrategy,
11 arithmetic_traits::{InvertOrZero, Square, TaggedInvertOrZero, TaggedMul, TaggedSquare},
12 underlier::{ScaledUnderlier, UnderlierType},
13};
14
15impl<U: UnderlierType + Pod, Scalar: BinaryField, const N: usize> TaggedMul<ScaledStrategy>
16 for PackedPrimitiveType<ScaledUnderlier<U, N>, Scalar>
17where
18 PackedPrimitiveType<U, Scalar>: std::ops::Mul<Output = PackedPrimitiveType<U, Scalar>>,
19{
20 fn mul(self, rhs: Self) -> Self {
21 Self::wrap(ScaledUnderlier(array::from_fn(|i| {
22 let lhs_i = self.0.0[i];
23 let rhs_i = rhs.0.0[i];
24 PackedPrimitiveType::peel(
25 PackedPrimitiveType::wrap(lhs_i) * PackedPrimitiveType::wrap(rhs_i),
26 )
27 })))
28 }
29}
30
31impl<U: UnderlierType + Pod, Scalar: BinaryField, const N: usize> TaggedSquare<ScaledStrategy>
32 for PackedPrimitiveType<ScaledUnderlier<U, N>, Scalar>
33where
34 PackedPrimitiveType<U, Scalar>: Square,
35{
36 fn square(self) -> Self {
37 Self::wrap(ScaledUnderlier(self.0.0.map(|sub_underlier| {
38 PackedPrimitiveType::peel(PackedPrimitiveType::wrap(sub_underlier).square())
39 })))
40 }
41}
42
43impl<U: UnderlierType + Pod, Scalar: BinaryField, const N: usize> TaggedInvertOrZero<ScaledStrategy>
44 for PackedPrimitiveType<ScaledUnderlier<U, N>, Scalar>
45where
46 PackedPrimitiveType<U, Scalar>: InvertOrZero,
47{
48 fn invert_or_zero(self) -> Self {
49 Self::wrap(ScaledUnderlier(self.0.0.map(|sub_underlier| {
50 PackedPrimitiveType::peel(PackedPrimitiveType::wrap(sub_underlier).invert_or_zero())
51 })))
52 }
53}