Skip to main content

sidereon_core/astro/math/
mat3.rs

1//! 3x3 matrix operations with exact floating-point rounding control.
2//!
3//! These routines are ported from the C++ inline_rxr, inline_tr, and
4//! inline_mxmxm functions which were compiled under `fp-contract=off`
5//! to match Python/Skyfield arithmetic.  Rust's default arithmetic
6//! operators do not fuse multiply-adds, so no special annotation is
7//! needed -- just avoid `f64::mul_add`.
8
9/// A row-major 3x3 matrix.
10pub type Mat3 = [[f64; 3]; 3];
11
12/// Matrix-vector product: `result = m * v`.
13pub fn mul_vec3(m: &Mat3, v: [f64; 3]) -> [f64; 3] {
14    [
15        m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2],
16        m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2],
17        m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2],
18    ]
19}
20
21/// Standard matrix multiply: `result = a * b`.
22pub fn inline_rxr(a: &Mat3, b: &Mat3) -> Mat3 {
23    let mut w = [[0.0_f64; 3]; 3];
24    for i in 0..3 {
25        for j in 0..3 {
26            let mut s = 0.0_f64;
27            for k in 0..3 {
28                s += a[i][k] * b[k][j];
29            }
30            w[i][j] = s;
31        }
32    }
33    w
34}
35
36/// Matrix transpose: `result = r^T`.
37pub fn inline_tr(r: &Mat3) -> Mat3 {
38    let mut rt = [[0.0_f64; 3]; 3];
39    for i in 0..3 {
40        for j in 0..3 {
41            rt[i][j] = r[j][i];
42        }
43    }
44    rt
45}
46
47/// Triple matrix product with Kahan-compensated summation.
48///
49/// Computes `result = A * B * C` without materialising the intermediate
50/// A*B matrix.  Each output element accumulates all 9 terms
51/// (matching numpy `einsum('ij,jk,kl->il')`) using Kahan summation to
52/// reduce floating-point drift.
53pub fn inline_mxmxm(a: &Mat3, b: &Mat3, c: &Mat3) -> Mat3 {
54    let mut w = [[0.0_f64; 3]; 3];
55    for i in 0..3 {
56        for l in 0..3 {
57            let mut s = 0.0_f64;
58            let mut comp = 0.0_f64; // Kahan compensation
59            for j in 0..3 {
60                for k in 0..3 {
61                    let term = a[i][j] * b[j][k] * c[k][l];
62                    let y = term - comp;
63                    let t = s + y;
64                    comp = (t - s) - y;
65                    s = t;
66                }
67            }
68            w[i][l] = s;
69        }
70    }
71    w
72}