1use crate::Transcendental;
11use std::ops::{
12 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
13};
14use wide::{f32x4, f32x8, f64x2, f64x4, CmpEq, CmpGe, CmpGt, CmpLe, CmpLt, CmpNe};
15
16use crate::math::vector::traits::{Vector, VectorMask, VectorTranscendental};
17
18#[derive(Copy, Clone, Debug, PartialEq)]
24pub struct F32x4(f32x4);
25
26#[derive(Copy, Clone, Debug, PartialEq)]
28pub struct F32x8(f32x8);
29
30#[derive(Copy, Clone, Debug, PartialEq)]
32pub struct F64x2(f64x2);
33
34#[derive(Copy, Clone, Debug, PartialEq)]
36pub struct F64x4(f64x4);
37
38impl Default for F32x4 {
43 fn default() -> Self {
44 Self(f32x4::splat(0.0))
45 }
46}
47
48impl Default for F32x8 {
49 fn default() -> Self {
50 Self(f32x8::splat(0.0))
51 }
52}
53
54impl Default for F64x2 {
55 fn default() -> Self {
56 Self(f64x2::splat(0.0))
57 }
58}
59
60impl Default for F64x4 {
61 fn default() -> Self {
62 Self(f64x4::splat(0.0))
63 }
64}
65
66impl Vector<f32, 4> for F32x4 {
71 fn splat(value: f32) -> Self {
72 F32x4(f32x4::splat(value))
73 }
74
75 fn load(slice: &[f32]) -> Self {
76 let mut arr = [0.0f32; 4];
77 arr.copy_from_slice(&slice[0..4]);
78 F32x4(f32x4::from(arr))
79 }
80
81 fn store(&self, slice: &mut [f32]) {
82 let arr: [f32; 4] = self.0.into();
83 slice[0..4].copy_from_slice(&arr);
84 }
85
86 fn extract(&self, index: usize) -> f32 {
87 let arr: [f32; 4] = self.0.into();
88 arr[index]
89 }
90
91 fn insert(&self, index: usize, value: f32) -> Self {
92 let mut arr: [f32; 4] = self.0.into();
93 arr[index] = value;
94 F32x4(f32x4::from(arr))
95 }
96
97 fn add(&self, other: &Self) -> Self {
98 F32x4(self.0 + other.0)
99 }
100
101 fn sub(&self, other: &Self) -> Self {
102 F32x4(self.0 - other.0)
103 }
104
105 fn mul(&self, other: &Self) -> Self {
106 F32x4(self.0 * other.0)
107 }
108
109 fn div(&self, other: &Self) -> Self {
110 F32x4(self.0 / other.0)
111 }
112
113 fn rem(&self, other: &Self) -> Self {
114 let a: [f32; 4] = self.0.into();
116 let b: [f32; 4] = other.0.into();
117 let mut arr = [0.0f32; 4];
118 for i in 0..4 {
119 arr[i] = a[i] % b[i];
120 }
121 F32x4(f32x4::from(arr))
122 }
123
124 fn neg(&self) -> Self {
125 F32x4(-self.0)
126 }
127
128 fn abs(&self) -> Self {
129 F32x4(self.0.abs())
130 }
131
132 fn min(&self, other: &Self) -> Self {
133 F32x4(self.0.min(other.0))
134 }
135
136 fn max(&self, other: &Self) -> Self {
137 F32x4(self.0.max(other.0))
138 }
139
140 fn clamp(&self, min: &Self, max: &Self) -> Self {
141 F32x4(self.0.max(min.0).min(max.0))
143 }
144}
145
146impl VectorTranscendental<f32, 4> for F32x4 {
147 fn sqrt(&self) -> Self {
148 F32x4(self.0.sqrt())
149 }
150 fn exp(&self) -> Self {
151 F32x4(self.0.exp())
152 }
153 fn ln(&self) -> Self {
154 F32x4(self.0.ln())
155 }
156 fn sin(&self) -> Self {
157 F32x4(self.0.sin())
158 }
159 fn cos(&self) -> Self {
160 F32x4(self.0.cos())
161 }
162 fn tan(&self) -> Self {
163 F32x4(self.0.tan())
164 }
165}
166
167impl Vector<f32, 8> for F32x8 {
172 fn splat(value: f32) -> Self {
173 F32x8(f32x8::splat(value))
174 }
175
176 fn load(slice: &[f32]) -> Self {
177 let mut arr = [0.0f32; 8];
178 arr.copy_from_slice(&slice[0..8]);
179 F32x8(f32x8::from(arr))
180 }
181
182 fn store(&self, slice: &mut [f32]) {
183 let arr: [f32; 8] = self.0.into();
184 slice[0..8].copy_from_slice(&arr);
185 }
186
187 fn extract(&self, index: usize) -> f32 {
188 let arr: [f32; 8] = self.0.into();
189 arr[index]
190 }
191
192 fn insert(&self, index: usize, value: f32) -> Self {
193 let mut arr: [f32; 8] = self.0.into();
194 arr[index] = value;
195 F32x8(f32x8::from(arr))
196 }
197
198 fn add(&self, other: &Self) -> Self {
199 F32x8(self.0 + other.0)
200 }
201
202 fn sub(&self, other: &Self) -> Self {
203 F32x8(self.0 - other.0)
204 }
205
206 fn mul(&self, other: &Self) -> Self {
207 F32x8(self.0 * other.0)
208 }
209
210 fn div(&self, other: &Self) -> Self {
211 F32x8(self.0 / other.0)
212 }
213
214 fn rem(&self, other: &Self) -> Self {
215 let a: [f32; 8] = self.0.into();
216 let b: [f32; 8] = other.0.into();
217 let mut arr = [0.0f32; 8];
218 for i in 0..8 {
219 arr[i] = a[i] % b[i];
220 }
221 F32x8(f32x8::from(arr))
222 }
223
224 fn neg(&self) -> Self {
225 F32x8(-self.0)
226 }
227
228 fn abs(&self) -> Self {
229 F32x8(self.0.abs())
230 }
231
232 fn min(&self, other: &Self) -> Self {
233 F32x8(self.0.min(other.0))
234 }
235
236 fn max(&self, other: &Self) -> Self {
237 F32x8(self.0.max(other.0))
238 }
239
240 fn clamp(&self, min: &Self, max: &Self) -> Self {
241 F32x8(self.0.max(min.0).min(max.0))
242 }
243}
244
245impl VectorTranscendental<f32, 8> for F32x8 {
246 fn sqrt(&self) -> Self {
247 F32x8(self.0.sqrt())
248 }
249 fn exp(&self) -> Self {
250 F32x8(self.0.exp())
251 }
252 fn ln(&self) -> Self {
253 F32x8(self.0.ln())
254 }
255 fn sin(&self) -> Self {
256 F32x8(self.0.sin())
257 }
258 fn cos(&self) -> Self {
259 F32x8(self.0.cos())
260 }
261 fn tan(&self) -> Self {
262 F32x8(self.0.tan())
263 }
264}
265
266impl Vector<f64, 2> for F64x2 {
271 fn splat(value: f64) -> Self {
272 F64x2(f64x2::splat(value))
273 }
274
275 fn load(slice: &[f64]) -> Self {
276 let mut arr = [0.0f64; 2];
277 arr.copy_from_slice(&slice[0..2]);
278 F64x2(f64x2::from(arr))
279 }
280
281 fn store(&self, slice: &mut [f64]) {
282 let arr: [f64; 2] = self.0.into();
283 slice[0..2].copy_from_slice(&arr);
284 }
285
286 fn extract(&self, index: usize) -> f64 {
287 let arr: [f64; 2] = self.0.into();
288 arr[index]
289 }
290
291 fn insert(&self, index: usize, value: f64) -> Self {
292 let mut arr: [f64; 2] = self.0.into();
293 arr[index] = value;
294 F64x2(f64x2::from(arr))
295 }
296
297 fn add(&self, other: &Self) -> Self {
298 F64x2(self.0 + other.0)
299 }
300
301 fn sub(&self, other: &Self) -> Self {
302 F64x2(self.0 - other.0)
303 }
304
305 fn mul(&self, other: &Self) -> Self {
306 F64x2(self.0 * other.0)
307 }
308
309 fn div(&self, other: &Self) -> Self {
310 F64x2(self.0 / other.0)
311 }
312
313 fn rem(&self, other: &Self) -> Self {
314 let a: [f64; 2] = self.0.into();
315 let b: [f64; 2] = other.0.into();
316 let mut arr = [0.0f64; 2];
317 for i in 0..2 {
318 arr[i] = a[i] % b[i];
319 }
320 F64x2(f64x2::from(arr))
321 }
322
323 fn neg(&self) -> Self {
324 F64x2(-self.0)
325 }
326
327 fn abs(&self) -> Self {
328 F64x2(self.0.abs())
329 }
330
331 fn min(&self, other: &Self) -> Self {
332 F64x2(self.0.min(other.0))
333 }
334
335 fn max(&self, other: &Self) -> Self {
336 F64x2(self.0.max(other.0))
337 }
338
339 fn clamp(&self, min: &Self, max: &Self) -> Self {
340 F64x2(self.0.max(min.0).min(max.0))
341 }
342}
343
344impl VectorTranscendental<f64, 2> for F64x2 {
345 fn sqrt(&self) -> Self {
346 F64x2(self.0.sqrt())
347 }
348 fn exp(&self) -> Self {
349 F64x2(self.0.exp())
350 }
351 fn ln(&self) -> Self {
352 F64x2(self.0.ln())
353 }
354 fn sin(&self) -> Self {
355 F64x2(self.0.sin())
356 }
357 fn cos(&self) -> Self {
358 F64x2(self.0.cos())
359 }
360 fn tan(&self) -> Self {
361 F64x2(self.0.tan())
362 }
363}
364
365impl Vector<f64, 4> for F64x4 {
370 fn splat(value: f64) -> Self {
371 F64x4(f64x4::splat(value))
372 }
373
374 fn load(slice: &[f64]) -> Self {
375 let mut arr = [0.0f64; 4];
376 arr.copy_from_slice(&slice[0..4]);
377 F64x4(f64x4::from(arr))
378 }
379
380 fn store(&self, slice: &mut [f64]) {
381 let arr: [f64; 4] = self.0.into();
382 slice[0..4].copy_from_slice(&arr);
383 }
384
385 fn extract(&self, index: usize) -> f64 {
386 let arr: [f64; 4] = self.0.into();
387 arr[index]
388 }
389
390 fn insert(&self, index: usize, value: f64) -> Self {
391 let mut arr: [f64; 4] = self.0.into();
392 arr[index] = value;
393 F64x4(f64x4::from(arr))
394 }
395
396 fn add(&self, other: &Self) -> Self {
397 F64x4(self.0 + other.0)
398 }
399
400 fn sub(&self, other: &Self) -> Self {
401 F64x4(self.0 - other.0)
402 }
403
404 fn mul(&self, other: &Self) -> Self {
405 F64x4(self.0 * other.0)
406 }
407
408 fn div(&self, other: &Self) -> Self {
409 F64x4(self.0 / other.0)
410 }
411
412 fn rem(&self, other: &Self) -> Self {
413 let a: [f64; 4] = self.0.into();
414 let b: [f64; 4] = other.0.into();
415 let mut arr = [0.0f64; 4];
416 for i in 0..4 {
417 arr[i] = a[i] % b[i];
418 }
419 F64x4(f64x4::from(arr))
420 }
421
422 fn neg(&self) -> Self {
423 F64x4(-self.0)
424 }
425
426 fn abs(&self) -> Self {
427 F64x4(self.0.abs())
428 }
429
430 fn min(&self, other: &Self) -> Self {
431 F64x4(self.0.min(other.0))
432 }
433
434 fn max(&self, other: &Self) -> Self {
435 F64x4(self.0.max(other.0))
436 }
437
438 fn clamp(&self, min: &Self, max: &Self) -> Self {
439 F64x4(self.0.max(min.0).min(max.0))
440 }
441}
442
443impl VectorTranscendental<f64, 4> for F64x4 {
444 fn sqrt(&self) -> Self {
445 F64x4(self.0.sqrt())
446 }
447 fn exp(&self) -> Self {
448 F64x4(self.0.exp())
449 }
450 fn ln(&self) -> Self {
451 F64x4(self.0.ln())
452 }
453 fn sin(&self) -> Self {
454 F64x4(self.0.sin())
455 }
456 fn cos(&self) -> Self {
457 F64x4(self.0.cos())
458 }
459 fn tan(&self) -> Self {
460 F64x4(self.0.tan())
461 }
462}
463
464impl VectorMask<f64, 4> for F64x4 {
469 type Mask = F64x4;
470
471 fn eq(&self, other: &Self) -> F64x4 {
472 F64x4(self.0.cmp_eq(other.0))
473 }
474 fn ne(&self, other: &Self) -> F64x4 {
475 F64x4(self.0.cmp_ne(other.0))
476 }
477 fn gt(&self, other: &Self) -> F64x4 {
478 F64x4(self.0.cmp_gt(other.0))
479 }
480 fn ge(&self, other: &Self) -> F64x4 {
481 F64x4(self.0.cmp_ge(other.0))
482 }
483 fn lt(&self, other: &Self) -> F64x4 {
484 F64x4(self.0.cmp_lt(other.0))
485 }
486 fn le(&self, other: &Self) -> F64x4 {
487 F64x4(self.0.cmp_le(other.0))
488 }
489 fn select(&self, other: &Self, mask: F64x4) -> Self {
490 F64x4(mask.0.blend(self.0, other.0))
491 }
492 fn all(mask: &F64x4) -> bool {
493 mask.0.move_mask() == 0b1111
494 }
495}
496
497impl VectorMask<f64, 2> for F64x2 {
502 type Mask = F64x2;
503
504 fn eq(&self, other: &Self) -> F64x2 {
505 F64x2(self.0.cmp_eq(other.0))
506 }
507 fn ne(&self, other: &Self) -> F64x2 {
508 F64x2(self.0.cmp_ne(other.0))
509 }
510 fn gt(&self, other: &Self) -> F64x2 {
511 F64x2(self.0.cmp_gt(other.0))
512 }
513 fn ge(&self, other: &Self) -> F64x2 {
514 F64x2(self.0.cmp_ge(other.0))
515 }
516 fn lt(&self, other: &Self) -> F64x2 {
517 F64x2(self.0.cmp_lt(other.0))
518 }
519 fn le(&self, other: &Self) -> F64x2 {
520 F64x2(self.0.cmp_le(other.0))
521 }
522 fn select(&self, other: &Self, mask: F64x2) -> Self {
523 F64x2(mask.0.blend(self.0, other.0))
524 }
525 fn all(mask: &F64x2) -> bool {
526 mask.0.move_mask() == 0b11
527 }
528}
529
530impl VectorMask<f32, 4> for F32x4 {
535 type Mask = F32x4;
536
537 fn eq(&self, other: &Self) -> F32x4 {
538 F32x4(self.0.cmp_eq(other.0))
539 }
540 fn ne(&self, other: &Self) -> F32x4 {
541 F32x4(self.0.cmp_ne(other.0))
542 }
543 fn gt(&self, other: &Self) -> F32x4 {
544 F32x4(self.0.cmp_gt(other.0))
545 }
546 fn ge(&self, other: &Self) -> F32x4 {
547 F32x4(self.0.cmp_ge(other.0))
548 }
549 fn lt(&self, other: &Self) -> F32x4 {
550 F32x4(self.0.cmp_lt(other.0))
551 }
552 fn le(&self, other: &Self) -> F32x4 {
553 F32x4(self.0.cmp_le(other.0))
554 }
555 fn select(&self, other: &Self, mask: F32x4) -> Self {
556 F32x4(mask.0.blend(self.0, other.0))
557 }
558 fn all(mask: &F32x4) -> bool {
559 mask.0.move_mask() == 0b1111
560 }
561}
562
563impl VectorMask<f32, 8> for F32x8 {
568 type Mask = F32x8;
569
570 fn eq(&self, other: &Self) -> F32x8 {
571 F32x8(self.0.cmp_eq(other.0))
572 }
573 fn ne(&self, other: &Self) -> F32x8 {
574 F32x8(self.0.cmp_ne(other.0))
575 }
576 fn gt(&self, other: &Self) -> F32x8 {
577 F32x8(self.0.cmp_gt(other.0))
578 }
579 fn ge(&self, other: &Self) -> F32x8 {
580 F32x8(self.0.cmp_ge(other.0))
581 }
582 fn lt(&self, other: &Self) -> F32x8 {
583 F32x8(self.0.cmp_lt(other.0))
584 }
585 fn le(&self, other: &Self) -> F32x8 {
586 F32x8(self.0.cmp_le(other.0))
587 }
588 fn select(&self, other: &Self, mask: F32x8) -> Self {
589 F32x8(mask.0.blend(self.0, other.0))
590 }
591 fn all(mask: &F32x8) -> bool {
592 mask.0.move_mask() == 0b1111_1111
593 }
594}
595
596impl Add for F32x4 {
601 type Output = Self;
602 fn add(self, rhs: Self) -> Self {
603 Self(self.0 + rhs.0)
604 }
605}
606
607impl Sub for F32x4 {
608 type Output = Self;
609 fn sub(self, rhs: Self) -> Self {
610 Self(self.0 - rhs.0)
611 }
612}
613
614impl Mul for F32x4 {
615 type Output = Self;
616 fn mul(self, rhs: Self) -> Self {
617 Self(self.0 * rhs.0)
618 }
619}
620
621impl Div for F32x4 {
622 type Output = Self;
623 fn div(self, rhs: Self) -> Self {
624 Self(self.0 / rhs.0)
625 }
626}
627
628impl Rem for F32x4 {
629 type Output = Self;
630 fn rem(self, rhs: Self) -> Self {
631 let a: [f32; 4] = self.0.into();
632 let b: [f32; 4] = rhs.0.into();
633 let mut arr = [0.0f32; 4];
634 for i in 0..4 {
635 arr[i] = a[i] % b[i];
636 }
637 Self(f32x4::from(arr))
638 }
639}
640
641impl Neg for F32x4 {
642 type Output = Self;
643 fn neg(self) -> Self {
644 Self(-self.0)
645 }
646}
647
648impl AddAssign for F32x4 {
649 fn add_assign(&mut self, rhs: Self) {
650 self.0 += rhs.0;
651 }
652}
653impl SubAssign for F32x4 {
654 fn sub_assign(&mut self, rhs: Self) {
655 self.0 -= rhs.0;
656 }
657}
658impl MulAssign for F32x4 {
659 fn mul_assign(&mut self, rhs: Self) {
660 self.0 *= rhs.0;
661 }
662}
663impl DivAssign for F32x4 {
664 fn div_assign(&mut self, rhs: Self) {
665 self.0 /= rhs.0;
666 }
667}
668impl RemAssign for F32x4 {
669 fn rem_assign(&mut self, rhs: Self) {
670 let a: [f32; 4] = self.0.into();
671 let b: [f32; 4] = rhs.0.into();
672 let mut arr = [0.0f32; 4];
673 for i in 0..4 {
674 arr[i] = a[i] % b[i];
675 }
676 self.0 = f32x4::from(arr);
677 }
678}
679
680impl Add for F32x8 {
683 type Output = Self;
684 fn add(self, rhs: Self) -> Self {
685 Self(self.0 + rhs.0)
686 }
687}
688
689impl Sub for F32x8 {
690 type Output = Self;
691 fn sub(self, rhs: Self) -> Self {
692 Self(self.0 - rhs.0)
693 }
694}
695
696impl Mul for F32x8 {
697 type Output = Self;
698 fn mul(self, rhs: Self) -> Self {
699 Self(self.0 * rhs.0)
700 }
701}
702
703impl Div for F32x8 {
704 type Output = Self;
705 fn div(self, rhs: Self) -> Self {
706 Self(self.0 / rhs.0)
707 }
708}
709
710impl Rem for F32x8 {
711 type Output = Self;
712 fn rem(self, rhs: Self) -> Self {
713 let a: [f32; 8] = self.0.into();
714 let b: [f32; 8] = rhs.0.into();
715 let mut arr = [0.0f32; 8];
716 for i in 0..8 {
717 arr[i] = a[i] % b[i];
718 }
719 Self(f32x8::from(arr))
720 }
721}
722
723impl Neg for F32x8 {
724 type Output = Self;
725 fn neg(self) -> Self {
726 Self(-self.0)
727 }
728}
729
730impl AddAssign for F32x8 {
731 fn add_assign(&mut self, rhs: Self) {
732 self.0 += rhs.0;
733 }
734}
735impl SubAssign for F32x8 {
736 fn sub_assign(&mut self, rhs: Self) {
737 self.0 -= rhs.0;
738 }
739}
740impl MulAssign for F32x8 {
741 fn mul_assign(&mut self, rhs: Self) {
742 self.0 *= rhs.0;
743 }
744}
745impl DivAssign for F32x8 {
746 fn div_assign(&mut self, rhs: Self) {
747 self.0 /= rhs.0;
748 }
749}
750impl RemAssign for F32x8 {
751 fn rem_assign(&mut self, rhs: Self) {
752 let a: [f32; 8] = self.0.into();
753 let b: [f32; 8] = rhs.0.into();
754 let mut arr = [0.0f32; 8];
755 for i in 0..8 {
756 arr[i] = a[i] % b[i];
757 }
758 self.0 = f32x8::from(arr);
759 }
760}
761
762impl Add for F64x2 {
763 type Output = Self;
764 fn add(self, rhs: Self) -> Self {
765 Self(self.0 + rhs.0)
766 }
767}
768
769impl Sub for F64x2 {
770 type Output = Self;
771 fn sub(self, rhs: Self) -> Self {
772 Self(self.0 - rhs.0)
773 }
774}
775
776impl Mul for F64x2 {
777 type Output = Self;
778 fn mul(self, rhs: Self) -> Self {
779 Self(self.0 * rhs.0)
780 }
781}
782
783impl Div for F64x2 {
784 type Output = Self;
785 fn div(self, rhs: Self) -> Self {
786 Self(self.0 / rhs.0)
787 }
788}
789
790impl Rem for F64x2 {
791 type Output = Self;
792 fn rem(self, rhs: Self) -> Self {
793 let a: [f64; 2] = self.0.into();
794 let b: [f64; 2] = rhs.0.into();
795 let mut arr = [0.0f64; 2];
796 for i in 0..2 {
797 arr[i] = a[i] % b[i];
798 }
799 Self(f64x2::from(arr))
800 }
801}
802
803impl Neg for F64x2 {
804 type Output = Self;
805 fn neg(self) -> Self {
806 Self(-self.0)
807 }
808}
809
810impl AddAssign for F64x2 {
811 fn add_assign(&mut self, rhs: Self) {
812 self.0 += rhs.0;
813 }
814}
815impl SubAssign for F64x2 {
816 fn sub_assign(&mut self, rhs: Self) {
817 self.0 -= rhs.0;
818 }
819}
820impl MulAssign for F64x2 {
821 fn mul_assign(&mut self, rhs: Self) {
822 self.0 *= rhs.0;
823 }
824}
825impl DivAssign for F64x2 {
826 fn div_assign(&mut self, rhs: Self) {
827 self.0 /= rhs.0;
828 }
829}
830impl RemAssign for F64x2 {
831 fn rem_assign(&mut self, rhs: Self) {
832 let a: [f64; 2] = self.0.into();
833 let b: [f64; 2] = rhs.0.into();
834 let mut arr = [0.0f64; 2];
835 for i in 0..2 {
836 arr[i] = a[i] % b[i];
837 }
838 self.0 = f64x2::from(arr);
839 }
840}
841
842impl Add for F64x4 {
843 type Output = Self;
844 fn add(self, rhs: Self) -> Self {
845 Self(self.0 + rhs.0)
846 }
847}
848
849impl Sub for F64x4 {
850 type Output = Self;
851 fn sub(self, rhs: Self) -> Self {
852 Self(self.0 - rhs.0)
853 }
854}
855
856impl Mul for F64x4 {
857 type Output = Self;
858 fn mul(self, rhs: Self) -> Self {
859 Self(self.0 * rhs.0)
860 }
861}
862
863impl Div for F64x4 {
864 type Output = Self;
865 fn div(self, rhs: Self) -> Self {
866 Self(self.0 / rhs.0)
867 }
868}
869
870impl Rem for F64x4 {
871 type Output = Self;
872 fn rem(self, rhs: Self) -> Self {
873 let a: [f64; 4] = self.0.into();
874 let b: [f64; 4] = rhs.0.into();
875 let mut arr = [0.0f64; 4];
876 for i in 0..4 {
877 arr[i] = a[i] % b[i];
878 }
879 Self(f64x4::from(arr))
880 }
881}
882
883impl Neg for F64x4 {
884 type Output = Self;
885 fn neg(self) -> Self {
886 Self(-self.0)
887 }
888}
889
890impl AddAssign for F64x4 {
891 fn add_assign(&mut self, rhs: Self) {
892 self.0 += rhs.0;
893 }
894}
895impl SubAssign for F64x4 {
896 fn sub_assign(&mut self, rhs: Self) {
897 self.0 -= rhs.0;
898 }
899}
900impl MulAssign for F64x4 {
901 fn mul_assign(&mut self, rhs: Self) {
902 self.0 *= rhs.0;
903 }
904}
905impl DivAssign for F64x4 {
906 fn div_assign(&mut self, rhs: Self) {
907 self.0 /= rhs.0;
908 }
909}
910impl RemAssign for F64x4 {
911 fn rem_assign(&mut self, rhs: Self) {
912 let a: [f64; 4] = self.0.into();
913 let b: [f64; 4] = rhs.0.into();
914 let mut arr = [0.0f64; 4];
915 for i in 0..4 {
916 arr[i] = a[i] % b[i];
917 }
918 self.0 = f64x4::from(arr);
919 }
920}
921
922#[cfg(test)]
927mod tests {
928 use super::*;
929 use crate::math::vector::traits::VectorMask;
930
931 #[test]
932 fn test_f32x4_basic() {
933 let a = F32x4::load(&[1.0, 2.0, 3.0, 4.0]);
934 let b = F32x4::load(&[5.0, 6.0, 7.0, 8.0]);
935
936 let c = a + b;
937 let mut arr = [0.0f32; 4];
938 c.store(&mut arr);
939 assert_eq!(arr, [6.0, 8.0, 10.0, 12.0]);
940
941 let c = a * b;
942 c.store(&mut arr);
943 assert_eq!(arr, [5.0, 12.0, 21.0, 32.0]);
944 }
945
946 #[test]
947 fn test_f32x4_math() {
948 let a = F32x4::load(&[0.0, 0.5, 1.0, 2.0]);
949 let sin_a = a.sin();
950 let mut arr = [0.0f32; 4];
951 sin_a.store(&mut arr);
952 let expected = [0.0f32.sin(), 0.5f32.sin(), 1.0f32.sin(), 2.0f32.sin()];
953 for i in 0..4 {
954 assert!((arr[i] - expected[i]).abs() < 1e-5);
955 }
956 }
957
958 #[test]
959 fn test_f64x2_basic() {
960 let a = F64x2::load(&[1.0, 2.0]);
961 let b = F64x2::load(&[3.0, 4.0]);
962
963 let c = a + b;
964 let mut arr = [0.0f64; 2];
965 c.store(&mut arr);
966 assert_eq!(arr, [4.0, 6.0]);
967 }
968
969 #[test]
970 fn test_f64x4_basic() {
971 let a = F64x4::load(&[1.0, 2.0, 3.0, 4.0]);
972 let b = F64x4::load(&[5.0, 6.0, 7.0, 8.0]);
973
974 let c = a + b;
975 let mut arr = [0.0f64; 4];
976 c.store(&mut arr);
977 assert_eq!(arr, [6.0, 8.0, 10.0, 12.0]);
978
979 let c = a * b;
980 c.store(&mut arr);
981 assert_eq!(arr, [5.0, 12.0, 21.0, 32.0]);
982 }
983
984 #[test]
985 fn test_f64x4_math() {
986 let a = F64x4::load(&[0.0, 0.5, 1.0, 2.0]);
987 let sqrt_a = a.sqrt();
988 let mut arr = [0.0f64; 4];
989 sqrt_a.store(&mut arr);
990 let expected = [0.0f64.sqrt(), 0.5f64.sqrt(), 1.0f64.sqrt(), 2.0f64.sqrt()];
991 for i in 0..4 {
992 assert!((arr[i] - expected[i]).abs() < 1e-12);
993 }
994
995 let exp_a = a.exp();
996 exp_a.store(&mut arr);
997 let expected = [0.0f64.exp(), 0.5f64.exp(), 1.0f64.exp(), 2.0f64.exp()];
998 for i in 0..4 {
999 assert!((arr[i] - expected[i]).abs() < 1e-12);
1000 }
1001 }
1002
1003 #[test]
1004 fn test_f64x4_vector_mask_lt() {
1005 let a = F64x4::load(&[1.0, 2.0, 3.0, 4.0]);
1008 let b = F64x4::load(&[3.0, 3.0, 3.0, 3.0]);
1009 let mask = <F64x4 as VectorMask<f64, 4>>::lt(&a, &b);
1010 assert_eq!(mask.0.move_mask() & 0b1111, 0b0011); }
1013
1014 #[test]
1015 fn test_f64x4_vector_mask_gt() {
1016 let a = F64x4::load(&[1.0, 2.0, 3.0, 4.0]);
1017 let b = F64x4::load(&[2.0, 2.0, 2.0, 2.0]);
1018 let mask = <F64x4 as VectorMask<f64, 4>>::gt(&a, &b);
1019 assert_eq!(mask.0.move_mask() & 0b1111, 0b1100); }
1021
1022 #[test]
1023 fn test_f64x4_vector_mask_eq() {
1024 let a = F64x4::load(&[1.0, 2.0, 3.0, 4.0]);
1025 let b = F64x4::load(&[1.0, 0.0, 3.0, 5.0]);
1026 let mask = <F64x4 as VectorMask<f64, 4>>::eq(&a, &b);
1027 assert_eq!(mask.0.move_mask() & 0b1111, 0b0101); }
1029
1030 #[test]
1031 fn test_f64x4_vector_mask_all() {
1032 let all_true = <F64x4 as VectorMask<f64, 4>>::lt(&F64x4::splat(1.0), &F64x4::splat(2.0));
1033 assert!(<F64x4 as VectorMask<f64, 4>>::all(&all_true));
1034
1035 let partial_true = <F64x4 as VectorMask<f64, 4>>::lt(
1036 &F64x4::load(&[1.0, 2.0, 3.0, 4.0]),
1037 &F64x4::splat(3.0),
1038 );
1039 assert!(!<F64x4 as VectorMask<f64, 4>>::all(&partial_true));
1040 }
1041
1042 #[test]
1043 fn test_f64x4_vector_mask_select() {
1044 let true_vals = F64x4::load(&[10.0, 20.0, 30.0, 40.0]);
1045 let false_vals = F64x4::load(&[1.0, 2.0, 3.0, 4.0]);
1046 let threshold = F64x4::load(&[5.0, 25.0, 25.0, 25.0]);
1048 let mask = <F64x4 as VectorMask<f64, 4>>::lt(&true_vals, &threshold);
1049 let selected = <F64x4 as VectorMask<f64, 4>>::select(&true_vals, &false_vals, mask);
1050 assert_eq!(mask.0.move_mask() & 0b1111, 0b0010);
1055 let mut arr = [0.0; 4];
1057 selected.store(&mut arr);
1058 assert!((arr[0] - 1.0).abs() < 1e-15);
1059 assert!((arr[1] - 20.0).abs() < 1e-15);
1060 assert!((arr[2] - 3.0).abs() < 1e-15);
1061 assert!((arr[3] - 4.0).abs() < 1e-15);
1062 }
1063}