rill_core/math/vector/
ops.rs1use super::traits::*;
6use crate::Transcendental;
7
8pub fn add_slices<T: Transcendental, const N: usize, V>(a: &[T], b: &[T], out: &mut [T])
14where
15 V: Vector<T, N>,
16{
17 assert_eq!(a.len(), b.len());
18 assert_eq!(a.len(), out.len());
19
20 let chunks = a.len() / N;
21 let remainder = a.len() % N;
22
23 for i in 0..chunks {
24 let start = i * N;
25 let a_vec = V::load(&a[start..start + N]);
26 let b_vec = V::load(&b[start..start + N]);
27 let result = a_vec + b_vec;
28 result.store(&mut out[start..start + N]);
29 }
30
31 if remainder > 0 {
33 let start = chunks * N;
34 for i in 0..remainder {
35 out[start + i] = a[start + i] + b[start + i];
36 }
37 }
38}
39
40pub fn sub_slices<T: Transcendental, const N: usize, V>(a: &[T], b: &[T], out: &mut [T])
42where
43 V: Vector<T, N>,
44{
45 assert_eq!(a.len(), b.len());
46 assert_eq!(a.len(), out.len());
47
48 let chunks = a.len() / N;
49 let remainder = a.len() % N;
50
51 for i in 0..chunks {
52 let start = i * N;
53 let a_vec = V::load(&a[start..start + N]);
54 let b_vec = V::load(&b[start..start + N]);
55 let result = a_vec - b_vec;
56 result.store(&mut out[start..start + N]);
57 }
58
59 if remainder > 0 {
60 let start = chunks * N;
61 for i in 0..remainder {
62 out[start + i] = a[start + i] - b[start + i];
63 }
64 }
65}
66
67pub fn mul_slices<T: Transcendental, const N: usize, V>(a: &[T], b: &[T], out: &mut [T])
69where
70 V: Vector<T, N>,
71{
72 assert_eq!(a.len(), b.len());
73 assert_eq!(a.len(), out.len());
74
75 let chunks = a.len() / N;
76 let remainder = a.len() % N;
77
78 for i in 0..chunks {
79 let start = i * N;
80 let a_vec = V::load(&a[start..start + N]);
81 let b_vec = V::load(&b[start..start + N]);
82 let result = a_vec * b_vec;
83 result.store(&mut out[start..start + N]);
84 }
85
86 if remainder > 0 {
87 let start = chunks * N;
88 for i in 0..remainder {
89 out[start + i] = a[start + i] * b[start + i];
90 }
91 }
92}
93
94pub fn div_slices<T: Transcendental, const N: usize, V>(a: &[T], b: &[T], out: &mut [T])
96where
97 V: Vector<T, N>,
98{
99 assert_eq!(a.len(), b.len());
100 assert_eq!(a.len(), out.len());
101
102 let chunks = a.len() / N;
103 let remainder = a.len() % N;
104
105 for i in 0..chunks {
106 let start = i * N;
107 let a_vec = V::load(&a[start..start + N]);
108 let b_vec = V::load(&b[start..start + N]);
109 let result = a_vec / b_vec;
110 result.store(&mut out[start..start + N]);
111 }
112
113 if remainder > 0 {
114 let start = chunks * N;
115 for i in 0..remainder {
116 out[start + i] = a[start + i] / b[start + i];
117 }
118 }
119}
120
121pub fn mul_scalar_slice<T: Transcendental, const N: usize, V>(a: &[T], scalar: T, out: &mut [T])
123where
124 V: Vector<T, N>,
125{
126 assert_eq!(a.len(), out.len());
127
128 let scalar_vec = V::splat(scalar);
129 let chunks = a.len() / N;
130 let remainder = a.len() % N;
131
132 for i in 0..chunks {
133 let start = i * N;
134 let a_vec = V::load(&a[start..start + N]);
135 let result = a_vec * scalar_vec;
136 result.store(&mut out[start..start + N]);
137 }
138
139 if remainder > 0 {
140 let start = chunks * N;
141 for i in 0..remainder {
142 out[start + i] = a[start + i] * scalar;
143 }
144 }
145}
146
147pub fn add_scalar_slice<T: Transcendental, const N: usize, V>(a: &[T], scalar: T, out: &mut [T])
149where
150 V: Vector<T, N>,
151{
152 assert_eq!(a.len(), out.len());
153
154 let scalar_vec = V::splat(scalar);
155 let chunks = a.len() / N;
156 let remainder = a.len() % N;
157
158 for i in 0..chunks {
159 let start = i * N;
160 let a_vec = V::load(&a[start..start + N]);
161 let result = a_vec + scalar_vec;
162 result.store(&mut out[start..start + N]);
163 }
164
165 if remainder > 0 {
166 let start = chunks * N;
167 for i in 0..remainder {
168 out[start + i] = a[start + i] + scalar;
169 }
170 }
171}
172
173#[cfg(test)]
178mod tests {
179 use super::*;
180
181 }