peroxide/traits/
pointer.rs1use crate::structure::ad::AD;
47use crate::structure::matrix::{Matrix, Shape};
48use crate::structure::sparse::SPMatrix;
49use crate::traits::{
50 fp::FPVector,
51 math::{LinearOp, Vector},
52 matrix::MatrixTrait,
53};
54use std::ops::{Add, Deref, Div, Mul, Sub};
55
56#[derive(Debug)]
60pub struct Redox<T: Vector> {
61 data: Box<T>,
62}
63
64impl<T: Vector> Deref for Redox<T> {
65 type Target = T;
66
67 fn deref(&self) -> &Self::Target {
68 &self.data
69 }
70}
71
72pub trait RedoxCommon {
73 type ToRedox;
74 fn from_vec(vec: Self::ToRedox) -> Self;
75 fn red(self) -> Self::ToRedox;
76}
77
78impl RedoxCommon for Redox<Vec<f64>> {
79 type ToRedox = Vec<f64>;
80 fn from_vec(vec: Self::ToRedox) -> Self {
81 Self {
82 data: Box::new(vec),
83 }
84 }
85
86 fn red(self) -> Self::ToRedox {
87 (*self).to_vec()
88 }
89}
90
91impl RedoxCommon for Redox<Vec<AD>> {
92 type ToRedox = Vec<AD>;
93 fn from_vec(vec: Self::ToRedox) -> Self {
94 Self {
95 data: Box::new(vec),
96 }
97 }
98
99 fn red(self) -> Self::ToRedox {
100 (*self).to_vec()
101 }
102}
103
104pub trait Oxide: Vector {
108 fn ox(self) -> Redox<Self>
109 where
110 Self: Sized;
111}
112
113impl<T: Vector> Add<Redox<T>> for Redox<T> {
117 type Output = Self;
118
119 fn add(self, rhs: Redox<T>) -> Self::Output {
120 Redox {
121 data: Box::new(self.add_vec(&rhs.data)),
122 }
123 }
124}
125
126impl<T: Vector + FPVector> Sub<Redox<T>> for Redox<T>
127where
128 <T as FPVector>::Scalar: Sub<Output = <T as FPVector>::Scalar>,
129{
130 type Output = Self;
131
132 fn sub(self, rhs: Redox<T>) -> Self::Output {
133 Redox {
134 data: Box::new(self.zip_with(|x, y| x - y, &rhs.data)),
135 }
136 }
137}
138
139impl<T: Vector + FPVector> Mul<Redox<T>> for Redox<T>
140where
141 <T as FPVector>::Scalar: Mul<Output = <T as FPVector>::Scalar>,
142{
143 type Output = Self;
144
145 fn mul(self, rhs: Redox<T>) -> Self::Output {
146 Redox {
147 data: Box::new(self.zip_with(|x, y| x * y, &rhs.data)),
148 }
149 }
150}
151
152impl<T: Vector + FPVector> Div<Redox<T>> for Redox<T>
153where
154 <T as FPVector>::Scalar: Div<Output = <T as FPVector>::Scalar>,
155{
156 type Output = Self;
157
158 fn div(self, rhs: Redox<T>) -> Self::Output {
159 Redox {
160 data: Box::new(self.zip_with(|x, y| x / y, &rhs.data)),
161 }
162 }
163}
164
165impl<T: Vector + FPVector> Add<f64> for Redox<T>
166where
167 <T as FPVector>::Scalar: Add<f64, Output = <T as FPVector>::Scalar>,
168{
169 type Output = Self;
170
171 fn add(self, rhs: f64) -> Self::Output {
172 Redox {
173 data: Box::new(self.fmap(|x| x + rhs)),
174 }
175 }
176}
177
178impl<T: Vector + FPVector> Sub<f64> for Redox<T>
179where
180 <T as FPVector>::Scalar: Sub<f64, Output = <T as FPVector>::Scalar>,
181{
182 type Output = Self;
183
184 fn sub(self, rhs: f64) -> Self::Output {
185 Redox {
186 data: Box::new(self.fmap(|x| x - rhs)),
187 }
188 }
189}
190
191impl<T: Vector + FPVector> Mul<f64> for Redox<T>
192where
193 <T as FPVector>::Scalar: Mul<f64, Output = <T as FPVector>::Scalar>,
194{
195 type Output = Self;
196
197 fn mul(self, rhs: f64) -> Self::Output {
198 Redox {
199 data: Box::new(self.fmap(|x| x * rhs)),
200 }
201 }
202}
203
204impl<T: Vector + FPVector> Div<f64> for Redox<T>
205where
206 <T as FPVector>::Scalar: Div<f64, Output = <T as FPVector>::Scalar>,
207{
208 type Output = Self;
209
210 fn div(self, rhs: f64) -> Self::Output {
211 Redox {
212 data: Box::new(self.fmap(|x| x / rhs)),
213 }
214 }
215}
216
217impl Mul<Redox<Vec<f64>>> for Matrix {
218 type Output = Redox<Vec<f64>>;
219
220 fn mul(self, rhs: Redox<Vec<f64>>) -> Self::Output {
221 Redox {
222 data: Box::new(self.apply(&*rhs)),
223 }
224 }
225}
226
227impl Mul<Redox<Vec<f64>>> for &Matrix {
228 type Output = Redox<Vec<f64>>;
229
230 fn mul(self, rhs: Redox<Vec<f64>>) -> Self::Output {
231 Redox {
232 data: Box::new(self.apply(&*rhs)),
233 }
234 }
235}
236
237impl Mul<Redox<Vec<f64>>> for SPMatrix {
239 type Output = Redox<Vec<f64>>;
240 fn mul(self, rhs: Redox<Vec<f64>>) -> Self::Output {
241 Redox {
242 data: Box::new(self.apply(&rhs.data)),
243 }
244 }
245}
246
247impl Mul<Redox<Vec<f64>>> for &SPMatrix {
248 type Output = Redox<Vec<f64>>;
249
250 fn mul(self, rhs: Redox<Vec<f64>>) -> Self::Output {
251 Redox {
252 data: Box::new(self.apply(&rhs.data)),
253 }
254 }
255}
256
257pub trait MatrixPtr {
262 unsafe fn row_ptr(&self, idx: usize) -> Vec<*const f64>;
263 unsafe fn col_ptr(&self, idx: usize) -> Vec<*const f64>;
264}
265
266impl MatrixPtr for Matrix {
267 unsafe fn row_ptr(&self, idx: usize) -> Vec<*const f64> {
285 assert!(idx < self.col, "Index out of range");
286 match self.shape {
287 Shape::Row => {
288 let mut v: Vec<*const f64> = vec![&0f64; self.col];
289 let start_idx = idx * self.col;
290 let p = self.ptr();
291 for (i, j) in (start_idx..start_idx + v.len()).enumerate() {
292 v[i] = p.add(j);
293 }
294 v
295 }
296 Shape::Col => {
297 let mut v: Vec<*const f64> = vec![&0f64; self.col];
298 let p = self.ptr();
299 for (i, elem) in v.iter_mut().enumerate() {
300 *elem = p.add(idx + i * self.row);
301 }
302 v
303 }
304 }
305 }
306
307 unsafe fn col_ptr(&self, idx: usize) -> Vec<*const f64> {
308 assert!(idx < self.col, "Index out of range");
309 match self.shape {
310 Shape::Col => {
311 let mut v: Vec<*const f64> = vec![&0f64; self.row];
312 let start_idx = idx * self.row;
313 let p = self.ptr();
314 for (i, j) in (start_idx..start_idx + v.len()).enumerate() {
315 v[i] = p.add(j);
316 }
317 v
318 }
319 Shape::Row => {
320 let mut v: Vec<*const f64> = vec![&0f64; self.row];
321 let p = self.ptr();
322 for (i, elem) in v.iter_mut().enumerate() {
323 *elem = p.add(idx + i * self.col);
324 }
325 v
326 }
327 }
328 }
329}