subsphere/
math.rs

1//! This module contains a minimal set of linear algebra types and functions used by this crate. It
2//! has a very specific grab bag of functionality and is not intended to be publicly exposed for
3//! general use.
4
5/// Contains functions related to vectors.
6pub(crate) mod vec {
7    /// Negates a vector.
8    #[inline]
9    pub const fn neg<const N: usize>(a: [f64; N]) -> [f64; N] {
10        let mut res = [0.0; N];
11        let mut i = 0;
12        while i < N {
13            res[i] = -a[i];
14            i += 1;
15        }
16        res
17    }
18
19    /// Adds `a` to `b`.
20    #[inline]
21    pub const fn add<const N: usize>(a: [f64; N], b: [f64; N]) -> [f64; N] {
22        let mut res = [0.0; N];
23        let mut i = 0;
24        while i < N {
25            res[i] = a[i] + b[i];
26            i += 1;
27        }
28        res
29    }
30
31    /// Subtracts `b` from `a`.
32    #[inline]
33    pub const fn sub<const N: usize>(a: [f64; N], b: [f64; N]) -> [f64; N] {
34        let mut res = [0.0; N];
35        let mut i = 0;
36        while i < N {
37            res[i] = a[i] - b[i];
38            i += 1;
39        }
40        res
41    }
42
43    /// Multiplies a vector by a scalar.
44    #[inline]
45    pub const fn mul<const N: usize>(a: [f64; N], b: f64) -> [f64; N] {
46        let mut res = [0.0; N];
47        let mut i = 0;
48        while i < N {
49            res[i] = a[i] * b;
50            i += 1;
51        }
52        res
53    }
54
55    /// Divides a vector by a scalar.
56    #[inline]
57    pub const fn div<const N: usize>(a: [f64; N], b: f64) -> [f64; N] {
58        let mut res = [0.0; N];
59        let mut i = 0;
60        while i < N {
61            res[i] = a[i] / b;
62            i += 1;
63        }
64        res
65    }
66
67    /// Computes the dot product of two vectors.
68    #[inline]
69    pub const fn dot<const N: usize>(a: [f64; N], b: [f64; N]) -> f64 {
70        let mut res = 0.0;
71        let mut i = 0;
72        while i < N {
73            res += a[i] * b[i];
74            i += 1;
75        }
76        res
77    }
78
79    /// Computes the cross product of two vectors.
80    #[inline]
81    pub const fn cross(a: [f64; 3], b: [f64; 3]) -> [f64; 3] {
82        [
83            a[1] * b[2] - a[2] * b[1],
84            a[2] * b[0] - a[0] * b[2],
85            a[0] * b[1] - a[1] * b[0],
86        ]
87    }
88
89    /// Normalizes a vector.
90    #[inline]
91    pub fn normalize<const N: usize>(a: [f64; N]) -> [f64; N] {
92        div(a, dot(a, a).sqrt())
93    }
94}
95
96/// Contains functions related to matrices.
97pub(crate) mod mat {
98    use super::*;
99
100    /// Multiplies a matrix with a vector.
101    #[inline]
102    pub const fn apply<const N: usize, const M: usize>(
103        mat: [[f64; N]; M],
104        vec: [f64; M],
105    ) -> [f64; N] {
106        let mut res = [0.0; N];
107        let mut i = 0;
108        while i < M {
109            res = vec::add(res, vec::mul(mat[i], vec[i]));
110            i += 1;
111        }
112        res
113    }
114
115    /// Computes the determinant of a 3x3 matrix.
116    #[inline]
117    pub const fn det_3(m: [[f64; 3]; 3]) -> f64 {
118        vec::dot(m[0], vec::cross(m[1], m[2]))
119    }
120
121    /// Computes the determinant of a 2x2 matrix.
122    #[inline]
123    pub const fn det_2(m: [[f64; 2]; 2]) -> f64 {
124        m[0][0] * m[1][1] - m[0][1] * m[1][0]
125    }
126
127    /// Computes the adjoint of a 2x2 matrix.
128    #[inline]
129    pub const fn adjoint_2(m: [[f64; 2]; 2]) -> [[f64; 2]; 2] {
130        let [[a, b], [c, d]] = m;
131        [[d, -b], [-c, a]]
132    }
133}