matrix/
f64.rs

1use std::ops::Mul;
2
3use crate::{
4    matrix::Transpose,
5    scalar::{Lerp, MulAdd, Sqrt},
6    utils::EPSILON,
7    vector::Angle,
8    Dot, Matrix, Scalar, Vector, V,
9};
10
11impl Scalar for f64 {
12    type AbsOutput = f64;
13
14    fn abs(&self) -> Self::AbsOutput {
15        if *self < 0. {
16            -self
17        } else {
18            self.clone()
19        }
20    }
21
22    fn one() -> Self {
23        1.
24    }
25
26    fn inv(self) -> Self {
27        1. / self
28    }
29
30    type TanOutput = f64;
31    fn tan(self) -> Self::TanOutput {
32        f64::tan(self)
33    }
34
35    type CosOutput = f64;
36    fn cos(self) -> Self::CosOutput {
37        f64::sin(self)
38    }
39
40    type SinOutput = f64;
41    fn sin(self) -> Self::SinOutput {
42        f64::sin(self)
43    }
44
45    fn is_non_zero(&self) -> bool {
46        self.abs() > EPSILON
47    }
48}
49
50impl MulAdd<f64, f64> for f64 {
51    fn mul_add(self, a: &f64, b: &f64) -> Self {
52        self.mul_add(*a, *b)
53    }
54}
55
56impl Sqrt for f64 {
57    fn sqrt(self: Self) -> Self {
58        self.powf(0.5)
59    }
60}
61
62impl Lerp for f64 {
63    fn lerp(u: Self, v: Self, t: f32) -> Self {
64        match t {
65            0. => u,
66            1. => v,
67            p => u + (v - u) * p as f64,
68        }
69    }
70}
71
72impl Dot<f64> for [f64] {
73    fn dot(&self, v: &Vector<f64>) -> f64 {
74        assert_eq!(v.size(), self.len(), "vectors must be the same size");
75
76        self * v
77    }
78}
79
80impl Dot<f64> for Vector<f64> {
81    fn dot(&self, v: &Vector<f64>) -> f64 {
82        assert_eq!(v.size(), self.size(), "vectors must be the same size");
83
84        self * v
85    }
86}
87
88impl Mul<&Vector<f64>> for &Vector<f64> {
89    type Output = f64;
90
91    fn mul(self, rhs: &Vector<f64>) -> Self::Output {
92        self * &rhs._d
93    }
94}
95
96impl Mul<&Vec<f64>> for &Vector<f64> {
97    type Output = f64;
98
99    fn mul(self, rhs: &Vec<f64>) -> Self::Output {
100        self * &rhs[..]
101    }
102}
103
104impl Mul<&Vector<f64>> for &Vec<f64> {
105    type Output = f64;
106
107    fn mul(self, rhs: &Vector<f64>) -> Self::Output {
108        rhs * self
109    }
110}
111
112impl Mul<&[f64]> for &Vector<f64> {
113    type Output = f64;
114
115    fn mul(self, rhs: &[f64]) -> Self::Output {
116        let mut sum = f64::default();
117
118        for (a, &b) in self._d.iter().zip(rhs) {
119            sum = a.mul_add(b, sum);
120        }
121
122        sum
123    }
124}
125
126impl Mul<&Vector<f64>> for &[f64] {
127    type Output = f64;
128
129    fn mul(self, rhs: &Vector<f64>) -> Self::Output {
130        rhs * self
131    }
132}
133
134impl MulAdd<f64, Vector<f64>> for Vector<f64> {
135    fn mul_add(self, a: &f64, b: &Vector<f64>) -> Self {
136        assert!(self.size() == b.size(), "vectors must be the same size");
137
138        let mut vec = Vec::with_capacity(self.size());
139
140        for i in 0..self.size() {
141            vec.push(self[i].mul_add(*a, b[i]))
142        }
143
144        V!(vec)
145    }
146}
147
148impl Angle for Vector<f64> {
149    type Output = f64;
150    fn angle_cos(u: &Vector<f64>, v: &Vector<f64>) -> Self::Output {
151        u.dot(v) / (u.norm() * v.norm())
152    }
153}
154
155impl Transpose<f64> for Matrix<f64> {
156    fn transpose(&self) -> Matrix<f64> {
157        let mut vec = Vec::with_capacity(self.rows * self.cols);
158        for i in 0..self.cols {
159            for j in 0..self.rows {
160                vec.push(self[j][i]);
161            }
162        }
163
164        Matrix {
165            rows: self.cols,
166            cols: self.rows,
167            _d: vec,
168        }
169    }
170}
171
172impl Lerp for Vector<f64> {
173    fn lerp(u: Self, v: Self, t: f32) -> Self {
174        match t {
175            0. => u,
176            1. => v,
177            p => {
178                let mut vec = Vec::with_capacity(u.size());
179
180                for i in 0..u.size() {
181                    vec.push((v[i] - u[i]).mul_add(p as f64, u[i]))
182                }
183
184                V!(vec)
185            }
186        }
187    }
188}
189
190impl Lerp for Matrix<f64> {
191    fn lerp(u: Self, v: Self, t: f32) -> Self {
192        match t {
193            0. => u,
194            1. => v,
195            p => {
196                let mut vec = Vec::with_capacity(u._d.len());
197
198                for i in 0..u._d.len() {
199                    vec.push((v._d[i] - u._d[i]).mul_add(p as f64, u._d[i]))
200                }
201
202                Matrix {
203                    _d: vec,
204                    cols: u.cols,
205                    rows: u.rows,
206                }
207            }
208        }
209    }
210}