1pub mod as_strided;
18pub mod broadcast;
19pub mod overlap_check;
20pub mod sliding_window;
21
22pub use as_strided::{as_strided, as_strided_unchecked};
25pub use broadcast::{broadcast_arrays, broadcast_shapes, broadcast_to};
26pub use sliding_window::sliding_window_view;
27
28#[cfg(test)]
29mod integration_tests {
30 use ferray_core::Array;
33 use ferray_core::dimension::{Ix1, Ix2};
34
35 use crate::{
36 as_strided, as_strided_unchecked, broadcast_arrays, broadcast_shapes, broadcast_to,
37 sliding_window_view,
38 };
39
40 #[test]
43 fn ac1_sliding_window_view() {
44 let a = Array::<i32, Ix1>::from_vec(Ix1::new([5]), vec![1, 2, 3, 4, 5]).unwrap();
45 let v = sliding_window_view(&a, &[3]).unwrap();
46 assert_eq!(v.shape(), &[3, 3]);
47 let data: Vec<i32> = v.iter().copied().collect();
48 assert_eq!(data, vec![1, 2, 3, 2, 3, 4, 3, 4, 5]);
49 }
50
51 #[test]
54 fn ac2_broadcast_to_no_alloc() {
55 let a = Array::<f64, Ix1>::ones(Ix1::new([3])).unwrap();
56 let v = broadcast_to(&a, &[4, 3]).unwrap();
57 assert_eq!(v.shape(), &[4, 3]);
58 assert_eq!(v.size(), 12);
59 assert_eq!(v.as_ptr(), a.as_ptr());
61 let data: Vec<f64> = v.iter().copied().collect();
63 assert_eq!(data, vec![1.0; 12]);
64 }
65
66 #[test]
68 fn ac3_broadcast_shapes() {
69 let result = broadcast_shapes(&[&[3, 1][..], &[1, 4][..]]).unwrap();
70 assert_eq!(result, vec![3, 4]);
71 }
72
73 #[test]
76 fn ac4_as_strided_safe_vs_overlapping() {
77 let a =
78 Array::<f64, Ix1>::from_vec(Ix1::new([6]), vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]).unwrap();
79
80 let v = as_strided(&a, &[2, 3], &[3, 1]).unwrap();
82 assert_eq!(v.shape(), &[2, 3]);
83 let data: Vec<f64> = v.iter().copied().collect();
84 assert_eq!(data, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
85
86 let a5 = Array::<f64, Ix1>::from_vec(Ix1::new([5]), vec![1.0, 2.0, 3.0, 4.0, 5.0]).unwrap();
88 let err = as_strided(&a5, &[3, 3], &[1, 1]);
89 assert!(err.is_err());
90 }
91
92 #[test]
96 fn ac5_as_strided_unchecked_requires_unsafe() {
97 let a = Array::<i32, Ix1>::from_vec(Ix1::new([5]), vec![1, 2, 3, 4, 5]).unwrap();
98 let v = unsafe { as_strided_unchecked(&a, &[3, 3], &[1, 1]).unwrap() };
101 assert_eq!(v.shape(), &[3, 3]);
102 let data: Vec<i32> = v.iter().copied().collect();
103 assert_eq!(data, vec![1, 2, 3, 2, 3, 4, 3, 4, 5]);
104 }
105
106 #[test]
111 fn broadcast_arrays_integration() {
112 let a = Array::<f64, Ix2>::ones(Ix2::new([4, 1])).unwrap();
113 let b = Array::<f64, Ix2>::ones(Ix2::new([1, 3])).unwrap();
114 let arrays = [a, b];
115 let views = broadcast_arrays(&arrays).unwrap();
116 assert_eq!(views.len(), 2);
117 assert_eq!(views[0].shape(), &[4, 3]);
118 assert_eq!(views[1].shape(), &[4, 3]);
119 }
120
121 #[test]
123 fn sliding_window_is_zero_copy() {
124 let a = Array::<f64, Ix1>::from_vec(Ix1::new([10]), (0..10).map(|i| i as f64).collect())
125 .unwrap();
126 let v = sliding_window_view(&a, &[4]).unwrap();
127 assert_eq!(v.shape(), &[7, 4]);
129 assert_eq!(v.as_ptr(), a.as_ptr());
131 }
132
133 #[test]
135 fn as_strided_skip_elements() {
136 let a = Array::<i32, Ix1>::from_vec(Ix1::new([10]), vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
137 .unwrap();
138 let v = as_strided(&a, &[3], &[3]).unwrap();
141 let data: Vec<i32> = v.iter().copied().collect();
142 assert_eq!(data, vec![0, 3, 6]);
143 }
144}