qfall_math/integer_mod_q/polynomial_ring_zq/
set.rs1use super::PolynomialRingZq;
12use crate::{
13 integer::Z, integer_mod_q::Zq, macros::for_others::implement_for_owned, traits::SetCoefficient,
14};
15use flint_sys::fmpz_poly::fmpz_poly_set_coeff_fmpz;
16
17impl<Integer: Into<Z>> SetCoefficient<Integer> for PolynomialRingZq {
18 unsafe fn set_coeff_unchecked(&mut self, index: i64, value: Integer) {
47 let value = value.into();
48
49 unsafe {
50 fmpz_poly_set_coeff_fmpz(&mut self.poly.poly, index, &value.value);
51 };
52 self.reduce();
53 }
54}
55
56impl SetCoefficient<&Zq> for PolynomialRingZq {
57 unsafe fn set_coeff_unchecked(&mut self, index: i64, value: &Zq) {
90 unsafe { self.set_coeff_unchecked(index, &value.value) };
91 }
92}
93
94implement_for_owned!(Zq, PolynomialRingZq, SetCoefficient);
95
96#[cfg(test)]
97mod test_set_coeff {
98 use crate::{
99 integer::{PolyOverZ, Z},
100 integer_mod_q::{ModulusPolynomialRingZq, PolynomialRingZq, Zq},
101 traits::SetCoefficient,
102 };
103 use std::str::FromStr;
104
105 #[test]
107 fn availability() {
108 let modulus = ModulusPolynomialRingZq::from_str("4 1 0 0 1 mod 17").unwrap();
109 let poly = PolyOverZ::from_str("3 0 1 1").unwrap();
110 let mut poly_ring = PolynomialRingZq::from((&poly, &modulus));
111
112 poly_ring.set_coeff(1, 3u64).unwrap();
113 poly_ring.set_coeff(1, 3u32).unwrap();
114 poly_ring.set_coeff(1, 3u16).unwrap();
115 poly_ring.set_coeff(1, 3u8).unwrap();
116 poly_ring.set_coeff(1, 3i64).unwrap();
117 poly_ring.set_coeff(1, 3i32).unwrap();
118 poly_ring.set_coeff(1, 3i16).unwrap();
119 poly_ring.set_coeff(1, 3i8).unwrap();
120 poly_ring.set_coeff(1, Z::from(3)).unwrap();
121 poly_ring.set_coeff(1, &Z::from(3)).unwrap();
122 poly_ring.set_coeff(1, &Zq::from((3, 17))).unwrap();
123 }
124
125 #[test]
127 fn set_coeff_large() {
128 let modulus = ModulusPolynomialRingZq::from_str("4 1 0 0 1 mod 17").unwrap();
129 let poly = PolyOverZ::from_str("3 0 1 1").unwrap();
130 let mut poly_ring = PolynomialRingZq::from((&poly, &modulus));
131
132 assert!(poly_ring.set_coeff(2, i32::MAX).is_ok());
133 assert!(poly_ring.set_coeff(2, i64::MAX).is_ok());
134 }
135
136 #[test]
138 fn set_index_large() {
139 let modulus = ModulusPolynomialRingZq::from_str("4 1 0 0 1 mod 17").unwrap();
140 let poly = PolyOverZ::from_str("3 0 1 1").unwrap();
141 let mut poly_ring = PolynomialRingZq::from((&poly, &modulus));
142
143 assert!(poly_ring.set_coeff(u8::MAX, 2).is_ok());
144 assert!(poly_ring.set_coeff(u16::MAX, 2).is_ok());
145 }
146
147 #[test]
149 fn set_coeff_working() {
150 let modulus = ModulusPolynomialRingZq::from_str("5 1 0 0 1 5 mod 17").unwrap();
151 let poly = PolyOverZ::from_str("3 0 2 1").unwrap();
152 let mut poly_ring = PolynomialRingZq::from((&poly, &modulus));
153 let value = 10000;
154
155 poly_ring.set_coeff(0, value).unwrap();
156 poly_ring.set_coeff(2, value).unwrap();
157
158 let cmp_poly = PolyOverZ::from_str("3 10000 2 10000").unwrap();
159 let cmp_poly_ring = PolynomialRingZq::from((&cmp_poly, &modulus));
160 assert_eq!(cmp_poly_ring, poly_ring);
161 }
162
163 #[test]
165 fn set_reduce() {
166 let modulus = ModulusPolynomialRingZq::from_str("4 1 0 0 1 mod 17").unwrap();
167 let poly = PolyOverZ::from(1);
168 let mut poly_ring = PolynomialRingZq::from((&poly, &modulus));
169
170 poly_ring.set_coeff(3, 1).unwrap();
171
172 let cmp_poly = PolyOverZ::from(0);
173 let cmp_poly_ring = PolynomialRingZq::from((&cmp_poly, &modulus));
174 assert_eq!(cmp_poly_ring, poly_ring);
175 }
176
177 #[test]
179 fn set_coeff_rest_zero() {
180 let modulus = ModulusPolynomialRingZq::from_str("7 1 8 0 0 1 0 12 mod 17").unwrap();
181 let poly = PolyOverZ::from_str("2 0 2").unwrap();
182 let mut poly_ring = PolynomialRingZq::from((&poly, &modulus));
183
184 poly_ring.set_coeff(5, 10).unwrap();
185
186 let cmp_poly = PolyOverZ::from_str("6 0 2 0 0 0 10").unwrap();
187 let cmp_poly_ring = PolynomialRingZq::from((&cmp_poly, &modulus));
188 assert_eq!(cmp_poly_ring, poly_ring);
189 }
190
191 #[test]
193 fn set_negative_index() {
194 let modulus = ModulusPolynomialRingZq::from_str("4 1 0 0 1 mod 17").unwrap();
195 let poly = PolyOverZ::from_str("3 0 1 1").unwrap();
196 let mut poly_ring = PolynomialRingZq::from((&poly, &modulus));
197
198 assert!(poly_ring.set_coeff(-1, 2).is_err());
199 assert!(poly_ring.set_coeff(i64::MIN, 2).is_err());
200 assert!(poly_ring.set_coeff(i32::MIN, 2).is_err());
201 assert!(poly_ring.set_coeff(i16::MIN, 2).is_err());
202 assert!(poly_ring.set_coeff(i8::MIN, 2).is_err());
203 }
204
205 #[test]
207 fn different_base() {
208 let modulus = ModulusPolynomialRingZq::from_str("4 1 0 0 1 mod 17").unwrap();
209 let poly = PolyOverZ::from_str("3 0 1 1").unwrap();
210 let mut poly_ring = PolynomialRingZq::from((&poly, &modulus));
211 let value = Zq::from((13, 18));
212
213 assert!(poly_ring.set_coeff(1, &value).is_err());
214 }
215}