1use std::ops::{Add, Mul, Sub};
4
5#[derive(Debug, Clone, Copy, PartialEq)]
10pub struct Quaternion {
11 pub w: f64,
13 pub x: f64,
15 pub y: f64,
17 pub z: f64,
19}
20
21impl Quaternion {
22 pub fn new(w: f64, x: f64, y: f64, z: f64) -> Self {
24 Self { w, x, y, z }
25 }
26
27 pub fn identity() -> Self {
29 Self::new(1.0, 0.0, 0.0, 0.0)
30 }
31
32 pub fn from_axis_angle(axis: [f64; 3], angle: f64) -> Self {
34 let half_angle = angle / 2.0;
35 let sin_half = half_angle.sin();
36 let cos_half = half_angle.cos();
37
38 let len = (axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]).sqrt();
40 let norm_axis = [axis[0] / len, axis[1] / len, axis[2] / len];
41
42 Self {
43 w: cos_half,
44 x: norm_axis[0] * sin_half,
45 y: norm_axis[1] * sin_half,
46 z: norm_axis[2] * sin_half,
47 }
48 }
49
50 pub fn magnitude(&self) -> f64 {
52 (self.w * self.w + self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
53 }
54
55 pub fn normalize(&self) -> Self {
57 let mag = self.magnitude();
58 if mag > 0.0 {
59 Self {
60 w: self.w / mag,
61 x: self.x / mag,
62 y: self.y / mag,
63 z: self.z / mag,
64 }
65 } else {
66 Self::identity()
67 }
68 }
69
70 pub fn conjugate(&self) -> Self {
72 Self {
73 w: self.w,
74 x: -self.x,
75 y: -self.y,
76 z: -self.z,
77 }
78 }
79
80 pub fn inverse(&self) -> Self {
82 let mag_sq = self.w * self.w + self.x * self.x + self.y * self.y + self.z * self.z;
83 if mag_sq > 0.0 {
84 let conj = self.conjugate();
85 Self {
86 w: conj.w / mag_sq,
87 x: conj.x / mag_sq,
88 y: conj.y / mag_sq,
89 z: conj.z / mag_sq,
90 }
91 } else {
92 Self::identity()
93 }
94 }
95
96 pub fn rotate_vector(&self, v: [f64; 3]) -> [f64; 3] {
98 let q = self.normalize();
99 let v_quat = Quaternion::new(0.0, v[0], v[1], v[2]);
100 let result = q * v_quat * q.conjugate();
101 [result.x, result.y, result.z]
102 }
103}
104
105impl Mul for Quaternion {
106 type Output = Self;
107
108 fn mul(self, other: Self) -> Self {
109 Self {
110 w: self.w * other.w - self.x * other.x - self.y * other.y - self.z * other.z,
111 x: self.w * other.x + self.x * other.w + self.y * other.z - self.z * other.y,
112 y: self.w * other.y - self.x * other.z + self.y * other.w + self.z * other.x,
113 z: self.w * other.z + self.x * other.y - self.y * other.x + self.z * other.w,
114 }
115 }
116}
117
118impl Add for Quaternion {
119 type Output = Self;
120
121 fn add(self, other: Self) -> Self {
122 Self {
123 w: self.w + other.w,
124 x: self.x + other.x,
125 y: self.y + other.y,
126 z: self.z + other.z,
127 }
128 }
129}
130
131impl Sub for Quaternion {
132 type Output = Self;
133
134 fn sub(self, other: Self) -> Self {
135 Self {
136 w: self.w - other.w,
137 x: self.x - other.x,
138 y: self.y - other.y,
139 z: self.z - other.z,
140 }
141 }
142}
143
144#[derive(Debug, Clone, Copy, PartialEq)]
146pub struct Complex64 {
147 pub re: f64,
149 pub im: f64,
151}
152
153impl Complex64 {
154 pub fn new(re: f64, im: f64) -> Self {
156 Self { re, im }
157 }
158
159 pub fn from_polar(r: f64, theta: f64) -> Self {
161 Self {
162 re: r * theta.cos(),
163 im: r * theta.sin(),
164 }
165 }
166
167 pub fn magnitude(&self) -> f64 {
169 (self.re * self.re + self.im * self.im).sqrt()
170 }
171
172 pub fn phase(&self) -> f64 {
174 self.im.atan2(self.re)
175 }
176
177 pub fn conjugate(&self) -> Self {
179 Self {
180 re: self.re,
181 im: -self.im,
182 }
183 }
184}
185
186impl Mul for Complex64 {
187 type Output = Self;
188
189 fn mul(self, other: Self) -> Self {
190 Self {
191 re: self.re * other.re - self.im * other.im,
192 im: self.re * other.im + self.im * other.re,
193 }
194 }
195}
196
197impl Add for Complex64 {
198 type Output = Self;
199
200 fn add(self, other: Self) -> Self {
201 Self {
202 re: self.re + other.re,
203 im: self.im + other.im,
204 }
205 }
206}
207
208#[derive(Debug, Clone, Copy, PartialEq)]
210pub struct Tensor4D {
211 pub components: [[f64; 4]; 4],
213}
214
215impl Tensor4D {
216 pub fn zeros() -> Self {
218 Self {
219 components: [[0.0; 4]; 4],
220 }
221 }
222
223 pub fn identity() -> Self {
225 let mut tensor = Self::zeros();
226 for i in 0..4 {
227 tensor.components[i][i] = 1.0;
228 }
229 tensor
230 }
231
232 pub fn minkowski() -> Self {
234 let mut tensor = Self::zeros();
235 tensor.components[0][0] = -1.0; tensor.components[1][1] = 1.0;
237 tensor.components[2][2] = 1.0;
238 tensor.components[3][3] = 1.0;
239 tensor
240 }
241
242 pub fn schwarzschild_metric(mass: f64, r: f64) -> Self {
244 let rs = 2.0 * mass; let mut tensor = Self::zeros();
246
247 if r > rs {
248 tensor.components[0][0] = -(1.0 - rs / r); tensor.components[1][1] = 1.0 / (1.0 - rs / r); tensor.components[2][2] = r * r; tensor.components[3][3] = r * r * r.sin().powi(2); }
253
254 tensor
255 }
256
257 pub fn get(&self, row: usize, col: usize) -> f64 {
259 self.components[row][col]
260 }
261
262 pub fn set(&mut self, row: usize, col: usize, value: f64) {
264 self.components[row][col] = value;
265 }
266
267 pub fn determinant(&self) -> f64 {
269 let m = &self.components;
272
273 let mut det = 0.0;
275 for j in 0..4 {
276 let sign = if j % 2 == 0 { 1.0 } else { -1.0 };
277 det += sign * m[0][j] * self.minor_3x3(0, j);
278 }
279 det
280 }
281
282 fn minor_3x3(&self, skip_row: usize, skip_col: usize) -> f64 {
283 let mut m3x3 = [[0.0; 3]; 3];
284 let mut i3 = 0;
285 for i in 0..4 {
286 if i == skip_row {
287 continue;
288 }
289 let mut j3 = 0;
290 for j in 0..4 {
291 if j == skip_col {
292 continue;
293 }
294 m3x3[i3][j3] = self.components[i][j];
295 j3 += 1;
296 }
297 i3 += 1;
298 }
299
300 m3x3[0][0] * (m3x3[1][1] * m3x3[2][2] - m3x3[1][2] * m3x3[2][1])
302 - m3x3[0][1] * (m3x3[1][0] * m3x3[2][2] - m3x3[1][2] * m3x3[2][0])
303 + m3x3[0][2] * (m3x3[1][0] * m3x3[2][1] - m3x3[1][1] * m3x3[2][0])
304 }
305}
306
307#[derive(Debug, Clone, Copy, PartialEq)]
309pub struct Spinor {
310 pub up: Complex64,
312 pub down: Complex64,
314}
315
316impl Spinor {
317 pub fn new(up: Complex64, down: Complex64) -> Self {
319 Self { up, down }
320 }
321
322 pub fn spin_up() -> Self {
324 Self {
325 up: Complex64::new(1.0, 0.0),
326 down: Complex64::new(0.0, 0.0),
327 }
328 }
329
330 pub fn spin_down() -> Self {
332 Self {
333 up: Complex64::new(0.0, 0.0),
334 down: Complex64::new(1.0, 0.0),
335 }
336 }
337
338 pub fn norm(&self) -> f64 {
340 (self.up.magnitude().powi(2) + self.down.magnitude().powi(2)).sqrt()
341 }
342
343 pub fn normalize(&self) -> Self {
345 let n = self.norm();
346 if n > 0.0 {
347 Self {
348 up: Complex64::new(self.up.re / n, self.up.im / n),
349 down: Complex64::new(self.down.re / n, self.down.im / n),
350 }
351 } else {
352 Self::spin_up()
353 }
354 }
355}
356
357#[derive(Debug, Clone)]
361pub struct QuaternionArray {
362 data: Vec<Quaternion>,
363}
364
365impl QuaternionArray {
366 pub fn new(data: Vec<Quaternion>) -> Self {
368 Self { data }
369 }
370
371 pub fn from_iter<I: IntoIterator<Item = Quaternion>>(iter: I) -> Self {
373 Self {
374 data: iter.into_iter().collect(),
375 }
376 }
377
378 pub fn value(&self, index: usize) -> Option<Quaternion> {
380 self.data.get(index).copied()
381 }
382
383 pub fn values(&self) -> &[Quaternion] {
385 &self.data
386 }
387
388 pub fn len(&self) -> usize {
390 self.data.len()
391 }
392
393 pub fn is_empty(&self) -> bool {
395 self.data.is_empty()
396 }
397
398 pub fn multiply(&self, other: &Self) -> Option<Self> {
400 if self.len() != other.len() {
401 return None;
402 }
403
404 let result: Vec<Quaternion> = self
405 .data
406 .iter()
407 .zip(other.data.iter())
408 .map(|(a, b)| *a * *b)
409 .collect();
410
411 Some(Self::new(result))
412 }
413
414 pub fn normalize(&self) -> Self {
416 let result: Vec<Quaternion> = self.data.iter().map(|q| q.normalize()).collect();
417 Self::new(result)
418 }
419
420 pub fn conjugate(&self) -> Self {
422 let result: Vec<Quaternion> = self.data.iter().map(|q| q.conjugate()).collect();
423 Self::new(result)
424 }
425
426 pub fn slerp(&self, other: &Self, t: f64) -> Option<Self> {
428 if self.len() != other.len() {
429 return None;
430 }
431
432 let result: Vec<Quaternion> = self
433 .data
434 .iter()
435 .zip(other.data.iter())
436 .map(|(a, b)| {
437 let dot = a.w * b.w + a.x * b.x + a.y * b.y + a.z * b.z;
439 let theta = dot.acos();
440 let sin_theta = theta.sin();
441
442 if sin_theta.abs() < 1e-10 {
443 *a } else {
445 let w1 = ((1.0 - t) * theta).sin() / sin_theta;
446 let w2 = (t * theta).sin() / sin_theta;
447
448 Quaternion::new(
449 a.w * w1 + b.w * w2,
450 a.x * w1 + b.x * w2,
451 a.y * w1 + b.y * w2,
452 a.z * w1 + b.z * w2,
453 )
454 }
455 })
456 .collect();
457
458 Some(Self::new(result))
459 }
460}
461
462#[derive(Debug, Clone)]
464pub struct ComplexArray {
465 data: Vec<Complex64>,
466}
467
468impl ComplexArray {
469 pub fn new(data: Vec<Complex64>) -> Self {
471 Self { data }
472 }
473
474 pub fn from_iter<I: IntoIterator<Item = Complex64>>(iter: I) -> Self {
476 Self {
477 data: iter.into_iter().collect(),
478 }
479 }
480
481 pub fn value(&self, index: usize) -> Option<Complex64> {
483 self.data.get(index).copied()
484 }
485
486 pub fn values(&self) -> &[Complex64] {
488 &self.data
489 }
490
491 pub fn len(&self) -> usize {
493 self.data.len()
494 }
495
496 pub fn is_empty(&self) -> bool {
498 self.data.is_empty()
499 }
500
501 pub fn multiply(&self, other: &Self) -> Option<Self> {
503 if self.len() != other.len() {
504 return None;
505 }
506
507 let result: Vec<Complex64> = self
508 .data
509 .iter()
510 .zip(other.data.iter())
511 .map(|(a, b)| *a * *b)
512 .collect();
513
514 Some(Self::new(result))
515 }
516
517 pub fn add(&self, other: &Self) -> Option<Self> {
519 if self.len() != other.len() {
520 return None;
521 }
522
523 let result: Vec<Complex64> = self
524 .data
525 .iter()
526 .zip(other.data.iter())
527 .map(|(a, b)| *a + *b)
528 .collect();
529
530 Some(Self::new(result))
531 }
532
533 pub fn magnitude(&self) -> Vec<f64> {
535 self.data.iter().map(|c| c.magnitude()).collect()
536 }
537
538 pub fn phase(&self) -> Vec<f64> {
540 self.data.iter().map(|c| c.phase()).collect()
541 }
542
543 pub fn conjugate(&self) -> Self {
545 let result: Vec<Complex64> = self.data.iter().map(|c| c.conjugate()).collect();
546 Self::new(result)
547 }
548}
549
550#[derive(Debug, Clone)]
552pub struct Tensor4DArray {
553 data: Vec<Tensor4D>,
554}
555
556impl Tensor4DArray {
557 pub fn new(data: Vec<Tensor4D>) -> Self {
559 Self { data }
560 }
561
562 pub fn from_iter<I: IntoIterator<Item = Tensor4D>>(iter: I) -> Self {
564 Self {
565 data: iter.into_iter().collect(),
566 }
567 }
568
569 pub fn value(&self, index: usize) -> Option<Tensor4D> {
571 self.data.get(index).copied()
572 }
573
574 pub fn values(&self) -> &[Tensor4D] {
576 &self.data
577 }
578
579 pub fn len(&self) -> usize {
581 self.data.len()
582 }
583
584 pub fn is_empty(&self) -> bool {
586 self.data.is_empty()
587 }
588}
589
590#[derive(Debug, Clone)]
592pub struct SpinorArray {
593 data: Vec<Spinor>,
594}
595
596impl SpinorArray {
597 pub fn new(data: Vec<Spinor>) -> Self {
599 Self { data }
600 }
601
602 pub fn from_iter<I: IntoIterator<Item = Spinor>>(iter: I) -> Self {
604 Self {
605 data: iter.into_iter().collect(),
606 }
607 }
608
609 pub fn value(&self, index: usize) -> Option<Spinor> {
611 self.data.get(index).copied()
612 }
613
614 pub fn values(&self) -> &[Spinor] {
616 &self.data
617 }
618
619 pub fn len(&self) -> usize {
621 self.data.len()
622 }
623
624 pub fn is_empty(&self) -> bool {
626 self.data.is_empty()
627 }
628
629 pub fn normalize(&self) -> Self {
631 let result: Vec<Spinor> = self.data.iter().map(|s| s.normalize()).collect();
632 Self::new(result)
633 }
634}
635
636#[cfg(test)]
637mod tests {
638 use super::*;
639
640 #[test]
641 fn test_quaternion_identity() {
642 let q = Quaternion::identity();
643 assert_eq!(q.w, 1.0);
644 assert_eq!(q.x, 0.0);
645 assert_eq!(q.magnitude(), 1.0);
646 }
647
648 #[test]
649 fn test_quaternion_multiplication() {
650 let q1 = Quaternion::new(1.0, 0.0, 0.0, 0.0);
651 let q2 = Quaternion::new(0.0, 1.0, 0.0, 0.0);
652 let result = q1 * q2;
653 assert_eq!(result.x, 1.0);
654 }
655
656 #[test]
657 fn test_quaternion_normalize() {
658 let q = Quaternion::new(2.0, 0.0, 0.0, 0.0);
659 let normalized = q.normalize();
660 assert!((normalized.magnitude() - 1.0).abs() < 1e-10);
661 }
662
663 #[test]
664 fn test_complex_magnitude() {
665 let c = Complex64::new(3.0, 4.0);
666 assert_eq!(c.magnitude(), 5.0);
667 }
668
669 #[test]
670 fn test_complex_multiplication() {
671 let c1 = Complex64::new(1.0, 2.0);
672 let c2 = Complex64::new(3.0, 4.0);
673 let result = c1 * c2;
674 assert_eq!(result.re, -5.0);
675 assert_eq!(result.im, 10.0);
676 }
677
678 #[test]
679 fn test_tensor4d_minkowski() {
680 let metric = Tensor4D::minkowski();
681 assert_eq!(metric.get(0, 0), -1.0);
682 assert_eq!(metric.get(1, 1), 1.0);
683 assert_eq!(metric.get(2, 2), 1.0);
684 assert_eq!(metric.get(3, 3), 1.0);
685 }
686
687 #[test]
688 fn test_tensor4d_schwarzschild() {
689 let metric = Tensor4D::schwarzschild_metric(1.0, 10.0);
690 assert!(metric.get(0, 0) < 0.0); assert!(metric.get(1, 1) > 0.0); }
693
694 #[test]
695 fn test_spinor_creation() {
696 let spinor = Spinor::spin_up();
697 assert_eq!(spinor.up.re, 1.0);
698 assert_eq!(spinor.down.re, 0.0);
699 assert!((spinor.norm() - 1.0).abs() < 1e-10);
700 }
701
702 #[test]
703 fn test_spinor_normalize() {
704 let spinor = Spinor::new(
705 Complex64::new(2.0, 0.0),
706 Complex64::new(2.0, 0.0),
707 );
708 let normalized = spinor.normalize();
709 assert!((normalized.norm() - 1.0).abs() < 1e-10);
710 }
711
712 #[test]
715 fn test_quaternion_array_creation() {
716 let q1 = Quaternion::identity();
717 let q2 = Quaternion::new(0.707, 0.707, 0.0, 0.0);
718 let array = QuaternionArray::new(vec![q1, q2]);
719
720 assert_eq!(array.len(), 2);
721 assert_eq!(array.value(0), Some(q1));
722 assert_eq!(array.value(1), Some(q2));
723 }
724
725 #[test]
726 fn test_quaternion_array_multiply() {
727 let q1 = Quaternion::identity();
728 let q2 = Quaternion::new(0.0, 1.0, 0.0, 0.0);
729 let array1 = QuaternionArray::new(vec![q1, q1]);
730 let array2 = QuaternionArray::new(vec![q2, q2]);
731
732 let result = array1.multiply(&array2).unwrap();
733 assert_eq!(result.len(), 2);
734 assert_eq!(result.value(0).unwrap().x, 1.0);
735 }
736
737 #[test]
738 fn test_quaternion_array_normalize() {
739 let q1 = Quaternion::new(2.0, 0.0, 0.0, 0.0);
740 let q2 = Quaternion::new(0.0, 3.0, 0.0, 0.0);
741 let array = QuaternionArray::new(vec![q1, q2]);
742
743 let normalized = array.normalize();
744 assert!((normalized.value(0).unwrap().magnitude() - 1.0).abs() < 1e-10);
745 assert!((normalized.value(1).unwrap().magnitude() - 1.0).abs() < 1e-10);
746 }
747
748 #[test]
749 fn test_quaternion_array_slerp() {
750 let q1 = Quaternion::identity();
751 let q2 = Quaternion::from_axis_angle([0.0, 0.0, 1.0], std::f64::consts::PI);
752 let array1 = QuaternionArray::new(vec![q1, q1]);
753 let array2 = QuaternionArray::new(vec![q2, q2]);
754
755 let result = array1.slerp(&array2, 0.5).unwrap();
756 assert_eq!(result.len(), 2);
757 assert!((result.value(0).unwrap().magnitude() - 1.0).abs() < 1e-10);
758 }
759
760 #[test]
761 fn test_complex_array_creation() {
762 let c1 = Complex64::new(1.0, 2.0);
763 let c2 = Complex64::new(3.0, 4.0);
764 let array = ComplexArray::new(vec![c1, c2]);
765
766 assert_eq!(array.len(), 2);
767 assert_eq!(array.value(0), Some(c1));
768 assert_eq!(array.value(1), Some(c2));
769 }
770
771 #[test]
772 fn test_complex_array_multiply() {
773 let c1 = Complex64::new(1.0, 2.0);
774 let c2 = Complex64::new(3.0, 4.0);
775 let array1 = ComplexArray::new(vec![c1, c1]);
776 let array2 = ComplexArray::new(vec![c2, c2]);
777
778 let result = array1.multiply(&array2).unwrap();
779 assert_eq!(result.len(), 2);
780 assert_eq!(result.value(0).unwrap().re, -5.0);
781 assert_eq!(result.value(0).unwrap().im, 10.0);
782 }
783
784 #[test]
785 fn test_complex_array_add() {
786 let c1 = Complex64::new(1.0, 2.0);
787 let c2 = Complex64::new(3.0, 4.0);
788 let array1 = ComplexArray::new(vec![c1, c1]);
789 let array2 = ComplexArray::new(vec![c2, c2]);
790
791 let result = array1.add(&array2).unwrap();
792 assert_eq!(result.len(), 2);
793 assert_eq!(result.value(0).unwrap().re, 4.0);
794 assert_eq!(result.value(0).unwrap().im, 6.0);
795 }
796
797 #[test]
798 fn test_complex_array_magnitude() {
799 let c1 = Complex64::new(3.0, 4.0);
800 let c2 = Complex64::new(5.0, 12.0);
801 let array = ComplexArray::new(vec![c1, c2]);
802
803 let magnitudes = array.magnitude();
804 assert_eq!(magnitudes[0], 5.0);
805 assert_eq!(magnitudes[1], 13.0);
806 }
807
808 #[test]
809 fn test_complex_array_phase() {
810 let c1 = Complex64::new(1.0, 1.0);
811 let array = ComplexArray::new(vec![c1]);
812
813 let phases = array.phase();
814 assert!((phases[0] - std::f64::consts::PI / 4.0).abs() < 1e-10);
815 }
816
817 #[test]
818 fn test_complex_array_conjugate() {
819 let c1 = Complex64::new(1.0, 2.0);
820 let c2 = Complex64::new(3.0, 4.0);
821 let array = ComplexArray::new(vec![c1, c2]);
822
823 let conj = array.conjugate();
824 assert_eq!(conj.value(0).unwrap().re, 1.0);
825 assert_eq!(conj.value(0).unwrap().im, -2.0);
826 assert_eq!(conj.value(1).unwrap().re, 3.0);
827 assert_eq!(conj.value(1).unwrap().im, -4.0);
828 }
829
830 #[test]
831 fn test_tensor4d_array_creation() {
832 let t1 = Tensor4D::minkowski();
833 let t2 = Tensor4D::zeros();
834 let array = Tensor4DArray::new(vec![t1, t2]);
835
836 assert_eq!(array.len(), 2);
837 assert_eq!(array.value(0), Some(t1));
838 assert_eq!(array.value(1), Some(t2));
839 }
840
841 #[test]
842 fn test_spinor_array_creation() {
843 let s1 = Spinor::spin_up();
844 let s2 = Spinor::spin_down();
845 let array = SpinorArray::new(vec![s1, s2]);
846
847 assert_eq!(array.len(), 2);
848 assert_eq!(array.value(0), Some(s1));
849 assert_eq!(array.value(1), Some(s2));
850 }
851
852 #[test]
853 fn test_spinor_array_normalize() {
854 let s1 = Spinor::new(Complex64::new(2.0, 0.0), Complex64::new(0.0, 0.0));
855 let s2 = Spinor::new(Complex64::new(0.0, 0.0), Complex64::new(3.0, 0.0));
856 let array = SpinorArray::new(vec![s1, s2]);
857
858 let normalized = array.normalize();
859 assert!((normalized.value(0).unwrap().norm() - 1.0).abs() < 1e-10);
860 assert!((normalized.value(1).unwrap().norm() - 1.0).abs() < 1e-10);
861 }
862}
863
864
865
866
867