Skip to main content

Complex

Struct Complex 

Source
pub struct Complex<T> {
    pub re: T,
    pub im: T,
}

Fields§

§re: T§im: T

Implementations§

Source§

impl<T> Complex<T>

Source

pub fn new(re: T, im: T) -> Self

Examples found in repository?
crates/competitive/src/num/complex.rs (line 19)
18    pub fn transpose(self) -> Self {
19        Self::new(self.im, self.re)
20    }
21    pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Complex<U> {
22        Complex::new(f(self.re), f(self.im))
23    }
24}
25impl<T> Zero for Complex<T>
26where
27    T: Zero,
28{
29    fn zero() -> Self {
30        Self::new(T::zero(), T::zero())
31    }
32}
33impl<T> One for Complex<T>
34where
35    T: Zero + One,
36{
37    fn one() -> Self {
38        Self::new(T::one(), T::zero())
39    }
40}
41impl<T> Complex<T>
42where
43    T: Zero + One,
44{
45    pub fn i() -> Self {
46        Self::new(T::zero(), T::one())
47    }
48}
49impl<T> Complex<T>
50where
51    T: Neg<Output = T>,
52{
53    pub fn conjugate(self) -> Self {
54        Self::new(self.re, -self.im)
55    }
56}
57impl<T> Complex<T>
58where
59    T: Mul<Output: Add>,
60{
61    pub fn dot(self, rhs: Self) -> <<T as Mul>::Output as Add>::Output {
62        self.re * rhs.re + self.im * rhs.im
63    }
64}
65impl<T> Complex<T>
66where
67    T: Mul<Output: Sub>,
68{
69    pub fn cross(self, rhs: Self) -> <<T as Mul>::Output as Sub>::Output {
70        self.re * rhs.im - self.im * rhs.re
71    }
72}
73impl<T> Complex<T>
74where
75    T: Mul<Output: Add> + Clone,
76{
77    pub fn norm(self) -> <<T as Mul>::Output as Add>::Output {
78        self.re.clone() * self.re + self.im.clone() * self.im
79    }
80}
81impl<T> Complex<T>
82where
83    T: Zero + Ord + Mul<Output: Ord>,
84{
85    pub fn cmp_by_arg(self, other: Self) -> Ordering {
86        fn pos<T>(c: &Complex<T>) -> bool
87        where
88            T: Zero + Ord,
89        {
90            let zero = T::zero();
91            c.im < zero || c.im <= zero && c.re < zero
92        }
93        pos(&self)
94            .cmp(&pos(&other))
95            .then_with(|| (self.re * other.im).cmp(&(self.im * other.re)).reverse())
96    }
97}
98impl<T> Complex<T>
99where
100    T: Float,
101{
102    pub fn polar(r: T, theta: T) -> Self {
103        Self::new(r * theta.cos(), r * theta.sin())
104    }
105    pub fn primitive_nth_root_of_unity(n: T) -> Self {
106        let theta = T::TAU / n;
107        Self::new(theta.cos(), theta.sin())
108    }
109    pub fn abs(self) -> T {
110        self.re.hypot(self.im)
111    }
112    pub fn unit(self) -> Self {
113        self / self.abs()
114    }
115    pub fn angle(self) -> T {
116        self.im.atan2(self.re)
117    }
118}
119impl<T> Add for Complex<T>
120where
121    T: Add,
122{
123    type Output = Complex<<T as Add>::Output>;
124    fn add(self, rhs: Self) -> Self::Output {
125        Complex::new(self.re + rhs.re, self.im + rhs.im)
126    }
127}
128impl<T> Add<T> for Complex<T>
129where
130    T: Add<Output = T>,
131{
132    type Output = Self;
133    fn add(self, rhs: T) -> Self::Output {
134        Self::new(self.re + rhs, self.im)
135    }
136}
137impl<T> Sub for Complex<T>
138where
139    T: Sub,
140{
141    type Output = Complex<<T as Sub>::Output>;
142    fn sub(self, rhs: Self) -> Self::Output {
143        Complex::new(self.re - rhs.re, self.im - rhs.im)
144    }
145}
146impl<T> Sub<T> for Complex<T>
147where
148    T: Sub<Output = T>,
149{
150    type Output = Self;
151    fn sub(self, rhs: T) -> Self::Output {
152        Self::new(self.re - rhs, self.im)
153    }
154}
155impl<T, U> Mul for Complex<T>
156where
157    T: Clone + Mul,
158    <T as Mul>::Output: Add<Output = U> + Sub<Output = U>,
159{
160    type Output = Complex<U>;
161    fn mul(self, rhs: Self) -> Self::Output {
162        Complex::new(
163            self.re.clone() * rhs.re.clone() - self.im.clone() * rhs.im.clone(),
164            self.re * rhs.im + self.im * rhs.re,
165        )
166    }
167}
168impl<T> Mul<T> for Complex<T>
169where
170    T: Clone + Mul,
171{
172    type Output = Complex<<T as Mul>::Output>;
173    fn mul(self, rhs: T) -> Self::Output {
174        Complex::new(self.re * rhs.clone(), self.im * rhs)
175    }
176}
177impl<T> Div for Complex<T>
178where
179    T: Clone + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Div,
180{
181    type Output = Complex<<T as Div>::Output>;
182    fn div(self, rhs: Self) -> Self::Output {
183        let d = rhs.re.clone() * rhs.re.clone() + rhs.im.clone() * rhs.im.clone();
184        Complex::new(
185            (self.re.clone() * rhs.re.clone() + self.im.clone() * rhs.im.clone()) / d.clone(),
186            (self.im * rhs.re - self.re * rhs.im) / d,
187        )
188    }
189}
190impl<T> Div<T> for Complex<T>
191where
192    T: Clone + Div,
193{
194    type Output = Complex<<T as Div>::Output>;
195    fn div(self, rhs: T) -> Self::Output {
196        Complex::new(self.re / rhs.clone(), self.im / rhs)
197    }
198}
199impl<T> Neg for Complex<T>
200where
201    T: Neg,
202{
203    type Output = Complex<<T as Neg>::Output>;
204    fn neg(self) -> Self::Output {
205        Complex::new(-self.re, -self.im)
206    }
207}
208macro_rules! impl_complex_ref_binop {
209    (impl<$T:ident> $imp:ident $method:ident ($l:ty, $r:ty) where $($w:ident)*) => {
210        impl<$T> $imp<$r> for &$l
211        where
212            $T: Clone $(+ $w<Output = $T>)*,
213        {
214            type Output = <$l as $imp<$r>>::Output;
215            fn $method(self, rhs: $r) -> <$l as $imp<$r>>::Output {
216                $imp::$method(self.clone(), rhs)
217            }
218        }
219        impl<$T> $imp<&$r> for $l
220        where
221            $T: Clone $(+ $w<Output = $T>)*,
222        {
223            type Output = <$l as $imp<$r>>::Output;
224            fn $method(self, rhs: &$r) -> <$l as $imp<$r>>::Output {
225                $imp::$method(self, rhs.clone())
226            }
227        }
228        impl<$T> $imp<&$r> for &$l
229        where
230            $T: Clone $(+ $w<Output = $T>)*,
231        {
232            type Output = <$l as $imp<$r>>::Output;
233            fn $method(self, rhs: &$r) -> <$l as $imp<$r>>::Output {
234                $imp::$method(self.clone(), rhs.clone())
235            }
236        }
237    };
238}
239impl_complex_ref_binop!(impl<T> Add add (Complex<T>, Complex<T>) where Add);
240impl_complex_ref_binop!(impl<T> Add add (Complex<T>, T) where Add);
241impl_complex_ref_binop!(impl<T> Sub sub (Complex<T>, Complex<T>) where Sub);
242impl_complex_ref_binop!(impl<T> Sub sub (Complex<T>, T) where Sub);
243impl_complex_ref_binop!(impl<T> Mul mul (Complex<T>, Complex<T>) where Add Sub Mul);
244impl_complex_ref_binop!(impl<T> Mul mul (Complex<T>, T) where Mul);
245impl_complex_ref_binop!(impl<T> Div div (Complex<T>, Complex<T>) where Add Sub Mul Div);
246impl_complex_ref_binop!(impl<T> Div div (Complex<T>, T) where Div);
247macro_rules! impl_complex_ref_unop {
248    (impl<$T:ident> $imp:ident $method:ident ($t:ty) where $($w:ident)*) => {
249        impl<$T> $imp for &$t
250        where
251            $T: Clone $(+ $w<Output = $T>)*,
252        {
253            type Output = <$t as $imp>::Output;
254            fn $method(self) -> <$t as $imp>::Output {
255                $imp::$method(self.clone())
256            }
257        }
258    };
259}
260impl_complex_ref_unop!(impl<T> Neg neg (Complex<T>) where Neg);
261macro_rules! impl_complex_op_assign {
262    (impl<$T:ident> $imp:ident $method:ident ($l:ty, $r:ty) $fromimp:ident $frommethod:ident where $($w:ident)*) => {
263        impl<$T> $imp<$r> for $l
264        where
265            $T: Clone $(+ $w<Output = $T>)*,
266        {
267            fn $method(&mut self, rhs: $r) {
268                *self = $fromimp::$frommethod(self.clone(), rhs);
269            }
270        }
271        impl<$T> $imp<&$r> for $l
272        where
273            $T: Clone $(+ $w<Output = $T>)*,
274        {
275            fn $method(&mut self, rhs: &$r) {
276                $imp::$method(self, rhs.clone());
277            }
278        }
279    };
280}
281impl_complex_op_assign!(impl<T> AddAssign add_assign (Complex<T>, Complex<T>) Add add where Add);
282impl_complex_op_assign!(impl<T> AddAssign add_assign (Complex<T>, T) Add add where Add);
283impl_complex_op_assign!(impl<T> SubAssign sub_assign (Complex<T>, Complex<T>) Sub sub where Sub);
284impl_complex_op_assign!(impl<T> SubAssign sub_assign (Complex<T>, T) Sub sub where Sub);
285impl_complex_op_assign!(impl<T> MulAssign mul_assign (Complex<T>, Complex<T>) Mul mul where Add Sub Mul);
286impl_complex_op_assign!(impl<T> MulAssign mul_assign (Complex<T>, T) Mul mul where Mul);
287impl_complex_op_assign!(impl<T> DivAssign div_assign (Complex<T>, Complex<T>) Div div where Add Sub Mul Div);
288impl_complex_op_assign!(impl<T> DivAssign div_assign (Complex<T>, T) Div div where Div);
289macro_rules! impl_complex_fold {
290    (impl<$T:ident> $imp:ident $method:ident ($t:ty) $identimp:ident $identmethod:ident $fromimp:ident $frommethod:ident where $($w:ident)* $(+ $x:ident)*) => {
291        impl<$T> $imp for $t
292        where
293            $T: $identimp $(+ $w<Output = $T>)* $(+ $x)*,
294        {
295            fn $method<I: Iterator<Item = Self>>(iter: I) -> Self {
296                iter.fold(<Self as $identimp>::$identmethod(), $fromimp::$frommethod)
297            }
298        }
299        impl<'a, $T: 'a> $imp<&'a $t> for $t
300        where
301            $T: Clone + $identimp $(+ $w<Output = $T>)* $(+ $x)*,
302        {
303            fn $method<I: Iterator<Item = &'a $t>>(iter: I) -> Self {
304                iter.fold(<Self as $identimp>::$identmethod(), $fromimp::$frommethod)
305            }
306        }
307    };
308}
309impl_complex_fold!(impl<T> Sum sum (Complex<T>) Zero zero Add add where Add);
310impl_complex_fold!(impl<T> Product product (Complex<T>) One one Mul mul where Add Sub Mul + Zero + Clone);
311
312impl<T: Scan> Scan for Complex<T> {
313    type Output = Complex<<T as Scan>::Output>;
314    fn scan<I: ScanSource>(iter: &mut I) -> Option<Self::Output> {
315        Some(Complex::new(
316            <T as Scan>::scan(iter)?,
317            <T as Scan>::scan(iter)?,
318        ))
319    }
More examples
Hide additional examples
crates/competitive/src/math/fast_fourier_transform.rs (line 101)
96    pub fn eval_twiddle(cache: &[Complex<f64>], step: usize, n: usize, k: usize) -> Complex<f64> {
97        let k = step * k;
98        let w = cache[(k >> 2) << 1].conjugate();
99        let w = match k & 3 {
100            0 => w,
101            1 => Complex::new(-w.re, -w.im),
102            2 => Complex::new(-w.im, w.re),
103            _ => Complex::new(w.im, -w.re),
104        };
105        cache[step * n].conjugate() * w
106    }
107
108    #[target_feature(enable = "avx2,fma")]
109    pub unsafe fn fft_soa(a: &mut [Complex4]) {
110        let n = a.len() * 4;
111        RotateCache::ensure(n / 2);
112        RotateCache::with(|cache| {
113            let parity = n.trailing_zeros() & 1;
114            for leaf in (0..n).step_by(16) {
115                let mut level = (n + leaf).trailing_zeros();
116                level -= u32::from(level & 1 != parity);
117                while level >= 4 {
118                    let len = 1usize << level;
119                    let q = leaf >> level;
120                    let width = len / 16;
121                    let start = q * width * 4;
122                    let (a, rest) = a[start..start + width * 4].split_at_mut(width);
123                    let (b, rest) = rest.split_at_mut(width);
124                    let (c, d) = rest.split_at_mut(width);
125                    let w1 = eval_twiddle(cache, 4, n >> level, q);
126                    let w2 = w1 * w1;
127                    let w3 = w1 * w2;
128                    let (w1r, w1i) = (_mm256_set1_pd(w1.re), _mm256_set1_pd(w1.im));
129                    let (w2r, w2i) = (_mm256_set1_pd(w2.re), _mm256_set1_pd(w2.im));
130                    let (w3r, w3i) = (_mm256_set1_pd(w3.re), _mm256_set1_pd(w3.im));
131                    for i in 0..width {
132                        let (ar, ai) = load4(&a[i]);
133                        let (br, bi) = load4(&b[i]);
134                        let (cr, ci) = load4(&c[i]);
135                        let (dr, di) = load4(&d[i]);
136                        let (br, bi) = mul4(br, bi, w1r, w1i);
137                        let (cr, ci) = mul4(cr, ci, w2r, w2i);
138                        let (dr, di) = mul4(dr, di, w3r, w3i);
139                        let acr = _mm256_add_pd(ar, cr);
140                        let aci = _mm256_add_pd(ai, ci);
141                        let bdr = _mm256_add_pd(br, dr);
142                        let bdi = _mm256_add_pd(bi, di);
143                        let acd_r = _mm256_sub_pd(ar, cr);
144                        let acd_i = _mm256_sub_pd(ai, ci);
145                        let bdd_r = _mm256_sub_pd(br, dr);
146                        let bdd_i = _mm256_sub_pd(bi, di);
147                        store4(&mut a[i], _mm256_add_pd(acr, bdr), _mm256_add_pd(aci, bdi));
148                        store4(&mut b[i], _mm256_sub_pd(acr, bdr), _mm256_sub_pd(aci, bdi));
149                        store4(
150                            &mut c[i],
151                            _mm256_sub_pd(acd_r, bdd_i),
152                            _mm256_add_pd(acd_i, bdd_r),
153                        );
154                        store4(
155                            &mut d[i],
156                            _mm256_add_pd(acd_r, bdd_i),
157                            _mm256_sub_pd(acd_i, bdd_r),
158                        );
159                    }
160                    level -= 2;
161                }
162            }
163            if parity != 0 {
164                let blocks = n / 8;
165                for k in 0..blocks {
166                    let w = eval_twiddle(cache, 2, blocks, k);
167                    let wr = _mm256_set1_pd(w.re);
168                    let wi = _mm256_set1_pd(w.im);
169                    let (ar, ai) = load4(&a[k * 2]);
170                    let (br, bi) = load4(&a[k * 2 + 1]);
171                    let (br, bi) = mul4(br, bi, wr, wi);
172                    store4(&mut a[k * 2], _mm256_add_pd(ar, br), _mm256_add_pd(ai, bi));
173                    store4(
174                        &mut a[k * 2 + 1],
175                        _mm256_sub_pd(ar, br),
176                        _mm256_sub_pd(ai, bi),
177                    );
178                }
179            }
180        });
181    }
182
183    #[target_feature(enable = "avx2,fma")]
184    pub unsafe fn ifft_soa(a: &mut [Complex4]) {
185        let n = a.len() * 4;
186        RotateCache::ensure(n / 2);
187        RotateCache::with(|cache| {
188            let parity = n.trailing_zeros() & 1;
189            if parity != 0 {
190                let blocks = n / 8;
191                for k in 0..blocks {
192                    let w = eval_twiddle(cache, 2, blocks, k).conjugate();
193                    let wr = _mm256_set1_pd(w.re);
194                    let wi = _mm256_set1_pd(w.im);
195                    let (ar, ai) = load4(&a[k * 2]);
196                    let (br, bi) = load4(&a[k * 2 + 1]);
197                    store4(&mut a[k * 2], _mm256_add_pd(ar, br), _mm256_add_pd(ai, bi));
198                    let (br, bi) = mul4(_mm256_sub_pd(ar, br), _mm256_sub_pd(ai, bi), wr, wi);
199                    store4(&mut a[k * 2 + 1], br, bi);
200                }
201            }
202            for leaf in (12..n).step_by(16) {
203                let max_level = (leaf + 3).trailing_ones();
204                let mut level = 4 + parity;
205                while level <= max_level {
206                    let len = 1usize << level;
207                    let q = leaf >> level;
208                    let width = len / 16;
209                    let start = q * width * 4;
210                    let (a, rest) = a[start..start + width * 4].split_at_mut(width);
211                    let (b, rest) = rest.split_at_mut(width);
212                    let (c, d) = rest.split_at_mut(width);
213                    let w1 = eval_twiddle(cache, 4, n >> level, q).conjugate();
214                    let w2 = w1 * w1;
215                    let w3 = w1 * w2;
216                    let (w1r, w1i) = (_mm256_set1_pd(w1.re), _mm256_set1_pd(w1.im));
217                    let (w2r, w2i) = (_mm256_set1_pd(w2.re), _mm256_set1_pd(w2.im));
218                    let (w3r, w3i) = (_mm256_set1_pd(w3.re), _mm256_set1_pd(w3.im));
219                    for i in 0..width {
220                        let (ar, ai) = load4(&a[i]);
221                        let (br, bi) = load4(&b[i]);
222                        let (cr, ci) = load4(&c[i]);
223                        let (dr, di) = load4(&d[i]);
224                        let abr = _mm256_add_pd(ar, br);
225                        let abi = _mm256_add_pd(ai, bi);
226                        let cdr = _mm256_add_pd(cr, dr);
227                        let cdi = _mm256_add_pd(ci, di);
228                        let abd_r = _mm256_sub_pd(ar, br);
229                        let abd_i = _mm256_sub_pd(ai, bi);
230                        let cdd_r = _mm256_sub_pd(cr, dr);
231                        let cdd_i = _mm256_sub_pd(ci, di);
232                        store4(&mut a[i], _mm256_add_pd(abr, cdr), _mm256_add_pd(abi, cdi));
233                        let (br, bi) = mul4(
234                            _mm256_add_pd(abd_r, cdd_i),
235                            _mm256_sub_pd(abd_i, cdd_r),
236                            w1r,
237                            w1i,
238                        );
239                        store4(&mut b[i], br, bi);
240                        let (cr, ci) =
241                            mul4(_mm256_sub_pd(abr, cdr), _mm256_sub_pd(abi, cdi), w2r, w2i);
242                        store4(&mut c[i], cr, ci);
243                        let (dr, di) = mul4(
244                            _mm256_sub_pd(abd_r, cdd_i),
245                            _mm256_add_pd(abd_i, cdd_r),
246                            w3r,
247                            w3i,
248                        );
249                        store4(&mut d[i], dr, di);
250                    }
251                    level += 2;
252                }
253            }
254            let scale = _mm256_set1_pd(4.0 / n as f64);
255            for value in a {
256                let (re, im) = load4(value);
257                store4(value, _mm256_mul_pd(re, scale), _mm256_mul_pd(im, scale));
258            }
259        });
260    }
261
262    #[target_feature(enable = "avx2,fma")]
263    unsafe fn dot_one_soa(a: &mut [Complex4], b: &[Complex4]) {
264        let n = a.len() * 4;
265        RotateCache::ensure(n / 2);
266        RotateCache::with(|cache| {
267            for i in 0..a.len() {
268                let (mut br, mut bi) = load4(&b[i]);
269                let mut rr = _mm256_setzero_pd();
270                let mut ri = _mm256_setzero_pd();
271                let w = eval_twiddle(cache, 1, a.len(), i);
272                let wr = _mm256_setr_pd(w.re, 1.0, 1.0, 1.0);
273                let wi = _mm256_setr_pd(w.im, 0.0, 0.0, 0.0);
274                for lane in 0..4 {
275                    let ar = _mm256_set1_pd(a[i].re[lane]);
276                    let ai = _mm256_set1_pd(a[i].im[lane]);
277                    multiply_accumulate4(&mut rr, &mut ri, ar, ai, br, bi);
278                    if lane != 3 {
279                        br = _mm256_permute4x64_pd::<0x93>(br);
280                        bi = _mm256_permute4x64_pd::<0x93>(bi);
281                        (br, bi) = mul4(br, bi, wr, wi);
282                    }
283                }
284                store4(&mut a[i], rr, ri);
285            }
286        });
287    }
288
289    #[inline]
290    fn pack_f64(values: impl Iterator<Item = f64>, n: usize) -> Vec<Complex4> {
291        let mut result = Vec::with_capacity(n / 4);
292        advise_huge_pages(&mut result);
293        result.resize(n / 4, Complex4::default());
294        for (i, value) in values.enumerate() {
295            if i < n {
296                result[i >> 2].re[i & 3] = value;
297            } else {
298                result[(i - n) >> 2].im[i & 3] = value;
299            }
300        }
301        result
302    }
303
304    #[target_feature(enable = "avx2,fma")]
305    pub unsafe fn convolve_f64_avx2(
306        a: impl ExactSizeIterator<Item = f64>,
307        b: impl ExactSizeIterator<Item = f64>,
308        range: std::ops::Range<usize>,
309    ) -> Vec<f64> {
310        let n = (range.end.next_power_of_two() / 2).max(4);
311        let mut fa = pack_f64(a, n);
312        let mut fb = pack_f64(b, n);
313        fft_soa(&mut fa);
314        fft_soa(&mut fb);
315        dot_one_soa(&mut fa, &fb);
316        drop(fb);
317        ifft_soa(&mut fa);
318        range
319            .map(|i| {
320                if i < n {
321                    fa[i >> 2].re[i & 3]
322                } else {
323                    fa[(i - n) >> 2].im[i & 3]
324                }
325            })
326            .collect()
327    }
328    #[target_feature(enable = "avx2")]
329    pub unsafe fn convolve_i64_avx2(a: Vec<i64>, b: Vec<i64>, len: usize) -> Vec<i64> {
330        super::convolve_i64_naive(a, b, len)
331    }
332    #[target_feature(enable = "avx512f,avx512dq,avx512cd,avx512bw,avx512vl")]
333    pub unsafe fn convolve_i64_avx512(a: Vec<i64>, b: Vec<i64>, len: usize) -> Vec<i64> {
334        super::convolve_i64_naive(a, b, len)
335    }
336}
337
338fn bit_reverse<T>(f: &mut [T]) {
339    let mut ip = vec![0u32];
340    let mut k = f.len();
341    let mut m = 1;
342    while 2 * m < k {
343        k /= 2;
344        for j in 0..m {
345            ip.push(ip[j] + k as u32);
346        }
347        m *= 2;
348    }
349    if m == k {
350        for i in 1..m {
351            for j in 0..i {
352                let ji = j + ip[i] as usize;
353                let ij = i + ip[j] as usize;
354                f.swap(ji, ij);
355            }
356        }
357    } else {
358        for i in 1..m {
359            for j in 0..i {
360                let ji = j + ip[i] as usize;
361                let ij = i + ip[j] as usize;
362                f.swap(ji, ij);
363                f.swap(ji + m, ij + m);
364            }
365        }
366    }
367}
368
369fn real_twiddles(n: usize, inverse: bool, mut f: impl FnMut(usize, Complex<f64>)) {
370    const BLOCK: usize = 256;
371    let sign = if inverse { 1.0 } else { -1.0 };
372    let step = Complex::primitive_nth_root_of_unity(sign * n as f64);
373    for start in (1..n / 4).step_by(BLOCK) {
374        let mut w = Complex::polar(1.0, sign * std::f64::consts::TAU * start as f64 / n as f64);
375        for k in start..(start + BLOCK).min(n / 4) {
376            f(k, w);
377            w *= step;
378        }
379    }
380}
381
382pub fn transform_real(t: impl IntoIterator<Item = f64>, len: usize) -> Vec<Complex<f64>> {
383    let n = len.max(4).next_power_of_two();
384    let mut f = vec![Complex::zero(); n / 2];
385    for (i, t) in t.into_iter().enumerate() {
386        if i & 1 == 0 {
387            f[i / 2].re = t;
388        } else {
389            f[i / 2].im = t;
390        }
391    }
392    fft(&mut f);
393    bit_reverse(&mut f);
394    f[0] = Complex::new(f[0].re + f[0].im, f[0].re - f[0].im);
395    f[n / 4] = f[n / 4].conjugate();
396    real_twiddles(n, false, |k, wk| {
397        let c = wk.conjugate().transpose() + 1.;
398        let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
399        f[k] -= d;
400        f[n / 2 - k] += d.conjugate();
401    });
402    f
403}
404
405pub fn inverse_transform_real(mut f: Vec<Complex<f64>>, len: usize) -> Vec<f64> {
406    let n = len.max(4).next_power_of_two();
407    assert_eq!(f.len(), n / 2);
408    f[0] = Complex::new((f[0].re + f[0].im) * 0.5, (f[0].re - f[0].im) * 0.5);
409    f[n / 4] = f[n / 4].conjugate();
410    real_twiddles(n, true, |k, wk| {
411        let c = wk.transpose().conjugate() + 1.;
412        let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
413        f[k] -= d;
414        f[n / 2 - k] += d.conjugate();
415    });
416    bit_reverse(&mut f);
417    ifft(&mut f);
418    let inv = 1. / (n / 2) as f64;
419    (0..len)
420        .map(|i| inv * if i & 1 == 0 { f[i / 2].re } else { f[i / 2].im })
421        .collect()
422}
crates/competitive/src/geometry/circle.rs (line 25)
15    pub fn cross_circle(&self, other: &Self) -> Option<(Complex<T>, Complex<T>)> {
16        let d = (self.c - other.c).abs();
17        let rc = (d * d + self.r * self.r - other.r * other.r) / (d + d);
18        let rs2 = self.r * self.r - rc * rc;
19        if Approx(rs2) < Approx(T::zero()) {
20            return None;
21        }
22        let rs = rs2.abs().sqrt();
23        let diff = (other.c - self.c) / d;
24        Some((
25            self.c + diff * Complex::new(rc, rs),
26            self.c + diff * Complex::new(rc, -rs),
27        ))
28    }
Source

