6
6
// option. This file may not be copied, modified, or distributed
7
7
// except according to those terms.
8
8
use std:: fmt;
9
+ use std:: slice:: Iter ;
9
10
use super :: {
10
11
ArrayBase ,
11
12
Data ,
@@ -15,72 +16,61 @@ use super::{
15
16
} ;
16
17
use crate :: dimension:: IntoDimension ;
17
18
18
- #[ derive( Debug ) ]
19
+ #[ derive( Debug , PartialEq ) ]
19
20
enum ArrayDisplayMode {
20
21
// Array is small enough to be printed without omitting any values.
21
22
Full ,
22
- // Omit central values of the nth axis. Since we print that axis horizontally, ellipses
23
- // on each row do something like a split of the array into 2 parts vertically.
24
- VSplit ,
25
- // Omit central values of the certain axis. Since we do it only once, ellipses on each row
26
- // do something like a split of the array into 2 parts horizontally.
27
- HSplit ( Ix ) ,
28
- // Both `VSplit` and `HSplit` hold.
29
- DoubleSplit ( Ix ) ,
23
+ // Omit central values of the nth axis.
24
+ OmitV ,
25
+ // Omit central values of certain axes (but not the last one).
26
+ // Vector is guaranteed to be non-empty.
27
+ OmitH ( Vec < Ix > ) ,
28
+ // Both `OmitV` and `OmitH` hold.
29
+ OmitBoth ( Vec < Ix > ) ,
30
30
}
31
31
32
- const PRINT_ELEMENTS_LIMIT : Ix = 5 ;
32
+ const PRINT_ELEMENTS_LIMIT : Ix = 2 ;
33
33
34
34
impl ArrayDisplayMode {
35
- fn from_shape ( shape : & [ Ix ] , limit : Ix ) -> ArrayDisplayMode
36
- {
35
+
36
+ fn from_shape ( shape : & [ Ix ] , limit : Ix ) -> ArrayDisplayMode {
37
37
let last_dim = match shape. len ( ) . checked_sub ( 1 ) {
38
38
Some ( v) => v,
39
39
None => {
40
40
return ArrayDisplayMode :: Full ;
41
41
}
42
42
} ;
43
43
44
+ let last_axis_ovf = shape[ last_dim] >= 2 * limit + 1 ;
44
45
let mut overflow_axes: Vec < Ix > = Vec :: with_capacity ( shape. len ( ) ) ;
45
46
for ( axis, axis_size) in shape. iter ( ) . enumerate ( ) . rev ( ) {
47
+ if axis == last_dim {
48
+ continue ;
49
+ }
46
50
if * axis_size >= 2 * limit + 1 {
47
51
overflow_axes. push ( axis) ;
48
52
}
49
53
}
50
54
51
- if overflow_axes. is_empty ( ) {
52
- return ArrayDisplayMode :: Full ;
53
- }
54
-
55
- let min_ovf_axis = * overflow_axes. iter ( ) . min ( ) . unwrap ( ) ;
56
- let max_ovf_axis = * overflow_axes. iter ( ) . max ( ) . unwrap ( ) ;
57
-
58
- if max_ovf_axis == last_dim {
59
- if min_ovf_axis != max_ovf_axis {
60
- ArrayDisplayMode :: DoubleSplit ( min_ovf_axis)
61
- } else {
62
- ArrayDisplayMode :: VSplit
63
- }
55
+ if !overflow_axes. is_empty ( ) && last_axis_ovf {
56
+ ArrayDisplayMode :: OmitBoth ( overflow_axes)
57
+ } else if !overflow_axes. is_empty ( ) {
58
+ ArrayDisplayMode :: OmitH ( overflow_axes)
59
+ } else if last_axis_ovf {
60
+ ArrayDisplayMode :: OmitV
64
61
} else {
65
- ArrayDisplayMode :: HSplit ( min_ovf_axis )
62
+ ArrayDisplayMode :: Full
66
63
}
67
64
}
68
65
69
- fn h_split_axis ( & self ) -> Option < Ix > {
66
+ fn h_axes_iter ( & self ) -> Option < Iter < Ix > > {
70
67
match self {
71
- ArrayDisplayMode :: DoubleSplit ( axis ) | ArrayDisplayMode :: HSplit ( axis ) => {
72
- Some ( * axis )
68
+ ArrayDisplayMode :: OmitH ( v ) | ArrayDisplayMode :: OmitBoth ( v ) => {
69
+ Some ( v . iter ( ) )
73
70
} ,
74
71
_ => None
75
72
}
76
73
}
77
-
78
- fn h_split_offset ( & self ) -> Option < Ix > {
79
- match self . h_split_axis ( ) {
80
- Some ( axis) => Some ( axis + 1usize ) ,
81
- None => None
82
- }
83
- }
84
74
}
85
75
86
76
fn format_array_v2 < A , S , D , F > ( view : & ArrayBase < S , D > ,
@@ -108,7 +98,7 @@ fn format_array_v2<A, S, D, F>(view: &ArrayBase<S, D>,
108
98
// Shows if ellipses for vertical split were printed.
109
99
let mut printed_ellipses_v = false ;
110
100
// Shows if ellipses for horizontal split were printed.
111
- let mut printed_ellipses_h = false ;
101
+ let mut printed_ellipses_h = vec ! [ false ; ndim ] ;
112
102
// Shows if the row was printed for the first time after horizontal split.
113
103
let mut no_rows_after_skip_yet = false ;
114
104
@@ -119,17 +109,20 @@ fn format_array_v2<A, S, D, F>(view: &ArrayBase<S, D>,
119
109
let take_n = if ndim == 0 { 1 } else { ndim - 1 } ;
120
110
let mut update_index = false ;
121
111
122
- let mut print_row = true ;
123
- match display_mode {
124
- ArrayDisplayMode :: HSplit ( axis ) | ArrayDisplayMode :: DoubleSplit ( axis) => {
125
- let sa_idx_max = view. shape ( ) . iter ( ) . skip ( axis) . next ( ) . unwrap ( ) ;
126
- let sa_idx_val = index. slice ( ) . iter ( ) . skip ( axis) . next ( ) . unwrap ( ) ;
127
- if sa_idx_val >= & limit && sa_idx_val < & ( sa_idx_max - & limit) {
128
- print_row = false ;
129
- no_rows_after_skip_yet = true ;
130
- }
112
+ let skip_row_for_axis = match display_mode . h_axes_iter ( ) {
113
+ Some ( iter ) => {
114
+ iter . filter ( | axis| {
115
+ let sa_idx_max = view. shape ( ) . iter ( ) . skip ( * * axis) . next ( ) . unwrap ( ) ;
116
+ let sa_idx_val = index. slice ( ) . iter ( ) . skip ( * * axis) . next ( ) . unwrap ( ) ;
117
+ sa_idx_val >= & limit && sa_idx_val < & ( sa_idx_max - & limit)
118
+ } )
119
+ . min ( )
120
+ . map ( |v| * v )
131
121
} ,
132
- _ => { }
122
+ None => None
123
+ } ;
124
+ if let Some ( _) = skip_row_for_axis {
125
+ no_rows_after_skip_yet = true ;
133
126
}
134
127
135
128
for ( i, ( a, b) ) in index. slice ( )
@@ -138,13 +131,9 @@ fn format_array_v2<A, S, D, F>(view: &ArrayBase<S, D>,
138
131
. zip ( last_index. slice ( ) . iter ( ) )
139
132
. enumerate ( ) {
140
133
if a != b {
141
- if let Some ( axis) = display_mode. h_split_axis ( ) {
142
- if i < axis {
143
- printed_ellipses_h = false ;
144
- }
145
- }
134
+ printed_ellipses_h. iter_mut ( ) . skip ( i + 1 ) . for_each ( |e| { * e = false ; } ) ;
146
135
147
- if print_row {
136
+ if skip_row_for_axis . is_none ( ) {
148
137
printed_ellipses_v = false ;
149
138
// New row.
150
139
// # of ['s needed
@@ -163,30 +152,31 @@ fn format_array_v2<A, S, D, F>(view: &ArrayBase<S, D>,
163
152
for _ in 0 ..n {
164
153
write ! ( f, "[" ) ?;
165
154
}
166
- } else if !printed_ellipses_h {
155
+ } else if !printed_ellipses_h[ skip_row_for_axis. unwrap ( ) ] {
156
+ let ax = skip_row_for_axis. unwrap ( ) ;
167
157
let n = ndim - i - 1 ;
168
158
for _ in 0 ..n {
169
159
write ! ( f, "]" ) ?;
170
160
}
171
161
write ! ( f, "," ) ?;
172
162
write ! ( f, "\n " ) ?;
173
- for _ in 0 ..display_mode . h_split_offset ( ) . unwrap ( ) {
163
+ for _ in 0 ..( ax + 1 ) {
174
164
write ! ( f, " " ) ?;
175
165
}
176
166
write ! ( f, "...,\n " ) ?;
177
- printed_ellipses_h = true ;
167
+ printed_ellipses_h[ ax ] = true ;
178
168
}
179
169
first = true ;
180
170
update_index = true ;
181
171
break ;
182
172
}
183
173
}
184
174
185
- if print_row {
175
+ if skip_row_for_axis . is_none ( ) {
186
176
let mut print_elt = true ;
187
177
let nth_idx_op = index. slice ( ) . iter ( ) . last ( ) ;
188
178
match display_mode {
189
- ArrayDisplayMode :: VSplit | ArrayDisplayMode :: DoubleSplit ( _) => {
179
+ ArrayDisplayMode :: OmitV | ArrayDisplayMode :: OmitBoth ( _) => {
190
180
let nth_idx_val = nth_idx_op. unwrap ( ) ;
191
181
if nth_idx_val >= & limit && nth_idx_val < & ( nth_idx_max. unwrap ( ) - & limit) {
192
182
print_elt = false ;
@@ -371,14 +361,15 @@ impl<'a, A: fmt::Binary, S, D: Dimension> fmt::Binary for ArrayBase<S, D>
371
361
mod format_tests {
372
362
use super :: * ;
373
363
364
+ #[ test]
374
365
fn test_array_display_mode_from_shape ( ) {
375
366
let mode = ArrayDisplayMode :: from_shape ( & [ 4 , 4 ] , 2 ) ;
376
367
assert_eq ! ( mode, ArrayDisplayMode :: Full ) ;
377
368
378
369
let mode = ArrayDisplayMode :: from_shape ( & [ 3 , 6 ] , 2 ) ;
379
- assert_eq ! ( mode, ArrayDisplayMode :: VSplit ) ;
370
+ assert_eq ! ( mode, ArrayDisplayMode :: OmitV ) ;
380
371
381
372
let mode = ArrayDisplayMode :: from_shape ( & [ 5 , 6 , 3 ] , 2 ) ;
382
- assert_eq ! ( mode, ArrayDisplayMode :: HSplit ( 1 ) ) ;
373
+ assert_eq ! ( mode, ArrayDisplayMode :: OmitH ( vec! [ 1 , 0 ] ) ) ;
383
374
}
384
375
}
0 commit comments