@@ -97,6 +97,83 @@ def test_arraywriters():
97
97
assert_true (arr_back .flags .c_contiguous )
98
98
99
99
100
+ def test_scaling_needed ():
101
+ # Structured types return True if dtypes same, raise error otherwise
102
+ dt_def = [('f' , 'i4' )]
103
+ arr = np .ones (10 , dt_def )
104
+ for t in NUMERIC_TYPES :
105
+ assert_raises (WriterError , ArrayWriter , arr , t )
106
+ narr = np .ones (10 , t )
107
+ assert_raises (WriterError , ArrayWriter , narr , dt_def )
108
+ assert_false (ArrayWriter (arr ).scaling_needed ())
109
+ assert_false (ArrayWriter (arr , dt_def ).scaling_needed ())
110
+ # Any numeric type that can cast, needs no scaling
111
+ for in_t in NUMERIC_TYPES :
112
+ for out_t in NUMERIC_TYPES :
113
+ if np .can_cast (in_t , out_t ):
114
+ aw = ArrayWriter (np .ones (10 , in_t ), out_t )
115
+ assert_false (aw .scaling_needed ())
116
+ for in_t in NUMERIC_TYPES :
117
+ # Numeric types to complex never need scaling
118
+ arr = np .ones (10 , in_t )
119
+ for out_t in COMPLEX_TYPES :
120
+ assert_false (ArrayWriter (arr , out_t ).scaling_needed ())
121
+ # Attempts to scale from complex to anything else fails
122
+ for in_t in COMPLEX_TYPES :
123
+ for out_t in FLOAT_TYPES + IUINT_TYPES :
124
+ arr = np .ones (10 , in_t )
125
+ assert_raises (WriterError , ArrayWriter , arr , out_t )
126
+ # Scaling from anything but complex to floats is OK
127
+ for in_t in FLOAT_TYPES + IUINT_TYPES :
128
+ arr = np .ones (10 , in_t )
129
+ for out_t in FLOAT_TYPES :
130
+ assert_false (ArrayWriter (arr , out_t ).scaling_needed ())
131
+ # For any other output type, arrays with no data don't need scaling
132
+ for in_t in FLOAT_TYPES + IUINT_TYPES :
133
+ arr_0 = np .zeros (10 , in_t )
134
+ arr_e = []
135
+ for out_t in IUINT_TYPES :
136
+ assert_false (ArrayWriter (arr_0 , out_t ).scaling_needed ())
137
+ assert_false (ArrayWriter (arr_e , out_t ).scaling_needed ())
138
+ # Going to (u)ints, non-finite arrays don't need scaling
139
+ for in_t in FLOAT_TYPES :
140
+ arr_nan = np .zeros (10 , in_t ) + np .nan
141
+ arr_inf = np .zeros (10 , in_t ) + np .inf
142
+ arr_minf = np .zeros (10 , in_t ) - np .inf
143
+ arr_mix = np .array ([np .nan , np .inf , - np .inf ], dtype = in_t )
144
+ for out_t in IUINT_TYPES :
145
+ for arr in (arr_nan , arr_inf , arr_minf , arr_mix ):
146
+ assert_false (ArrayWriter (arr , out_t ).scaling_needed ())
147
+ # Floats as input always need scaling
148
+ for in_t in FLOAT_TYPES :
149
+ arr = np .ones (10 , in_t )
150
+ for out_t in IUINT_TYPES :
151
+ # We need an arraywriter that will tolerate construction when
152
+ # scaling is needed
153
+ assert_true (SlopeArrayWriter (arr , out_t ).scaling_needed ())
154
+ # in-range (u)ints don't need scaling
155
+ for in_t in IUINT_TYPES :
156
+ in_info = np .iinfo (in_t )
157
+ in_min , in_max = in_info .min , in_info .max
158
+ for out_t in IUINT_TYPES :
159
+ out_info = np .iinfo (out_t )
160
+ out_min , out_max = out_info .min , out_info .max
161
+ if in_min >= out_min and in_max <= out_max :
162
+ arr = np .array ([in_min , in_max ], in_t )
163
+ assert_true (np .can_cast (arr .dtype , out_t ))
164
+ # We've already tested this with can_cast above, but...
165
+ assert_false (ArrayWriter (arr , out_t ).scaling_needed ())
166
+ continue
167
+ # The output data type does not include the input data range
168
+ max_min = max (in_min , out_min ) # 0 for input or output uint
169
+ min_max = min (in_max , out_max )
170
+ arr = np .array ([max_min , min_max ], in_t )
171
+ assert_false (ArrayWriter (arr , out_t ).scaling_needed ())
172
+ assert_true (SlopeInterArrayWriter (arr + 1 , out_t ).scaling_needed ())
173
+ if in_t in INT_TYPES :
174
+ assert_true (SlopeInterArrayWriter (arr - 1 , out_t ).scaling_needed ())
175
+
176
+
100
177
def test_special_rt ():
101
178
# Test that zeros; none finite - round trip to zeros
102
179
for arr in (np .array ([np .inf , np .nan , - np .inf ]),
0 commit comments