pub fn transpose(self) -> Self

Examples found in repository?
crates/competitive/src/math/fast_fourier_transform.rs (line 397)
382pub fn transform_real(t: impl IntoIterator<Item = f64>, len: usize) -> Vec<Complex<f64>> {
383    let n = len.max(4).next_power_of_two();
384    let mut f = vec![Complex::zero(); n / 2];
385    for (i, t) in t.into_iter().enumerate() {
386        if i & 1 == 0 {
387            f[i / 2].re = t;
388        } else {
389            f[i / 2].im = t;
390        }
391    }
392    fft(&mut f);
393    bit_reverse(&mut f);
394    f[0] = Complex::new(f[0].re + f[0].im, f[0].re - f[0].im);
395    f[n / 4] = f[n / 4].conjugate();
396    real_twiddles(n, false, |k, wk| {
397        let c = wk.conjugate().transpose() + 1.;
398        let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
399        f[k] -= d;
400        f[n / 2 - k] += d.conjugate();
401    });
402    f
403}
404
405pub fn inverse_transform_real(mut f: Vec<Complex<f64>>, len: usize) -> Vec<f64> {
406    let n = len.max(4).next_power_of_two();
407    assert_eq!(f.len(), n / 2);
408    f[0] = Complex::new((f[0].re + f[0].im) * 0.5, (f[0].re - f[0].im) * 0.5);
409    f[n / 4] = f[n / 4].conjugate();
410    real_twiddles(n, true, |k, wk| {
411        let c = wk.transpose().conjugate() + 1.;
412        let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
413        f[k] -= d;
414        f[n / 2 - k] += d.conjugate();
415    });
416    bit_reverse(&mut f);
417    ifft(&mut f);
418    let inv = 1. / (n / 2) as f64;
419    (0..len)
420        .map(|i| inv * if i & 1 == 0 { f[i / 2].re } else { f[i / 2].im })
421        .collect()
422}
Source

