Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/integer/mat_poly_over_z/arithmetic/mul_scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ arithmetic_trait_borrowed_to_owned!(Mul, mul, Z, MatPolyOverZ, MatPolyOverZ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, MatPolyOverZ, Z, MatPolyOverZ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Z, MatPolyOverZ, MatPolyOverZ);

implement_for_others!(Z, MatPolyOverZ, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);
implement_for_others!(Z, MatPolyOverZ, MatPolyOverZ, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);

impl Mul<&PolyOverZ> for &MatPolyOverZ {
type Output = MatPolyOverZ;
Expand Down
152 changes: 150 additions & 2 deletions src/integer/mat_z/arithmetic/mul_scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use super::super::MatZ;
use crate::integer::Z;
use crate::integer_mod_q::{MatZq, Zq};
use crate::macros::arithmetics::{
arithmetic_assign_between_types, arithmetic_assign_trait_borrowed_to_owned,
arithmetic_trait_borrowed_to_owned, arithmetic_trait_mixed_borrowed_owned,
Expand Down Expand Up @@ -60,7 +61,7 @@ arithmetic_trait_borrowed_to_owned!(Mul, mul, Z, MatZ, MatZ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, MatZ, Z, MatZ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Z, MatZ, MatZ);

implement_for_others!(Z, MatZ, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);
implement_for_others!(Z, MatZ, MatZ, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);

impl Mul<&Q> for &MatZ {
type Output = MatQ;
Expand All @@ -75,7 +76,7 @@ impl Mul<&Q> for &MatZ {
/// # Examples
/// ```
/// use qfall_math::integer::MatZ;
/// use qfall_math::rational::{MatQ, Q};
/// use qfall_math::rational::Q;
/// use std::str::FromStr;
///
/// let mat_1 = MatZ::from_str("[[2, 1],[1, 2]]").unwrap();
Expand All @@ -96,6 +97,42 @@ arithmetic_trait_borrowed_to_owned!(Mul, mul, Q, MatZ, MatQ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, MatZ, Q, MatQ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Q, MatZ, MatQ);

implement_for_others!(Q, MatZ, MatQ, Mul Scalar for f32 f64);

impl Mul<&Zq> for &MatZ {
type Output = MatZq;
/// Implements the [`Mul`] trait for a [`MatZ`] matrix with a [`Zq`] representative of a residue class.
/// [`Mul`] is implemented for any combination of owned and borrowed values.
///
/// Parameters:
/// - `scalar`: specifies the scalar by which the matrix is multiplied
///
/// Returns the product of `self` and `scalar` as a [`MatZq`].
///
/// # Examples
/// ```
/// use qfall_math::integer::MatZ;
/// use qfall_math::integer_mod_q::Zq;
/// use std::str::FromStr;
///
/// let mat_1 = MatZ::from_str("[[2, 1],[1, 2]]").unwrap();
/// let zq = Zq::from((1,3));
///
/// let mat_2 = &mat_1 * &zq;
/// ```
fn mul(self, scalar: &Zq) -> Self::Output {
let out = MatZq::from((self, scalar.get_mod()));
out * scalar
}
}

arithmetic_trait_reverse!(Mul, mul, Zq, MatZ, MatZq);

arithmetic_trait_borrowed_to_owned!(Mul, mul, MatZ, Zq, MatZq);
arithmetic_trait_borrowed_to_owned!(Mul, mul, Zq, MatZ, MatZq);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, MatZ, Zq, MatZq);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Zq, MatZ, MatZq);

impl MulAssign<&Z> for MatZ {
/// Computes the scalar multiplication of `self` and `scalar` reusing
/// the memory of `self`.
Expand Down Expand Up @@ -243,6 +280,24 @@ mod test_mul {
assert_eq!(mat_3, integer_1 * mat_1);
assert_eq!(mat_4, integer_2 * mat_2);
}

/// Checks if scalar multiplication is available for any integer type
#[test]
fn availability() {
let mat = MatZ::from_str("[[2, 1],[1, 2]]").unwrap();
let integer = Z::from(3);

let _ = &mat * 1u8;
let _ = &mat * 1u16;
let _ = &mat * 1u32;
let _ = &mat * 1u64;
let _ = &mat * 1i8;
let _ = &mat * 1i16;
let _ = &mat * 1i32;
let _ = &mat * 1i64;
let _ = &mat * &integer;
let _ = &mat * integer;
}
}

#[cfg(test)]
Expand Down Expand Up @@ -328,6 +383,99 @@ mod test_mul_q {
assert_eq!(mat_3, rational_1 * mat_1);
assert_eq!(mat_4, rational_2 * mat_2);
}

/// Checks if scalar multiplication is available for any rational type
#[test]
fn availability() {
let mat = MatZ::from_str("[[2, 1],[1, 2]]").unwrap();
let rational = Q::from(3);

let _ = &mat * 1.0f32;
let _ = &mat * 1.0f64;
let _ = &mat * &rational;
let _ = &mat * rational;
}
}

#[cfg(test)]
mod test_mul_zq {
use super::MatZ;
use crate::integer_mod_q::{MatZq, Zq};
use std::str::FromStr;

/// Checks if scalar multiplication works fine for both borrowed
#[test]
fn borrowed_correctness() {
let mat_1 = MatZ::from_str("[[2, 1],[1, 2]]").unwrap();
let mat_2 = mat_1.clone();
let mat_3 = MatZq::from_str("[[1, 2],[2, 1]] mod 3").unwrap();
let zq = Zq::from((2, 3));

let mat_1 = &mat_1 * &zq;
let mat_2 = &zq * &mat_2;

assert_eq!(mat_3, mat_1);
assert_eq!(mat_3, mat_2);
}

/// Checks if scalar multiplication works fine for both owned
#[test]
fn owned_correctness() {
let mat_1 = MatZ::from_str("[[2, 1],[1, 2]]").unwrap();
let mat_2 = mat_1.clone();
let mat_3 = MatZq::from_str("[[2, 1],[1, 2]] mod 3").unwrap();
let zq = Zq::from((1, 3));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also, check with another value than 1 (mod 3)


let mat_1 = mat_1 * zq.clone();
let mat_2 = zq * mat_2;

assert_eq!(mat_3, mat_1);
assert_eq!(mat_3, mat_2);
}

/// Checks if scalar multiplication works fine for half owned/borrowed
#[test]
fn half_correctness() {
let mat_1 = MatZ::from_str("[[2, 1],[1, 2]]").unwrap();
let mat_2 = mat_1.clone();
let mat_3 = mat_1.clone();
let mat_4 = mat_1.clone();
let mat_5 = MatZq::from_str("[[2, 1],[1, 2]] mod 3").unwrap();
let zq = Zq::from((1, 3));

let mat_1 = mat_1 * &zq;
let mat_2 = &zq * mat_2;
let mat_3 = &mat_3 * zq.clone();
let mat_4 = zq * &mat_4;

assert_eq!(mat_5, mat_1);
assert_eq!(mat_5, mat_2);
assert_eq!(mat_5, mat_3);
assert_eq!(mat_5, mat_4);
}

/// Checks if scalar multiplication works fine for matrices of different dimensions
#[test]
fn different_dimensions_correctness() {
let mat_1 = MatZ::from_str("[[1],[0],[4]]").unwrap();
let mat_2 = MatZ::from_str("[[2, 5, 6],[1, 3, 1]]").unwrap();
let mat_3 = MatZq::from_str("[[1],[0],[1]] mod 3").unwrap();
let mat_4 = MatZq::from_str("[[2, 2, 0],[1, 0, 1]] mod 3").unwrap();
let integer = Zq::from((1, 3));

assert_eq!(mat_3, &integer * mat_1);
assert_eq!(mat_4, integer * mat_2);
}

/// Checks if scalar multiplication is available for any rational type
#[test]
fn availability() {
let mat = MatZ::from_str("[[2, 1],[1, 2]]").unwrap();
let zq = Zq::from((1, 3));

let _ = &mat * &zq;
let _ = &mat * zq;
}
}

#[cfg(test)]
Expand Down
6 changes: 5 additions & 1 deletion src/integer/poly_over_z/arithmetic/mul_scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ arithmetic_trait_borrowed_to_owned!(Mul, mul, Z, PolyOverZ, PolyOverZ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, PolyOverZ, Z, PolyOverZ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Z, PolyOverZ, PolyOverZ);

implement_for_others!(Z, PolyOverZ, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);
implement_for_others!(Z, PolyOverZ, PolyOverZ, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);

impl Mul<&Zq> for &PolyOverZ {
type Output = PolyOverZq;
Expand Down Expand Up @@ -146,6 +146,8 @@ arithmetic_trait_borrowed_to_owned!(Mul, mul, Q, PolyOverZ, PolyOverQ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, PolyOverZ, Q, PolyOverQ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Q, PolyOverZ, PolyOverQ);

implement_for_others!(Q, PolyOverZ, PolyOverQ, Mul Scalar for f32 f64);

impl MulAssign<&Z> for PolyOverZ {
/// Computes the scalar multiplication of `self` and `scalar` reusing
/// the memory of `self`.
Expand Down Expand Up @@ -375,5 +377,7 @@ mod test_mul_q {
_ = q.clone() * &poly;
_ = &q * poly.clone();
_ = poly.clone() * &q;
_ = &poly * 1.0f32;
_ = &poly * 1.0f64;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ arithmetic_trait_borrowed_to_owned!(Mul, mul, Z, MatPolynomialRingZq, MatPolynom
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, MatPolynomialRingZq, Z, MatPolynomialRingZq);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Z, MatPolynomialRingZq, MatPolynomialRingZq);

implement_for_others!(Z, MatPolynomialRingZq, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);
implement_for_others!(Z, MatPolynomialRingZq, MatPolynomialRingZq, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);

impl Mul<&Zq> for &MatPolynomialRingZq {
type Output = MatPolynomialRingZq;
Expand Down
2 changes: 1 addition & 1 deletion src/integer_mod_q/mat_zq/arithmetic/mul_scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ arithmetic_trait_borrowed_to_owned!(Mul, mul, Z, MatZq, MatZq);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, MatZq, Z, MatZq);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Z, MatZq, MatZq);

implement_for_others!(Z, MatZq, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);
implement_for_others!(Z, MatZq, MatZq, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);

impl Mul<&Zq> for &MatZq {
type Output = MatZq;
Expand Down
2 changes: 1 addition & 1 deletion src/integer_mod_q/poly_over_zq/arithmetic/mul_scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ arithmetic_trait_borrowed_to_owned!(Mul, mul, Z, PolyOverZq, PolyOverZq);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, PolyOverZq, Z, PolyOverZq);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Z, PolyOverZq, PolyOverZq);

implement_for_others!(Z, PolyOverZq, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);
implement_for_others!(Z, PolyOverZq, PolyOverZq, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);

impl Mul<&Zq> for &PolyOverZq {
type Output = PolyOverZq;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ arithmetic_trait_borrowed_to_owned!(Mul, mul, Z, PolynomialRingZq, PolynomialRin
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, PolynomialRingZq, Z, PolynomialRingZq);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Z, PolynomialRingZq, PolynomialRingZq);

implement_for_others!(Z, PolynomialRingZq, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);
implement_for_others!(Z, PolynomialRingZq, PolynomialRingZq, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);

impl Mul<&Zq> for &PolynomialRingZq {
type Output = PolynomialRingZq;
Expand Down
24 changes: 12 additions & 12 deletions src/macros/for_others.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
/// Implements a specified trait using implicit conversions to a bridge type.
///
/// - ['Mul'](std::ops::Mul) with signature
/// `($bridge_type, $type, Mul Scalar for $source_type)`
/// - ['Div'](std::ops::Mul) with signature
/// `($bridge_type, $type, Div Scalar for $source_type)`
/// `($bridge_type, $type, $output_type, Mul Scalar for $source_type)`
/// - ['Div'](std::ops::Div) with signature
/// `($bridge_type, $type, $output_type, Div Scalar for $source_type)`
/// - ['Rem'](std::ops::Rem) with signature
/// `($bridge_type, $type, Rem for $source_type)`
/// - ['PartialEq'](std::cmp::PartialEq) with signature
Expand All @@ -32,16 +32,16 @@
///
/// # Examples
/// ```compile_fail
/// implement_for_others!(Z, MatZ, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);
/// implement_for_others!(Z, MatZ, MatZ, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);
/// implement_for_others!(Z, Q, PartialEq for fmpz i8 i16 i32 i64 u8 u16 u32 u64);
/// implement_for_others!(Z, Q, PartialOrd for fmpz i8 i16 i32 i64 u8 u16 u32 u64);
/// implement_for_others!(Z, PolyOverZ, Rem for i8 i16 i32 i64 u8 u16 u32 u64);
/// ```
macro_rules! implement_for_others {
// [`Mul`] trait scalar
($bridge_type:ident, $type:ident, Mul Scalar for $($source_type:ident)*) => {
($bridge_type:ident, $type:ident, $output_type:ident, Mul Scalar for $($source_type:ident)*) => {
$(#[doc(hidden)] impl Mul<$source_type> for &$type {
type Output = $type;
type Output = $output_type;
paste::paste! {
#[doc = "Documentation can be found at [`" $type "::mul`]."]
fn mul(self, scalar: $source_type) -> Self::Output {
Expand All @@ -52,7 +52,7 @@ macro_rules! implement_for_others {

#[doc(hidden)]
impl Mul<$source_type> for $type {
type Output = $type;
type Output = $output_type;
paste::paste! {
#[doc = "Documentation can be found at [`" $type "::mul`]."]
fn mul(self, scalar: $source_type) -> Self::Output {
Expand All @@ -63,7 +63,7 @@ macro_rules! implement_for_others {

#[doc(hidden)]
impl Mul<&$type> for $source_type {
type Output = $type;
type Output = $output_type;
paste::paste! {
#[doc = "Documentation can be found at [`" $type "::mul`]."]
fn mul(self, matrix: &$type) -> Self::Output {
Expand All @@ -74,7 +74,7 @@ macro_rules! implement_for_others {

#[doc(hidden)]
impl Mul<$type> for $source_type {
type Output = $type;
type Output = $output_type;
paste::paste! {
#[doc = "Documentation can be found at [`" $type "::mul`]."]
fn mul(self, matrix: $type) -> Self::Output {
Expand All @@ -85,9 +85,9 @@ macro_rules! implement_for_others {
};

// [`Div`] trait scalar
($bridge_type:ident, $type:ident, Div Scalar for $($source_type:ident)*) => {
($bridge_type:ident, $type:ident, $output_type:ident, Div Scalar for $($source_type:ident)*) => {
$(#[doc(hidden)] impl Div<$source_type> for &$type {
type Output = $type;
type Output = $output_type;
paste::paste! {
#[doc = "Documentation can be found at [`" $type "::div`]."]
fn div(self, scalar: $source_type) -> Self::Output {
Expand All @@ -98,7 +98,7 @@ macro_rules! implement_for_others {

#[doc(hidden)]
impl Div<$source_type> for $type {
type Output = $type;
type Output = $output_type;
paste::paste! {
#[doc = "Documentation can be found at [`" $type "::div`]."]
fn div(self, scalar: $source_type) -> Self::Output {
Expand Down
4 changes: 2 additions & 2 deletions src/rational/mat_q/arithmetic/div_scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl Div<&Z> for &MatQ {
arithmetic_trait_borrowed_to_owned!(Div, div, MatQ, Z, MatQ);
arithmetic_trait_mixed_borrowed_owned!(Div, div, MatQ, Z, MatQ);

implement_for_others!(Z, MatQ, Div Scalar for i8 i16 i32 i64 u8 u16 u32 u64);
implement_for_others!(Z, MatQ, MatQ, Div Scalar for i8 i16 i32 i64 u8 u16 u32 u64);

impl Div<&Q> for &MatQ {
type Output = MatQ;
Expand Down Expand Up @@ -95,7 +95,7 @@ impl Div<&Q> for &MatQ {
arithmetic_trait_borrowed_to_owned!(Div, div, MatQ, Q, MatQ);
arithmetic_trait_mixed_borrowed_owned!(Div, div, MatQ, Q, MatQ);

implement_for_others!(Q, MatQ, Div Scalar for f32 f64);
implement_for_others!(Q, MatQ, MatQ, Div Scalar for f32 f64);

impl DivAssign<&Q> for MatQ {
/// Computes the scalar multiplication of `self` and `other` reusing
Expand Down
7 changes: 5 additions & 2 deletions src/rational/mat_q/arithmetic/mul_scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ arithmetic_trait_borrowed_to_owned!(Mul, mul, Q, MatQ, MatQ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, MatQ, Q, MatQ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Q, MatQ, MatQ);

implement_for_others!(Z, MatQ, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);
implement_for_others!(Z, MatQ, MatQ, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);

impl Mul<&Q> for &MatQ {
type Output = MatQ;
Expand Down Expand Up @@ -97,7 +97,7 @@ arithmetic_trait_borrowed_to_owned!(Mul, mul, Z, MatQ, MatQ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, MatQ, Z, MatQ);
arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Z, MatQ, MatQ);

implement_for_others!(Q, MatQ, Mul Scalar for f32 f64);
implement_for_others!(Q, MatQ, MatQ, Mul Scalar for f32 f64);

impl MulAssign<&Q> for MatQ {
/// Computes the scalar multiplication of `self` and `other` reusing
Expand Down Expand Up @@ -140,6 +140,7 @@ impl MulAssign<&Z> for MatQ {
arithmetic_assign_trait_borrowed_to_owned!(MulAssign, mul_assign, MatQ, Q);
arithmetic_assign_trait_borrowed_to_owned!(MulAssign, mul_assign, MatQ, Z);
arithmetic_assign_between_types!(MulAssign, mul_assign, MatQ, Z, u64 u32 u16 u8 i64 i32 i16 i8);
arithmetic_assign_between_types!(MulAssign, mul_assign, MatQ, Q, f32 f64);

#[cfg(test)]
mod test_mul_z {
Expand Down Expand Up @@ -404,5 +405,7 @@ mod test_mul_assign {
a *= 1_i16;
a *= 1_i32;
a *= 1_i64;
a *= 1.0_f32;
a *= 1.0_f64;
}
}
Loading
Loading