cp_library_rs/algebraic_structure/
affine1d.rs1use std::{
4 fmt::Debug,
5 ops::{Add, Mul},
6};
7
8use crate::{algebraic_structure::monoid::Monoid, linear_algrebra::matrix_exp::Matrix};
9
10use num_traits::{One, Zero};
11
12pub type Affine<T> = (T, T);
14
15pub trait AffineTransform<T> {
17 fn id_() -> Self;
19 fn compose(&self, rhs: &Self) -> Self;
22 fn apply(&self, x: T) -> T;
24 fn pow(&self, p: usize) -> Self;
26}
27
28impl<T> AffineTransform<T> for Affine<T>
29where
30 T: Add<Output = T> + Mul<Output = T> + Zero + One + Copy + PartialEq,
31{
32 fn id_() -> Self {
33 (T::one(), T::zero())
34 }
35 fn compose(&self, rhs: &Self) -> Self {
36 let &(a1, b1) = rhs;
37 let &(a2, b2) = self;
38 (a2 * a1, a2 * b1 + b2)
41 }
42 fn apply(&self, x: T) -> T {
43 let &(a, b) = self;
44 a * x + b
45 }
46 fn pow(&self, mut p: usize) -> Self {
47 let &(a, b) = self;
49 let mut tmp = Matrix([[a, b], [T::zero(), T::one()]]);
50 let mut res = Matrix::id();
51 while p > 0 {
52 if p & 1 == 1 {
53 res = tmp.dot(&res);
54 }
55 tmp = tmp.dot(&tmp);
56 p >>= 1;
57 }
58 (res.0[0][0], res.0[0][1])
59 }
60}
61
62impl<T> Monoid for Affine<T>
64where
65 T: Clone + Debug,
66 Affine<T>: AffineTransform<T>,
67{
68 type Val = Affine<T>;
69 fn e() -> Self::Val {
70 AffineTransform::id_()
71 }
72 fn op(left: &Self::Val, right: &Self::Val) -> Self::Val {
73 right.compose(left)
74 }
75}