pub fn map<U>(self, f: impl FnMut(T) -> U) -> Complex<U>

Source§

impl<T> Complex<T>
where T: Zero + One,

Source

pub fn i() -> Self

Source§

impl<T> Complex<T>
where T: Neg<Output = T>,

Source

pub fn conjugate(self) -> Self

Examples found in repository?
crates/competitive/src/math/fast_fourier_transform.rs (line 98)
96    pub fn eval_twiddle(cache: &[Complex<f64>], step: usize, n: usize, k: usize) -> Complex<f64> {
97        let k = step * k;
98        let w = cache[(k >> 2) << 1].conjugate();
99        let w = match k & 3 {
100            0 => w,
101            1 => Complex::new(-w.re, -w.im),
102            2 => Complex::new(-w.im, w.re),
103            _ => Complex::new(w.im, -w.re),
104        };
105        cache[step * n].conjugate() * w
106    }
107
108    #[target_feature(enable = "avx2,fma")]
109    pub unsafe fn fft_soa(a: &mut [Complex4]) {
110        let n = a.len() * 4;
111        RotateCache::ensure(n / 2);
112        RotateCache::with(|cache| {
113            let parity = n.trailing_zeros() & 1;
114            for leaf in (0..n).step_by(16) {
115                let mut level = (n + leaf).trailing_zeros();
116                level -= u32::from(level & 1 != parity);
117                while level >= 4 {
118                    let len = 1usize << level;
119                    let q = leaf >> level;
120                    let width = len / 16;
121                    let start = q * width * 4;
122                    let (a, rest) = a[start..start + width * 4].split_at_mut(width);
123                    let (b, rest) = rest.split_at_mut(width);
124                    let (c, d) = rest.split_at_mut(width);
125                    let w1 = eval_twiddle(cache, 4, n >> level, q);
126                    let w2 = w1 * w1;
127                    let w3 = w1 * w2;
128                    let (w1r, w1i) = (_mm256_set1_pd(w1.re), _mm256_set1_pd(w1.im));
129                    let (w2r, w2i) = (_mm256_set1_pd(w2.re), _mm256_set1_pd(w2.im));
130                    let (w3r, w3i) = (_mm256_set1_pd(w3.re), _mm256_set1_pd(w3.im));
131                    for i in 0..width {
132                        let (ar, ai) = load4(&a[i]);
133                        let (br, bi) = load4(&b[i]);
134                        let (cr, ci) = load4(&c[i]);
135                        let (dr, di) = load4(&d[i]);
136                        let (br, bi) = mul4(br, bi, w1r, w1i);
137                        let (cr, ci) = mul4(cr, ci, w2r, w2i);
138                        let (dr, di) = mul4(dr, di, w3r, w3i);
139                        let acr = _mm256_add_pd(ar, cr);
140                        let aci = _mm256_add_pd(ai, ci);
141                        let bdr = _mm256_add_pd(br, dr);
142                        let bdi = _mm256_add_pd(bi, di);
143                        let acd_r = _mm256_sub_pd(ar, cr);
144                        let acd_i = _mm256_sub_pd(ai, ci);
145                        let bdd_r = _mm256_sub_pd(br, dr);
146                        let bdd_i = _mm256_sub_pd(bi, di);
147                        store4(&mut a[i], _mm256_add_pd(acr, bdr), _mm256_add_pd(aci, bdi));
148                        store4(&mut b[i], _mm256_sub_pd(acr, bdr), _mm256_sub_pd(aci, bdi));
149                        store4(
150                            &mut c[i],
151                            _mm256_sub_pd(acd_r, bdd_i),
152                            _mm256_add_pd(acd_i, bdd_r),
153                        );
154                        store4(
155                            &mut d[i],
156                            _mm256_add_pd(acd_r, bdd_i),
157                            _mm256_sub_pd(acd_i, bdd_r),
158                        );
159                    }
160                    level -= 2;
161                }
162            }
163            if parity != 0 {
164                let blocks = n / 8;
165                for k in 0..blocks {
166                    let w = eval_twiddle(cache, 2, blocks, k);
167                    let wr = _mm256_set1_pd(w.re);
168                    let wi = _mm256_set1_pd(w.im);
169                    let (ar, ai) = load4(&a[k * 2]);
170                    let (br, bi) = load4(&a[k * 2 + 1]);
171                    let (br, bi) = mul4(br, bi, wr, wi);
172                    store4(&mut a[k * 2], _mm256_add_pd(ar, br), _mm256_add_pd(ai, bi));
173                    store4(
174                        &mut a[k * 2 + 1],
175                        _mm256_sub_pd(ar, br),
176                        _mm256_sub_pd(ai, bi),
177                    );
178                }
179            }
180        });
181    }
182
183    #[target_feature(enable = "avx2,fma")]
184    pub unsafe fn ifft_soa(a: &mut [Complex4]) {
185        let n = a.len() * 4;
186        RotateCache::ensure(n / 2);
187        RotateCache::with(|cache| {
188            let parity = n.trailing_zeros() & 1;
189            if parity != 0 {
190                let blocks = n / 8;
191                for k in 0..blocks {
192                    let w = eval_twiddle(cache, 2, blocks, k).conjugate();
193                    let wr = _mm256_set1_pd(w.re);
194                    let wi = _mm256_set1_pd(w.im);
195                    let (ar, ai) = load4(&a[k * 2]);
196                    let (br, bi) = load4(&a[k * 2 + 1]);
197                    store4(&mut a[k * 2], _mm256_add_pd(ar, br), _mm256_add_pd(ai, bi));
198                    let (br, bi) = mul4(_mm256_sub_pd(ar, br), _mm256_sub_pd(ai, bi), wr, wi);
199                    store4(&mut a[k * 2 + 1], br, bi);
200                }
201            }
202            for leaf in (12..n).step_by(16) {
203                let max_level = (leaf + 3).trailing_ones();
204                let mut level = 4 + parity;
205                while level <= max_level {
206                    let len = 1usize << level;
207                    let q = leaf >> level;
208                    let width = len / 16;
209                    let start = q * width * 4;
210                    let (a, rest) = a[start..start + width * 4].split_at_mut(width);
211                    let (b, rest) = rest.split_at_mut(width);
212                    let (c, d) = rest.split_at_mut(width);
213                    let w1 = eval_twiddle(cache, 4, n >> level, q).conjugate();
214                    let w2 = w1 * w1;
215                    let w3 = w1 * w2;
216                    let (w1r, w1i) = (_mm256_set1_pd(w1.re), _mm256_set1_pd(w1.im));
217                    let (w2r, w2i) = (_mm256_set1_pd(w2.re), _mm256_set1_pd(w2.im));
218                    let (w3r, w3i) = (_mm256_set1_pd(w3.re), _mm256_set1_pd(w3.im));
219                    for i in 0..width {
220                        let (ar, ai) = load4(&a[i]);
221                        let (br, bi) = load4(&b[i]);
222                        let (cr, ci) = load4(&c[i]);
223                        let (dr, di) = load4(&d[i]);
224                        let abr = _mm256_add_pd(ar, br);
225                        let abi = _mm256_add_pd(ai, bi);
226                        let cdr = _mm256_add_pd(cr, dr);
227                        let cdi = _mm256_add_pd(ci, di);
228                        let abd_r = _mm256_sub_pd(ar, br);
229                        let abd_i = _mm256_sub_pd(ai, bi);
230                        let cdd_r = _mm256_sub_pd(cr, dr);
231                        let cdd_i = _mm256_sub_pd(ci, di);
232                        store4(&mut a[i], _mm256_add_pd(abr, cdr), _mm256_add_pd(abi, cdi));
233                        let (br, bi) = mul4(
234                            _mm256_add_pd(abd_r, cdd_i),
235                            _mm256_sub_pd(abd_i, cdd_r),
236                            w1r,
237                            w1i,
238                        );
239                        store4(&mut b[i], br, bi);
240                        let (cr, ci) =
241                            mul4(_mm256_sub_pd(abr, cdr), _mm256_sub_pd(abi, cdi), w2r, w2i);
242                        store4(&mut c[i], cr, ci);
243                        let (dr, di) = mul4(
244                            _mm256_sub_pd(abd_r, cdd_i),
245                            _mm256_add_pd(abd_i, cdd_r),
246                            w3r,
247                            w3i,
248                        );
249                        store4(&mut d[i], dr, di);
250                    }
251                    level += 2;
252                }
253            }
254            let scale = _mm256_set1_pd(4.0 / n as f64);
255            for value in a {
256                let (re, im) = load4(value);
257                store4(value, _mm256_mul_pd(re, scale), _mm256_mul_pd(im, scale));
258            }
259        });
260    }
261
262    #[target_feature(enable = "avx2,fma")]
263    unsafe fn dot_one_soa(a: &mut [Complex4], b: &[Complex4]) {
264        let n = a.len() * 4;
265        RotateCache::ensure(n / 2);
266        RotateCache::with(|cache| {
267            for i in 0..a.len() {
268                let (mut br, mut bi) = load4(&b[i]);
269                let mut rr = _mm256_setzero_pd();
270                let mut ri = _mm256_setzero_pd();
271                let w = eval_twiddle(cache, 1, a.len(), i);
272                let wr = _mm256_setr_pd(w.re, 1.0, 1.0, 1.0);
273                let wi = _mm256_setr_pd(w.im, 0.0, 0.0, 0.0);
274                for lane in 0..4 {
275                    let ar = _mm256_set1_pd(a[i].re[lane]);
276                    let ai = _mm256_set1_pd(a[i].im[lane]);
277                    multiply_accumulate4(&mut rr, &mut ri, ar, ai, br, bi);
278                    if lane != 3 {
279                        br = _mm256_permute4x64_pd::<0x93>(br);
280                        bi = _mm256_permute4x64_pd::<0x93>(bi);
281                        (br, bi) = mul4(br, bi, wr, wi);
282                    }
283                }
284                store4(&mut a[i], rr, ri);
285            }
286        });
287    }
288
289    #[inline]
290    fn pack_f64(values: impl Iterator<Item = f64>, n: usize) -> Vec<Complex4> {
291        let mut result = Vec::with_capacity(n / 4);
292        advise_huge_pages(&mut result);
293        result.resize(n / 4, Complex4::default());
294        for (i, value) in values.enumerate() {
295            if i < n {
296                result[i >> 2].re[i & 3] = value;
297            } else {
298                result[(i - n) >> 2].im[i & 3] = value;
299            }
300        }
301        result
302    }
303
304    #[target_feature(enable = "avx2,fma")]
305    pub unsafe fn convolve_f64_avx2(
306        a: impl ExactSizeIterator<Item = f64>,
307        b: impl ExactSizeIterator<Item = f64>,
308        range: std::ops::Range<usize>,
309    ) -> Vec<f64> {
310        let n = (range.end.next_power_of_two() / 2).max(4);
311        let mut fa = pack_f64(a, n);
312        let mut fb = pack_f64(b, n);
313        fft_soa(&mut fa);
314        fft_soa(&mut fb);
315        dot_one_soa(&mut fa, &fb);
316        drop(fb);
317        ifft_soa(&mut fa);
318        range
319            .map(|i| {
320                if i < n {
321                    fa[i >> 2].re[i & 3]
322                } else {
323                    fa[(i - n) >> 2].im[i & 3]
324                }
325            })
326            .collect()
327    }
328    #[target_feature(enable = "avx2")]
329    pub unsafe fn convolve_i64_avx2(a: Vec<i64>, b: Vec<i64>, len: usize) -> Vec<i64> {
330        super::convolve_i64_naive(a, b, len)
331    }
332    #[target_feature(enable = "avx512f,avx512dq,avx512cd,avx512bw,avx512vl")]
333    pub unsafe fn convolve_i64_avx512(a: Vec<i64>, b: Vec<i64>, len: usize) -> Vec<i64> {
334        super::convolve_i64_naive(a, b, len)
335    }
336}
337
338fn bit_reverse<T>(f: &mut [T]) {
339    let mut ip = vec![0u32];
340    let mut k = f.len();
341    let mut m = 1;
342    while 2 * m < k {
343        k /= 2;
344        for j in 0..m {
345            ip.push(ip[j] + k as u32);
346        }
347        m *= 2;
348    }
349    if m == k {
350        for i in 1..m {
351            for j in 0..i {
352                let ji = j + ip[i] as usize;
353                let ij = i + ip[j] as usize;
354                f.swap(ji, ij);
355            }
356        }
357    } else {
358        for i in 1..m {
359            for j in 0..i {
360                let ji = j + ip[i] as usize;
361                let ij = i + ip[j] as usize;
362                f.swap(ji, ij);
363                f.swap(ji + m, ij + m);
364            }
365        }
366    }
367}
368
369fn real_twiddles(n: usize, inverse: bool, mut f: impl FnMut(usize, Complex<f64>)) {
370    const BLOCK: usize = 256;
371    let sign = if inverse { 1.0 } else { -1.0 };
372    let step = Complex::primitive_nth_root_of_unity(sign * n as f64);
373    for start in (1..n / 4).step_by(BLOCK) {
374        let mut w = Complex::polar(1.0, sign * std::f64::consts::TAU * start as f64 / n as f64);
375        for k in start..(start + BLOCK).min(n / 4) {
376            f(k, w);
377            w *= step;
378        }
379    }
380}
381
382pub fn transform_real(t: impl IntoIterator<Item = f64>, len: usize) -> Vec<Complex<f64>> {
383    let n = len.max(4).next_power_of_two();
384    let mut f = vec![Complex::zero(); n / 2];
385    for (i, t) in t.into_iter().enumerate() {
386        if i & 1 == 0 {
387            f[i / 2].re = t;
388        } else {
389            f[i / 2].im = t;
390        }
391    }
392    fft(&mut f);
393    bit_reverse(&mut f);
394    f[0] = Complex::new(f[0].re + f[0].im, f[0].re - f[0].im);
395    f[n / 4] = f[n / 4].conjugate();
396    real_twiddles(n, false, |k, wk| {
397        let c = wk.conjugate().transpose() + 1.;
398        let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
399        f[k] -= d;
400        f[n / 2 - k] += d.conjugate();
401    });
402    f
403}
404
405pub fn inverse_transform_real(mut f: Vec<Complex<f64>>, len: usize) -> Vec<f64> {
406    let n = len.max(4).next_power_of_two();
407    assert_eq!(f.len(), n / 2);
408    f[0] = Complex::new((f[0].re + f[0].im) * 0.5, (f[0].re - f[0].im) * 0.5);
409    f[n / 4] = f[n / 4].conjugate();
410    real_twiddles(n, true, |k, wk| {
411        let c = wk.transpose().conjugate() + 1.;
412        let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
413        f[k] -= d;
414        f[n / 2 - k] += d.conjugate();
415    });
416    bit_reverse(&mut f);
417    ifft(&mut f);
418    let inv = 1. / (n / 2) as f64;
419    (0..len)
420        .map(|i| inv * if i & 1 == 0 { f[i / 2].re } else { f[i / 2].im })
421        .collect()
422}
Source§

