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}