pub struct Complex<T> {
pub re: T,
pub im: T,
}
Fields§
§re: T
§im: T
Implementations§
Source§impl<T> Complex<T>
impl<T> Complex<T>
Sourcepub fn new(re: T, im: T) -> Self
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,
60 <T as Mul>::Output: Add,
61{
62 pub fn dot(self, rhs: Self) -> <<T as Mul>::Output as Add>::Output {
63 self.re * rhs.re + self.im * rhs.im
64 }
65}
66impl<T> Complex<T>
67where
68 T: Mul,
69 <T as Mul>::Output: Sub,
70{
71 pub fn cross(self, rhs: Self) -> <<T as Mul>::Output as Sub>::Output {
72 self.re * rhs.im - self.im * rhs.re
73 }
74}
75impl<T> Complex<T>
76where
77 T: Mul + Clone,
78 <T as Mul>::Output: Add,
79{
80 pub fn norm(self) -> <<T as Mul>::Output as Add>::Output {
81 self.re.clone() * self.re + self.im.clone() * self.im
82 }
83}
84impl<T> Complex<T>
85where
86 T: Zero + Ord + Mul,
87 <T as Mul>::Output: Ord,
88{
89 pub fn cmp_by_arg(self, other: Self) -> Ordering {
90 fn pos<T>(c: &Complex<T>) -> bool
91 where
92 T: Zero + Ord,
93 {
94 let zero = T::zero();
95 c.im < zero || c.im <= zero && c.re < zero
96 }
97 pos(&self)
98 .cmp(&pos(&other))
99 .then_with(|| (self.re * other.im).cmp(&(self.im * other.re)).reverse())
100 }
101}
102impl<T> Complex<T>
103where
104 T: Float,
105{
106 pub fn polar(r: T, theta: T) -> Self {
107 Self::new(r * theta.cos(), r * theta.sin())
108 }
109 pub fn primitive_nth_root_of_unity(n: T) -> Self {
110 let theta = T::TAU / n;
111 Self::new(theta.cos(), theta.sin())
112 }
113 pub fn abs(self) -> T {
114 self.re.hypot(self.im)
115 }
116 pub fn unit(self) -> Self {
117 self / self.abs()
118 }
119 pub fn angle(self) -> T {
120 self.im.atan2(self.re)
121 }
122}
123impl<T> Add for Complex<T>
124where
125 T: Add,
126{
127 type Output = Complex<<T as Add>::Output>;
128 fn add(self, rhs: Self) -> Self::Output {
129 Complex::new(self.re + rhs.re, self.im + rhs.im)
130 }
131}
132impl<T> Add<T> for Complex<T>
133where
134 T: Add<Output = T>,
135{
136 type Output = Self;
137 fn add(self, rhs: T) -> Self::Output {
138 Self::new(self.re + rhs, self.im)
139 }
140}
141impl<T> Sub for Complex<T>
142where
143 T: Sub,
144{
145 type Output = Complex<<T as Sub>::Output>;
146 fn sub(self, rhs: Self) -> Self::Output {
147 Complex::new(self.re - rhs.re, self.im - rhs.im)
148 }
149}
150impl<T> Sub<T> for Complex<T>
151where
152 T: Sub<Output = T>,
153{
154 type Output = Self;
155 fn sub(self, rhs: T) -> Self::Output {
156 Self::new(self.re - rhs, self.im)
157 }
158}
159impl<T, U> Mul for Complex<T>
160where
161 T: Clone + Mul,
162 <T as Mul>::Output: Add<Output = U> + Sub<Output = U>,
163{
164 type Output = Complex<U>;
165 fn mul(self, rhs: Self) -> Self::Output {
166 Complex::new(
167 self.re.clone() * rhs.re.clone() - self.im.clone() * rhs.im.clone(),
168 self.re * rhs.im + self.im * rhs.re,
169 )
170 }
171}
172impl<T> Mul<T> for Complex<T>
173where
174 T: Clone + Mul,
175{
176 type Output = Complex<<T as Mul>::Output>;
177 fn mul(self, rhs: T) -> Self::Output {
178 Complex::new(self.re * rhs.clone(), self.im * rhs)
179 }
180}
181impl<T> Div for Complex<T>
182where
183 T: Clone + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Div,
184{
185 type Output = Complex<<T as Div>::Output>;
186 fn div(self, rhs: Self) -> Self::Output {
187 let d = rhs.re.clone() * rhs.re.clone() + rhs.im.clone() * rhs.im.clone();
188 Complex::new(
189 (self.re.clone() * rhs.re.clone() + self.im.clone() * rhs.im.clone()) / d.clone(),
190 (self.im * rhs.re - self.re * rhs.im) / d,
191 )
192 }
193}
194impl<T> Div<T> for Complex<T>
195where
196 T: Clone + Div,
197{
198 type Output = Complex<<T as Div>::Output>;
199 fn div(self, rhs: T) -> Self::Output {
200 Complex::new(self.re / rhs.clone(), self.im / rhs)
201 }
202}
203impl<T> Neg for Complex<T>
204where
205 T: Neg,
206{
207 type Output = Complex<<T as Neg>::Output>;
208 fn neg(self) -> Self::Output {
209 Complex::new(-self.re, -self.im)
210 }
211}
212macro_rules! impl_complex_ref_binop {
213 (impl<$T:ident> $imp:ident $method:ident ($l:ty, $r:ty) where $($w:ident)*) => {
214 impl<$T> $imp<$r> for &$l
215 where
216 $T: Clone $(+ $w<Output = $T>)*,
217 {
218 type Output = <$l as $imp<$r>>::Output;
219 fn $method(self, rhs: $r) -> <$l as $imp<$r>>::Output {
220 $imp::$method(self.clone(), rhs)
221 }
222 }
223 impl<$T> $imp<&$r> for $l
224 where
225 $T: Clone $(+ $w<Output = $T>)*,
226 {
227 type Output = <$l as $imp<$r>>::Output;
228 fn $method(self, rhs: &$r) -> <$l as $imp<$r>>::Output {
229 $imp::$method(self, rhs.clone())
230 }
231 }
232 impl<$T> $imp<&$r> for &$l
233 where
234 $T: Clone $(+ $w<Output = $T>)*,
235 {
236 type Output = <$l as $imp<$r>>::Output;
237 fn $method(self, rhs: &$r) -> <$l as $imp<$r>>::Output {
238 $imp::$method(self.clone(), rhs.clone())
239 }
240 }
241 };
242}
243impl_complex_ref_binop!(impl<T> Add add (Complex<T>, Complex<T>) where Add);
244impl_complex_ref_binop!(impl<T> Add add (Complex<T>, T) where Add);
245impl_complex_ref_binop!(impl<T> Sub sub (Complex<T>, Complex<T>) where Sub);
246impl_complex_ref_binop!(impl<T> Sub sub (Complex<T>, T) where Sub);
247impl_complex_ref_binop!(impl<T> Mul mul (Complex<T>, Complex<T>) where Add Sub Mul);
248impl_complex_ref_binop!(impl<T> Mul mul (Complex<T>, T) where Mul);
249impl_complex_ref_binop!(impl<T> Div div (Complex<T>, Complex<T>) where Add Sub Mul Div);
250impl_complex_ref_binop!(impl<T> Div div (Complex<T>, T) where Div);
251macro_rules! impl_complex_ref_unop {
252 (impl<$T:ident> $imp:ident $method:ident ($t:ty) where $($w:ident)*) => {
253 impl<$T> $imp for &$t
254 where
255 $T: Clone $(+ $w<Output = $T>)*,
256 {
257 type Output = <$t as $imp>::Output;
258 fn $method(self) -> <$t as $imp>::Output {
259 $imp::$method(self.clone())
260 }
261 }
262 };
263}
264impl_complex_ref_unop!(impl<T> Neg neg (Complex<T>) where Neg);
265macro_rules! impl_complex_op_assign {
266 (impl<$T:ident> $imp:ident $method:ident ($l:ty, $r:ty) $fromimp:ident $frommethod:ident where $($w:ident)*) => {
267 impl<$T> $imp<$r> for $l
268 where
269 $T: Clone $(+ $w<Output = $T>)*,
270 {
271 fn $method(&mut self, rhs: $r) {
272 *self = $fromimp::$frommethod(self.clone(), rhs);
273 }
274 }
275 impl<$T> $imp<&$r> for $l
276 where
277 $T: Clone $(+ $w<Output = $T>)*,
278 {
279 fn $method(&mut self, rhs: &$r) {
280 $imp::$method(self, rhs.clone());
281 }
282 }
283 };
284}
285impl_complex_op_assign!(impl<T> AddAssign add_assign (Complex<T>, Complex<T>) Add add where Add);
286impl_complex_op_assign!(impl<T> AddAssign add_assign (Complex<T>, T) Add add where Add);
287impl_complex_op_assign!(impl<T> SubAssign sub_assign (Complex<T>, Complex<T>) Sub sub where Sub);
288impl_complex_op_assign!(impl<T> SubAssign sub_assign (Complex<T>, T) Sub sub where Sub);
289impl_complex_op_assign!(impl<T> MulAssign mul_assign (Complex<T>, Complex<T>) Mul mul where Add Sub Mul);
290impl_complex_op_assign!(impl<T> MulAssign mul_assign (Complex<T>, T) Mul mul where Mul);
291impl_complex_op_assign!(impl<T> DivAssign div_assign (Complex<T>, Complex<T>) Div div where Add Sub Mul Div);
292impl_complex_op_assign!(impl<T> DivAssign div_assign (Complex<T>, T) Div div where Div);
293macro_rules! impl_complex_fold {
294 (impl<$T:ident> $imp:ident $method:ident ($t:ty) $identimp:ident $identmethod:ident $fromimp:ident $frommethod:ident where $($w:ident)* $(+ $x:ident)*) => {
295 impl<$T> $imp for $t
296 where
297 $T: $identimp $(+ $w<Output = $T>)* $(+ $x)*,
298 {
299 fn $method<I: Iterator<Item = Self>>(iter: I) -> Self {
300 iter.fold(<Self as $identimp>::$identmethod(), $fromimp::$frommethod)
301 }
302 }
303 impl<'a, $T: 'a> $imp<&'a $t> for $t
304 where
305 $T: Clone + $identimp $(+ $w<Output = $T>)* $(+ $x)*,
306 {
307 fn $method<I: Iterator<Item = &'a $t>>(iter: I) -> Self {
308 iter.fold(<Self as $identimp>::$identmethod(), $fromimp::$frommethod)
309 }
310 }
311 };
312}
313impl_complex_fold!(impl<T> Sum sum (Complex<T>) Zero zero Add add where Add);
314impl_complex_fold!(impl<T> Product product (Complex<T>) One one Mul mul where Add Sub Mul + Zero + Clone);
315
316impl<T: IterScan> IterScan for Complex<T> {
317 type Output = Complex<<T as IterScan>::Output>;
318 fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
319 Some(Complex::new(
320 <T as IterScan>::scan(iter)?,
321 <T as IterScan>::scan(iter)?,
322 ))
323 }
More examples
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 }
crates/competitive/src/math/fast_fourier_transform.rs (line 86)
74 fn transform(t: Self::T, len: usize) -> Self::F {
75 let n = len.max(4).next_power_of_two();
76 let mut f = vec![Complex::zero(); n / 2];
77 for (i, t) in t.into_iter().enumerate() {
78 if i & 1 == 0 {
79 f[i / 2].re = t as f64;
80 } else {
81 f[i / 2].im = t as f64;
82 }
83 }
84 fft(&mut f);
85 bit_reverse(&mut f);
86 f[0] = Complex::new(f[0].re + f[0].im, f[0].re - f[0].im);
87 f[n / 4] = f[n / 4].conjugate();
88 let w = Complex::primitive_nth_root_of_unity(-(n as f64));
89 let mut wk = Complex::<f64>::one();
90 for k in 1..n / 4 {
91 wk *= w;
92 let c = wk.conjugate().transpose() + 1.;
93 let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
94 f[k] -= d;
95 f[n / 2 - k] += d.conjugate();
96 }
97 f
98 }
99 fn inverse_transform(mut f: Self::F, len: usize) -> Self::T {
100 let n = len.max(4).next_power_of_two();
101 assert_eq!(f.len(), n / 2);
102 f[0] = Complex::new((f[0].re + f[0].im) * 0.5, (f[0].re - f[0].im) * 0.5);
103 f[n / 4] = f[n / 4].conjugate();
104 let w = Complex::primitive_nth_root_of_unity(n as f64);
105 let mut wk = Complex::<f64>::one();
106 for k in 1..n / 4 {
107 wk *= w;
108 let c = wk.transpose().conjugate() + 1.;
109 let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
110 f[k] -= d;
111 f[n / 2 - k] += d.conjugate();
112 }
113 bit_reverse(&mut f);
114 ifft(&mut f);
115 let inv = 1. / (n / 2) as f64;
116 (0..len)
117 .map(|i| (inv * if i & 1 == 0 { f[i / 2].re } else { f[i / 2].im }).round() as i64)
118 .collect()
119 }
Sourcepub fn transpose(self) -> Self
pub fn transpose(self) -> Self
Examples found in repository?
crates/competitive/src/math/fast_fourier_transform.rs (line 92)
74 fn transform(t: Self::T, len: usize) -> Self::F {
75 let n = len.max(4).next_power_of_two();
76 let mut f = vec![Complex::zero(); n / 2];
77 for (i, t) in t.into_iter().enumerate() {
78 if i & 1 == 0 {
79 f[i / 2].re = t as f64;
80 } else {
81 f[i / 2].im = t as f64;
82 }
83 }
84 fft(&mut f);
85 bit_reverse(&mut f);
86 f[0] = Complex::new(f[0].re + f[0].im, f[0].re - f[0].im);
87 f[n / 4] = f[n / 4].conjugate();
88 let w = Complex::primitive_nth_root_of_unity(-(n as f64));
89 let mut wk = Complex::<f64>::one();
90 for k in 1..n / 4 {
91 wk *= w;
92 let c = wk.conjugate().transpose() + 1.;
93 let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
94 f[k] -= d;
95 f[n / 2 - k] += d.conjugate();
96 }
97 f
98 }
99 fn inverse_transform(mut f: Self::F, len: usize) -> Self::T {
100 let n = len.max(4).next_power_of_two();
101 assert_eq!(f.len(), n / 2);
102 f[0] = Complex::new((f[0].re + f[0].im) * 0.5, (f[0].re - f[0].im) * 0.5);
103 f[n / 4] = f[n / 4].conjugate();
104 let w = Complex::primitive_nth_root_of_unity(n as f64);
105 let mut wk = Complex::<f64>::one();
106 for k in 1..n / 4 {
107 wk *= w;
108 let c = wk.transpose().conjugate() + 1.;
109 let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
110 f[k] -= d;
111 f[n / 2 - k] += d.conjugate();
112 }
113 bit_reverse(&mut f);
114 ifft(&mut f);
115 let inv = 1. / (n / 2) as f64;
116 (0..len)
117 .map(|i| (inv * if i & 1 == 0 { f[i / 2].re } else { f[i / 2].im }).round() as i64)
118 .collect()
119 }
pub fn map<U>(self, f: impl FnMut(T) -> U) -> Complex<U>
Source§impl<T> Complex<T>where
T: Neg<Output = T>,
impl<T> Complex<T>where
T: Neg<Output = T>,
Sourcepub fn conjugate(self) -> Self
pub fn conjugate(self) -> Self
Examples found in repository?
crates/competitive/src/math/fast_fourier_transform.rs (line 87)
74 fn transform(t: Self::T, len: usize) -> Self::F {
75 let n = len.max(4).next_power_of_two();
76 let mut f = vec![Complex::zero(); n / 2];
77 for (i, t) in t.into_iter().enumerate() {
78 if i & 1 == 0 {
79 f[i / 2].re = t as f64;
80 } else {
81 f[i / 2].im = t as f64;
82 }
83 }
84 fft(&mut f);
85 bit_reverse(&mut f);
86 f[0] = Complex::new(f[0].re + f[0].im, f[0].re - f[0].im);
87 f[n / 4] = f[n / 4].conjugate();
88 let w = Complex::primitive_nth_root_of_unity(-(n as f64));
89 let mut wk = Complex::<f64>::one();
90 for k in 1..n / 4 {
91 wk *= w;
92 let c = wk.conjugate().transpose() + 1.;
93 let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
94 f[k] -= d;
95 f[n / 2 - k] += d.conjugate();
96 }
97 f
98 }
99 fn inverse_transform(mut f: Self::F, len: usize) -> Self::T {
100 let n = len.max(4).next_power_of_two();
101 assert_eq!(f.len(), n / 2);
102 f[0] = Complex::new((f[0].re + f[0].im) * 0.5, (f[0].re - f[0].im) * 0.5);
103 f[n / 4] = f[n / 4].conjugate();
104 let w = Complex::primitive_nth_root_of_unity(n as f64);
105 let mut wk = Complex::<f64>::one();
106 for k in 1..n / 4 {
107 wk *= w;
108 let c = wk.transpose().conjugate() + 1.;
109 let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
110 f[k] -= d;
111 f[n / 2 - k] += d.conjugate();
112 }
113 bit_reverse(&mut f);
114 ifft(&mut f);
115 let inv = 1. / (n / 2) as f64;
116 (0..len)
117 .map(|i| (inv * if i & 1 == 0 { f[i / 2].re } else { f[i / 2].im }).round() as i64)
118 .collect()
119 }
120 fn multiply(f: &mut Self::F, g: &Self::F) {
121 assert_eq!(f.len(), g.len());
122 f[0].re *= g[0].re;
123 f[0].im *= g[0].im;
124 for (f, g) in f.iter_mut().zip(g.iter()).skip(1) {
125 *f *= *g;
126 }
127 }
128}
129
130pub fn fft(a: &mut [Complex<f64>]) {
131 let n = a.len();
132 RotateCache::ensure(n / 2);
133 RotateCache::with(|cache| {
134 let mut v = n / 2;
135 while v > 0 {
136 for (a, wj) in a.chunks_exact_mut(v << 1).zip(cache) {
137 let (l, r) = a.split_at_mut(v);
138 for (x, y) in l.iter_mut().zip(r) {
139 let ajv = wj * *y;
140 *y = *x - ajv;
141 *x += ajv;
142 }
143 }
144 v >>= 1;
145 }
146 });
147}
148
149pub fn ifft(a: &mut [Complex<f64>]) {
150 let n = a.len();
151 RotateCache::ensure(n / 2);
152 RotateCache::with(|cache| {
153 let mut v = 1;
154 while v < n {
155 for (a, wj) in a
156 .chunks_exact_mut(v << 1)
157 .zip(cache.iter().map(|wj| wj.conjugate()))
158 {
159 let (l, r) = a.split_at_mut(v);
160 for (x, y) in l.iter_mut().zip(r) {
161 let ajv = *x - *y;
162 *x += *y;
163 *y = wj * ajv;
164 }
165 }
166 v <<= 1;
167 }
168 });
169}
Source§impl<T> Complex<T>
impl<T> Complex<T>
Sourcepub fn dot(self, rhs: Self) -> <<T as Mul>::Output as Add>::Output
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::ccw(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
crates/competitive/src/geometry/ccw.rs (line 46)
35 pub fn ccw<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 ccw_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>
impl<T> Complex<T>
Sourcepub fn cross(self, rhs: Self) -> <<T as Mul>::Output as Sub>::Output
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::ccw(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
crates/competitive/src/geometry/ccw.rs (line 42)
35 pub fn ccw<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 ccw_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>
impl<T> Complex<T>
Sourcepub fn norm(self) -> <<T as Mul>::Output as Add>::Output
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: Float,
impl<T> Complex<T>where
T: Float,
pub fn polar(r: T, theta: T) -> Self
Sourcepub fn primitive_nth_root_of_unity(n: T) -> Self
pub fn primitive_nth_root_of_unity(n: T) -> Self
Examples found in repository?
crates/competitive/src/math/fast_fourier_transform.rs (line 25)
7 fn ensure(n: usize) {
8 assert_eq!(n.count_ones(), 1, "call with power of two but {}", n);
9 Self::modify(|cache| {
10 let mut m = cache.len();
11 assert!(
12 m.count_ones() <= 1,
13 "length might be power of two but {}",
14 m
15 );
16 if m >= n {
17 return;
18 }
19 cache.reserve_exact(n - m);
20 if cache.is_empty() {
21 cache.push(Complex::one());
22 m += 1;
23 }
24 while m < n {
25 let p = Complex::primitive_nth_root_of_unity(-((m * 4) as f64));
26 for i in 0..m {
27 cache.push(cache[i] * p);
28 }
29 m <<= 1;
30 }
31 assert_eq!(cache.len(), n);
32 });
33 }
34}
35crate::impl_assoc_value!(RotateCache, Vec<Complex<f64>>, vec![Complex::one()]);
36
37fn bit_reverse<T>(f: &mut [T]) {
38 let mut ip = vec![0u32];
39 let mut k = f.len();
40 let mut m = 1;
41 while 2 * m < k {
42 k /= 2;
43 for j in 0..m {
44 ip.push(ip[j] + k as u32);
45 }
46 m *= 2;
47 }
48 if m == k {
49 for i in 1..m {
50 for j in 0..i {
51 let ji = j + ip[i] as usize;
52 let ij = i + ip[j] as usize;
53 f.swap(ji, ij);
54 }
55 }
56 } else {
57 for i in 1..m {
58 for j in 0..i {
59 let ji = j + ip[i] as usize;
60 let ij = i + ip[j] as usize;
61 f.swap(ji, ij);
62 f.swap(ji + m, ij + m);
63 }
64 }
65 }
66}
67
68impl ConvolveSteps for ConvolveRealFft {
69 type T = Vec<i64>;
70 type F = Vec<Complex<f64>>;
71 fn length(t: &Self::T) -> usize {
72 t.len()
73 }
74 fn transform(t: Self::T, len: usize) -> Self::F {
75 let n = len.max(4).next_power_of_two();
76 let mut f = vec![Complex::zero(); n / 2];
77 for (i, t) in t.into_iter().enumerate() {
78 if i & 1 == 0 {
79 f[i / 2].re = t as f64;
80 } else {
81 f[i / 2].im = t as f64;
82 }
83 }
84 fft(&mut f);
85 bit_reverse(&mut f);
86 f[0] = Complex::new(f[0].re + f[0].im, f[0].re - f[0].im);
87 f[n / 4] = f[n / 4].conjugate();
88 let w = Complex::primitive_nth_root_of_unity(-(n as f64));
89 let mut wk = Complex::<f64>::one();
90 for k in 1..n / 4 {
91 wk *= w;
92 let c = wk.conjugate().transpose() + 1.;
93 let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
94 f[k] -= d;
95 f[n / 2 - k] += d.conjugate();
96 }
97 f
98 }
99 fn inverse_transform(mut f: Self::F, len: usize) -> Self::T {
100 let n = len.max(4).next_power_of_two();
101 assert_eq!(f.len(), n / 2);
102 f[0] = Complex::new((f[0].re + f[0].im) * 0.5, (f[0].re - f[0].im) * 0.5);
103 f[n / 4] = f[n / 4].conjugate();
104 let w = Complex::primitive_nth_root_of_unity(n as f64);
105 let mut wk = Complex::<f64>::one();
106 for k in 1..n / 4 {
107 wk *= w;
108 let c = wk.transpose().conjugate() + 1.;
109 let d = c * (f[k] - f[n / 2 - k].conjugate()) * 0.5;
110 f[k] -= d;
111 f[n / 2 - k] += d.conjugate();
112 }
113 bit_reverse(&mut f);
114 ifft(&mut f);
115 let inv = 1. / (n / 2) as f64;
116 (0..len)
117 .map(|i| (inv * if i & 1 == 0 { f[i / 2].re } else { f[i / 2].im }).round() as i64)
118 .collect()
119 }
Sourcepub fn abs(self) -> T
pub fn abs(self) -> T
Examples found in repository?
More examples
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}
Sourcepub fn unit(self) -> Self
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::ccw(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 }
pub fn angle(self) -> T
Trait Implementations§
Source§impl<T> AddAssign<&Complex<T>> for Complex<T>
impl<T> AddAssign<&Complex<T>> for Complex<T>
Source§fn add_assign(&mut self, rhs: &Complex<T>)
fn add_assign(&mut self, rhs: &Complex<T>)
Performs the
+=
operation. Read moreSource§impl<T> AddAssign<&T> for Complex<T>
impl<T> AddAssign<&T> for Complex<T>
Source§fn add_assign(&mut self, rhs: &T)
fn add_assign(&mut self, rhs: &T)
Performs the
+=
operation. Read moreSource§impl<T> AddAssign<T> for Complex<T>
impl<T> AddAssign<T> for Complex<T>
Source§fn add_assign(&mut self, rhs: T)
fn add_assign(&mut self, rhs: T)
Performs the
+=
operation. Read moreSource§impl<T> AddAssign for Complex<T>
impl<T> AddAssign for Complex<T>
Source§fn add_assign(&mut self, rhs: Complex<T>)
fn add_assign(&mut self, rhs: Complex<T>)
Performs the
+=
operation. Read moreSource§impl<T> DivAssign<&Complex<T>> for Complex<T>
impl<T> DivAssign<&Complex<T>> for Complex<T>
Source§fn div_assign(&mut self, rhs: &Complex<T>)
fn div_assign(&mut self, rhs: &Complex<T>)
Performs the
/=
operation. Read moreSource§impl<T> DivAssign<&T> for Complex<T>
impl<T> DivAssign<&T> for Complex<T>
Source§fn div_assign(&mut self, rhs: &T)
fn div_assign(&mut self, rhs: &T)
Performs the
/=
operation. Read moreSource§impl<T> DivAssign<T> for Complex<T>
impl<T> DivAssign<T> for Complex<T>
Source§fn div_assign(&mut self, rhs: T)
fn div_assign(&mut self, rhs: T)
Performs the
/=
operation. Read moreSource§impl<T> DivAssign for Complex<T>
impl<T> DivAssign for Complex<T>
Source§fn div_assign(&mut self, rhs: Complex<T>)
fn div_assign(&mut self, rhs: Complex<T>)
Performs the
/=
operation. Read moreSource§impl<T> MulAssign<&Complex<T>> for Complex<T>
impl<T> MulAssign<&Complex<T>> for Complex<T>
Source§fn mul_assign(&mut self, rhs: &Complex<T>)
fn mul_assign(&mut self, rhs: &Complex<T>)
Performs the
*=
operation. Read moreSource§impl<T> MulAssign<&T> for Complex<T>
impl<T> MulAssign<&T> for Complex<T>
Source§fn mul_assign(&mut self, rhs: &T)
fn mul_assign(&mut self, rhs: &T)
Performs the
*=
operation. Read moreSource§impl<T> MulAssign<T> for Complex<T>
impl<T> MulAssign<T> for Complex<T>
Source§fn mul_assign(&mut self, rhs: T)
fn mul_assign(&mut self, rhs: T)
Performs the
*=
operation. Read moreSource§impl<T> MulAssign for Complex<T>
impl<T> MulAssign for Complex<T>
Source§fn mul_assign(&mut self, rhs: Complex<T>)
fn mul_assign(&mut self, rhs: Complex<T>)
Performs the
*=
operation. Read moreSource§impl<T: Ord> Ord for Complex<T>
impl<T: Ord> Ord for Complex<T>
1.21.0 · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Compares and returns the maximum of two values. Read more
Source§impl<T: PartialOrd> PartialOrd for Complex<T>
impl<T: PartialOrd> PartialOrd for Complex<T>
Source§impl<T> SubAssign<&Complex<T>> for Complex<T>
impl<T> SubAssign<&Complex<T>> for Complex<T>
Source§fn sub_assign(&mut self, rhs: &Complex<T>)
fn sub_assign(&mut self, rhs: &Complex<T>)
Performs the
-=
operation. Read moreSource§impl<T> SubAssign<&T> for Complex<T>
impl<T> SubAssign<&T> for Complex<T>
Source§fn sub_assign(&mut self, rhs: &T)
fn sub_assign(&mut self, rhs: &T)
Performs the
-=
operation. Read moreSource§impl<T> SubAssign<T> for Complex<T>
impl<T> SubAssign<T> for Complex<T>
Source§fn sub_assign(&mut self, rhs: T)
fn sub_assign(&mut self, rhs: T)
Performs the
-=
operation. Read moreSource§impl<T> SubAssign for Complex<T>
impl<T> SubAssign for Complex<T>
Source§fn sub_assign(&mut self, rhs: Complex<T>)
fn sub_assign(&mut self, rhs: Complex<T>)
Performs the
-=
operation. Read moreimpl<T: Copy> Copy for Complex<T>
impl<T: Eq> Eq for Complex<T>
impl<T> StructuralPartialEq for Complex<T>
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> UnwindSafe for Complex<T>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> AsTotalOrd for Twhere
T: PartialOrd,
impl<T> AsTotalOrd for Twhere
T: PartialOrd,
fn as_total_ord(&self) -> TotalOrd<&T>
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more