impl<T> Complex<T>
where T: Mul<Output: Add>,

Source

pub fn dot(self, rhs: Self) -> <<T as Mul>::Output as Add>::Output

Examples found in repository?
crates/competitive/src/geometry/line.rs (line 27)
26    pub fn is_orthogonal(&self, other: &Self) -> bool {
27        Approx(self.dir().dot(other.dir())) == Approx(T::zero())
28    }
29}
30impl<T> Line<T>
31where
32    T: Ccwable + Float,
33{
34    pub fn projection(&self, p: Complex<T>) -> Complex<T> {
35        let e = self.dir().unit();
36        self.p1 + e * (p - self.p1).dot(e)
37    }
38    pub fn reflection(&self, p: Complex<T>) -> Complex<T> {
39        let d = self.projection(p) - p;
40        p + d + d
41    }
42    pub fn distance_point(&self, p: Complex<T>) -> T {
43        (p / self.dir().unit()).re
44    }
45}
46
47#[derive(Clone, Debug, PartialEq)]
48pub struct LineSegment<T> {
49    p1: Complex<T>,
50    p2: Complex<T>,
51}
52impl<T> LineSegment<T> {
53    pub fn new(p1: Complex<T>, p2: Complex<T>) -> Self {
54        LineSegment { p1, p2 }
55    }
56}
57impl<T> LineSegment<T>
58where
59    T: Ccwable,
60{
61    pub fn dir(&self) -> Complex<T> {
62        self.p2 - self.p1
63    }
64    pub fn ccw(&self, p: Complex<T>) -> Ccw {
65        Ccw::new(self.p1, self.p2, p)
66    }
67    pub fn is_parallel(&self, other: &Self) -> bool {
68        Approx(self.dir().cross(other.dir())) == Approx(T::zero())
69    }
70    pub fn is_orthogonal(&self, other: &Self) -> bool {
71        Approx(self.dir().dot(other.dir())) == Approx(T::zero())
72    }
73    pub fn intersect(&self, other: &Self) -> bool {
74        self.ccw(other.p1) as i8 * self.ccw(other.p2) as i8 <= 0
75            && other.ccw(self.p1) as i8 * other.ccw(self.p2) as i8 <= 0
76    }
77    pub fn intersect_point(&self, p: Complex<T>) -> bool {
78        self.ccw(p) == Ccw::OnSegment
79    }
80}
81impl<T> LineSegment<T>
82where
83    T: Ccwable + Float,
84{
85    pub fn projection(&self, p: Complex<T>) -> Complex<T> {
86        let e = self.dir().unit();
87        self.p1 + e * (p - self.p1).dot(e)
88    }
More examples
Hide additional examples
crates/competitive/src/geometry/ccw.rs (line 46)
35    pub fn new<T>(a: Complex<T>, b: Complex<T>, c: Complex<T>) -> Self
36    where
37        T: Ccwable,
38    {
39        let x = b - a;
40        let y = c - a;
41        let zero = T::zero();
42        match x.cross(y).approx_cmp(&zero) {
43            Ordering::Less => Self::Clockwise,
44            Ordering::Greater => Self::CounterClockwise,
45            Ordering::Equal => {
46                if Approx(x.dot(y)) < Approx(zero) {
47                    Self::OnlineBack
48                } else if Approx((a - b).dot(c - b)) < Approx(zero) {
49                    Self::OnlineFront
50                } else {
51                    Self::OnSegment
52                }
53            }
54        }
55    }
56    pub fn new_open<T>(a: Complex<T>, b: Complex<T>, c: Complex<T>) -> Self
57    where
58        T: Ccwable,
59    {
60        let x = b - a;
61        let y = c - a;
62        let zero = T::zero();
63        match x.cross(y).approx_cmp(&zero) {
64            Ordering::Less => Self::Clockwise,
65            Ordering::Greater => Self::CounterClockwise,
66            Ordering::Equal => {
67                if Approx(x.dot(y)) <= Approx(zero) {
68                    Self::OnlineBack
69                } else if Approx((a - b).dot(c - b)) <= Approx(zero) {
70                    Self::OnlineFront
71                } else {
72                    Self::OnSegment
73                }
74            }
75        }
76    }
Source§

impl<T> Complex<T>
where T: Mul<Output: Sub>,

Source

pub fn cross(self, rhs: Self) -> <<T as Mul>::Output as Sub>::Output

Examples found in repository?
crates/competitive/src/geometry/line.rs (line 24)
23    pub fn is_parallel(&self, other: &Self) -> bool {
24        Approx(self.dir().cross(other.dir())) == Approx(T::zero())
25    }
26    pub fn is_orthogonal(&self, other: &Self) -> bool {
27        Approx(self.dir().dot(other.dir())) == Approx(T::zero())
28    }
29}
30impl<T> Line<T>
31where
32    T: Ccwable + Float,
33{
34    pub fn projection(&self, p: Complex<T>) -> Complex<T> {
35        let e = self.dir().unit();
36        self.p1 + e * (p - self.p1).dot(e)
37    }
38    pub fn reflection(&self, p: Complex<T>) -> Complex<T> {
39        let d = self.projection(p) - p;
40        p + d + d
41    }
42    pub fn distance_point(&self, p: Complex<T>) -> T {
43        (p / self.dir().unit()).re
44    }
45}
46
47#[derive(Clone, Debug, PartialEq)]
48pub struct LineSegment<T> {
49    p1: Complex<T>,
50    p2: Complex<T>,
51}
52impl<T> LineSegment<T> {
53    pub fn new(p1: Complex<T>, p2: Complex<T>) -> Self {
54        LineSegment { p1, p2 }
55    }
56}
57impl<T> LineSegment<T>
58where
59    T: Ccwable,
60{
61    pub fn dir(&self) -> Complex<T> {
62        self.p2 - self.p1
63    }
64    pub fn ccw(&self, p: Complex<T>) -> Ccw {
65        Ccw::new(self.p1, self.p2, p)
66    }
67    pub fn is_parallel(&self, other: &Self) -> bool {
68        Approx(self.dir().cross(other.dir())) == Approx(T::zero())
69    }
70    pub fn is_orthogonal(&self, other: &Self) -> bool {
71        Approx(self.dir().dot(other.dir())) == Approx(T::zero())
72    }
73    pub fn intersect(&self, other: &Self) -> bool {
74        self.ccw(other.p1) as i8 * self.ccw(other.p2) as i8 <= 0
75            && other.ccw(self.p1) as i8 * other.ccw(self.p2) as i8 <= 0
76    }
77    pub fn intersect_point(&self, p: Complex<T>) -> bool {
78        self.ccw(p) == Ccw::OnSegment
79    }
80}
81impl<T> LineSegment<T>
82where
83    T: Ccwable + Float,
84{
85    pub fn projection(&self, p: Complex<T>) -> Complex<T> {
86        let e = self.dir().unit();
87        self.p1 + e * (p - self.p1).dot(e)
88    }
89    pub fn reflection(&self, p: Complex<T>) -> Complex<T> {
90        let d = self.projection(p) - p;
91        p + d + d
92    }
93    pub fn cross_point(&self, other: &Self) -> Option<Complex<T>> {
94        if self.intersect(other) {
95            let a = self.dir().cross(other.dir());
96            let b = self.dir().cross(self.p2 - other.p1);
97            if Approx(a.abs()) == Approx(T::zero()) && Approx(b.abs()) == Approx(T::zero()) {
98                Some(other.p1)
99            } else {
100                Some(other.p1 + (other.dir() * b / a))
101            }
102        } else {
103            None
104        }
105    }
More examples
Hide additional examples
crates/competitive/src/geometry/ccw.rs (line 42)
35    pub fn new<T>(a: Complex<T>, b: Complex<T>, c: Complex<T>) -> Self
36    where
37        T: Ccwable,
38    {
39        let x = b - a;
40        let y = c - a;
41        let zero = T::zero();
42        match x.cross(y).approx_cmp(&zero) {
43            Ordering::Less => Self::Clockwise,
44            Ordering::Greater => Self::CounterClockwise,
45            Ordering::Equal => {
46                if Approx(x.dot(y)) < Approx(zero) {
47                    Self::OnlineBack
48                } else if Approx((a - b).dot(c - b)) < Approx(zero) {
49                    Self::OnlineFront
50                } else {
51                    Self::OnSegment
52                }
53            }
54        }
55    }
56    pub fn new_open<T>(a: Complex<T>, b: Complex<T>, c: Complex<T>) -> Self
57    where
58        T: Ccwable,
59    {
60        let x = b - a;
61        let y = c - a;
62        let zero = T::zero();
63        match x.cross(y).approx_cmp(&zero) {
64            Ordering::Less => Self::Clockwise,
65            Ordering::Greater => Self::CounterClockwise,
66            Ordering::Equal => {
67                if Approx(x.dot(y)) <= Approx(zero) {
68                    Self::OnlineBack
69                } else if Approx((a - b).dot(c - b)) <= Approx(zero) {
70                    Self::OnlineFront
71                } else {
72                    Self::OnSegment
73                }
74            }
75        }
76    }
crates/competitive/src/geometry/polygon.rs (line 34)
23pub fn convex_diameter<T>(ps: &[Complex<T>]) -> T
24where
25    T: PartialOrd + Ccwable,
26{
27    let n = ps.len();
28    let mut i = (0..n).max_by_key(|&i| TotalOrd(ps[i].re)).unwrap_or(0);
29    let mut j = (0..n).min_by_key(|&i| TotalOrd(ps[i].re)).unwrap_or(0);
30    let mut res = (ps[i] - ps[j]).norm();
31    let (maxi, maxj) = (i, j);
32    loop {
33        let (ni, nj) = ((i + 1) % n, (j + 1) % n);
34        if Approx((ps[ni] - ps[i]).cross(ps[nj] - ps[j])) < Approx(T::zero()) {
35            i = ni;
36        } else {
37            j = nj;
38        }
39        let d = (ps[i] - ps[j]).norm();
40        if res < d {
41            res = d;
42        }
43        if i == maxi && j == maxj {
44            break;
45        }
46    }
47    res
48}
Source§

impl<T> Complex<T>
where T: Mul<Output: Add> + Clone,

Source

pub fn norm(self) -> <<T as Mul>::Output as Add>::Output

Examples found in repository?
crates/competitive/src/geometry/polygon.rs (line 30)
23pub fn convex_diameter<T>(ps: &[Complex<T>]) -> T
24where
25    T: PartialOrd + Ccwable,
26{
27    let n = ps.len();
28    let mut i = (0..n).max_by_key(|&i| TotalOrd(ps[i].re)).unwrap_or(0);
29    let mut j = (0..n).min_by_key(|&i| TotalOrd(ps[i].re)).unwrap_or(0);
30    let mut res = (ps[i] - ps[j]).norm();
31    let (maxi, maxj) = (i, j);
32    loop {
33        let (ni, nj) = ((i + 1) % n, (j + 1) % n);
34        if Approx((ps[ni] - ps[i]).cross(ps[nj] - ps[j])) < Approx(T::zero()) {
35            i = ni;
36        } else {
37            j = nj;
38        }
39        let d = (ps[i] - ps[j]).norm();
40        if res < d {
41            res = d;
42        }
43        if i == maxi && j == maxj {
44            break;
45        }
46    }
47    res
48}
Source§

impl<T> Complex<T>
where T: Zero + Ord + Mul<Output: Ord>,

Source

pub fn cmp_by_arg(self, other: Self) -> Ordering

Source§

impl<T> Complex<T>
where T: Float,

Source

pub fn polar(r: T, theta: T) -> Self

Examples found in repository?
crates/competitive/src/math/fast_fourier_transform.rs (line 374)
369fn real_twiddles(n: usize, inverse: bool, mut f: impl FnMut(usize, Complex<f64>)) {
370    const BLOCK: usize = 256;
371    let sign = if inverse { 1.0 } else { -1.0 };
372    let step = Complex::primitive_nth_root_of_unity(sign * n as f64);
373    for start in (1..n / 4).step_by(BLOCK) {
374        let mut w = Complex::polar(1.0, sign * std::f64::consts::TAU * start as f64 / n as f64);
375        for k in start..(start + BLOCK).min(n / 4) {
376            f(k, w);
377            w *= step;
378        }
379    }
380}
Source

pub fn primitive_nth_root_of_unity(n: T) -> Self

Examples found in repository?
crates/competitive/src/math/fast_fourier_transform.rs (line 27)
9    pub fn ensure(n: usize) {
10        assert_eq!(n.count_ones(), 1, "call with power of two but {}", n);
11        Self::modify(|cache| {
12            let mut m = cache.len();
13            assert!(
14                m.count_ones() <= 1,
15                "length might be power of two but {}",
16                m
17            );
18            if m >= n {
19                return;
20            }
21            cache.reserve_exact(n - m);
22            if cache.is_empty() {
23                cache.push(Complex::one());
24                m += 1;
25            }
26            while m < n {
27                let p = Complex::primitive_nth_root_of_unity(-((m * 4) as f64));
28                for i in 0..m {
29                    cache.push(cache[i] * p);
30                }
31                m <<= 1;
32            }
33            assert_eq!(cache.len(), n);
34        });
35    }
36}
37crate::impl_assoc_value!(RotateCache, Vec<Complex<f64>>, vec![Complex::one()]);
38
39#[cfg(target_arch = "x86_64")]
40pub mod simd {
41    // These primitives are called only after AVX2 and FMA have been detected.
42    #![allow(clippy::missing_safety_doc, unsafe_op_in_unsafe_fn)]
43
44    use super::{AssociatedValue, Complex, RotateCache, advise_huge_pages};
45    use std::arch::x86_64::*;
46
47    #[derive(Clone, Copy, Default)]
48    #[repr(C, align(32))]
49    pub struct Complex4 {
50        pub re: [f64; 4],
51        pub im: [f64; 4],
52    }
53
54    #[target_feature(enable = "avx2,fma")]
55    #[inline]
56    pub unsafe fn load4(value: &Complex4) -> (__m256d, __m256d) {
57        (
58            _mm256_load_pd(value.re.as_ptr()),
59            _mm256_load_pd(value.im.as_ptr()),
60        )
61    }
62
63    #[target_feature(enable = "avx2,fma")]
64    #[inline]
65    pub unsafe fn store4(value: &mut Complex4, re: __m256d, im: __m256d) {
66        _mm256_store_pd(value.re.as_mut_ptr(), re);
67        _mm256_store_pd(value.im.as_mut_ptr(), im);
68    }
69
70    #[target_feature(enable = "avx2,fma")]
71    #[inline]
72    pub unsafe fn mul4(ar: __m256d, ai: __m256d, br: __m256d, bi: __m256d) -> (__m256d, __m256d) {
73        (
74            _mm256_fmsub_pd(ar, br, _mm256_mul_pd(ai, bi)),
75            _mm256_fmadd_pd(ai, br, _mm256_mul_pd(ar, bi)),
76        )
77    }
78
79    #[target_feature(enable = "avx2,fma")]
80    #[inline]
81    pub unsafe fn multiply_accumulate4(
82        rr: &mut __m256d,
83        ri: &mut __m256d,
84        ar: __m256d,
85        ai: __m256d,
86        br: __m256d,
87        bi: __m256d,
88    ) {
89        *rr = _mm256_fmadd_pd(ar, br, *rr);
90        *rr = _mm256_fnmadd_pd(ai, bi, *rr);
91        *ri = _mm256_fmadd_pd(ai, br, *ri);
92        *ri = _mm256_fmadd_pd(ar, bi, *ri);
93    }
94
95    #[inline]
96    pub fn eval_twiddle(cache: &[Complex<f64>], step: usize, n: usize, k: usize) -> Complex<f64> {
97        let k = step * k;
98        let w = cache[(k >> 2) << 1].conjugate();
99        let w = match k & 3 {
100            0 => w,
101            1 => Complex::new(-w.re, -w.im),
102            2 => Complex::new(-w.im, w.re),
103            _ => Complex::new(w.im, -w.re),
104        };
105        cache[step * n].conjugate() * w
106    }
107
108    #[target_feature(enable = "avx2,fma")]
109    pub unsafe fn fft_soa(a: &mut [Complex4]) {
110        let n = a.len() * 4;
111        RotateCache::ensure(n / 2);
112        RotateCache::with(|cache| {
113            let parity = n.trailing_zeros() & 1;
114            for leaf in (0..n).step_by(16) {
115                let mut level = (n + leaf).trailing_zeros();
116                level -= u32::from(level & 1 != parity);
117                while level >= 4 {
118                    let len = 1usize << level;
119                    let q = leaf >> level;
120                    let width = len / 16;
121                    let start = q * width * 4;
122                    let (a, rest) = a[start..start + width * 4].split_at_mut(width);
123                    let (b, rest) = rest.split_at_mut(width);
124                    let (c, d) = rest.split_at_mut(width);
125                    let w1 = eval_twiddle(cache, 4, n >> level, q);
126                    let w2 = w1 * w1;
127                    let w3 = w1 * w2;
128                    let (w1r, w1i) = (_mm256_set1_pd(w1.re), _mm256_set1_pd(w1.im));
129                    let (w2r, w2i) = (_mm256_set1_pd(w2.re), _mm256_set1_pd(w2.im));
130                    let (w3r, w3i) = (_mm256_set1_pd(w3.re), _mm256_set1_pd(w3.im));
131                    for i in 0..width {
132                        let (ar, ai) = load4(&a[i]);
133                        let (br, bi) = load4(&b[i]);
134                        let (cr, ci) = load4(&c[i]);
135                        let (dr, di) = load4(&d[i]);
136                        let (br, bi) = mul4(br, bi, w1r, w1i);
137                        let (cr, ci) = mul4(cr, ci, w2r, w2i);
138                        let (dr, di) = mul4(dr, di, w3r, w3i);
139                        let acr = _mm256_add_pd(ar, cr);
140                        let aci = _mm256_add_pd(ai, ci);
141                        let bdr = _mm256_add_pd(br, dr);
142                        let bdi = _mm256_add_pd(bi, di);
143                        let acd_r = _mm256_sub_pd(ar, cr);
144                        let acd_i = _mm256_sub_pd(ai, ci);
145                        let bdd_r = _mm256_sub_pd(br, dr);
146                        let bdd_i = _mm256_sub_pd(bi, di);
147                        store4(&mut a[i], _mm256_add_pd(acr, bdr), _mm256_add_pd(aci, bdi));
148                        store4(&mut b[i], _mm256_sub_pd(acr, bdr), _mm256_sub_pd(aci, bdi));
149                        store4(
150                            &mut c[i],
151                            _mm256_sub_pd(acd_r, bdd_i),
152                            _mm256_add_pd(acd_i, bdd_r),
153                        );
154                        store4(
155                            &mut d[i],
156                            _mm256_add_pd(acd_r, bdd_i),
157                            _mm256_sub_pd(acd_i, bdd_r),
158                        );
159                    }
160                    level -= 2;
161                }
162            }
163            if parity != 0 {
164                let blocks = n / 8;
165                for k in 0..blocks {
166                    let w = eval_twiddle(cache, 2, blocks, k);
167                    let wr = _mm256_set1_pd(w.re);
168                    let wi = _mm256_set1_pd(w.im);
169                    let (ar, ai) = load4(&a[k * 2]);
170                    let (br, bi) = load4(&a[k * 2 + 1]);
171                    let (br, bi) = mul4(br, bi, wr, wi);
172                    store4(&mut a[k * 2], _mm256_add_pd(ar, br), _mm256_add_pd(ai, bi));
173                    store4(
174                        &mut a[k * 2 + 1],
175                        _mm256_sub_pd(ar, br),
176                        _mm256_sub_pd(ai, bi),
177                    );
178                }
179            }
180        });
181    }
182
183    #[target_feature(enable = "avx2,fma")]
184    pub unsafe fn ifft_soa(a: &mut [Complex4]) {
185        let n = a.len() * 4;
186        RotateCache::ensure(n / 2);
187        RotateCache::with(|cache| {
188            let parity = n.trailing_zeros() & 1;
189            if parity != 0 {
190                let blocks = n / 8;
191                for k in 0..blocks {
192                    let w = eval_twiddle(cache, 2, blocks, k).conjugate();
193                    let wr = _mm256_set1_pd(w.re);
194                    let wi = _mm256_set1_pd(w.im);
195                    let (ar, ai) = load4(&a[k * 2]);
196                    let (br, bi) = load4(&a[k * 2 + 1]);
197                    store4(&mut a[k * 2], _mm256_add_pd(ar, br), _mm256_add_pd(ai, bi));
198                    let (br, bi) = mul4(_mm256_sub_pd(ar, br), _mm256_sub_pd(ai, bi), wr, wi);
199                    store4(&mut a[k * 2 + 1], br, bi);
200                }
201            }
202            for leaf in (12..n).step_by(16) {
203                let max_level = (leaf + 3).trailing_ones();
204                let mut level = 4 + parity;
205                while level <= max_level {
206                    let len = 1usize << level;
207                    let q = leaf >> level;
208                    let width = len / 16;
209                    let start = q * width * 4;
210                    let (a, rest) = a[start..start + width * 4].split_at_mut(width);
211                    let (b, rest) = rest.split_at_mut(width);
212                    let (c, d) = rest.split_at_mut(width);
213                    let w1 = eval_twiddle(cache, 4, n >> level, q).conjugate();
214                    let w2 = w1 * w1;
215                    let w3 = w1 * w2;
216                    let (w1r, w1i) = (_mm256_set1_pd(w1.re), _mm256_set1_pd(w1.im));
217                    let (w2r, w2i) = (_mm256_set1_pd(w2.re), _mm256_set1_pd(w2.im));
218                    let (w3r, w3i) = (_mm256_set1_pd(w3.re), _mm256_set1_pd(w3.im));
219                    for i in 0..width {
220                        let (ar, ai) = load4(&a[i]);
221                        let (br, bi) = load4(&b[i]);
222                        let (cr, ci) = load4(&c[i]);
223                        let (dr, di) = load4(&d[i]);
224                        let abr = _mm256_add_pd(ar, br);
225                        let abi = _mm256_add_pd(ai, bi);
226                        let cdr = _mm256_add_pd(cr, dr);
227                        let cdi = _mm256_add_pd(ci, di);
228                        let abd_r = _mm256_sub_pd(ar, br);
229                        let abd_i = _mm256_sub_pd(ai, bi);
230                        let cdd_r = _mm256_sub_pd(cr, dr);
231                        let cdd_i = _mm256_sub_pd(ci, di);
232                        store4(&mut a[i], _mm256_add_pd(abr, cdr), _mm256_add_pd(abi, cdi));
233                        let (br, bi) = mul4(
234                            _mm256_add_pd(abd_r, cdd_i),
235                            _mm256_sub_pd(abd_i, cdd_r),
236                            w1r,
237                            w1i,
238                        );
239                        store4(&mut b[i], br, bi);
240                        let (cr, ci) =
241                            mul4(_mm256_sub_pd(abr, cdr), _mm256_sub_pd(abi, cdi), w2r, w2i);
242                        store4(&mut c[i], cr, ci);
243                        let (dr, di) = mul4(
244                            _mm256_sub_pd(abd_r, cdd_i),
245                            _mm256_add_pd(abd_i, cdd_r),
246                            w3r,
247                            w3i,
248                        );
249                        store4(&mut d[i], dr, di);
250                    }
251                    level += 2;
252                }
253            }
254            let scale = _mm256_set1_pd(4.0 / n as f64);
255            for value in a {
256                let (re, im) = load4(value);
257                store4(value, _mm256_mul_pd(re, scale), _mm256_mul_pd(im, scale));
258            }
259        });
260    }
261
262    #[target_feature(enable = "avx2,fma")]
263    unsafe fn dot_one_soa(a: &mut [Complex4], b: &[Complex4]) {
264        let n = a.len() * 4;
265        RotateCache::ensure(n / 2);
266        RotateCache::with(|cache| {
267            for i in 0..a.len() {
268                let (mut br, mut bi) = load4(&b[i]);
269                let mut rr = _mm256_setzero_pd();
270                let mut ri = _mm256_setzero_pd();
271                let w = eval_twiddle(cache, 1, a.len(), i);
272                let wr = _mm256_setr_pd(w.re, 1.0, 1.0, 1.0);
273                let wi = _mm256_setr_pd(w.im, 0.0, 0.0, 0.0);
274                for lane in 0..4 {
275                    let ar = _mm256_set1_pd(a[i].re[lane]);
276                    let ai = _mm256_set1_pd(a[i].im[lane]);
277                    multiply_accumulate4(&mut rr, &mut ri, ar, ai, br, bi);
278                    if lane != 3 {
279                        br = _mm256_permute4x64_pd::<0x93>(br);
280                        bi = _mm256_permute4x64_pd::<0x93>(bi);
281                        (br, bi) = mul4(br, bi, wr, wi);
282                    }
283                }
284                store4(&mut a[i], rr, ri);
285            }
286        });
287    }
288
289    #[inline]
290    fn pack_f64(values: impl Iterator<Item = f64>, n: usize) -> Vec<Complex4> {
291        let mut result = Vec::with_capacity(n / 4);
292        advise_huge_pages(&mut result);
293        result.resize(n / 4, Complex4::default());
294        for (i, value) in values.enumerate() {
295            if i < n {
296                result[i >> 2].re[i & 3] = value;
297            } else {
298                result[(i - n) >> 2].im[i & 3] = value;
299            }
300        }
301        result
302    }
303
304    #[target_feature(enable = "avx2,fma")]
305    pub unsafe fn convolve_f64_avx2(
306        a: impl ExactSizeIterator<Item = f64>,
307        b: impl ExactSizeIterator<Item = f64>,
308        range: std::ops::Range<usize>,
309    ) -> Vec<f64> {
310        let n = (range.end.next_power_of_two() / 2).max(4);
311        let mut fa = pack_f64(a, n);
312        let mut fb = pack_f64(b, n);
313        fft_soa(&mut fa);
314        fft_soa(&mut fb);
315        dot_one_soa(&mut fa, &fb);
316        drop(fb);
317        ifft_soa(&mut fa);
318        range
319            .map(|i| {
320                if i < n {
321                    fa[i >> 2].re[i & 3]
322                } else {
323                    fa[(i - n) >> 2].im[i & 3]
324                }
325            })
326            .collect()
327    }
328    #[target_feature(enable = "avx2")]
329    pub unsafe fn convolve_i64_avx2(a: Vec<i64>, b: Vec<i64>, len: usize) -> Vec<i64> {
330        super::convolve_i64_naive(a, b, len)
331    }
332    #[target_feature(enable = "avx512f,avx512dq,avx512cd,avx512bw,avx512vl")]
333    pub unsafe fn convolve_i64_avx512(a: Vec<i64>, b: Vec<i64>, len: usize) -> Vec<i64> {
334        super::convolve_i64_naive(a, b, len)
335    }
336}
337
338fn bit_reverse<T>(f: &mut [T]) {
339    let mut ip = vec![0u32];
340    let mut k = f.len();
341    let mut m = 1;
342    while 2 * m < k {
343        k /= 2;
344        for j in 0..m {
345            ip.push(ip[j] + k as u32);
346        }
347        m *= 2;
348    }
349    if m == k {
350        for i in 1..m {
351            for j in 0..i {
352                let ji = j + ip[i] as usize;
353                let ij = i + ip[j] as usize;
354                f.swap(ji, ij);
355            }
356        }
357    } else {
358        for i in 1..m {
359            for j in 0..i {
360                let ji = j + ip[i] as usize;
361                let ij = i + ip[j] as usize;
362                f.swap(ji, ij);
363                f.swap(ji + m, ij + m);
364            }
365        }
366    }
367}
368
369fn real_twiddles(n: usize, inverse: bool, mut f: impl FnMut(usize, Complex<f64>)) {
370    const BLOCK: usize = 256;
371    let sign = if inverse { 1.0 } else { -1.0 };
372    let step = Complex::primitive_nth_root_of_unity(sign * n as f64);
373    for start in (1..n / 4).step_by(BLOCK) {
374        let mut w = Complex::polar(1.0, sign * std::f64::consts::TAU * start as f64 / n as f64);
375        for k in start..(start + BLOCK).min(n / 4) {
376            f(k, w);
377            w *= step;
378        }
379    }
380}
Source

