diff --git a/code/ndarray.c b/code/ndarray.c index 96750735..04827706 100644 --- a/code/ndarray.c +++ b/code/ndarray.c @@ -586,43 +586,10 @@ void ndarray_copy_array(ndarray_obj_t *source, ndarray_obj_t *target, uint8_t sh } #endif - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { - #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - memcpy(tarray, sarray, target->itemsize); - tarray += target->itemsize; - sarray += source->strides[ULAB_MAX_DIMS - 1]; - l++; - } while(l < source->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - sarray -= source->strides[ULAB_MAX_DIMS - 1] * source->shape[ULAB_MAX_DIMS-1]; - sarray += source->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < source->shape[ULAB_MAX_DIMS - 2]); - #endif - #if ULAB_MAX_DIMS > 2 - sarray -= source->strides[ULAB_MAX_DIMS - 2] * source->shape[ULAB_MAX_DIMS-2]; - sarray += source->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < source->shape[ULAB_MAX_DIMS - 3]); - #endif - #if ULAB_MAX_DIMS > 3 - sarray -= source->strides[ULAB_MAX_DIMS - 3] * source->shape[ULAB_MAX_DIMS-3]; - sarray += source->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < source->shape[ULAB_MAX_DIMS - 4]); - #endif + ITERATOR_HEAD(); + memcpy(tarray, sarray, target->itemsize); + tarray += target->itemsize; + ITERATOR_TAIL(source, sarray); } ndarray_obj_t *ndarray_new_view(ndarray_obj_t *source, uint8_t ndim, size_t *shape, int32_t *strides, int32_t offset) { @@ -676,69 +643,36 @@ ndarray_obj_t *ndarray_copy_view_convert_type(ndarray_obj_t *source, uint8_t dty uint8_t complex_size = 2 * sizeof(mp_float_t); #endif - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { + ITERATOR_HEAD() + mp_obj_t item; + #if ULAB_SUPPORTS_COMPLEX + if(source->dtype == NDARRAY_COMPLEX) { + if(dtype != NDARRAY_COMPLEX) { + mp_raise_TypeError(MP_ERROR_TEXT("cannot convert complex type")); + } else { + memcpy(array, sarray, complex_size); + } + } else { #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - mp_obj_t item; - #if ULAB_SUPPORTS_COMPLEX - if(source->dtype == NDARRAY_COMPLEX) { - if(dtype != NDARRAY_COMPLEX) { - mp_raise_TypeError(MP_ERROR_TEXT("cannot convert complex type")); - } else { - memcpy(array, sarray, complex_size); - } - } else { - #endif - if((source->dtype == NDARRAY_FLOAT) && (dtype != NDARRAY_FLOAT)) { - // floats must be treated separately, because they can't directly be converted to integer types - mp_float_t f = ndarray_get_float_value(sarray, source->dtype); - item = mp_obj_new_int((int32_t)MICROPY_FLOAT_C_FUN(round)(f)); - } else { - item = mp_binary_get_val_array(source->dtype, sarray, 0); - } - #if ULAB_SUPPORTS_COMPLEX - if(dtype == NDARRAY_COMPLEX) { - ndarray_set_value(NDARRAY_FLOAT, array, 0, item); - } else { - ndarray_set_value(dtype, array, 0, item); - } - } - #else - ndarray_set_value(dtype, array, 0, item); - #endif - array += ndarray->itemsize; - sarray += source->strides[ULAB_MAX_DIMS - 1]; - l++; - } while(l < source->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - sarray -= source->strides[ULAB_MAX_DIMS - 1] * source->shape[ULAB_MAX_DIMS-1]; - sarray += source->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < source->shape[ULAB_MAX_DIMS - 2]); - #endif - #if ULAB_MAX_DIMS > 2 - sarray -= source->strides[ULAB_MAX_DIMS - 2] * source->shape[ULAB_MAX_DIMS-2]; - sarray += source->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < source->shape[ULAB_MAX_DIMS - 3]); + if((source->dtype == NDARRAY_FLOAT) && (dtype != NDARRAY_FLOAT)) { + // floats must be treated separately, because they can't directly be converted to integer types + mp_float_t f = ndarray_get_float_value(sarray, source->dtype); + item = mp_obj_new_int((int32_t)MICROPY_FLOAT_C_FUN(round)(f)); + } else { + item = mp_binary_get_val_array(source->dtype, sarray, 0); + } + #if ULAB_SUPPORTS_COMPLEX + if(dtype == NDARRAY_COMPLEX) { + ndarray_set_value(NDARRAY_FLOAT, array, 0, item); + } else { + ndarray_set_value(dtype, array, 0, item); + } + } + #else + ndarray_set_value(dtype, array, 0, item); #endif - #if ULAB_MAX_DIMS > 3 - sarray -= source->strides[ULAB_MAX_DIMS - 3] * source->shape[ULAB_MAX_DIMS-3]; - sarray += source->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < source->shape[ULAB_MAX_DIMS - 4]); - #endif + array += ndarray->itemsize; + ITERATOR_TAIL(source, sarray); return ndarray; } @@ -765,54 +699,21 @@ mp_obj_t ndarray_byteswap(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ return MP_OBJ_FROM_PTR(ndarray); } else { uint8_t *array = (uint8_t *)ndarray->array; - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { - #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - if(self->dtype == NDARRAY_FLOAT) { - #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT - SWAP(uint8_t, array[0], array[3]); - SWAP(uint8_t, array[1], array[2]); - #else - SWAP(uint8_t, array[0], array[7]); - SWAP(uint8_t, array[1], array[6]); - SWAP(uint8_t, array[2], array[5]); - SWAP(uint8_t, array[3], array[4]); - #endif - } else { - SWAP(uint8_t, array[0], array[1]); - } - array += ndarray->strides[ULAB_MAX_DIMS - 1]; - l++; - } while(l < ndarray->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - array -= ndarray->strides[ULAB_MAX_DIMS - 1] * ndarray->shape[ULAB_MAX_DIMS-1]; - array += ndarray->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < ndarray->shape[ULAB_MAX_DIMS - 2]); + ITERATOR_HEAD(); + if(self->dtype == NDARRAY_FLOAT) { + #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT + SWAP(uint8_t, array[0], array[3]); + SWAP(uint8_t, array[1], array[2]); + #else + SWAP(uint8_t, array[0], array[7]); + SWAP(uint8_t, array[1], array[6]); + SWAP(uint8_t, array[2], array[5]); + SWAP(uint8_t, array[3], array[4]); #endif - #if ULAB_MAX_DIMS > 2 - array -= ndarray->strides[ULAB_MAX_DIMS - 2] * ndarray->shape[ULAB_MAX_DIMS-2]; - array += ndarray->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < ndarray->shape[ULAB_MAX_DIMS - 3]); - #endif - #if ULAB_MAX_DIMS > 3 - array -= ndarray->strides[ULAB_MAX_DIMS - 3] * ndarray->shape[ULAB_MAX_DIMS-3]; - array += ndarray->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < ndarray->shape[ULAB_MAX_DIMS - 4]); - #endif + } else { + SWAP(uint8_t, array[0], array[1]); + } + ITERATOR_TAIL(ndarray, array); } return MP_OBJ_FROM_PTR(ndarray); } @@ -1441,43 +1342,10 @@ mp_obj_t ndarray_flatten(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a uint8_t *array = (uint8_t *)ndarray->array; if(memcmp(order, "C", 1) == 0) { // C-type ordering - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { - #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - memcpy(array, sarray, self->itemsize); - array += ndarray->strides[ULAB_MAX_DIMS - 1]; - sarray += self->strides[ULAB_MAX_DIMS - 1]; - l++; - } while(l < self->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - sarray -= self->strides[ULAB_MAX_DIMS - 1] * self->shape[ULAB_MAX_DIMS-1]; - sarray += self->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < self->shape[ULAB_MAX_DIMS - 2]); - #endif - #if ULAB_MAX_DIMS > 2 - sarray -= self->strides[ULAB_MAX_DIMS - 2] * self->shape[ULAB_MAX_DIMS-2]; - sarray += self->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < self->shape[ULAB_MAX_DIMS - 3]); - #endif - #if ULAB_MAX_DIMS > 3 - sarray -= self->strides[ULAB_MAX_DIMS - 3] * self->shape[ULAB_MAX_DIMS-3]; - sarray += self->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < self->shape[ULAB_MAX_DIMS - 4]); - #endif + ITERATOR_HEAD(); + memcpy(array, sarray, self->itemsize); + array += ndarray->strides[ULAB_MAX_DIMS - 1]; + ITERATOR_TAIL(self, sarray); } else { // 'F', Fortran-type ordering #if ULAB_MAX_DIMS > 3 size_t i = 0; diff --git a/code/ndarray.h b/code/ndarray.h index 3e82b385..d027134e 100644 --- a/code/ndarray.h +++ b/code/ndarray.h @@ -709,4 +709,89 @@ ndarray_obj_t *ndarray_from_mp_obj(mp_obj_t , uint8_t ); #endif /* ULAB_MAX_DIMS == 4 */ #endif /* ULAB_HAS_FUNCTION_ITERATOR */ + +// iterator macro for traversing arrays over all dimensions +#if ULAB_MAX_DIMS == 1 +#define ITERATOR_HEAD()\ + size_t _l_ = 0;\ + do { + +#define ITERATOR_TAIL(_source_, _source_array_)\ + (_source_array_) += (_source_)->strides[ULAB_MAX_DIMS - 1];\ + _l_++;\ + } while(_l_ < (_source_)->shape[ULAB_MAX_DIMS - 1]); + +#endif /* ULAB_MAX_DIMS == 1 */ + +#if ULAB_MAX_DIMS == 2 +#define ITERATOR_HEAD()\ + size_t _k_ = 0;\ + do {\ + size_t _l_ = 0;\ + do { + +#define ITERATOR_TAIL(_source_, _source_array_)\ + (_source_array_) += (_source_)->strides[ULAB_MAX_DIMS - 1];\ + _l_++;\ + } while(_l_ < (_source_)->shape[ULAB_MAX_DIMS - 1]);\ + (_source_array_) -= (_source_)->strides[ULAB_MAX_DIMS - 1] * (_source_)->shape[ULAB_MAX_DIMS - 1];\ + (_source_array_) += (_source_)->strides[ULAB_MAX_DIMS - 2];\ + _k_++;\ + } while(_k_ < (_source_)->shape[ULAB_MAX_DIMS - 2]); +#endif /* ULAB_MAX_DIMS == 2 */ + +#if ULAB_MAX_DIMS == 3 +#define ITERATOR_HEAD()\ + size_t _j_ = 0;\ + do {\ + size_t _k_ = 0;\ + do {\ + size_t _l_ = 0;\ + do { + +#define ITERATOR_TAIL(_source_, _source_array_)\ + (_source_array_) += (_source_)->strides[ULAB_MAX_DIMS - 1];\ + _l_++;\ + } while(_l_ < (_source_)->shape[ULAB_MAX_DIMS - 1]);\ + (_source_array_) -= (_source_)->strides[ULAB_MAX_DIMS - 1] * (_source_)->shape[ULAB_MAX_DIMS - 1];\ + (_source_array_) += (_source_)->strides[ULAB_MAX_DIMS - 2];\ + _k_++;\ + } while(_k_ < (_source_)->shape[ULAB_MAX_DIMS - 2]);\ + (_source_array_) -= (_source_)->strides[ULAB_MAX_DIMS - 2] * (_source_)->shape[ULAB_MAX_DIMS - 2];\ + (_source_array_) += (_source_)->strides[ULAB_MAX_DIMS - 3];\ + j++;\ + } while(j < (_source_)->shape[ULAB_MAX_DIMS - 3]); + +#endif /* ULAB_MAX_DIMS == 3 */ + +#if ULAB_MAX_DIMS == 4 +#define ITERATOR_HEAD()\ + size_t _i_ = 0;\ + do {\ + size_t _j_ = 0;\ + do {\ + size_t _k_ = 0;\ + do {\ + size_t _l_ = 0;\ + do { + +#define ITERATOR_TAIL(_source_, _source_array_)\ + (_source_array_) += (_source_)->strides[ULAB_MAX_DIMS - 1];\ + _l_++;\ + } while(_l_ < (_source_)->shape[ULAB_MAX_DIMS - 1]);\ + (_source_array_) -= (_source_)->strides[ULAB_MAX_DIMS - 1] * (_source_)->shape[ULAB_MAX_DIMS - 1];\ + (_source_array_) += (_source_)->strides[ULAB_MAX_DIMS - 2];\ + _k_++;\ + } while(_k_ < (_source_)->shape[ULAB_MAX_DIMS - 2]);\ + (_source_array_) -= (_source_)->strides[ULAB_MAX_DIMS - 2] * (_source_)->shape[ULAB_MAX_DIMS - 2];\ + (_source_array_) += (_source_)->strides[ULAB_MAX_DIMS - 3];\ + _j_++;\ + } while(_j_ < (_source_)->shape[ULAB_MAX_DIMS - 3]);\ + (_source_array_) -= (_source_)->strides[ULAB_MAX_DIMS - 3] * (_source_)->shape[ULAB_MAX_DIMS - 3];\ + (_source_array_) += (_source_)->strides[ULAB_MAX_DIMS - 4];\ + _i_++;\ + } while(_i_ < (_source_)->shape[ULAB_MAX_DIMS - 4]); +#endif /* ULAB_MAX_DIMS == 4 */ + + #endif diff --git a/code/numpy/compare.c b/code/numpy/compare.c index b2762e41..5845a9dd 100644 --- a/code/numpy/compare.c +++ b/code/numpy/compare.c @@ -260,48 +260,14 @@ static mp_obj_t compare_isinf_isfinite(mp_obj_t _x, uint8_t mask) { } uint8_t *xarray = (uint8_t *)x->array; - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { - #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - mp_float_t value = *(mp_float_t *)xarray; - if(isnan(value)) { - *rarray++ = 0; - } else { - *rarray++ = isinf(value) ? mask : 1 - mask; - } - xarray += x->strides[ULAB_MAX_DIMS - 1]; - l++; - } while(l < x->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - xarray -= x->strides[ULAB_MAX_DIMS - 1] * x->shape[ULAB_MAX_DIMS-1]; - xarray += x->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < x->shape[ULAB_MAX_DIMS - 2]); - #endif - #if ULAB_MAX_DIMS > 2 - xarray -= x->strides[ULAB_MAX_DIMS - 2] * x->shape[ULAB_MAX_DIMS-2]; - xarray += x->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < x->shape[ULAB_MAX_DIMS - 3]); - #endif - #if ULAB_MAX_DIMS > 3 - xarray -= x->strides[ULAB_MAX_DIMS - 3] * x->shape[ULAB_MAX_DIMS-3]; - xarray += x->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < x->shape[ULAB_MAX_DIMS - 4]); - #endif - + ITERATOR_HEAD(); + mp_float_t value = *(mp_float_t *)xarray; + if(isnan(value)) { + *rarray++ = 0; + } else { + *rarray++ = isinf(value) ? mask : 1 - mask; + } + ITERATOR_TAIL(x, xarray); return MP_OBJ_FROM_PTR(results); } else { mp_raise_TypeError(MP_ERROR_TEXT("wrong input type")); diff --git a/code/numpy/io/io.c b/code/numpy/io/io.c index 95e62adc..6e72ff8a 100644 --- a/code/numpy/io/io.c +++ b/code/numpy/io/io.c @@ -338,7 +338,7 @@ static mp_obj_t io_loadtxt(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw buffer[read] = '\0'; offset = buffer; while(*offset != '\0') { - if(*offset == comment_char) { + while(*offset == comment_char) { // clear the line till the end, or the buffer's end while((*offset != '\0')) { offset++; @@ -425,7 +425,7 @@ static mp_obj_t io_loadtxt(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw offset = buffer; while(*offset != '\0') { - if(*offset == comment_char) { + while(*offset == comment_char) { // clear the line till the end, or the buffer's end while((*offset != '\0')) { offset++; @@ -619,48 +619,14 @@ static mp_obj_t io_save(mp_obj_t file, mp_obj_t ndarray_) { uint8_t *array = (uint8_t *)ndarray->array; - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { - #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - memcpy(buffer+offset, array, sz); - offset += sz; - if(offset == ULAB_IO_BUFFER_SIZE) { - stream_p->write(stream, buffer, offset, &error); - offset = 0; - } - array += ndarray->strides[ULAB_MAX_DIMS - 1]; - l++; - } while(l < ndarray->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - array -= ndarray->strides[ULAB_MAX_DIMS - 1] * ndarray->shape[ULAB_MAX_DIMS-1]; - array += ndarray->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < ndarray->shape[ULAB_MAX_DIMS - 2]); - #endif - #if ULAB_MAX_DIMS > 2 - array -= ndarray->strides[ULAB_MAX_DIMS - 2] * ndarray->shape[ULAB_MAX_DIMS-2]; - array += ndarray->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < ndarray->shape[ULAB_MAX_DIMS - 3]); - #endif - #if ULAB_MAX_DIMS > 3 - array -= ndarray->strides[ULAB_MAX_DIMS - 3] * ndarray->shape[ULAB_MAX_DIMS-3]; - array += ndarray->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < ndarray->shape[ULAB_MAX_DIMS - 4]); - #endif - + ITERATOR_HEAD(); + memcpy(buffer+offset, array, sz); + offset += sz; + if(offset == ULAB_IO_BUFFER_SIZE) { + stream_p->write(stream, buffer, offset, &error); + offset = 0; + } + ITERATOR_TAIL(ndarray, array); stream_p->write(stream, buffer, offset, &error); stream_p->ioctl(stream, MP_STREAM_CLOSE, 0, &error); @@ -751,16 +717,32 @@ static mp_obj_t io_savetxt(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw char *buffer = m_new(char, ULAB_IO_BUFFER_SIZE); int error; + size_t len_comment; + char *comments; + + if(mp_obj_is_str(args[5].u_obj)) { + const char *_comments = mp_obj_str_get_data(args[5].u_obj, &len_comment); + comments = (char *)_comments; + } else { + len_comment = 2; + comments = m_new(char, len_comment); + comments[0] = '#'; + comments[1] = ' '; + } + if(mp_obj_is_str(args[3].u_obj)) { size_t _len; - if(mp_obj_is_str(args[5].u_obj)) { - const char *comments = mp_obj_str_get_data(args[5].u_obj, &_len); - stream_p->write(stream, comments, _len, &error); - } else { - stream_p->write(stream, "# ", 2, &error); - } const char *header = mp_obj_str_get_data(args[3].u_obj, &_len); - stream_p->write(stream, header, _len, &error); + + stream_p->write(stream, comments, len_comment, &error); + + // We can't write the header in the single chunk, for it might contain line breaks + for(size_t i = 0; i < _len; header++, i++) { + stream_p->write(stream, header, 1, &error); + if((*header == '\n') && (i < _len)) { + stream_p->write(stream, comments, len_comment, &error); + } + } stream_p->write(stream, "\n", 1, &error); } @@ -799,16 +781,19 @@ static mp_obj_t io_savetxt(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw } while(k < ndarray->shape[ULAB_MAX_DIMS - 2]); #endif - if(mp_obj_is_str(args[4].u_obj)) { + if(mp_obj_is_str(args[4].u_obj)) { // footer string size_t _len; - if(mp_obj_is_str(args[5].u_obj)) { - const char *comments = mp_obj_str_get_data(args[5].u_obj, &_len); - stream_p->write(stream, comments, _len, &error); - } else { - stream_p->write(stream, "# ", 2, &error); - } const char *footer = mp_obj_str_get_data(args[4].u_obj, &_len); - stream_p->write(stream, footer, _len, &error); + + stream_p->write(stream, comments, len_comment, &error); + + // We can't write the header in the single chunk, for it might contain line breaks + for(size_t i = 0; i < _len; footer++, i++) { + stream_p->write(stream, footer, 1, &error); + if((*footer == '\n') && (i < _len)) { + stream_p->write(stream, comments, len_comment, &error); + } + } stream_p->write(stream, "\n", 1, &error); } diff --git a/code/numpy/poly.c b/code/numpy/poly.c index 8b8e1435..91fc01f1 100644 --- a/code/numpy/poly.c +++ b/code/numpy/poly.c @@ -197,42 +197,9 @@ mp_obj_t poly_polyval(mp_obj_t o_p, mp_obj_t o_x) { // TODO: these loops are really nothing, but the re-impplementation of // ITERATE_VECTOR from vectorise.c. We could pass a function pointer here - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { - #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - *array++ = poly_eval(func(sarray), p, plen); - sarray += source->strides[ULAB_MAX_DIMS - 1]; - l++; - } while(l < source->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - sarray -= source->strides[ULAB_MAX_DIMS - 1] * source->shape[ULAB_MAX_DIMS-1]; - sarray += source->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < source->shape[ULAB_MAX_DIMS - 2]); - #endif - #if ULAB_MAX_DIMS > 2 - sarray -= source->strides[ULAB_MAX_DIMS - 2] * source->shape[ULAB_MAX_DIMS-2]; - sarray += source->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < source->shape[ULAB_MAX_DIMS - 3]); - #endif - #if ULAB_MAX_DIMS > 3 - sarray -= source->strides[ULAB_MAX_DIMS - 3] * source->shape[ULAB_MAX_DIMS-3]; - sarray += source->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < source->shape[ULAB_MAX_DIMS - 4]); - #endif + ITERATOR_HEAD(); + *array++ = poly_eval(func(sarray), p, plen); + ITERATOR_TAIL(source, sarray); } else { // o_x had better be a one-dimensional standard iterable ndarray = ndarray_new_linear_array(mp_obj_get_int(mp_obj_len_maybe(o_x)), NDARRAY_FLOAT); diff --git a/code/numpy/vector.c b/code/numpy/vector.c index 95e2e207..d17bd850 100644 --- a/code/numpy/vector.c +++ b/code/numpy/vector.c @@ -91,43 +91,10 @@ static mp_obj_t vector_generic_vector(size_t n_args, const mp_obj_t *pos_args, m mp_float_t (*func)(void *) = ndarray_get_float_function(source->dtype); - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { - #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - mp_float_t value = func(sarray); - *tarray++ = f(value); - sarray += source->strides[ULAB_MAX_DIMS - 1]; - l++; - } while(l < source->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - sarray -= source->strides[ULAB_MAX_DIMS - 1] * source->shape[ULAB_MAX_DIMS-1]; - sarray += source->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < source->shape[ULAB_MAX_DIMS - 2]); - #endif /* ULAB_MAX_DIMS > 1 */ - #if ULAB_MAX_DIMS > 2 - sarray -= source->strides[ULAB_MAX_DIMS - 2] * source->shape[ULAB_MAX_DIMS-2]; - sarray += source->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < source->shape[ULAB_MAX_DIMS - 3]); - #endif /* ULAB_MAX_DIMS > 2 */ - #if ULAB_MAX_DIMS > 3 - sarray -= source->strides[ULAB_MAX_DIMS - 3] * source->shape[ULAB_MAX_DIMS-3]; - sarray += source->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < source->shape[ULAB_MAX_DIMS - 4]); - #endif /* ULAB_MAX_DIMS > 3 */ + ITERATOR_HEAD(); + mp_float_t value = func(sarray); + *tarray++ = f(value); + ITERATOR_TAIL(source, sarray); #else if(source->dtype == NDARRAY_UINT8) { ITERATE_VECTOR(uint8_t, target, tarray, tstrides, source, sarray); @@ -171,43 +138,10 @@ static mp_obj_t vector_generic_vector(mp_obj_t o_in, mp_float_t (*f)(mp_float_t) mp_float_t (*func)(void *) = ndarray_get_float_function(source->dtype); - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { - #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - mp_float_t value = func(sarray); - *array++ = f(value); - sarray += source->strides[ULAB_MAX_DIMS - 1]; - l++; - } while(l < source->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - sarray -= source->strides[ULAB_MAX_DIMS - 1] * source->shape[ULAB_MAX_DIMS-1]; - sarray += source->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < source->shape[ULAB_MAX_DIMS - 2]); - #endif /* ULAB_MAX_DIMS > 1 */ - #if ULAB_MAX_DIMS > 2 - sarray -= source->strides[ULAB_MAX_DIMS - 2] * source->shape[ULAB_MAX_DIMS-2]; - sarray += source->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < source->shape[ULAB_MAX_DIMS - 3]); - #endif /* ULAB_MAX_DIMS > 2 */ - #if ULAB_MAX_DIMS > 3 - sarray -= source->strides[ULAB_MAX_DIMS - 3] * source->shape[ULAB_MAX_DIMS-3]; - sarray += source->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < source->shape[ULAB_MAX_DIMS - 4]); - #endif /* ULAB_MAX_DIMS > 3 */ + ITERATOR_HEAD(); + mp_float_t value = func(sarray); + *array++ = f(value); + ITERATOR_TAIL(source, sarray); #else if(source->dtype == NDARRAY_UINT8) { ITERATE_VECTOR(uint8_t, array, source, sarray); @@ -327,43 +261,11 @@ mp_obj_t vector_around(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_arg mp_float_t (*func)(void *) = ndarray_get_float_function(source->dtype); - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { - #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - mp_float_t f = func(sarray); - *narray++ = MICROPY_FLOAT_C_FUN(round)(f * mul) / mul; - sarray += source->strides[ULAB_MAX_DIMS - 1]; - l++; - } while(l < source->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - sarray -= source->strides[ULAB_MAX_DIMS - 1] * source->shape[ULAB_MAX_DIMS-1]; - sarray += source->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < source->shape[ULAB_MAX_DIMS - 2]); - #endif - #if ULAB_MAX_DIMS > 2 - sarray -= source->strides[ULAB_MAX_DIMS - 2] * source->shape[ULAB_MAX_DIMS-2]; - sarray += source->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < source->shape[ULAB_MAX_DIMS - 3]); - #endif - #if ULAB_MAX_DIMS > 3 - sarray -= source->strides[ULAB_MAX_DIMS - 3] * source->shape[ULAB_MAX_DIMS-3]; - sarray += source->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < source->shape[ULAB_MAX_DIMS - 4]); - #endif + ITERATOR_HEAD(); + mp_float_t f = func(sarray); + *narray++ = MICROPY_FLOAT_C_FUN(round)(f * mul) / mul; + ITERATOR_TAIL(source, sarray); + return MP_OBJ_FROM_PTR(ndarray); } @@ -631,46 +533,13 @@ static mp_obj_t vector_exp(mp_obj_t o_in) { mp_float_t *array = (mp_float_t *)ndarray->array; uint8_t itemsize = sizeof(mp_float_t); - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { - #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - mp_float_t real = *(mp_float_t *)sarray; - mp_float_t imag = *(mp_float_t *)(sarray + itemsize); - mp_float_t exp_real = MICROPY_FLOAT_C_FUN(exp)(real); - *array++ = exp_real * MICROPY_FLOAT_C_FUN(cos)(imag); - *array++ = exp_real * MICROPY_FLOAT_C_FUN(sin)(imag); - sarray += source->strides[ULAB_MAX_DIMS - 1]; - l++; - } while(l < source->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - sarray -= source->strides[ULAB_MAX_DIMS - 1] * source->shape[ULAB_MAX_DIMS-1]; - sarray += source->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < source->shape[ULAB_MAX_DIMS - 2]); - #endif /* ULAB_MAX_DIMS > 1 */ - #if ULAB_MAX_DIMS > 2 - sarray -= source->strides[ULAB_MAX_DIMS - 2] * source->shape[ULAB_MAX_DIMS-2]; - sarray += source->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < source->shape[ULAB_MAX_DIMS - 3]); - #endif /* ULAB_MAX_DIMS > 2 */ - #if ULAB_MAX_DIMS > 3 - sarray -= source->strides[ULAB_MAX_DIMS - 3] * source->shape[ULAB_MAX_DIMS-3]; - sarray += source->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < source->shape[ULAB_MAX_DIMS - 4]); - #endif /* ULAB_MAX_DIMS > 3 */ + ITERATOR_HEAD(); + mp_float_t real = *(mp_float_t *)sarray; + mp_float_t imag = *(mp_float_t *)(sarray + itemsize); + mp_float_t exp_real = MICROPY_FLOAT_C_FUN(exp)(real); + *array++ = exp_real * MICROPY_FLOAT_C_FUN(cos)(imag); + *array++ = exp_real * MICROPY_FLOAT_C_FUN(sin)(imag); + ITERATOR_TAIL(source, sarray); return MP_OBJ_FROM_PTR(ndarray); } } @@ -921,97 +790,33 @@ mp_obj_t vector_sqrt(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) mp_float_t *array = (mp_float_t *)ndarray->array; uint8_t itemsize = sizeof(mp_float_t); - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { - #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - mp_float_t real = *(mp_float_t *)sarray; - mp_float_t imag = *(mp_float_t *)(sarray + itemsize); - mp_float_t sqrt_abs = MICROPY_FLOAT_C_FUN(sqrt)(real * real + imag * imag); - sqrt_abs = MICROPY_FLOAT_C_FUN(sqrt)(sqrt_abs); - mp_float_t theta = MICROPY_FLOAT_CONST(0.5) * MICROPY_FLOAT_C_FUN(atan2)(imag, real); - *array++ = sqrt_abs * MICROPY_FLOAT_C_FUN(cos)(theta); - *array++ = sqrt_abs * MICROPY_FLOAT_C_FUN(sin)(theta); - sarray += source->strides[ULAB_MAX_DIMS - 1]; - l++; - } while(l < source->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - sarray -= source->strides[ULAB_MAX_DIMS - 1] * source->shape[ULAB_MAX_DIMS-1]; - sarray += source->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < source->shape[ULAB_MAX_DIMS - 2]); - #endif /* ULAB_MAX_DIMS > 1 */ - #if ULAB_MAX_DIMS > 2 - sarray -= source->strides[ULAB_MAX_DIMS - 2] * source->shape[ULAB_MAX_DIMS-2]; - sarray += source->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < source->shape[ULAB_MAX_DIMS - 3]); - #endif /* ULAB_MAX_DIMS > 2 */ - #if ULAB_MAX_DIMS > 3 - sarray -= source->strides[ULAB_MAX_DIMS - 3] * source->shape[ULAB_MAX_DIMS-3]; - sarray += source->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < source->shape[ULAB_MAX_DIMS - 4]); - #endif /* ULAB_MAX_DIMS > 3 */ + ITERATOR_HEAD(); + mp_float_t real = *(mp_float_t *)sarray; + mp_float_t imag = *(mp_float_t *)(sarray + itemsize); + mp_float_t sqrt_abs = MICROPY_FLOAT_C_FUN(sqrt)(real * real + imag * imag); + sqrt_abs = MICROPY_FLOAT_C_FUN(sqrt)(sqrt_abs); + mp_float_t theta = MICROPY_FLOAT_CONST(0.5) * MICROPY_FLOAT_C_FUN(atan2)(imag, real); + *array++ = sqrt_abs * MICROPY_FLOAT_C_FUN(cos)(theta); + *array++ = sqrt_abs * MICROPY_FLOAT_C_FUN(sin)(theta); + ITERATOR_TAIL(source, sarray); + return MP_OBJ_FROM_PTR(ndarray); } else if(source->dtype == NDARRAY_FLOAT) { uint8_t *sarray = (uint8_t *)source->array; ndarray_obj_t *ndarray = ndarray_new_dense_ndarray(source->ndim, source->shape, NDARRAY_COMPLEX); mp_float_t *array = (mp_float_t *)ndarray->array; - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { - #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - mp_float_t value = *(mp_float_t *)sarray; - if(value >= MICROPY_FLOAT_CONST(0.0)) { - *array++ = MICROPY_FLOAT_C_FUN(sqrt)(value); - array++; - } else { - array++; - *array++ = MICROPY_FLOAT_C_FUN(sqrt)(-value); - } - sarray += source->strides[ULAB_MAX_DIMS - 1]; - l++; - } while(l < source->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - sarray -= source->strides[ULAB_MAX_DIMS - 1] * source->shape[ULAB_MAX_DIMS-1]; - sarray += source->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < source->shape[ULAB_MAX_DIMS - 2]); - #endif /* ULAB_MAX_DIMS > 1 */ - #if ULAB_MAX_DIMS > 2 - sarray -= source->strides[ULAB_MAX_DIMS - 2] * source->shape[ULAB_MAX_DIMS-2]; - sarray += source->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < source->shape[ULAB_MAX_DIMS - 3]); - #endif /* ULAB_MAX_DIMS > 2 */ - #if ULAB_MAX_DIMS > 3 - sarray -= source->strides[ULAB_MAX_DIMS - 3] * source->shape[ULAB_MAX_DIMS-3]; - sarray += source->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < source->shape[ULAB_MAX_DIMS - 4]); - #endif /* ULAB_MAX_DIMS > 3 */ + ITERATOR_HEAD(); + mp_float_t value = *(mp_float_t *)sarray; + if(value >= MICROPY_FLOAT_CONST(0.0)) { + *array++ = MICROPY_FLOAT_C_FUN(sqrt)(value); + array++; + } else { + array++; + *array++ = MICROPY_FLOAT_C_FUN(sqrt)(-value); + } + ITERATOR_TAIL(source, sarray); + return MP_OBJ_FROM_PTR(ndarray); } else { mp_raise_TypeError(MP_ERROR_TEXT("input dtype must be float or complex")); @@ -1071,45 +876,12 @@ static mp_obj_t vector_vectorized_function_call(mp_obj_t self_in, size_t n_args, uint8_t *sarray = (uint8_t *)source->array; uint8_t *narray = (uint8_t *)ndarray->array; - #if ULAB_MAX_DIMS > 3 - size_t i = 0; - do { - #endif - #if ULAB_MAX_DIMS > 2 - size_t j = 0; - do { - #endif - #if ULAB_MAX_DIMS > 1 - size_t k = 0; - do { - #endif - size_t l = 0; - do { - avalue[0] = mp_binary_get_val_array(source->dtype, sarray, 0); - fvalue = MP_OBJ_TYPE_GET_SLOT(self->type, call)(self->fun, 1, 0, avalue); - ndarray_set_value(self->otypes, narray, 0, fvalue); - sarray += source->strides[ULAB_MAX_DIMS - 1]; - narray += ndarray->itemsize; - l++; - } while(l < source->shape[ULAB_MAX_DIMS - 1]); - #if ULAB_MAX_DIMS > 1 - sarray -= source->strides[ULAB_MAX_DIMS - 1] * source->shape[ULAB_MAX_DIMS - 1]; - sarray += source->strides[ULAB_MAX_DIMS - 2]; - k++; - } while(k < source->shape[ULAB_MAX_DIMS - 2]); - #endif /* ULAB_MAX_DIMS > 1 */ - #if ULAB_MAX_DIMS > 2 - sarray -= source->strides[ULAB_MAX_DIMS - 2] * source->shape[ULAB_MAX_DIMS - 2]; - sarray += source->strides[ULAB_MAX_DIMS - 3]; - j++; - } while(j < source->shape[ULAB_MAX_DIMS - 3]); - #endif /* ULAB_MAX_DIMS > 2 */ - #if ULAB_MAX_DIMS > 3 - sarray -= source->strides[ULAB_MAX_DIMS - 3] * source->shape[ULAB_MAX_DIMS - 3]; - sarray += source->strides[ULAB_MAX_DIMS - 4]; - i++; - } while(i < source->shape[ULAB_MAX_DIMS - 4]); - #endif /* ULAB_MAX_DIMS > 3 */ + ITERATOR_HEAD(); + avalue[0] = mp_binary_get_val_array(source->dtype, sarray, 0); + fvalue = MP_OBJ_TYPE_GET_SLOT(self->type, call)(self->fun, 1, 0, avalue); + ndarray_set_value(self->otypes, narray, 0, fvalue); + narray += ndarray->itemsize; + ITERATOR_TAIL(source, sarray); return MP_OBJ_FROM_PTR(ndarray); } else if(mp_obj_is_type(args[0], &mp_type_tuple) || mp_obj_is_type(args[0], &mp_type_list) || diff --git a/code/ulab.c b/code/ulab.c index 6858f41d..bd420ae8 100644 --- a/code/ulab.c +++ b/code/ulab.c @@ -33,7 +33,7 @@ #include "user/user.h" #include "utils/utils.h" -#define ULAB_VERSION 6.7.4 +#define ULAB_VERSION 6.7.6 #define xstr(s) str(s) #define str(s) #s diff --git a/docs/ulab-change-log.md b/docs/ulab-change-log.md index 2a06dda0..b96b51db 100644 --- a/docs/ulab-change-log.md +++ b/docs/ulab-change-log.md @@ -1,8 +1,15 @@ Thu, 29 May 2025 +version 6.7.6 + + loadtxt can deal with multi-line comments + +Thu, 29 May 2025 + version 6.7.5 fix typo and shape in radnom module + Sun, 16 Mar 2025 version 6.7.4