Skip to main content

bixverse_core/utils/
traits.rs

1//! Various traits in bixverse
2
3use faer::traits::{ComplexField, RealField};
4use num_traits::float::TotalOrder;
5use num_traits::{Float, FromPrimitive, ToPrimitive};
6
7use std::fmt::Display;
8
9use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
10
11///////////////////
12// Numeric trait //
13///////////////////
14
15/// Trait for floating-point types used in Bixverse. Has all of the common
16/// floating-point operations and traits.
17pub trait BixverseFloat:
18    Float
19    + FromPrimitive
20    + ToPrimitive
21    + ComplexField
22    + Copy
23    + 'static
24    + RealField
25    + AddAssign
26    + DivAssign
27    + SubAssign
28    + MulAssign
29    + Div
30    + Display
31    + Sub
32    + Mul
33    + Div
34    + TotalOrder
35    + Clone
36{
37}
38
39impl<T> BixverseFloat for T where
40    T: Float
41        + FromPrimitive
42        + ToPrimitive
43        + ComplexField
44        + Copy
45        + 'static
46        + RealField
47        + AddAssign
48        + DivAssign
49        + SubAssign
50        + MulAssign
51        + Div
52        + Display
53        + Sub
54        + Mul
55        + Div
56        + TotalOrder
57        + Clone
58{
59}
60
61/// More general numeric trait that includes also integers
62pub trait BixverseNumeric:
63    Clone
64    + Default
65    + Copy
66    + Sync
67    + Send
68    + Add<Output = Self>
69    + Mul<Output = Self>
70    + Sub<Output = Self>
71    + AddAssign
72    + PartialEq
73    + Sub
74    + DivAssign
75{
76}
77
78impl<T> BixverseNumeric for T where
79    T: Clone
80        + Default
81        + Copy
82        + Sync
83        + Send
84        + Add<Output = Self>
85        + Mul<Output = Self>
86        + Sub<Output = Self>
87        + AddAssign
88        + PartialEq
89        + Sub
90        + DivAssign
91{
92}
93
94///////////////////
95// Index casting //
96///////////////////
97
98/// Casts index vectors between `usize` and `u32` (memory-width conversion).
99pub trait VecIndexCast<U> {
100    /// Casts the index vector element-wise to the target integer type.
101    fn index_cast(self) -> Vec<U>;
102}
103
104impl VecIndexCast<u32> for Vec<usize> {
105    fn index_cast(self) -> Vec<u32> {
106        self.into_iter().map(|x| x as u32).collect()
107    }
108}
109
110impl VecIndexCast<u32> for &[usize] {
111    fn index_cast(self) -> Vec<u32> {
112        self.iter().map(|&x| x as u32).collect()
113    }
114}
115
116impl VecIndexCast<usize> for Vec<u32> {
117    fn index_cast(self) -> Vec<usize> {
118        self.into_iter().map(|x| x as usize).collect()
119    }
120}
121
122impl VecIndexCast<usize> for &[u32] {
123    fn index_cast(self) -> Vec<usize> {
124        self.iter().map(|&x| x as usize).collect()
125    }
126}
127
128////////////////////
129// R vector stuff //
130////////////////////
131
132/// Converts vectors between integer types for R compatibility.
133pub trait VecConvert<U> {
134    /// Converts usize vectors into i32 for fast R transfer
135    fn r_int_convert(self) -> Vec<U>;
136
137    /// Converts vectors from usize to i32, while adding one (shifting from
138    /// 0-indexed data to 1-indexed data) or vice versa from i32 to usize while
139    /// subtracting 1 (shifting from 1-indexed data to 0-indexed data).
140    fn r_int_convert_shift(self) -> Vec<U>;
141}
142
143impl VecConvert<i32> for Vec<usize> {
144    fn r_int_convert(self) -> Vec<i32> {
145        self.into_iter().map(|x| x as i32).collect()
146    }
147    fn r_int_convert_shift(self) -> Vec<i32> {
148        self.into_iter().map(|x| (x as i32) + 1).collect()
149    }
150}
151
152impl VecConvert<i32> for &[&usize] {
153    fn r_int_convert(self) -> Vec<i32> {
154        self.iter().map(|&&x| x as i32).collect()
155    }
156    fn r_int_convert_shift(self) -> Vec<i32> {
157        self.iter().map(|&&x| (x as i32) + 1).collect()
158    }
159}
160
161impl VecConvert<i32> for Vec<u32> {
162    fn r_int_convert(self) -> Vec<i32> {
163        self.into_iter().map(|x| x as i32).collect()
164    }
165    fn r_int_convert_shift(self) -> Vec<i32> {
166        self.into_iter().map(|x| (x as i32) + 1).collect()
167    }
168}
169
170impl VecConvert<usize> for Vec<i32> {
171    fn r_int_convert(self) -> Vec<usize> {
172        self.into_iter().map(|x| x as usize).collect()
173    }
174    fn r_int_convert_shift(self) -> Vec<usize> {
175        self.into_iter().map(|x| (x - 1) as usize).collect()
176    }
177}
178
179impl VecConvert<i32> for &[usize] {
180    fn r_int_convert(self) -> Vec<i32> {
181        self.iter().map(|&x| x as i32).collect()
182    }
183    fn r_int_convert_shift(self) -> Vec<i32> {
184        self.iter().map(|&x| (x as i32) + 1).collect()
185    }
186}
187
188impl VecConvert<usize> for &[i32] {
189    fn r_int_convert(self) -> Vec<usize> {
190        self.iter().map(|&x| x as usize).collect()
191    }
192    fn r_int_convert_shift(self) -> Vec<usize> {
193        self.iter().map(|&x| (x - 1) as usize).collect()
194    }
195}
196
197/// Converts vectors between floating-point types for R compatibility.
198pub trait VecFloatConvert<U> {
199    /// Converts the R double vectors from/to f64 to f32
200    fn r_float_convert(self) -> Vec<U>;
201}
202
203impl VecFloatConvert<f32> for Vec<f64> {
204    fn r_float_convert(self) -> Vec<f32> {
205        self.into_iter().map(|x| x as f32).collect()
206    }
207}
208
209impl VecFloatConvert<f64> for Vec<f32> {
210    fn r_float_convert(self) -> Vec<f64> {
211        self.into_iter().map(|x| x as f64).collect()
212    }
213}
214
215impl VecFloatConvert<f64> for &[f32] {
216    fn r_float_convert(self) -> Vec<f64> {
217        self.iter().map(|x| *x as f64).collect()
218    }
219}
220
221impl VecFloatConvert<f32> for &[f64] {
222    fn r_float_convert(self) -> Vec<f32> {
223        self.iter().map(|&x| x as f32).collect()
224    }
225}