pub fn abs(self) -> T

Examples found in repository?
crates/competitive/src/num/complex.rs (line 113)
112    pub fn unit(self) -> Self {
113        self / self.abs()
114    }
More examples
Hide additional examples
crates/competitive/src/geometry/line.rs (line 109)
106    pub fn distance_point(&self, p: Complex<T>) -> T {
107        let r = self.projection(p);
108        if self.intersect_point(r) {
109            (r - p).abs()
110        } else {
111            (self.p1 - p).abs().min((self.p2 - p).abs())
112        }
113    }
crates/competitive/src/geometry/circle.rs (line 16)
15    pub fn cross_circle(&self, other: &Self) -> Option<(Complex<T>, Complex<T>)> {
16        let d = (self.c - other.c).abs();
17        let rc = (d * d + self.r * self.r - other.r * other.r) / (d + d);
18        let rs2 = self.r * self.r - rc * rc;
19        if Approx(rs2) < Approx(T::zero()) {
20            return None;
21        }
22        let rs = rs2.abs().sqrt();
23        let diff = (other.c - self.c) / d;
24        Some((
25            self.c + diff * Complex::new(rc, rs),
26            self.c + diff * Complex::new(rc, -rs),
27        ))
28    }
29    pub fn contains_point(&self, p: Complex<T>) -> bool {
30        Approx((self.c - p).abs()) <= Approx(self.r)
31    }
crates/competitive/src/geometry/closest_pair.rs (line 33)
8fn closest_pair_inner(a: &mut [Complex<f64>]) -> f64 {
9    use std::cmp::min;
10    let n = a.len();
11    if n <= 1 {
12        return f64::INFINITY;
13    }
14    let m = n / 2;
15    let x = a[m].re;
16    let mut d = min(
17        TotalOrd(closest_pair_inner(&mut a[0..m])),
18        TotalOrd(closest_pair_inner(&mut a[m..n])),
19    )
20    .0;
21    a.sort_by_key(|&p| TotalOrd(p.im));
22    let mut b: Vec<Complex<f64>> = vec![];
23    for a in a.iter() {
24        if (a.re - x).abs() >= d {
25            continue;
26        }
27        let k = b.len();
28        for j in 0..k {
29            let p = *a - b[k - j - 1];
30            if p.im >= d {
31                break;
32            }
33            d = min(TotalOrd(d), TotalOrd(p.abs())).0;
34        }
35        b.push(*a);
36    }
37    d
38}
Source

