Ring

Trait Ring 

Source
pub trait Ring: SemiRing<Additive: Invertible> {
    // Provided methods
    fn neg(x: &Self::T) -> Self::T { ... }
    fn sub(x: &Self::T, y: &Self::T) -> Self::T { ... }
    fn sub_assign(x: &mut Self::T, y: &Self::T) { ... }
}

Provided Methods§

Source

fn neg(x: &Self::T) -> Self::T

additive inverse: $-$

Examples found in repository?
crates/competitive/src/math/matrix.rs (line 215)
209    pub fn determinant(&mut self) -> R::T {
210        assert_eq!(self.shape.0, self.shape.1);
211        let mut neg = false;
212        self.row_reduction_with(false, |r, p, _| neg ^= r != p);
213        let mut d = R::one();
214        if neg {
215            d = R::neg(&d);
216        }
217        for i in 0..self.shape.0 {
218            R::mul_assign(&mut d, &self[i][i]);
219        }
220        d
221    }
222
223    pub fn solve_system_of_linear_equations(
224        &self,
225        b: &[R::T],
226    ) -> Option<SystemOfLinearEquationsSolution<R>> {
227        assert_eq!(self.shape.0, b.len());
228        let (n, m) = self.shape;
229        let mut c = Matrix::<R>::zeros((n, m + 1));
230        for i in 0..n {
231            c[i][..m].clone_from_slice(&self[i]);
232            c[i][m] = b[i].clone();
233        }
234        let mut reduced = vec![!0; m + 1];
235        c.row_reduction_with(true, |r, _, c| reduced[c] = r);
236        if reduced[m] != !0 {
237            return None;
238        }
239        let mut particular = vec![R::zero(); m];
240        let mut basis = vec![];
241        for j in 0..m {
242            if reduced[j] != !0 {
243                particular[j] = c[reduced[j]][m].clone();
244            } else {
245                let mut v = vec![R::zero(); m];
246                v[j] = R::one();
247                for i in 0..m {
248                    if reduced[i] != !0 {
249                        R::sub_assign(&mut v[i], &c[reduced[i]][j]);
250                    }
251                }
252                basis.push(v);
253            }
254        }
255        Some(SystemOfLinearEquationsSolution { particular, basis })
256    }
257
258    pub fn inverse(&self) -> Option<Matrix<R>> {
259        assert_eq!(self.shape.0, self.shape.1);
260        let n = self.shape.0;
261        let mut c = Matrix::<R>::zeros((n, n * 2));
262        for i in 0..n {
263            c[i][..n].clone_from_slice(&self[i]);
264            c[i][n + i] = R::one();
265        }
266        c.row_reduction(true);
267        if (0..n).any(|i| R::is_zero(&c[i][i])) {
268            None
269        } else {
270            Some(Self::from_vec(
271                c.data.into_iter().map(|r| r[n..].to_vec()).collect(),
272            ))
273        }
274    }
275
276    pub fn characteristic_polynomial(&mut self) -> Vec<R::T> {
277        let n = self.shape.0;
278        if n == 0 {
279            return vec![R::one()];
280        }
281        assert!(self.data.iter().all(|a| a.len() == n));
282        for j in 0..(n - 1) {
283            if let Some(x) = ((j + 1)..n).find(|&x| !R::is_zero(&self[x][j])) {
284                self.data.swap(j + 1, x);
285                self.data.iter_mut().for_each(|a| a.swap(j + 1, x));
286                let inv = R::inv(&self[j + 1][j]);
287                let mut v = vec![];
288                let src = std::mem::take(&mut self[j + 1]);
289                for a in self.data[(j + 2)..].iter_mut() {
290                    let mul = R::mul(&a[j], &inv);
291                    for (a, src) in a[j..].iter_mut().zip(src[j..].iter()) {
292                        R::sub_assign(a, &R::mul(&mul, src));
293                    }
294                    v.push(mul);
295                }
296                self[j + 1] = src;
297                for a in self.data.iter_mut() {
298                    let v = a[(j + 2)..]
299                        .iter()
300                        .zip(v.iter())
301                        .fold(R::zero(), |s, a| R::add(&s, &R::mul(a.0, a.1)));
302                    R::add_assign(&mut a[j + 1], &v);
303                }
304            }
305        }
306        let mut dp = vec![vec![R::one()]];
307        for i in 0..n {
308            let mut next = vec![R::zero(); i + 2];
309            for (j, dp) in dp[i].iter().enumerate() {
310                R::sub_assign(&mut next[j], &R::mul(dp, &self[i][i]));
311                R::add_assign(&mut next[j + 1], dp);
312            }
313            let mut mul = R::one();
314            for j in (0..i).rev() {
315                mul = R::mul(&mul, &self[j + 1][j]);
316                let c = R::mul(&mul, &self[j][i]);
317                for (next, dp) in next.iter_mut().zip(dp[j].iter()) {
318                    R::sub_assign(next, &R::mul(&c, dp));
319                }
320            }
321            dp.push(next);
322        }
323        dp.pop().unwrap()
324    }
325}
326
327impl<R> Index<usize> for Matrix<R>
328where
329    R: SemiRing,
330{
331    type Output = Vec<R::T>;
332    fn index(&self, index: usize) -> &Self::Output {
333        &self.data[index]
334    }
335}
336
337impl<R> IndexMut<usize> for Matrix<R>
338where
339    R: SemiRing,
340{
341    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
342        &mut self.data[index]
343    }
344}
345
346impl<R> Index<(usize, usize)> for Matrix<R>
347where
348    R: SemiRing,
349{
350    type Output = R::T;
351    fn index(&self, index: (usize, usize)) -> &Self::Output {
352        &self.data[index.0][index.1]
353    }
354}
355
356impl<R> IndexMut<(usize, usize)> for Matrix<R>
357where
358    R: SemiRing,
359{
360    fn index_mut(&mut self, index: (usize, usize)) -> &mut Self::Output {
361        &mut self.data[index.0][index.1]
362    }
363}
364
365macro_rules! impl_matrix_pairwise_binop {
366    ($imp:ident, $method:ident, $imp_assign:ident, $method_assign:ident $(where [$($clauses:tt)*])?) => {
367        impl<R> $imp_assign for Matrix<R>
368        where
369            R: SemiRing,
370            $($($clauses)*)?
371        {
372            fn $method_assign(&mut self, rhs: Self) {
373                self.pairwise_assign(&rhs, |a, b| R::$method_assign(a, b));
374            }
375        }
376        impl<R> $imp_assign<&Matrix<R>> for Matrix<R>
377        where
378            R: SemiRing,
379            $($($clauses)*)?
380        {
381            fn $method_assign(&mut self, rhs: &Self) {
382                self.pairwise_assign(rhs, |a, b| R::$method_assign(a, b));
383            }
384        }
385        impl<R> $imp for Matrix<R>
386        where
387            R: SemiRing,
388            $($($clauses)*)?
389        {
390            type Output = Matrix<R>;
391            fn $method(mut self, rhs: Self) -> Self::Output {
392                self.$method_assign(rhs);
393                self
394            }
395        }
396        impl<R> $imp<&Matrix<R>> for Matrix<R>
397        where
398            R: SemiRing,
399            $($($clauses)*)?
400        {
401            type Output = Matrix<R>;
402            fn $method(mut self, rhs: &Self) -> Self::Output {
403                self.$method_assign(rhs);
404                self
405            }
406        }
407        impl<R> $imp<Matrix<R>> for &Matrix<R>
408        where
409            R: SemiRing,
410            $($($clauses)*)?
411        {
412            type Output = Matrix<R>;
413            fn $method(self, mut rhs: Matrix<R>) -> Self::Output {
414                rhs.pairwise_assign(self, |a, b| *a = R::$method(b, a));
415                rhs
416            }
417        }
418        impl<R> $imp<&Matrix<R>> for &Matrix<R>
419        where
420            R: SemiRing,
421            $($($clauses)*)?
422        {
423            type Output = Matrix<R>;
424            fn $method(self, rhs: &Matrix<R>) -> Self::Output {
425                let mut this = self.clone();
426                this.$method_assign(rhs);
427                this
428            }
429        }
430    };
431}
432
433impl_matrix_pairwise_binop!(Add, add, AddAssign, add_assign);
434impl_matrix_pairwise_binop!(Sub, sub, SubAssign, sub_assign where [R: SemiRing<Additive: Invertible>]);
435
436impl<R> Mul for Matrix<R>
437where
438    R: SemiRing,
439{
440    type Output = Matrix<R>;
441    fn mul(self, rhs: Self) -> Self::Output {
442        (&self).mul(&rhs)
443    }
444}
445impl<R> Mul<&Matrix<R>> for Matrix<R>
446where
447    R: SemiRing,
448{
449    type Output = Matrix<R>;
450    fn mul(self, rhs: &Matrix<R>) -> Self::Output {
451        (&self).mul(rhs)
452    }
453}
454impl<R> Mul<Matrix<R>> for &Matrix<R>
455where
456    R: SemiRing,
457{
458    type Output = Matrix<R>;
459    fn mul(self, rhs: Matrix<R>) -> Self::Output {
460        self.mul(&rhs)
461    }
462}
463impl<R> Mul<&Matrix<R>> for &Matrix<R>
464where
465    R: SemiRing,
466{
467    type Output = Matrix<R>;
468    fn mul(self, rhs: &Matrix<R>) -> Self::Output {
469        assert_eq!(self.shape.1, rhs.shape.0);
470        let mut res = Matrix::zeros((self.shape.0, rhs.shape.1));
471        for i in 0..self.shape.0 {
472            for k in 0..self.shape.1 {
473                for j in 0..rhs.shape.1 {
474                    R::add_assign(&mut res[i][j], &R::mul(&self[i][k], &rhs[k][j]));
475                }
476            }
477        }
478        res
479    }
480}
481
482impl<R> MulAssign<&R::T> for Matrix<R>
483where
484    R: SemiRing,
485{
486    fn mul_assign(&mut self, rhs: &R::T) {
487        for i in 0..self.shape.0 {
488            for j in 0..self.shape.1 {
489                R::mul_assign(&mut self[(i, j)], rhs);
490            }
491        }
492    }
493}
494
495impl<R> Neg for Matrix<R>
496where
497    R: SemiRing<Additive: Invertible>,
498{
499    type Output = Self;
500
501    fn neg(self) -> Self::Output {
502        self.map(|x| R::neg(x))
503    }
504}
505
506impl<R> Neg for &Matrix<R>
507where
508    R: SemiRing<Additive: Invertible>,
509{
510    type Output = Matrix<R>;
511
512    fn neg(self) -> Self::Output {
513        self.map(|x| R::neg(x))
514    }
More examples
Hide additional examples
crates/competitive/src/math/floor_sum.rs (line 318)
300pub fn floor_sum_polynomial_i64<T, const X: usize, const Y: usize>(
301    l: i64,
302    r: i64,
303    a: i64,
304    b: i64,
305    m: u64,
306) -> [[T; Y]; X]
307where
308    T: Clone + Zero + One + Add<Output = T> + Mul<Output = T>,
309    AddMulOperation<T>: SemiRing<T = T, Additive: Invertible>,
310{
311    assert!(l <= r);
312    assert!(m > 0);
313
314    if a < 0 {
315        let mut ans = floor_sum_polynomial_i64::<T, X, Y>(-r + 1, -l + 1, -a, b, m);
316        for ans in ans.iter_mut().skip(1).step_by(2) {
317            for ans in ans.iter_mut() {
318                *ans = AddMulOperation::<T>::neg(ans);
319            }
320        }
321        return ans;
322    }
323
324    let add_x = l;
325    let n = (r - l) as u64;
326    let b = a * add_x + b;
327
328    let add_y = b.div_euclid(m as i64);
329    let b = b.rem_euclid(m as i64);
330    assert!(a >= 0);
331    assert!(b >= 0);
332    let data = floor_monoid_product::<FloorSum<AddMulOperation<T>, X, Y>>(
333        FloorSum::<AddMulOperation<T>, X, Y>::to_x(),
334        FloorSum::<AddMulOperation<T>, X, Y>::to_y(),
335        n,
336        a as u64,
337        b as u64,
338        m,
339    );
340
341    let offset = FloorSum::<AddMulOperation<T>, X, Y>::offset(add_x, add_y);
342    FloorSum::<AddMulOperation<T>, X, Y>::operate(&offset, &data).dp
343}
crates/competitive/src/algorithm/automata_learning.rs (line 562)
523    pub fn train_sample(&mut self, sample: &[usize]) -> bool {
524        let Some((prefix, suffix)) = self.split_sample(sample) else {
525            return false;
526        };
527        self.prefixes.push(prefix);
528        self.suffixes.push(suffix);
529        let n = self.inv_h.shape.0;
530        let prefix = &self.prefixes[n];
531        let suffix = &self.suffixes[n];
532        let u = Matrix::<F>::new_with((n, 1), |i, _| {
533            self.automaton.behavior(
534                self.prefixes[i]
535                    .iter()
536                    .cloned()
537                    .chain(suffix.iter().cloned()),
538            )
539        });
540        let v = Matrix::<F>::new_with((1, n), |_, j| {
541            self.automaton.behavior(
542                prefix
543                    .iter()
544                    .cloned()
545                    .chain(self.suffixes[j].iter().cloned()),
546            )
547        });
548        let w = Matrix::<F>::new_with((1, 1), |_, _| {
549            self.automaton
550                .behavior(prefix.iter().cloned().chain(suffix.iter().cloned()))
551        });
552        let t = &self.inv_h * &u;
553        let s = &v * &self.inv_h;
554        let d = F::inv(&(&w - &(&v * &t))[0][0]);
555        let dh = &t * &s;
556        for i in 0..n {
557            for j in 0..n {
558                F::add_assign(&mut self.inv_h[i][j], &F::mul(&dh[i][j], &d));
559            }
560        }
561        self.inv_h
562            .add_col_with(|i, _| F::neg(&F::mul(&t[i][0], &d)));
563        self.inv_h.add_row_with(|_, j| {
564            if j != n {
565                F::neg(&F::mul(&s[0][j], &d))
566            } else {
567                d.clone()
568            }
569        });
570
571        for (x, transition) in self.wfa.transitions.iter_mut().enumerate() {
572            let b = &(&self.nh[x] * &t) * &s;
573            for i in 0..n {
574                for j in 0..n {
575                    F::add_assign(&mut transition[i][j], &F::mul(&b[i][j], &d));
576                }
577            }
578        }
579        for (x, nh) in self.nh.iter_mut().enumerate() {
580            nh.add_col_with(|i, j| {
581                self.automaton.behavior(
582                    self.prefixes[i]
583                        .iter()
584                        .cloned()
585                        .chain([x])
586                        .chain(self.suffixes[j].iter().cloned()),
587                )
588            });
589            nh.add_row_with(|i, j| {
590                self.automaton.behavior(
591                    self.prefixes[i]
592                        .iter()
593                        .cloned()
594                        .chain([x])
595                        .chain(self.suffixes[j].iter().cloned()),
596                )
597            });
598        }
599        self.wfa
600            .initial_weights
601            .add_col_with(|_, _| if n == 0 { F::one() } else { F::zero() });
602        self.wfa
603            .final_weights
604            .add_row_with(|_, _| self.automaton.behavior(prefix.iter().cloned()));
605        for (x, transition) in self.wfa.transitions.iter_mut().enumerate() {
606            transition.add_col_with(|_, _| F::zero());
607            transition.add_row_with(|_, _| F::zero());
608            for i in 0..=n {
609                for j in 0..=n {
610                    if i == n || j == n {
611                        for k in 0..=n {
612                            if i != n && j != n && k != n {
613                                continue;
614                            }
615                            F::add_assign(
616                                &mut transition[i][k],
617                                &F::mul(&self.nh[x][i][j], &self.inv_h[j][k]),
618                            );
619                        }
620                    } else {
621                        let k = n;
622                        F::add_assign(
623                            &mut transition[i][k],
624                            &F::mul(&self.nh[x][i][j], &self.inv_h[j][k]),
625                        );
626                    }
627                }
628            }
629        }
630        true
631    }
Source

fn sub(x: &Self::T, y: &Self::T) -> Self::T

additive right inversed operaion: $-$

Examples found in repository?
crates/competitive/src/string/rolling_hash.rs (line 527)
525    fn muln_sub(&mut self, l: &R::T, r: &R::T, n: usize) -> R::T {
526        if let Some(pow) = self.pow.get(n) {
527            R::sub(r, &R::mul(l, pow))
528        } else {
529            let pow = <R::Multiplicative as Monoid>::pow(self.base.clone(), n);
530            R::sub(r, &R::mul(l, &pow))
531        }
532    }
More examples
Hide additional examples
crates/competitive/src/math/quotient_array.rs (line 98)
82    pub fn min_25_sieve<R>(&self, mut f: impl FnMut(u64, u32) -> T) -> Self
83    where
84        T: Clone + One,
85        R: Ring<T = T, Additive: Invertible>,
86    {
87        let mut dp = self.clone();
88        with_prime_list(self.isqrtn, |pl| {
89            for &p in pl.primes_lte(self.isqrtn).iter().rev() {
90                let k = self.quotient_index(p);
91                for (i, q) in Self::index_iter(self.n, self.isqrtn).enumerate() {
92                    let mut pc = p;
93                    if pc * p > q {
94                        break;
95                    }
96                    let mut c = 1;
97                    while q / p >= pc {
98                        let x = R::mul(&f(p, c), &(R::sub(&dp[q / pc], &self.data[k])));
99                        let x = R::add(&x, &f(p, c + 1));
100                        dp.data[i] = R::add(&dp.data[i], &x);
101                        c += 1;
102                        pc *= p;
103                    }
104                }
105            }
106        });
107        for x in &mut dp.data {
108            *x = R::add(x, &T::one());
109        }
110        dp
111    }
Source

fn sub_assign(x: &mut Self::T, y: &Self::T)

Examples found in repository?
crates/competitive/src/math/matrix.rs (line 190)
159    pub fn row_reduction_with<F>(&mut self, normalize: bool, mut f: F)
160    where
161        F: FnMut(usize, usize, usize),
162    {
163        let (n, m) = self.shape;
164        let mut c = 0;
165        for r in 0..n {
166            loop {
167                if c >= m {
168                    return;
169                }
170                if let Some(pivot) = (r..n).find(|&p| !R::is_zero(&self[p][c])) {
171                    f(r, pivot, c);
172                    self.data.swap(r, pivot);
173                    break;
174                };
175                c += 1;
176            }
177            let d = R::inv(&self[r][c]);
178            if normalize {
179                for j in c..m {
180                    R::mul_assign(&mut self[r][j], &d);
181                }
182            }
183            for i in (0..n).filter(|&i| i != r) {
184                let mut e = self[i][c].clone();
185                if !normalize {
186                    R::mul_assign(&mut e, &d);
187                }
188                for j in c..m {
189                    let e = R::mul(&e, &self[r][j]);
190                    R::sub_assign(&mut self[i][j], &e);
191                }
192            }
193            c += 1;
194        }
195    }
196
197    pub fn row_reduction(&mut self, normalize: bool) {
198        self.row_reduction_with(normalize, |_, _, _| {});
199    }
200
201    pub fn rank(&mut self) -> usize {
202        let n = self.shape.0;
203        self.row_reduction(false);
204        (0..n)
205            .filter(|&i| !self.data[i].iter().all(|x| R::is_zero(x)))
206            .count()
207    }
208
209    pub fn determinant(&mut self) -> R::T {
210        assert_eq!(self.shape.0, self.shape.1);
211        let mut neg = false;
212        self.row_reduction_with(false, |r, p, _| neg ^= r != p);
213        let mut d = R::one();
214        if neg {
215            d = R::neg(&d);
216        }
217        for i in 0..self.shape.0 {
218            R::mul_assign(&mut d, &self[i][i]);
219        }
220        d
221    }
222
223    pub fn solve_system_of_linear_equations(
224        &self,
225        b: &[R::T],
226    ) -> Option<SystemOfLinearEquationsSolution<R>> {
227        assert_eq!(self.shape.0, b.len());
228        let (n, m) = self.shape;
229        let mut c = Matrix::<R>::zeros((n, m + 1));
230        for i in 0..n {
231            c[i][..m].clone_from_slice(&self[i]);
232            c[i][m] = b[i].clone();
233        }
234        let mut reduced = vec![!0; m + 1];
235        c.row_reduction_with(true, |r, _, c| reduced[c] = r);
236        if reduced[m] != !0 {
237            return None;
238        }
239        let mut particular = vec![R::zero(); m];
240        let mut basis = vec![];
241        for j in 0..m {
242            if reduced[j] != !0 {
243                particular[j] = c[reduced[j]][m].clone();
244            } else {
245                let mut v = vec![R::zero(); m];
246                v[j] = R::one();
247                for i in 0..m {
248                    if reduced[i] != !0 {
249                        R::sub_assign(&mut v[i], &c[reduced[i]][j]);
250                    }
251                }
252                basis.push(v);
253            }
254        }
255        Some(SystemOfLinearEquationsSolution { particular, basis })
256    }
257
258    pub fn inverse(&self) -> Option<Matrix<R>> {
259        assert_eq!(self.shape.0, self.shape.1);
260        let n = self.shape.0;
261        let mut c = Matrix::<R>::zeros((n, n * 2));
262        for i in 0..n {
263            c[i][..n].clone_from_slice(&self[i]);
264            c[i][n + i] = R::one();
265        }
266        c.row_reduction(true);
267        if (0..n).any(|i| R::is_zero(&c[i][i])) {
268            None
269        } else {
270            Some(Self::from_vec(
271                c.data.into_iter().map(|r| r[n..].to_vec()).collect(),
272            ))
273        }
274    }
275
276    pub fn characteristic_polynomial(&mut self) -> Vec<R::T> {
277        let n = self.shape.0;
278        if n == 0 {
279            return vec![R::one()];
280        }
281        assert!(self.data.iter().all(|a| a.len() == n));
282        for j in 0..(n - 1) {
283            if let Some(x) = ((j + 1)..n).find(|&x| !R::is_zero(&self[x][j])) {
284                self.data.swap(j + 1, x);
285                self.data.iter_mut().for_each(|a| a.swap(j + 1, x));
286                let inv = R::inv(&self[j + 1][j]);
287                let mut v = vec![];
288                let src = std::mem::take(&mut self[j + 1]);
289                for a in self.data[(j + 2)..].iter_mut() {
290                    let mul = R::mul(&a[j], &inv);
291                    for (a, src) in a[j..].iter_mut().zip(src[j..].iter()) {
292                        R::sub_assign(a, &R::mul(&mul, src));
293                    }
294                    v.push(mul);
295                }
296                self[j + 1] = src;
297                for a in self.data.iter_mut() {
298                    let v = a[(j + 2)..]
299                        .iter()
300                        .zip(v.iter())
301                        .fold(R::zero(), |s, a| R::add(&s, &R::mul(a.0, a.1)));
302                    R::add_assign(&mut a[j + 1], &v);
303                }
304            }
305        }
306        let mut dp = vec![vec![R::one()]];
307        for i in 0..n {
308            let mut next = vec![R::zero(); i + 2];
309            for (j, dp) in dp[i].iter().enumerate() {
310                R::sub_assign(&mut next[j], &R::mul(dp, &self[i][i]));
311                R::add_assign(&mut next[j + 1], dp);
312            }
313            let mut mul = R::one();
314            for j in (0..i).rev() {
315                mul = R::mul(&mul, &self[j + 1][j]);
316                let c = R::mul(&mul, &self[j][i]);
317                for (next, dp) in next.iter_mut().zip(dp[j].iter()) {
318                    R::sub_assign(next, &R::mul(&c, dp));
319                }
320            }
321            dp.push(next);
322        }
323        dp.pop().unwrap()
324    }

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<R> Ring for R
where R: SemiRing<Additive: Invertible>,