Skip to content

Commit 8046888

Browse files
committed
simplified array contraction algorithm
1 parent 0b20b30 commit 8046888

File tree

7 files changed

+77
-69
lines changed

7 files changed

+77
-69
lines changed

code/ndarray.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,6 @@ bool ndarray_is_dense(ndarray_obj_t *ndarray) {
598598

599599
ndarray_obj_t *ndarray_new_ndarray(uint8_t ndim, size_t *shape, int32_t *strides, uint8_t dtype) {
600600
// Creates the base ndarray with shape, and initialises the values to straight 0s
601-
// the function should work in the general n-dimensional case
602601
ndarray_obj_t *ndarray = m_new_obj(ndarray_obj_t);
603602
ndarray->base.type = &ulab_ndarray_type;
604603
ndarray->dtype = dtype == NDARRAY_BOOL ? NDARRAY_UINT8 : dtype;
@@ -618,10 +617,12 @@ ndarray_obj_t *ndarray_new_ndarray(uint8_t ndim, size_t *shape, int32_t *strides
618617
ndarray->len *= shape[i-1];
619618
}
620619

621-
uint8_t *array = m_new(byte, ndarray->itemsize * ndarray->len);
620+
// if the length is 0, still allocate a single item, so that contractions can be handled
621+
size_t len = ndarray->itemsize * MAX(1, ndarray->len);
622+
uint8_t *array = m_new(byte, len);
622623
// this should set all elements to 0, irrespective of the of the dtype (all bits are zero)
623624
// we could, perhaps, leave this step out, and initialise the array only, when needed
624-
memset(array, 0, ndarray->len * ndarray->itemsize);
625+
memset(array, 0, len);
625626
ndarray->array = array;
626627
return ndarray;
627628
}

code/numpy/linalg/linalg.c

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -385,14 +385,8 @@ static mp_obj_t linalg_norm(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
385385
// always get a float, so that we don't have to resolve the dtype later
386386
mp_float_t (*func)(void *) = ndarray_get_float_function(ndarray->dtype);
387387
shape_strides _shape_strides = tools_reduce_axes(ndarray, axis);
388-
mp_float_t *rarray = NULL;
389-
ndarray_obj_t *results = NULL;
390-
if((axis != mp_const_none) && (ndarray->ndim > 1)) {
391-
results = ndarray_new_dense_ndarray(MAX(1, ndarray->ndim-1), _shape_strides.shape, NDARRAY_FLOAT);
392-
rarray = results->array;
393-
} else {
394-
rarray = m_new(mp_float_t, 1);
395-
}
388+
ndarray_obj_t *results = ndarray_new_dense_ndarray(_shape_strides.ndim, _shape_strides.shape, NDARRAY_FLOAT);
389+
mp_float_t *rarray = (mp_float_t *)results->array;
396390

397391
#if ULAB_MAX_DIMS > 3
398392
size_t i = 0;
@@ -418,28 +412,26 @@ static mp_obj_t linalg_norm(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
418412
l++;
419413
} while(l < _shape_strides.shape[0]);
420414
*rarray = MICROPY_FLOAT_C_FUN(sqrt)(dot * (count - 1));
421-
if(results != NULL) {
422-
rarray++;
423-
}
424415
#if ULAB_MAX_DIMS > 1
416+
rarray += _shape_strides.increment;
425417
array -= _shape_strides.strides[0] * _shape_strides.shape[0];
426418
array += _shape_strides.strides[ULAB_MAX_DIMS - 1];
427419
k++;
428420
} while(k < _shape_strides.shape[ULAB_MAX_DIMS - 1]);
429421
#endif
430422
#if ULAB_MAX_DIMS > 2
431-
array -= _shape_strides.strides[ULAB_MAX_DIMS - 1] * _shape_strides.shape[ULAB_MAX_DIMS-1];
423+
array -= _shape_strides.strides[ULAB_MAX_DIMS - 1] * _shape_strides.shape[ULAB_MAX_DIMS - 1];
432424
array += _shape_strides.strides[ULAB_MAX_DIMS - 2];
433425
j++;
434426
} while(j < _shape_strides.shape[ULAB_MAX_DIMS - 2]);
435427
#endif
436428
#if ULAB_MAX_DIMS > 3
437-
array -= _shape_strides.strides[ULAB_MAX_DIMS - 2] * _shape_strides.shape[ULAB_MAX_DIMS-2];
429+
array -= _shape_strides.strides[ULAB_MAX_DIMS - 2] * _shape_strides.shape[ULAB_MAX_DIMS - 2];
438430
array += _shape_strides.strides[ULAB_MAX_DIMS - 3];
439431
i++;
440432
} while(i < _shape_strides.shape[ULAB_MAX_DIMS - 3]);
441433
#endif
442-
if(results == NULL) {
434+
if(results->ndim == 0) {
443435
return mp_obj_new_float(*rarray);
444436
}
445437
return results;

code/numpy/numerical/numerical.c

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ static mp_obj_t numerical_sum_mean_std_iterable(mp_obj_t oin, uint8_t optype, si
190190

191191
static mp_obj_t numerical_sum_mean_std_ndarray(ndarray_obj_t *ndarray, mp_obj_t axis, uint8_t optype, size_t ddof) {
192192
uint8_t *array = (uint8_t *)ndarray->array;
193+
shape_strides _shape_strides = tools_reduce_axes(ndarray, axis);
193194

194195
if(axis == mp_const_none) {
195196
// work with the flattened array
@@ -223,26 +224,26 @@ static mp_obj_t numerical_sum_mean_std_ndarray(ndarray_obj_t *ndarray, mp_obj_t
223224
S = s;
224225
}
225226
M = m;
226-
array += ndarray->strides[ULAB_MAX_DIMS - 1];
227+
array += _shape_strides.strides[ULAB_MAX_DIMS - 1];
227228
l++;
228-
} while(l < ndarray->shape[ULAB_MAX_DIMS - 1]);
229+
} while(l < _shape_strides.shape[ULAB_MAX_DIMS - 1]);
229230
#if ULAB_MAX_DIMS > 1
230-
array -= ndarray->strides[ULAB_MAX_DIMS - 1] * ndarray->shape[ULAB_MAX_DIMS-1];
231-
array += ndarray->strides[ULAB_MAX_DIMS - 2];
231+
array -= _shape_strides.strides[ULAB_MAX_DIMS - 1] * _shape_strides.shape[ULAB_MAX_DIMS - 1];
232+
array += _shape_strides.strides[ULAB_MAX_DIMS - 2];
232233
k++;
233-
} while(k < ndarray->shape[ULAB_MAX_DIMS - 2]);
234+
} while(k < _shape_strides.shape[ULAB_MAX_DIMS - 2]);
234235
#endif
235236
#if ULAB_MAX_DIMS > 2
236-
array -= ndarray->strides[ULAB_MAX_DIMS - 2] * ndarray->shape[ULAB_MAX_DIMS-2];
237-
array += ndarray->strides[ULAB_MAX_DIMS - 3];
237+
array -= _shape_strides.strides[ULAB_MAX_DIMS - 2] * _shape_strides.shape[ULAB_MAX_DIMS - 2];
238+
array += _shape_strides.strides[ULAB_MAX_DIMS - 3];
238239
j++;
239-
} while(j < ndarray->shape[ULAB_MAX_DIMS - 3]);
240+
} while(j < _shape_strides.shape[ULAB_MAX_DIMS - 3]);
240241
#endif
241242
#if ULAB_MAX_DIMS > 3
242-
array -= ndarray->strides[ULAB_MAX_DIMS - 3] * ndarray->shape[ULAB_MAX_DIMS-3];
243-
array += ndarray->strides[ULAB_MAX_DIMS - 4];
243+
array -= _shape_strides.strides[ULAB_MAX_DIMS - 3] * _shape_strides.shape[ULAB_MAX_DIMS - 3];
244+
array += _shape_strides.strides[ULAB_MAX_DIMS - 4];
244245
i++;
245-
} while(i < ndarray->shape[ULAB_MAX_DIMS - 4]);
246+
} while(i < _shape_strides.shape[ULAB_MAX_DIMS - 4]);
246247
#endif
247248
if(optype == NUMERICAL_SUM) {
248249
// numpy returns an integer for integer input types
@@ -258,18 +259,12 @@ static mp_obj_t numerical_sum_mean_std_ndarray(ndarray_obj_t *ndarray, mp_obj_t
258259
return mp_obj_new_float(MICROPY_FLOAT_C_FUN(sqrt)(S / (ndarray->len - ddof)));
259260
}
260261
} else {
261-
shape_strides _shape_strides = tools_reduce_axes(ndarray, axis);
262-
// if(ndarray->ndim == 1) {
263-
// // if we have the single dimension, axis = 0 is equivalent to axis = None
264-
// // the call to tools_reduce_axes() has made sure that axis = 0
265-
// return numerical_sum_mean_std_ndarray(ndarray, mp_const_none, optype, ddof);
266-
// }
267262
ndarray_obj_t *results = NULL;
268263
uint8_t *rarray = NULL;
269-
264+
mp_float_t *farray = NULL;
270265
if(optype == NUMERICAL_SUM) {
271-
results = ndarray_new_dense_ndarray(MAX(1, ndarray->ndim-1), _shape_strides.shape, ndarray->dtype);
272-
rarray = (uint8_t *)results->array;
266+
results = ndarray_new_dense_ndarray(_shape_strides.ndim, _shape_strides.shape, ndarray->dtype);
267+
rarray = (uint8_t *)results->array;
273268
// TODO: numpy promotes the output to the highest integer type
274269
if(ndarray->dtype == NDARRAY_UINT8) {
275270
RUN_SUM(uint8_t, array, results, rarray, _shape_strides);
@@ -282,37 +277,37 @@ static mp_obj_t numerical_sum_mean_std_ndarray(ndarray_obj_t *ndarray, mp_obj_t
282277
} else {
283278
// for floats, the sum might be inaccurate with the naive summation
284279
// call mean, and multiply with the number of samples
285-
mp_float_t *r = (mp_float_t *)results->array;
286-
RUN_MEAN_STD(mp_float_t, array, r, _shape_strides, 0.0, 0);
280+
farray = (mp_float_t *)results->array;
281+
RUN_MEAN_STD(mp_float_t, array, farray, _shape_strides, 0.0, 0);
287282
mp_float_t norm = (mp_float_t)_shape_strides.shape[0];
288283
// re-wind the array here
289-
r = (mp_float_t *)results->array;
284+
farray = (mp_float_t *)results->array;
290285
for(size_t i=0; i < results->len; i++) {
291-
*r++ *= norm;
286+
*farray++ *= norm;
292287
}
293288
}
294289
} else {
295290
bool isStd = optype == NUMERICAL_STD ? 1 : 0;
296-
results = ndarray_new_dense_ndarray(MAX(1, ndarray->ndim-1), _shape_strides.shape, NDARRAY_FLOAT);
291+
results = ndarray_new_dense_ndarray(_shape_strides.ndim, _shape_strides.shape, NDARRAY_FLOAT);
292+
farray = (mp_float_t *)results->array;
297293
// we can return the 0 array here, if the degrees of freedom is larger than the length of the axis
298294
if((optype == NUMERICAL_STD) && (_shape_strides.shape[0] <= ddof)) {
299295
return MP_OBJ_FROM_PTR(results);
300296
}
301297
mp_float_t div = optype == NUMERICAL_STD ? (mp_float_t)(_shape_strides.shape[0] - ddof) : 0.0;
302-
mp_float_t *rarray = (mp_float_t *)results->array;
303298
if(ndarray->dtype == NDARRAY_UINT8) {
304-
RUN_MEAN_STD(uint8_t, array, rarray, _shape_strides, div, isStd);
299+
RUN_MEAN_STD(uint8_t, array, farray, _shape_strides, div, isStd);
305300
} else if(ndarray->dtype == NDARRAY_INT8) {
306-
RUN_MEAN_STD(int8_t, array, rarray, _shape_strides, div, isStd);
301+
RUN_MEAN_STD(int8_t, array, farray, _shape_strides, div, isStd);
307302
} else if(ndarray->dtype == NDARRAY_UINT16) {
308-
RUN_MEAN_STD(uint16_t, array, rarray, _shape_strides, div, isStd);
303+
RUN_MEAN_STD(uint16_t, array, farray, _shape_strides, div, isStd);
309304
} else if(ndarray->dtype == NDARRAY_INT16) {
310-
RUN_MEAN_STD(int16_t, array, rarray, _shape_strides, div, isStd);
305+
RUN_MEAN_STD(int16_t, array, farray, _shape_strides, div, isStd);
311306
} else {
312-
RUN_MEAN_STD(mp_float_t, array, rarray, _shape_strides, div, isStd);
307+
RUN_MEAN_STD(mp_float_t, array, farray, _shape_strides, div, isStd);
313308
}
314309
}
315-
if(ndarray->ndim == 1) { // return a scalar here
310+
if(results->ndim == 0) { // return a scalar here
316311
return mp_binary_get_val_array(results->dtype, results->array, 0);
317312
}
318313
return MP_OBJ_FROM_PTR(results);

code/numpy/numerical/numerical.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@
318318
(array) += (ss).strides[ULAB_MAX_DIMS - 1];\
319319
l++;\
320320
} while(l < (ss).shape[ULAB_MAX_DIMS - 1]);\
321-
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS-1];\
321+
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS - 1];\
322322
(array) += (ss).strides[ULAB_MAX_DIMS - 2];\
323323
k++;\
324324
} while(k < (ss).shape[ULAB_MAX_DIMS - 2]);\
@@ -334,7 +334,7 @@
334334
(array) += (ss).strides[ULAB_MAX_DIMS - 1];\
335335
l++;\
336336
} while(l < (ss).shape[ULAB_MAX_DIMS - 1]);\
337-
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS-1];\
337+
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS - 1];\
338338
(array) += (ss).strides[ULAB_MAX_DIMS - 2];\
339339
k++;\
340340
} while(k < (ss).shape[ULAB_MAX_DIMS - 2]);\
@@ -350,7 +350,7 @@
350350
(array) += (ss).strides[ULAB_MAX_DIMS - 1];\
351351
l++;\
352352
} while(l < (ss).shape[ULAB_MAX_DIMS - 1]);\
353-
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS-1];\
353+
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS - 1];\
354354
(array) += (ss).strides[ULAB_MAX_DIMS - 2];\
355355
k++;\
356356
} while(k < (ss).shape[ULAB_MAX_DIMS - 2]);\
@@ -366,7 +366,7 @@
366366
(array) += (ss).strides[ULAB_MAX_DIMS - 1];\
367367
l++;\
368368
} while(l < (ss).shape[ULAB_MAX_DIMS - 1]);\
369-
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS-1];\
369+
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS - 1];\
370370
(array) += (ss).strides[ULAB_MAX_DIMS - 2];\
371371
k++;\
372372
} while(k < (ss).shape[ULAB_MAX_DIMS - 2]);\
@@ -456,11 +456,11 @@
456456
(array) += (ss).strides[ULAB_MAX_DIMS - 1];\
457457
l++;\
458458
} while(l < (ss).shape[ULAB_MAX_DIMS - 1]);\
459-
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS-1];\
459+
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS - 1];\
460460
(array) += (ss).strides[ULAB_MAX_DIMS - 2];\
461461
k++;\
462462
} while(k < (ss).shape[ULAB_MAX_DIMS - 2]);\
463-
(array) -= (ss).strides[ULAB_MAX_DIMS - 2] * (ss).shape[ULAB_MAX_DIMS-2];\
463+
(array) -= (ss).strides[ULAB_MAX_DIMS - 2] * (ss).shape[ULAB_MAX_DIMS - 2];\
464464
(array) += (ss).strides[ULAB_MAX_DIMS - 3];\
465465
j++;\
466466
} while(j < (ss).shape[ULAB_MAX_DIMS - 3]);\
@@ -478,11 +478,11 @@
478478
(array) += (ss).strides[ULAB_MAX_DIMS - 1];\
479479
l++;\
480480
} while(l < (ss).shape[ULAB_MAX_DIMS - 1]);\
481-
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS-1];\
481+
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS - 1];\
482482
(array) += (ss).strides[ULAB_MAX_DIMS - 2];\
483483
k++;\
484484
} while(k < (ss).shape[ULAB_MAX_DIMS - 2]);\
485-
(array) -= (ss).strides[ULAB_MAX_DIMS - 2] * (ss).shape[ULAB_MAX_DIMS-2];\
485+
(array) -= (ss).strides[ULAB_MAX_DIMS - 2] * (ss).shape[ULAB_MAX_DIMS - 2];\
486486
(array) += (ss).strides[ULAB_MAX_DIMS - 3];\
487487
j++;\
488488
} while(j < (ss).shape[ULAB_MAX_DIMS - 3]);\
@@ -500,11 +500,11 @@
500500
(array) += (ss).strides[ULAB_MAX_DIMS - 1];\
501501
l++;\
502502
} while(l < (ss).shape[ULAB_MAX_DIMS - 1]);\
503-
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS-1];\
503+
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS - 1];\
504504
(array) += (ss).strides[ULAB_MAX_DIMS - 2];\
505505
k++;\
506506
} while(k < (ss).shape[ULAB_MAX_DIMS - 2]);\
507-
(array) -= (ss).strides[ULAB_MAX_DIMS - 2] * (ss).shape[ULAB_MAX_DIMS-2];\
507+
(array) -= (ss).strides[ULAB_MAX_DIMS - 2] * (ss).shape[ULAB_MAX_DIMS - 2];\
508508
(array) += (ss).strides[ULAB_MAX_DIMS - 3];\
509509
j++;\
510510
} while(j < (ss).shape[ULAB_MAX_DIMS - 3]);\
@@ -522,11 +522,11 @@
522522
(array) += (ss).strides[ULAB_MAX_DIMS - 1];\
523523
l++;\
524524
} while(l < (ss).shape[ULAB_MAX_DIMS - 1]);\
525-
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS-1];\
525+
(array) -= (ss).strides[ULAB_MAX_DIMS - 1] * (ss).shape[ULAB_MAX_DIMS - 1];\
526526
(array) += (ss).strides[ULAB_MAX_DIMS - 2];\
527527
k++;\
528528
} while(k < (ss).shape[ULAB_MAX_DIMS - 2]);\
529-
(array) -= (ss).strides[ULAB_MAX_DIMS - 2] * (ss).shape[ULAB_MAX_DIMS-2];\
529+
(array) -= (ss).strides[ULAB_MAX_DIMS - 2] * (ss).shape[ULAB_MAX_DIMS - 2];\
530530
(array) += (ss).strides[ULAB_MAX_DIMS - 3];\
531531
j++;\
532532
} while(j < (ss).shape[ULAB_MAX_DIMS - 3]);\