pub fn unit(self) -> Self

Examples found in repository?
crates/competitive/src/geometry/line.rs (line 35)
34    pub fn projection(&self, p: Complex<T>) -> Complex<T> {
35        let e = self.dir().unit();
36        self.p1 + e * (p - self.p1).dot(e)
37    }
38    pub fn reflection(&self, p: Complex<T>) -> Complex<T> {
39        let d = self.projection(p) - p;
40        p + d + d
41    }
42    pub fn distance_point(&self, p: Complex<T>) -> T {
43        (p / self.dir().unit()).re
44    }
45}
46
47#[derive(Clone, Debug, PartialEq)]
48pub struct LineSegment<T> {
49    p1: Complex<T>,
50    p2: Complex<T>,
51}
52impl<T> LineSegment<T> {
53    pub fn new(p1: Complex<T>, p2: Complex<T>) -> Self {
54        LineSegment { p1, p2 }
55    }
56}
57impl<T> LineSegment<T>
58where
59    T: Ccwable,
60{
61    pub fn dir(&self) -> Complex<T> {
62        self.p2 - self.p1
63    }
64    pub fn ccw(&self, p: Complex<T>) -> Ccw {
65        Ccw::new(self.p1, self.p2, p)
66    }
67    pub fn is_parallel(&self, other: &Self) -> bool {
68        Approx(self.dir().cross(other.dir())) == Approx(T::zero())
69    }
70    pub fn is_orthogonal(&self, other: &Self) -> bool {
71        Approx(self.dir().dot(other.dir())) == Approx(T::zero())
72    }
73    pub fn intersect(&self, other: &Self) -> bool {
74        self.ccw(other.p1) as i8 * self.ccw(other.p2) as i8 <= 0
75            && other.ccw(self.p1) as i8 * other.ccw(self.p2) as i8 <= 0
76    }
77    pub fn intersect_point(&self, p: Complex<T>) -> bool {
78        self.ccw(p) == Ccw::OnSegment
79    }
80}
81impl<T> LineSegment<T>
82where
83    T: Ccwable + Float,
84{
85    pub fn projection(&self, p: Complex<T>) -> Complex<T> {
86        let e = self.dir().unit();
87        self.p1 + e * (p - self.p1).dot(e)
88    }
Source

pub fn angle(self) -> T

Trait Implementations§

Source§

impl<T> Add for Complex<T>
where T: Add,

Source§

type Output = Complex<<T as Add>::Output>

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Self) -> Self::Output

