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