@@ -3,6 +3,7 @@ use crate::imp_prelude::*;
33use crate :: IntoDimension ;
44use crate :: Layout ;
55use crate :: NdProducer ;
6+ use crate :: Slice ;
67
78/// Window producer and iterable
89///
@@ -24,16 +25,19 @@ impl<'a, A, D: Dimension> Windows<'a, A, D> {
2425
2526 let mut unit_stride = D :: zeros ( ndim) ;
2627 unit_stride. slice_mut ( ) . fill ( 1 ) ;
27-
28+
2829 Windows :: new_with_stride ( a, window, unit_stride)
2930 }
3031
31- pub ( crate ) fn new_with_stride < E > ( a : ArrayView < ' a , A , D > , window_size : E , strides : E ) -> Self
32+ pub ( crate ) fn new_with_stride < E > ( a : ArrayView < ' a , A , D > , window_size : E , axis_strides : E ) -> Self
3233 where
3334 E : IntoDimension < Dim = D > ,
3435 {
3536 let window = window_size. into_dimension ( ) ;
36- let strides_d = strides. into_dimension ( ) ;
37+
38+ let strides = axis_strides. into_dimension ( ) ;
39+ let window_strides = a. strides . clone ( ) ;
40+
3741 ndassert ! (
3842 a. ndim( ) == window. ndim( ) ,
3943 concat!(
@@ -44,45 +48,35 @@ impl<'a, A, D: Dimension> Windows<'a, A, D> {
4448 a. ndim( ) ,
4549 a. shape( )
4650 ) ;
51+
4752 ndassert ! (
48- a. ndim( ) == strides_d . ndim( ) ,
53+ a. ndim( ) == strides . ndim( ) ,
4954 concat!(
5055 "Stride dimension {} does not match array dimension {} " ,
5156 "(with array of shape {:?})"
5257 ) ,
53- strides_d . ndim( ) ,
58+ strides . ndim( ) ,
5459 a. ndim( ) ,
5560 a. shape( )
5661 ) ;
57- let mut size = a. dim ;
58- for ( ( sz, & ws) , & stride) in size
59- . slice_mut ( )
60- . iter_mut ( )
61- . zip ( window. slice ( ) )
62- . zip ( strides_d. slice ( ) )
63- {
64- assert_ne ! ( ws, 0 , "window-size must not be zero!" ) ;
65- assert_ne ! ( stride, 0 , "stride cannot have a dimension as zero!" ) ;
66- // cannot use std::cmp::max(0, ..) since arithmetic underflow panics
67- * sz = if * sz < ws {
68- 0
69- } else {
70- ( ( * sz - ( ws - 1 ) - 1 ) / stride) + 1
71- } ;
72- }
73- let window_strides = a. strides . clone ( ) ;
7462
75- let mut array_strides = a. strides . clone ( ) ;
76- for ( arr_stride, ix_stride) in array_strides. slice_mut ( ) . iter_mut ( ) . zip ( strides_d. slice ( ) ) {
77- * arr_stride *= ix_stride;
78- }
63+ let mut base = a;
64+ base. slice_each_axis_inplace ( |ax_desc| {
65+ let len = ax_desc. len ;
66+ let wsz = window[ ax_desc. axis . index ( ) ] ;
67+ let stride = strides[ ax_desc. axis . index ( ) ] ;
7968
80- unsafe {
81- Windows {
82- base : ArrayView :: new ( a. ptr , size, array_strides) ,
83- window,
84- strides : window_strides,
69+ if len < wsz {
70+ Slice :: new ( 0 , Some ( 0 ) , 1 )
71+ } else {
72+ Slice :: new ( 0 , Some ( ( len - wsz + 1 ) as isize ) , stride as isize )
8573 }
74+ } ) ;
75+
76+ Windows {
77+ base,
78+ window,
79+ strides : window_strides,
8680 }
8781 }
8882}
0 commit comments