Performs the + operation. Read more
Source§

impl<T> Add<&Complex<T>> for Complex<T>
where T: Clone + Add<Output = T>,

Source§

type Output = <Complex<T> as Add>::Output

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &Complex<T>) -> <Complex<T> as Add<Complex<T>>>::Output

Performs the + operation. Read more
Source§

impl<T> Add<&Complex<T>> for &Complex<T>
where T: Clone + Add<Output = T>,

Source§

type Output = <Complex<T> as Add>::Output

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &Complex<T>) -> <Complex<T> as Add<Complex<T>>>::Output

Performs the + operation. Read more
Source§

impl<T> Add<&T> for Complex<T>
where T: Clone + Add<Output = T>,

Source§

type Output = <Complex<T> as Add<T>>::Output

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &T) -> <Complex<T> as Add<T>>::Output

Performs the + operation. Read more
Source§

impl<T> Add<&T> for &Complex<T>
where T: Clone + Add<Output = T>,

Source§

type Output = <Complex<T> as Add<T>>::Output

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &T) -> <Complex<T> as Add<T>>::Output

Performs the + operation. Read more
Source§

impl<T> Add<Complex<T>> for &Complex<T>
where T: Clone + Add<Output = T>,

Source§

type Output = <Complex<T> as Add>::Output

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Complex<T>) -> <Complex<T> as Add<Complex<T>>>::Output

Performs the + operation. Read more
Source§

impl<T> Add<T> for Complex<T>
where T: Add<Output = T>,

Source§

type Output = Complex<T>

The resulting type after applying the + operator.
Source§

fn add(self, rhs: T) -> Self::Output

Performs the + operation. Read more
Source§

impl<T> Add<T> for &Complex<T>
where T: Clone + Add<Output = T>,

Source§

type Output = <Complex<T> as Add<T>>::Output

The resulting type after applying the + operator.
Source§

fn add(self, rhs: T) -> <Complex<T> as Add<T>>::Output

Performs the + operation. Read more
Source§

impl<T> AddAssign for Complex<T>
where T: Clone + Add<Output = T>,

Source§

fn add_assign(&mut self, rhs: Complex<T>)

Performs the += operation. Read more
Source§

impl<T> AddAssign<&Complex<T>> for Complex<T>
where T: Clone + Add<Output = T>,

Source§

fn add_assign(&mut self, rhs: &Complex<T>)

Performs the += operation. Read more
Source§

impl<T> AddAssign<&T> for Complex<T>
where T: Clone + Add<Output = T>,

Source§

fn add_assign(&mut self, rhs: &T)

Performs the += operation. Read more
Source§

impl<T> AddAssign<T> for Complex<T>
where T: Clone + Add<Output = T>,

Source§

fn add_assign(&mut self, rhs: T)

Performs the += operation. Read more
Source§

impl<T: Clone> Clone for Complex<T>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Copy> Copy for Complex<T>

Source§

impl<T: Debug> Debug for Complex<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Default> Default for Complex<T>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<T> Div for Complex<T>
where T: Clone + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Div,

Source§

type Output = Complex<<T as Div>::Output>

The resulting type after applying the / operator.
Source§

fn div(self, rhs: Self) -> Self::Output

Performs the / operation. Read more
Source§

impl<T> Div<&Complex<T>> for Complex<T>
where T: Clone + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Div<Output = T>,

Source§

type Output = <Complex<T> as Div>::Output

The resulting type after applying the / operator.
Source§

fn div(self, rhs: &Complex<T>) -> <Complex<T> as Div<Complex<T>>>::Output

Performs the / operation. Read more
Source§

impl<T> Div<&Complex<T>> for &Complex<T>
where T: Clone + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Div<Output = T>,

Source§

type Output = <Complex<T> as Div>::Output

The resulting type after applying the / operator.
Source§

fn div(self, rhs: &Complex<T>) -> <Complex<T> as Div<Complex<T>>>::Output

Performs the / operation. Read more
Source§

