binius_field/
arithmetic_traits.rsuse std::ops::Deref;
use crate::{
linear_transformation::{FieldLinearTransformation, Transformation},
packed::PackedBinaryField,
};
pub trait Square {
fn square(self) -> Self;
}
pub trait InvertOrZero {
fn invert_or_zero(self) -> Self;
}
pub trait MulAlpha {
fn mul_alpha(self) -> Self;
}
pub trait Broadcast<Scalar> {
fn broadcast(scalar: Scalar) -> Self;
}
pub trait TaggedMul<Strategy> {
fn mul(self, rhs: Self) -> Self;
}
macro_rules! impl_mul_with {
($name:ident @ $strategy:ty) => {
impl std::ops::Mul for $name {
type Output = Self;
#[inline]
fn mul(self, rhs: Self) -> Self {
$crate::tracing::trace_multiplication!($name);
$crate::arithmetic_traits::TaggedMul::<$strategy>::mul(self, rhs)
}
}
};
($name:ty => $bigger:ty) => {
impl std::ops::Mul for $name {
type Output = Self;
#[inline]
fn mul(self, rhs: Self) -> Self {
$crate::arch::portable::packed::mul_as_bigger_type::<_, $bigger>(self, rhs)
}
}
};
}
pub(crate) use impl_mul_with;
pub trait TaggedSquare<Strategy> {
fn square(self) -> Self;
}
macro_rules! impl_square_with {
($name:ident @ $strategy:ty) => {
impl $crate::arithmetic_traits::Square for $name {
#[inline]
fn square(self) -> Self {
$crate::arithmetic_traits::TaggedSquare::<$strategy>::square(self)
}
}
};
($name:ty => $bigger:ty) => {
impl $crate::arithmetic_traits::Square for $name {
#[inline]
fn square(self) -> Self {
$crate::arch::portable::packed::square_as_bigger_type::<_, $bigger>(self)
}
}
};
}
pub(crate) use impl_square_with;
pub trait TaggedInvertOrZero<Strategy> {
fn invert_or_zero(self) -> Self;
}
macro_rules! impl_invert_with {
($name:ident @ $strategy:ty) => {
impl $crate::arithmetic_traits::InvertOrZero for $name {
#[inline]
fn invert_or_zero(self) -> Self {
$crate::arithmetic_traits::TaggedInvertOrZero::<$strategy>::invert_or_zero(self)
}
}
};
($name:ty => $bigger:ty) => {
impl $crate::arithmetic_traits::InvertOrZero for $name {
#[inline]
fn invert_or_zero(self) -> Self {
$crate::arch::portable::packed::invert_as_bigger_type::<_, $bigger>(self)
}
}
};
}
pub(crate) use impl_invert_with;
pub trait TaggedMulAlpha<Strategy> {
fn mul_alpha(self) -> Self;
}
macro_rules! impl_mul_alpha_with {
($name:ident @ $strategy:ty) => {
impl $crate::arithmetic_traits::MulAlpha for $name {
#[inline]
fn mul_alpha(self) -> Self {
$crate::arithmetic_traits::TaggedMulAlpha::<$strategy>::mul_alpha(self)
}
}
};
($name:ty => $bigger:ty) => {
impl $crate::arithmetic_traits::MulAlpha for $name {
#[inline]
fn mul_alpha(self) -> Self {
$crate::arch::portable::packed::mul_alpha_as_bigger_type::<_, $bigger>(self)
}
}
};
}
pub(crate) use impl_mul_alpha_with;
#[allow(private_bounds)]
pub trait TaggedPackedTransformationFactory<Strategy, OP>: PackedBinaryField
where
OP: PackedBinaryField,
{
type PackedTransformation<Data: Deref<Target = [OP::Scalar]>>: Transformation<Self, OP>;
fn make_packed_transformation<Data: Deref<Target = [OP::Scalar]>>(
transformation: FieldLinearTransformation<OP::Scalar, Data>,
) -> Self::PackedTransformation<Data>;
}
macro_rules! impl_transformation_with_strategy {
($name:ty, $strategy:ty) => {
impl<OP> $crate::linear_transformation::PackedTransformationFactory<OP> for $name
where
OP: $crate::packed::PackedBinaryField
+ $crate::underlier::WithUnderlier<
Underlier = <$name as $crate::underlier::WithUnderlier>::Underlier,
>,
{
type PackedTransformation<Data: std::ops::Deref<Target = [OP::Scalar]>> =
<Self as $crate::arithmetic_traits::TaggedPackedTransformationFactory<
$strategy,
OP,
>>::PackedTransformation<Data>;
fn make_packed_transformation<Data: std::ops::Deref<Target = [OP::Scalar]>>(
transformation: $crate::linear_transformation::FieldLinearTransformation<
OP::Scalar,
Data,
>,
) -> Self::PackedTransformation<Data> {
<Self as $crate::arithmetic_traits::TaggedPackedTransformationFactory<
$strategy,
OP,
>>::make_packed_transformation(transformation)
}
}
};
}
pub(crate) use impl_transformation_with_strategy;