code/ulab_tools.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,33 +161,54 @@ void *ndarray_set_float_function(uint8_t dtype) {
161161

162162
shape_strides tools_reduce_axes(ndarray_obj_t *ndarray, mp_obj_t axis) {
163163
// TODO: replace numerical_reduce_axes with this function, wherever applicable
164+
// This function should be used, whenever a tensor is contracted;
165+
// The shape and strides at `axis` are moved to the zeroth position,
166+
// everything else is aligned to the right
164167
if(!mp_obj_is_int(axis) & (axis != mp_const_none)) {
165168
mp_raise_TypeError(translate("axis must be None, or an integer"));
166169
}
167170
shape_strides _shape_strides;
168-
size_t *shape = m_new(size_t, ULAB_MAX_DIMS);
171+
172+
size_t *shape = m_new(size_t, ULAB_MAX_DIMS + 1);
169173
_shape_strides.shape = shape;
170-
int32_t *strides = m_new(int32_t, ULAB_MAX_DIMS);
174+
int32_t *strides = m_new(int32_t, ULAB_MAX_DIMS + 1);
171175
_shape_strides.strides = strides;
172176

177+
_shape_strides.increment = 0;
178+
// this is the contracted dimension (won't be overwritten for axis == None)
179+
_shape_strides.ndim = 0;
180+
173181
memcpy(_shape_strides.shape, ndarray->shape, sizeof(size_t) * ULAB_MAX_DIMS);
174182
memcpy(_shape_strides.strides, ndarray->strides, sizeof(int32_t) * ULAB_MAX_DIMS);
183+
184+
if(axis == mp_const_none) {
185+
return _shape_strides;
186+
}
187+
175188
uint8_t index = ULAB_MAX_DIMS - 1; // value of index for axis == mp_const_none (won't be overwritten)
176-
if(axis != mp_const_none) { // i.e., axis is a valid integer
189+
190+
if(axis != mp_const_none) { // i.e., axis is an integer
177191
int8_t ax = mp_obj_get_int(axis);
178192
if(ax < 0) ax += ndarray->ndim;
179193
if((ax < 0) || (ax > ndarray->ndim - 1)) {
180194
mp_raise_ValueError(translate("index out of range"));
181195
}
182196
index = ULAB_MAX_DIMS - ndarray->ndim + ax;
197+
_shape_strides.ndim = ndarray->ndim - 1;
183198
}
199+
184200
// move the value stored at index to the leftmost position, and align everything else to the right
185201
_shape_strides.shape[0] = ndarray->shape[index];
186202
_shape_strides.strides[0] = ndarray->strides[index];
187203
for(uint8_t i = 0; i < index; i++) {
188-
// entries to the left of index must be shifted to the right
204+
// entries to the right of index must be shifted by one position to the left
189205
_shape_strides.shape[i + 1] = ndarray->shape[i];
190206
_shape_strides.strides[i + 1] = ndarray->strides[i];
191207
}
208+
209+
if(_shape_strides.ndim != 0) {
210+
_shape_strides.increment = 1;
211+
}
212+
192213
return _shape_strides;
193214
}

code/ulab_tools.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
#define SWAP(t, a, b) { t tmp = a; a = b; b = tmp; }
1717

1818
typedef struct _shape_strides_t {
19-
int8_t axis;
19+
uint8_t increment;
20+
uint8_t ndim;
2021
size_t *shape;
2122
int32_t *strides;
2223
} shape_strides;

tests/numpy/numericals.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from ulab import numpy as np
44
except ImportError:
55
import numpy as np
6-
6+
77
print("Testing np.min:")
88
print(np.min([1]))
99
print(np.min(np.array([1], dtype=np.float)))
@@ -173,7 +173,6 @@
173173
a = np.array([253, 254, 255], dtype=np.uint8)
174174
#print(np.std(a))
175175
print(math.isclose(np.std(a), 0.816496580927726, rel_tol=1e-06, abs_tol=1e-06))
176-
#print(np.std(a, axis=0)) ## Here is problem
177176
print(math.isclose(np.std(a, axis=0), 0.816496580927726, rel_tol=1e-06, abs_tol=1e-06))
178177
a = np.array([range(255-3, 255),range(240-3, 240),range(250-3,250)], dtype=np.float)
179178
#print(np.std(a))
@@ -213,4 +212,3 @@
213212
print(np.clip(a, 3, 5))
214213
a = np.array([1,2,3,4,5,6,7], dtype=np.float)
215214
print(np.clip(a, 3, 5))
216-

0 commit comments

Comments
 (0)