impl<T> Div<&T> for Complex<T>
where T: Clone + Div<Output = T>,

Source§

type Output = <Complex<T> as Div<T>>::Output

The resulting type after applying the / operator.
Source§

fn div(self, rhs: &T) -> <Complex<T> as Div<T>>::Output

Performs the / operation. Read more
Source§

impl<T> Div<&T> for &Complex<T>
where T: Clone + Div<Output = T>,

Source§

type Output = <Complex<T> as Div<T>>::Output

The resulting type after applying the / operator.
Source§

fn div(self, rhs: &T) -> <Complex<T> as Div<T>>::Output

Performs the / operation. Read more
Source§

impl<T> Div<Complex<T>> for &Complex<T>
where T: Clone + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Div<Output = T>,

Source§

type Output = <Complex<T> as Div>::Output

The resulting type after applying the / operator.
Source§

fn div(self, rhs: Complex<T>) -> <Complex<T> as Div<Complex<T>>>::Output

Performs the / operation. Read more
Source§

impl<T> Div<T> for Complex<T>
where T: Clone + Div,

Source§

type Output = Complex<<T as Div>::Output>

The resulting type after applying the / operator.
Source§

fn div(self, rhs: T) -> Self::Output

Performs the / operation. Read more
Source§

impl<T> Div<T> for &Complex<T>
where T: Clone + Div<Output = T>,

Source§

type Output = <Complex<T> as Div<T>>::Output

The resulting type after applying the / operator.
Source§

fn div(self, rhs: T) -> <Complex<T> as Div<T>>::Output

Performs the / operation. Read more
Source§

impl<T> DivAssign for Complex<T>
where T: Clone + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Div<Output = T>,

Source§

fn div_assign(&mut self, rhs: Complex<T>)

Performs the /= operation. Read more
Source§

impl<T> DivAssign<&Complex<T>> for Complex<T>
where T: Clone + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Div<Output = T>,

Source§

fn div_assign(&mut self, rhs: &Complex<T>)

Performs the /= operation. Read more
Source§

impl<T> DivAssign<&T> for Complex<T>
where T: Clone + Div<Output = T>,

Source§

fn div_assign(&mut self, rhs: &T)

Performs the /= operation. Read more
Source§

impl<T> DivAssign<T> for Complex<T>
where T: Clone + Div<Output = T>,

Source§

fn div_assign(&mut self, rhs: T)

Performs the /= operation. Read more
Source§

impl<T: Eq> Eq for Complex<T>

Source§

impl<T: Hash> Hash for Complex<T>

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<T, U> Mul for Complex<T>
where T: Clone + Mul, <T as Mul>::Output: Add<Output = U> + Sub<Output = U>,

Source§

type Output = Complex<U>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Self) -> Self::Output

Performs the * operation. Read more
Source§

impl<T> Mul<&Complex<T>> for Complex<T>
where T: Clone + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,

Source§

type Output = <Complex<T> as Mul>::Output

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &Complex<T>) -> <Complex<T> as Mul<Complex<T>>>::Output

Performs the * operation. Read more
Source§

impl<T> Mul<&Complex<T>> for &Complex<T>
where T: Clone + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,

Source§

type Output = <Complex<T> as Mul>::Output

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &Complex<T>) -> <Complex<T> as Mul<Complex<T>>>::Output

Performs the * operation. Read more
Source§

impl<T> Mul<&T> for Complex<T>
where T: Clone + Mul<Output = T>,

Source§

type Output = <Complex<T> as Mul<T>>::Output

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &T) -> <Complex<T> as Mul<T>>::Output

Performs the * operation. Read more
Source§

impl<T> Mul<&T> for &Complex<T>
where T: Clone + Mul<Output = T>,

Source§

type Output = <Complex<T> as Mul<T>>::Output

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &T) -> <Complex<T> as Mul<T>>::Output

Performs the * operation. Read more
Source§

impl<T> Mul<Complex<T>> for &Complex<T>
where T: Clone + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,

Source§

type Output = <Complex<T> as Mul>::Output

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Complex<T>) -> <Complex<T> as Mul<Complex<T>>>::Output

Performs the * operation. Read more
Source§

impl<T> Mul<T> for Complex<T>
where T: Clone + Mul,

Source§

type Output = Complex<<T as Mul>::Output>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: T) -> Self::Output

Performs the * operation. Read more
Source§

impl<T> Mul<T> for &Complex<T>
where T: Clone + Mul<Output = T>,

Source§

type Output = <Complex<T> as Mul<T>>::Output

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: T) -> <Complex<T> as Mul<T>>::Output

Performs the * operation. Read more
Source§

impl<T> MulAssign for Complex<T>
where T: Clone + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,

Source§

fn mul_assign(&mut self, rhs: Complex<T>)

Performs the *= operation. Read more
Source§

impl<T> MulAssign<&Complex<T>> for Complex<T>
where T: Clone + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,

Source§

fn mul_assign(&mut self, rhs: &Complex<T>)

Performs the *= operation. Read more
Source§

impl<T> MulAssign<&T> for Complex<T>
where T: Clone + Mul<Output = T>,

Source§

fn mul_assign(&mut self, rhs: &T)

Performs the *= operation. Read more
Source§

impl<T> MulAssign<T> for Complex<T>
where T: Clone + Mul<Output = T>,

Source§

fn mul_assign(&mut self, rhs: T)

Performs the *= operation. Read more
Source§

impl<T> Neg for Complex<T>
where T: Neg,

Source§

type Output = Complex<<T as Neg>::Output>

The resulting type after applying the - operator.
Source§

fn neg(self) -> Self::Output

Performs the unary - operation. Read more
Source§

impl<T> Neg for &Complex<T>
where T: Clone + Neg<Output = T>,

Source§

type Output = <Complex<T> as Neg>::Output

The resulting type after applying the - operator.
Source§

fn neg(self) -> <Complex<T> as Neg>::Output

Performs the unary - operation. Read more
Source§

impl<T> One for Complex<T>
where T: Zero + One,

Source§

fn one() -> Self

Source§

fn is_one(&self) -> bool
where Self: PartialEq,

Source§

fn set_one(&mut self)

Source§

impl<T: Ord> Ord for Complex<T>

Source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 (const: unstable) · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 (const: unstable) · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 (const: unstable) · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

fn clamp_to<R>(self, range: R) -> Self
where Self: Sized, R: ClampBounds<Self>,

🔬This is a nightly-only experimental API. (clamp_to)
Restrict a value to a certain range. Read more
Source§

impl<T: PartialEq> PartialEq for Complex<T>

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl<T: PartialOrd> PartialOrd for Complex<T>

Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 (const: unstable) · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 (const: unstable) · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 (const: unstable) · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 (const: unstable) · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<T> Product for Complex<T>
where T: One + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Zero + Clone,

Source§

fn product<I: Iterator<Item = Self>>(iter: I) -> Self

Takes an iterator and generates Self from the elements by multiplying the items.
Source§

impl<'a, T> Product<&'a Complex<T>> for Complex<T>
where T: Clone + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Zero + 'a,

Source§

fn product<I: Iterator<Item = &'a Complex<T>>>(iter: I) -> Self

Takes an iterator and generates Self from the elements by multiplying the items.
Source§

impl<T: Scan> Scan for Complex<T>

Source§

impl<T: PartialEq> StructuralPartialEq for Complex<T>

Source§

impl<T> Sub for Complex<T>
where T: Sub,

Source§

type Output = Complex<<T as Sub>::Output>

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Self) -> Self::Output

Performs the - operation. Read more
Source§

impl<T> Sub<&Complex<T>> for Complex<T>
where T: Clone + Sub<Output = T>,

Source§

type Output = <Complex<T> as Sub>::Output

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: &Complex<T>) -> <Complex<T> as Sub<Complex<T>>>::Output

Performs the - operation. Read more
Source§

impl<T> Sub<&Complex<T>> for &Complex<T>
where T: Clone + Sub<Output = T>,

Source§

type Output = <Complex<T> as Sub>::Output

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: &Complex<T>) -> <Complex<T> as Sub<Complex<T>>>::Output

Performs the - operation. Read more
Source§

impl<T> Sub<&T> for Complex<T>
where T: Clone + Sub<Output = T>,

Source§

type Output = <Complex<T> as Sub<T>>::Output

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: &T) -> <Complex<T> as Sub<T>>::Output

Performs the - operation. Read more
Source§

impl<T> Sub<&T> for &Complex<T>
where T: Clone + Sub<Output = T>,

Source§

type Output = <Complex<T> as Sub<T>>::Output

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: &T) -> <Complex<T> as Sub<T>>::Output

Performs the - operation. Read more
Source§

impl<T> Sub<Complex<T>> for &Complex<T>
where T: Clone + Sub<Output = T>,

Source§

type Output = <Complex<T> as Sub>::Output

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Complex<T>) -> <Complex<T> as Sub<Complex<T>>>::Output

Performs the - operation. Read more
Source§

impl<T> Sub<T> for Complex<T>
where T: Sub<Output = T>,

Source§

type Output = Complex<T>

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: T) -> Self::Output

Performs the - operation. Read more
Source§

impl<T> Sub<T> for &Complex<T>
where T: Clone + Sub<Output = T>,

Source§

type Output = <Complex<T> as Sub<T>>::Output

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: T) -> <Complex<T> as Sub<T>>::Output

Performs the - operation. Read more
Source§

impl<T> SubAssign for Complex<T>
where T: Clone + Sub<Output = T>,

Source§

fn sub_assign(&mut self, rhs: Complex<T>)

Performs the -= operation. Read more
Source§

impl<T> SubAssign<&Complex<T>> for Complex<T>
where T: Clone + Sub<Output = T>,

Source§

fn sub_assign(&mut self, rhs: &Complex<T>)

Performs the -= operation. Read more
Source§

impl<T> SubAssign<&T> for Complex<T>
where T: Clone + Sub<Output = T>,

Source§

fn sub_assign(&mut self, rhs: &T)

Performs the -= operation. Read more
Source§

impl<T> SubAssign<T> for Complex<T>
where T: Clone + Sub<Output = T>,

Source§

fn sub_assign(&mut self, rhs: T)

Performs the -= operation. Read more
Source§

impl<T> Sum for Complex<T>
where T: Zero + Add<Output = T>,

Source§

fn sum<I: Iterator<Item = Self>>(iter: I) -> Self

Takes an iterator and generates Self from the elements by “summing up” the items.
Source§

impl<'a, T> Sum<&'a Complex<T>> for Complex<T>
where T: Clone + Zero + Add<Output = T> + 'a,

Source§

fn sum<I: Iterator<Item = &'a Complex<T>>>(iter: I) -> Self

Takes an iterator and generates Self from the elements by “summing up” the items.
Source§

impl<T> Zero for Complex<T>
where T: Zero,

Source§

fn zero() -> Self

Source§

fn is_zero(&self) -> bool
where Self: PartialEq,

Source§

fn set_zero(&mut self)

Auto Trait Implementations§

§

impl<T> Freeze for Complex<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for Complex<T>
where T: RefUnwindSafe,

§

impl<T> Send for Complex<T>
where T: Send,

§

impl<T> Sync for Complex<T>
where T: Sync,

§

impl<T> Unpin for Complex<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for Complex<T>
where T: UnsafeUnpin,

§

impl<T> UnwindSafe for Complex<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AsTotalOrd for T
where T: PartialOrd,

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PartialOrdExt for T
where T: PartialOrd,

Source§

fn chmin(&mut self, other: T)

Source§

fn chmax(&mut self, other: T)

Source§

fn minmax(self, other: T) -> (T, T)

Source§

impl<T> ToArrayVecScalar for T

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.