commit
cf0180e05e
15 changed files with 496 additions and 293 deletions
|
|
@ -17,7 +17,6 @@
|
|||
#include "py/binary.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objarray.h"
|
||||
#include "compat.h"
|
||||
#include "ndarray.h"
|
||||
#include "fft.h"
|
||||
|
||||
|
|
@ -79,11 +78,11 @@ void fft_kernel(mp_float_t *real, mp_float_t *imag, int n, int isign) {
|
|||
}
|
||||
|
||||
mp_obj_t fft_fft_ifft_spectrum(size_t n_args, mp_obj_t arg_re, mp_obj_t arg_im, uint8_t type) {
|
||||
if(!mp_obj_is_type(arg_re, &ulab_ndarray_type)) {
|
||||
if(!MP_OBJ_IS_TYPE(arg_re, &ulab_ndarray_type)) {
|
||||
mp_raise_NotImplementedError(translate("FFT is defined for ndarrays only"));
|
||||
}
|
||||
if(n_args == 2) {
|
||||
if(!mp_obj_is_type(arg_im, &ulab_ndarray_type)) {
|
||||
if(!MP_OBJ_IS_TYPE(arg_im, &ulab_ndarray_type)) {
|
||||
mp_raise_NotImplementedError(translate("FFT is defined for ndarrays only"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,20 +15,19 @@
|
|||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/misc.h"
|
||||
#include "compat.h"
|
||||
#include "filter.h"
|
||||
|
||||
#if ULAB_FILTER_CONVOLVE
|
||||
mp_obj_t filter_convolve(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_a, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_v, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_a, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_v, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
};
|
||||
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(2, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
if(!mp_obj_is_type(args[0].u_obj, &ulab_ndarray_type) || !mp_obj_is_type(args[1].u_obj, &ulab_ndarray_type)) {
|
||||
if(!MP_OBJ_IS_TYPE(args[0].u_obj, &ulab_ndarray_type) || !MP_OBJ_IS_TYPE(args[1].u_obj, &ulab_ndarray_type)) {
|
||||
mp_raise_TypeError(translate("convolve arguments must be ndarrays"));
|
||||
}
|
||||
|
||||
|
|
@ -48,23 +47,36 @@ mp_obj_t filter_convolve(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
|
|||
ndarray_obj_t *out = create_new_ndarray(1, len, NDARRAY_FLOAT);
|
||||
mp_float_t *outptr = out->array->items;
|
||||
int off = len_c-1;
|
||||
for(int k=-off; k<len-off; k++) {
|
||||
mp_float_t accum = (mp_float_t)0;
|
||||
int top_n = MIN(len_c, len_a - k);
|
||||
int bot_n = MAX(-k, 0);
|
||||
for(int n=bot_n; n<top_n; n++) {
|
||||
int idx_c = len_c - n - 1;
|
||||
int idx_a = n+k;
|
||||
mp_float_t ai = (mp_float_t)0, ci = (mp_float_t)0;
|
||||
if(idx_a >= 0 && idx_a < len_a) {
|
||||
ai = ndarray_get_float_value(a->array->items, a->array->typecode, idx_a);
|
||||
|
||||
if(a->array->typecode == NDARRAY_FLOAT && c->array->typecode == NDARRAY_FLOAT) {
|
||||
mp_float_t* a_items = (mp_float_t*)a->array->items;
|
||||
mp_float_t* c_items = (mp_float_t*)c->array->items;
|
||||
for(int k=-off; k<len-off; k++) {
|
||||
mp_float_t accum = (mp_float_t)0;
|
||||
int top_n = MIN(len_c, len_a - k);
|
||||
int bot_n = MAX(-k, 0);
|
||||
mp_float_t* a_ptr = a_items + bot_n + k;
|
||||
mp_float_t* a_end = a_ptr + (top_n - bot_n);
|
||||
mp_float_t* c_ptr = c_items + len_c - bot_n - 1;
|
||||
for(; a_ptr != a_end;) {
|
||||
accum += *a_ptr++ * *c_ptr--;
|
||||
}
|
||||
if(idx_c >= 0 && idx_c < len_c) {
|
||||
ci = ndarray_get_float_value(c->array->items, c->array->typecode, idx_c);
|
||||
}
|
||||
accum += ai * ci;
|
||||
*outptr++ = accum;
|
||||
}
|
||||
} else {
|
||||
for(int k=-off; k<len-off; k++) {
|
||||
mp_float_t accum = (mp_float_t)0;
|
||||
int top_n = MIN(len_c, len_a - k);
|
||||
int bot_n = MAX(-k, 0);
|
||||
for(int n=bot_n; n<top_n; n++) {
|
||||
int idx_c = len_c - n - 1;
|
||||
int idx_a = n+k;
|
||||
mp_float_t ai = ndarray_get_float_value(a->array->items, a->array->typecode, idx_a);
|
||||
mp_float_t ci = ndarray_get_float_value(c->array->items, c->array->typecode, idx_c);
|
||||
accum += ai * ci;
|
||||
}
|
||||
*outptr++ = accum;
|
||||
}
|
||||
*outptr++ = accum;
|
||||
}
|
||||
|
||||
return out;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/misc.h"
|
||||
#include "compat.h"
|
||||
#include "linalg.h"
|
||||
|
||||
#if ULAB_LINALG_TRANSPOSE
|
||||
|
|
@ -57,7 +56,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(linalg_transpose_obj, linalg_transpose);
|
|||
#if ULAB_LINALG_RESHAPE
|
||||
mp_obj_t linalg_reshape(mp_obj_t self_in, mp_obj_t shape) {
|
||||
ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if(!mp_obj_is_type(shape, &mp_type_tuple) || (MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(shape)) != 2)) {
|
||||
if(!MP_OBJ_IS_TYPE(shape, &mp_type_tuple) || (MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(shape)) != 2)) {
|
||||
mp_raise_ValueError(translate("shape must be a 2-tuple"));
|
||||
}
|
||||
|
||||
|
|
@ -83,20 +82,20 @@ MP_DEFINE_CONST_FUN_OBJ_2(linalg_reshape_obj, linalg_reshape);
|
|||
#if ULAB_LINALG_SIZE
|
||||
mp_obj_t linalg_size(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_axis, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_axis, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
};
|
||||
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(1, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
if(!mp_obj_is_type(args[0].u_obj, &ulab_ndarray_type)) {
|
||||
if(!MP_OBJ_IS_TYPE(args[0].u_obj, &ulab_ndarray_type)) {
|
||||
mp_raise_TypeError(translate("size is defined for ndarrays only"));
|
||||
} else {
|
||||
ndarray_obj_t *ndarray = MP_OBJ_TO_PTR(args[0].u_obj);
|
||||
if(args[1].u_obj == mp_const_none) {
|
||||
return mp_obj_new_int(ndarray->array->len);
|
||||
} else if(mp_obj_is_int(args[1].u_obj)) {
|
||||
} else if(MP_OBJ_IS_INT(args[1].u_obj)) {
|
||||
uint8_t ax = mp_obj_get_int(args[1].u_obj);
|
||||
if(ax == 0) {
|
||||
if(ndarray->m == 1) {
|
||||
|
|
@ -169,11 +168,11 @@ bool linalg_invert_matrix(mp_float_t *data, size_t N) {
|
|||
#if ULAB_LINALG_INV
|
||||
mp_obj_t linalg_inv(mp_obj_t o_in) {
|
||||
// since inv is not a class method, we have to inspect the input argument first
|
||||
if(!mp_obj_is_type(o_in, &ulab_ndarray_type)) {
|
||||
if(!MP_OBJ_IS_TYPE(o_in, &ulab_ndarray_type)) {
|
||||
mp_raise_TypeError(translate("only ndarrays can be inverted"));
|
||||
}
|
||||
ndarray_obj_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
if(!mp_obj_is_type(o_in, &ulab_ndarray_type)) {
|
||||
if(!MP_OBJ_IS_TYPE(o_in, &ulab_ndarray_type)) {
|
||||
mp_raise_TypeError(translate("only ndarray objects can be inverted"));
|
||||
}
|
||||
if(o->m != o->n) {
|
||||
|
|
@ -206,7 +205,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(linalg_inv_obj, linalg_inv);
|
|||
#if ULAB_LINALG_DOT
|
||||
mp_obj_t linalg_dot(mp_obj_t _m1, mp_obj_t _m2) {
|
||||
// TODO: should the results be upcast?
|
||||
if(!mp_obj_is_type(_m1, &ulab_ndarray_type) || !mp_obj_is_type(_m2, &ulab_ndarray_type)) {
|
||||
if(!MP_OBJ_IS_TYPE(_m1, &ulab_ndarray_type) || !MP_OBJ_IS_TYPE(_m2, &ulab_ndarray_type)) {
|
||||
mp_raise_TypeError(translate("arguments must be ndarrays"));
|
||||
}
|
||||
ndarray_obj_t *m1 = MP_OBJ_TO_PTR(_m1);
|
||||
|
|
@ -247,14 +246,14 @@ mp_obj_t linalg_zeros_ones(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw
|
|||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
uint8_t dtype = args[1].u_int;
|
||||
if(!mp_obj_is_int(args[0].u_obj) && !mp_obj_is_type(args[0].u_obj, &mp_type_tuple)) {
|
||||
if(!MP_OBJ_IS_INT(args[0].u_obj) && !MP_OBJ_IS_TYPE(args[0].u_obj, &mp_type_tuple)) {
|
||||
mp_raise_TypeError(translate("input argument must be an integer or a 2-tuple"));
|
||||
}
|
||||
ndarray_obj_t *ndarray = NULL;
|
||||
if(mp_obj_is_int(args[0].u_obj)) {
|
||||
if(MP_OBJ_IS_INT(args[0].u_obj)) {
|
||||
size_t n = mp_obj_get_int(args[0].u_obj);
|
||||
ndarray = create_new_ndarray(1, n, dtype);
|
||||
} else if(mp_obj_is_type(args[0].u_obj, &mp_type_tuple)) {
|
||||
} else if(MP_OBJ_IS_TYPE(args[0].u_obj, &mp_type_tuple)) {
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(args[0].u_obj);
|
||||
if(tuple->len != 2) {
|
||||
mp_raise_TypeError(translate("input argument must be an integer or a 2-tuple"));
|
||||
|
|
@ -292,7 +291,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(linalg_ones_obj, 0, linalg_ones);
|
|||
mp_obj_t linalg_eye(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_M, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_M, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_k, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_dtype, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NDARRAY_FLOAT} },
|
||||
};
|
||||
|
|
@ -335,7 +334,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(linalg_eye_obj, 0, linalg_eye);
|
|||
|
||||
#if ULAB_LINALG_DET
|
||||
mp_obj_t linalg_det(mp_obj_t oin) {
|
||||
if(!mp_obj_is_type(oin, &ulab_ndarray_type)) {
|
||||
if(!MP_OBJ_IS_TYPE(oin, &ulab_ndarray_type)) {
|
||||
mp_raise_TypeError(translate("function defined for ndarrays only"));
|
||||
}
|
||||
ndarray_obj_t *in = MP_OBJ_TO_PTR(oin);
|
||||
|
|
@ -376,7 +375,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(linalg_det_obj, linalg_det);
|
|||
|
||||
#if ULAB_LINALG_EIG
|
||||
mp_obj_t linalg_eig(mp_obj_t oin) {
|
||||
if(!mp_obj_is_type(oin, &ulab_ndarray_type)) {
|
||||
if(!MP_OBJ_IS_TYPE(oin, &ulab_ndarray_type)) {
|
||||
mp_raise_TypeError(translate("function defined for ndarrays only"));
|
||||
}
|
||||
ndarray_obj_t *in = MP_OBJ_TO_PTR(oin);
|
||||
|
|
|
|||
102
code/ndarray.c
102
code/ndarray.c
|
|
@ -17,7 +17,6 @@
|
|||
#include "py/binary.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "compat.h"
|
||||
#include "ndarray.h"
|
||||
|
||||
// This function is copied verbatim from objarray.c
|
||||
|
|
@ -155,7 +154,7 @@ mp_obj_t ndarray_copy(mp_obj_t self_in) {
|
|||
|
||||
STATIC uint8_t ndarray_init_helper(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_dtype, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NDARRAY_FLOAT } },
|
||||
};
|
||||
|
||||
|
|
@ -166,13 +165,7 @@ STATIC uint8_t ndarray_init_helper(size_t n_args, const mp_obj_t *pos_args, mp_m
|
|||
return dtype;
|
||||
}
|
||||
|
||||
mp_obj_t ndarray_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
mp_arg_check_num(n_args, kw_args, 1, 2, true);
|
||||
size_t n_kw = 0;
|
||||
if (kw_args != 0) {
|
||||
n_kw = kw_args->used;
|
||||
}
|
||||
mp_map_init_fixed_table(kw_args, n_kw, args + n_args);
|
||||
STATIC mp_obj_t ndarray_make_new_core(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
uint8_t dtype = ndarray_init_helper(n_args, args, kw_args);
|
||||
|
||||
size_t len1, len2=0, i=0;
|
||||
|
|
@ -219,6 +212,25 @@ mp_obj_t ndarray_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj
|
|||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
#ifdef CIRCUITPY
|
||||
mp_obj_t ndarray_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
mp_arg_check_num(n_args, kw_args, 1, 2, true);
|
||||
size_t n_kw = 0;
|
||||
if (kw_args != 0) {
|
||||
n_kw = kw_args->used;
|
||||
}
|
||||
mp_map_init_fixed_table(kw_args, n_kw, args + n_args);
|
||||
return ndarray_make_new_core(type, n_args, n_kw, args, kw_args);
|
||||
}
|
||||
#else
|
||||
mp_obj_t ndarray_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 1, 2, true);
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
return ndarray_make_new_core(type, n_args, n_kw, args, &kw_args);
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t slice_length(mp_bound_slice_t slice) {
|
||||
int32_t len, correction = 1;
|
||||
if(slice.step > 0) correction = -1;
|
||||
|
|
@ -234,7 +246,7 @@ size_t true_length(mp_obj_t bool_list) {
|
|||
mp_obj_t item, iterable = mp_getiter(bool_list, &iter_buf);
|
||||
size_t trues = 0;
|
||||
while((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
|
||||
if(!mp_obj_is_type(item, &mp_type_bool)) {
|
||||
if(!MP_OBJ_IS_TYPE(item, &mp_type_bool)) {
|
||||
// numpy seems to be a little bit inconsistent in when an index is considered
|
||||
// to be True/False. Bail out immediately, if the items are not True/False
|
||||
return 0;
|
||||
|
|
@ -249,9 +261,9 @@ size_t true_length(mp_obj_t bool_list) {
|
|||
mp_bound_slice_t generate_slice(mp_uint_t n, mp_obj_t index) {
|
||||
// micropython seems to have difficulties with negative steps
|
||||
mp_bound_slice_t slice;
|
||||
if(mp_obj_is_type(index, &mp_type_slice)) {
|
||||
if(MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
|
||||
mp_seq_get_fast_slice_indexes(n, index, &slice);
|
||||
} else if(mp_obj_is_int(index)) {
|
||||
} else if(MP_OBJ_IS_INT(index)) {
|
||||
int32_t _index = mp_obj_get_int(index);
|
||||
if(_index < 0) {
|
||||
_index += n;
|
||||
|
|
@ -465,7 +477,7 @@ mp_obj_t ndarray_get_slice(ndarray_obj_t *ndarray, mp_obj_t index, ndarray_obj_t
|
|||
mp_bound_slice_t row_slice = simple_slice(0, 0, 1), column_slice = simple_slice(0, 0, 1);
|
||||
|
||||
size_t m = 0, n = 0;
|
||||
if(mp_obj_is_int(index) && (ndarray->m == 1) && (values == NULL)) {
|
||||
if(MP_OBJ_IS_INT(index) && (ndarray->m == 1) && (values == NULL)) {
|
||||
// we have a row vector, and don't want to assign
|
||||
column_slice = generate_slice(ndarray->n, index);
|
||||
if(slice_length(column_slice) == 1) { // we were asked for a single item
|
||||
|
|
@ -474,7 +486,7 @@ mp_obj_t ndarray_get_slice(ndarray_obj_t *ndarray, mp_obj_t index, ndarray_obj_t
|
|||
}
|
||||
}
|
||||
|
||||
if(mp_obj_is_int(index) || mp_obj_is_type(index, &mp_type_slice)) {
|
||||
if(MP_OBJ_IS_INT(index) || MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
|
||||
if(ndarray->m == 1) { // we have a row vector
|
||||
column_slice = generate_slice(ndarray->n, index);
|
||||
row_slice = simple_slice(0, 1, 1);
|
||||
|
|
@ -485,7 +497,7 @@ mp_obj_t ndarray_get_slice(ndarray_obj_t *ndarray, mp_obj_t index, ndarray_obj_t
|
|||
m = slice_length(row_slice);
|
||||
n = slice_length(column_slice);
|
||||
return iterate_slice_list(ndarray, m, n, row_slice, column_slice, mp_const_none, mp_const_none, values);
|
||||
} else if(mp_obj_is_type(index, &mp_type_list)) {
|
||||
} else if(MP_OBJ_IS_TYPE(index, &mp_type_list)) {
|
||||
n = true_length(index);
|
||||
if(ndarray->m == 1) { // we have a flat array
|
||||
// we might have to separate the n == 1 case
|
||||
|
|
@ -500,17 +512,17 @@ mp_obj_t ndarray_get_slice(ndarray_obj_t *ndarray, mp_obj_t index, ndarray_obj_t
|
|||
if(tuple->len != 2) {
|
||||
mp_raise_msg(&mp_type_IndexError, translate("too many indices"));
|
||||
}
|
||||
if(!(mp_obj_is_type(tuple->items[0], &mp_type_list) ||
|
||||
mp_obj_is_type(tuple->items[0], &mp_type_slice) ||
|
||||
mp_obj_is_int(tuple->items[0])) ||
|
||||
!(mp_obj_is_type(tuple->items[1], &mp_type_list) ||
|
||||
mp_obj_is_type(tuple->items[1], &mp_type_slice) ||
|
||||
mp_obj_is_int(tuple->items[1]))) {
|
||||
if(!(MP_OBJ_IS_TYPE(tuple->items[0], &mp_type_list) ||
|
||||
MP_OBJ_IS_TYPE(tuple->items[0], &mp_type_slice) ||
|
||||
MP_OBJ_IS_INT(tuple->items[0])) ||
|
||||
!(MP_OBJ_IS_TYPE(tuple->items[1], &mp_type_list) ||
|
||||
MP_OBJ_IS_TYPE(tuple->items[1], &mp_type_slice) ||
|
||||
MP_OBJ_IS_INT(tuple->items[1]))) {
|
||||
mp_raise_msg(&mp_type_IndexError, translate("indices must be integers, slices, or Boolean lists"));
|
||||
}
|
||||
if(mp_obj_is_type(tuple->items[0], &mp_type_list)) { // rows are indexed by Boolean list
|
||||
if(MP_OBJ_IS_TYPE(tuple->items[0], &mp_type_list)) { // rows are indexed by Boolean list
|
||||
m = true_length(tuple->items[0]);
|
||||
if(mp_obj_is_type(tuple->items[1], &mp_type_list)) {
|
||||
if(MP_OBJ_IS_TYPE(tuple->items[1], &mp_type_list)) {
|
||||
n = true_length(tuple->items[1]);
|
||||
return iterate_slice_list(ndarray, m, n, row_slice, column_slice,
|
||||
tuple->items[0], tuple->items[1], values);
|
||||
|
|
@ -524,7 +536,7 @@ mp_obj_t ndarray_get_slice(ndarray_obj_t *ndarray, mp_obj_t index, ndarray_obj_t
|
|||
} else { // rows are indexed by a slice, or an integer
|
||||
row_slice = generate_slice(ndarray->m, tuple->items[0]);
|
||||
m = slice_length(row_slice);
|
||||
if(mp_obj_is_type(tuple->items[1], &mp_type_list)) { // columns are indexed by a Boolean list
|
||||
if(MP_OBJ_IS_TYPE(tuple->items[1], &mp_type_list)) { // columns are indexed by a Boolean list
|
||||
n = true_length(tuple->items[1]);
|
||||
return iterate_slice_list(ndarray, m, n, row_slice, column_slice,
|
||||
mp_const_none, tuple->items[1], values);
|
||||
|
|
@ -545,12 +557,12 @@ mp_obj_t ndarray_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
|||
if (value == MP_OBJ_SENTINEL) { // return value(s)
|
||||
return ndarray_get_slice(self, index, NULL);
|
||||
} else { // assignment to slices; the value must be an ndarray, or a scalar
|
||||
if(!mp_obj_is_type(value, &ulab_ndarray_type) &&
|
||||
!mp_obj_is_int(value) && !mp_obj_is_float(value)) {
|
||||
if(!MP_OBJ_IS_TYPE(value, &ulab_ndarray_type) &&
|
||||
!MP_OBJ_IS_INT(value) && !mp_obj_is_float(value)) {
|
||||
mp_raise_ValueError(translate("right hand side must be an ndarray, or a scalar"));
|
||||
} else {
|
||||
ndarray_obj_t *values = NULL;
|
||||
if(mp_obj_is_int(value)) {
|
||||
if(MP_OBJ_IS_INT(value)) {
|
||||
values = create_new_ndarray(1, 1, self->array->typecode);
|
||||
mp_binary_set_val_array(values->array->typecode, values->array->items, 0, value);
|
||||
} else if(mp_obj_is_float(value)) {
|
||||
|
|
@ -628,22 +640,14 @@ mp_obj_t ndarray_shape(mp_obj_t self_in) {
|
|||
return mp_obj_new_tuple(2, tuple);
|
||||
}
|
||||
|
||||
mp_obj_t ndarray_rawsize(mp_obj_t self_in) {
|
||||
// returns a 5-tuple with the
|
||||
//
|
||||
// 0. number of rows
|
||||
// 1. number of columns
|
||||
// 2. length of the storage (should be equal to the product of 1. and 2.)
|
||||
// 3. length of the data storage in bytes
|
||||
// 4. datum size in bytes
|
||||
mp_obj_t ndarray_size(mp_obj_t self_in) {
|
||||
ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL));
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(self->m);
|
||||
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(self->n);
|
||||
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(self->array->len);
|
||||
tuple->items[3] = MP_OBJ_NEW_SMALL_INT(self->bytes);
|
||||
tuple->items[4] = MP_OBJ_NEW_SMALL_INT(mp_binary_get_size('@', self->array->typecode, NULL));
|
||||
return tuple;
|
||||
return mp_obj_new_int(self->array->len);
|
||||
}
|
||||
|
||||
mp_obj_t ndarray_itemsize(mp_obj_t self_in) {
|
||||
ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return MP_OBJ_NEW_SMALL_INT(mp_binary_get_size('@', self->array->typecode, NULL));
|
||||
}
|
||||
|
||||
mp_obj_t ndarray_flatten(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
|
|
@ -692,7 +696,7 @@ mp_obj_t ndarray_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
|||
// TODO: implement in-place operators
|
||||
mp_obj_t RHS = MP_OBJ_NULL;
|
||||
bool rhs_is_scalar = true;
|
||||
if(mp_obj_is_int(rhs)) {
|
||||
if(MP_OBJ_IS_INT(rhs)) {
|
||||
int32_t ivalue = mp_obj_get_int(rhs);
|
||||
if((ivalue > 0) && (ivalue < 256)) {
|
||||
CREATE_SINGLE_ITEM(RHS, uint8_t, NDARRAY_UINT8, ivalue);
|
||||
|
|
@ -713,7 +717,7 @@ mp_obj_t ndarray_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
|||
rhs_is_scalar = false;
|
||||
}
|
||||
//else
|
||||
if(mp_obj_is_type(lhs, &ulab_ndarray_type) && mp_obj_is_type(RHS, &ulab_ndarray_type)) {
|
||||
if(MP_OBJ_IS_TYPE(lhs, &ulab_ndarray_type) && MP_OBJ_IS_TYPE(RHS, &ulab_ndarray_type)) {
|
||||
// next, the ndarray stuff
|
||||
ndarray_obj_t *ol = MP_OBJ_TO_PTR(lhs);
|
||||
ndarray_obj_t *or = MP_OBJ_TO_PTR(RHS);
|
||||
|
|
@ -913,3 +917,13 @@ mp_int_t ndarray_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint
|
|||
// buffer_p.get_buffer() returns zero for success, while mp_get_buffer returns true for success
|
||||
return !mp_get_buffer(self->array, bufinfo, flags);
|
||||
}
|
||||
|
||||
void ndarray_attributes(mp_obj_t self_in, qstr attribute, mp_obj_t *destination) {
|
||||
if(attribute == MP_QSTR_size) {
|
||||
destination[0] = ndarray_size(self_in);
|
||||
} else if(attribute == MP_QSTR_itemsize) {
|
||||
destination[0] = ndarray_itemsize(self_in);
|
||||
} else if(attribute == MP_QSTR_shape) {
|
||||
destination[0] = ndarray_shape(self_in);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,17 +58,23 @@ void ndarray_assign_elements(mp_obj_array_t *, mp_obj_t , uint8_t , size_t *);
|
|||
ndarray_obj_t *create_new_ndarray(size_t , size_t , uint8_t );
|
||||
|
||||
mp_obj_t ndarray_copy(mp_obj_t );
|
||||
#ifdef CIRCUITPY
|
||||
mp_obj_t ndarray_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args);
|
||||
#else
|
||||
mp_obj_t ndarray_make_new(const mp_obj_type_t *, size_t , size_t , const mp_obj_t *);
|
||||
#endif
|
||||
mp_obj_t ndarray_subscr(mp_obj_t , mp_obj_t , mp_obj_t );
|
||||
mp_obj_t ndarray_getiter(mp_obj_t , mp_obj_iter_buf_t *);
|
||||
mp_obj_t ndarray_binary_op(mp_binary_op_t , mp_obj_t , mp_obj_t );
|
||||
mp_obj_t ndarray_unary_op(mp_unary_op_t , mp_obj_t );
|
||||
|
||||
mp_obj_t ndarray_shape(mp_obj_t );
|
||||
mp_obj_t ndarray_rawsize(mp_obj_t );
|
||||
mp_obj_t ndarray_size(mp_obj_t );
|
||||
mp_obj_t ndarray_flatten(size_t , const mp_obj_t *, mp_map_t *);
|
||||
mp_int_t ndarray_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags);
|
||||
|
||||
void ndarray_attributes(mp_obj_t , qstr , mp_obj_t *);
|
||||
|
||||
#define CREATE_SINGLE_ITEM(outarray, type, typecode, value) do {\
|
||||
ndarray_obj_t *tmp = create_new_ndarray(1, 1, (typecode));\
|
||||
type *tmparr = (type *)tmp->array->items;\
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/builtin.h"
|
||||
#include "py/misc.h"
|
||||
#include "compat.h"
|
||||
#include "numerical.h"
|
||||
|
||||
enum NUMERICAL_FUNCTION_TYPE {
|
||||
|
|
@ -33,11 +32,11 @@ enum NUMERICAL_FUNCTION_TYPE {
|
|||
#if ULAB_NUMERICAL_LINSPACE
|
||||
mp_obj_t numerical_linspace(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_num, MP_ARG_INT, {.u_int = 50} },
|
||||
{ MP_QSTR_endpoint, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_TRUE} },
|
||||
{ MP_QSTR_retstep, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_FALSE} },
|
||||
{ MP_QSTR_endpoint, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_true} },
|
||||
{ MP_QSTR_retstep, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_false} },
|
||||
{ MP_QSTR_dtype, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NDARRAY_FLOAT} },
|
||||
};
|
||||
|
||||
|
|
@ -259,8 +258,8 @@ mp_obj_t numerical_argmin_argmax_ndarray(ndarray_obj_t *ndarray, mp_obj_t axis,
|
|||
|
||||
STATIC mp_obj_t numerical_function(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, uint8_t optype) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} } ,
|
||||
{ MP_QSTR_axis, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} } ,
|
||||
{ MP_QSTR_axis, MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
};
|
||||
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
|
|
@ -345,8 +344,8 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_mean_obj, 1, numerical_mean);
|
|||
|
||||
mp_obj_t numerical_std(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } } ,
|
||||
{ MP_QSTR_axis, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } } ,
|
||||
{ MP_QSTR_axis, MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_ddof, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
};
|
||||
|
||||
|
|
@ -376,9 +375,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_std_obj, 1, numerical_std);
|
|||
#if ULAB_NUMERICAL_ROLL
|
||||
mp_obj_t numerical_roll(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_axis, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_axis, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
};
|
||||
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
|
|
@ -460,14 +459,14 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_roll_obj, 2, numerical_roll);
|
|||
#if ULAB_NUMERICAL_FLIP
|
||||
mp_obj_t numerical_flip(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_axis, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_axis, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
};
|
||||
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(1, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
if(!mp_obj_is_type(args[0].u_obj, &ulab_ndarray_type)) {
|
||||
if(!MP_OBJ_IS_TYPE(args[0].u_obj, &ulab_ndarray_type)) {
|
||||
mp_raise_TypeError(translate("flip argument must be an ndarray"));
|
||||
}
|
||||
if((args[1].u_obj != mp_const_none) &&
|
||||
|
|
@ -511,7 +510,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_flip_obj, 1, numerical_flip);
|
|||
#if ULAB_NUMERICAL_DIFF
|
||||
mp_obj_t numerical_diff(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_n, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1 } },
|
||||
{ MP_QSTR_axis, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1 } },
|
||||
};
|
||||
|
|
@ -519,7 +518,7 @@ mp_obj_t numerical_diff(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
|
|||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(1, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
if(!mp_obj_is_type(args[0].u_obj, &ulab_ndarray_type)) {
|
||||
if(!MP_OBJ_IS_TYPE(args[0].u_obj, &ulab_ndarray_type)) {
|
||||
mp_raise_TypeError(translate("diff argument must be an ndarray"));
|
||||
}
|
||||
|
||||
|
|
@ -582,7 +581,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_diff_obj, 1, numerical_diff);
|
|||
|
||||
#if ULAB_NUMERICAL_SORT
|
||||
mp_obj_t numerical_sort_helper(mp_obj_t oin, mp_obj_t axis, uint8_t inplace) {
|
||||
if(!mp_obj_is_type(oin, &ulab_ndarray_type)) {
|
||||
if(!MP_OBJ_IS_TYPE(oin, &ulab_ndarray_type)) {
|
||||
mp_raise_TypeError(translate("sort argument must be an ndarray"));
|
||||
}
|
||||
|
||||
|
|
@ -640,7 +639,7 @@ mp_obj_t numerical_sort_helper(mp_obj_t oin, mp_obj_t axis, uint8_t inplace) {
|
|||
// numpy function
|
||||
mp_obj_t numerical_sort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_axis, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_int = -1 } },
|
||||
};
|
||||
|
||||
|
|
@ -655,7 +654,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_sort_obj, 1, numerical_sort);
|
|||
// method of an ndarray
|
||||
mp_obj_t numerical_sort_inplace(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_axis, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_int = -1 } },
|
||||
};
|
||||
|
||||
|
|
@ -671,12 +670,12 @@ MP_DEFINE_CONST_FUN_OBJ_KW(numerical_sort_inplace_obj, 1, numerical_sort_inplace
|
|||
#if ULAB_NUMERICAL_ARGSORT
|
||||
mp_obj_t numerical_argsort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } },
|
||||
{ MP_QSTR_axis, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_int = -1 } },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(1, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
if(!mp_obj_is_type(args[0].u_obj, &ulab_ndarray_type)) {
|
||||
if(!MP_OBJ_IS_TYPE(args[0].u_obj, &ulab_ndarray_type)) {
|
||||
mp_raise_TypeError(translate("argsort argument must be an ndarray"));
|
||||
}
|
||||
|
||||
|
|
|
|||
13
code/poly.c
13
code/poly.c
|
|
@ -12,24 +12,23 @@
|
|||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/objarray.h"
|
||||
#include "compat.h"
|
||||
#include "ndarray.h"
|
||||
#include "linalg.h"
|
||||
#include "poly.h"
|
||||
|
||||
#if ULAB_POLY_POLYVAL || ULAB_POLY_POLYFIT
|
||||
bool object_is_nditerable(mp_obj_t o_in) {
|
||||
if(mp_obj_is_type(o_in, &ulab_ndarray_type) ||
|
||||
mp_obj_is_type(o_in, &mp_type_tuple) ||
|
||||
mp_obj_is_type(o_in, &mp_type_list) ||
|
||||
mp_obj_is_type(o_in, &mp_type_range)) {
|
||||
if(MP_OBJ_IS_TYPE(o_in, &ulab_ndarray_type) ||
|
||||
MP_OBJ_IS_TYPE(o_in, &mp_type_tuple) ||
|
||||
MP_OBJ_IS_TYPE(o_in, &mp_type_list) ||
|
||||
MP_OBJ_IS_TYPE(o_in, &mp_type_range)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t get_nditerable_len(mp_obj_t o_in) {
|
||||
if(mp_obj_is_type(o_in, &ulab_ndarray_type)) {
|
||||
if(MP_OBJ_IS_TYPE(o_in, &ulab_ndarray_type)) {
|
||||
ndarray_obj_t *in = MP_OBJ_TO_PTR(o_in);
|
||||
return in->array->len;
|
||||
} else {
|
||||
|
|
@ -44,7 +43,7 @@ mp_obj_t poly_polyval(mp_obj_t o_p, mp_obj_t o_x) {
|
|||
// TODO: there is a bug here: matrices won't work,
|
||||
// because there is a single iteration loop
|
||||
size_t m, n;
|
||||
if(mp_obj_is_type(o_x, &ulab_ndarray_type)) {
|
||||
if(MP_OBJ_IS_TYPE(o_x, &ulab_ndarray_type)) {
|
||||
ndarray_obj_t *ndx = MP_OBJ_TO_PTR(o_x);
|
||||
m = ndx->m;
|
||||
n = ndx->n;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include "py/objarray.h"
|
||||
|
||||
#include "ulab.h"
|
||||
#include "compat.h"
|
||||
#include "ndarray.h"
|
||||
#include "linalg.h"
|
||||
#include "vectorise.h"
|
||||
|
|
@ -28,16 +27,13 @@
|
|||
#include "filter.h"
|
||||
#include "numerical.h"
|
||||
|
||||
STATIC MP_DEFINE_STR_OBJ(ulab_version_obj, "0.31.0");
|
||||
STATIC MP_DEFINE_STR_OBJ(ulab_version_obj, "0.32.0");
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_shape_obj, ndarray_shape);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_rawsize_obj, ndarray_rawsize);
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(ndarray_flatten_obj, 1, ndarray_flatten);
|
||||
|
||||
STATIC const mp_rom_map_elem_t ulab_ndarray_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_shape), MP_ROM_PTR(&ndarray_shape_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_rawsize), MP_ROM_PTR(&ndarray_rawsize_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_flatten), MP_ROM_PTR(&ndarray_flatten_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_flatten), MP_ROM_PTR(&ndarray_flatten_obj) },
|
||||
#if ULAB_LINALG_TRANSPOSE
|
||||
{ MP_ROM_QSTR(MP_QSTR_transpose), MP_ROM_PTR(&linalg_transpose_obj) },
|
||||
#endif
|
||||
|
|
@ -60,6 +56,7 @@ const mp_obj_type_t ulab_ndarray_type = {
|
|||
.binary_op = ndarray_binary_op,
|
||||
.buffer_p = { .get_buffer = ndarray_get_buffer, },
|
||||
.locals_dict = (mp_obj_dict_t*)&ulab_ndarray_locals_dict,
|
||||
.attr = ndarray_attributes,
|
||||
};
|
||||
|
||||
STATIC const mp_map_elem_t ulab_globals_table[] = {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@
|
|||
#define ULAB_POLY_POLYFIT (1)
|
||||
|
||||
//
|
||||
#define ULAB_NUMERICAL_ARGSORT (1)
|
||||
#define ULAB_NUMERICAL_LINSPACE (1)
|
||||
#define ULAB_NUMERICAL_SUM (1)
|
||||
#define ULAB_NUMERICAL_MEAN (1)
|
||||
|
|
@ -67,6 +66,7 @@
|
|||
#define ULAB_NUMERICAL_FLIP (1)
|
||||
#define ULAB_NUMERICAL_DIFF (1)
|
||||
#define ULAB_NUMERICAL_SORT (1)
|
||||
#define ULAB_NUMERICAL_ARGSORT (1)
|
||||
|
||||
// FFT costs about 2 kB of flash space
|
||||
#define ULAB_FFT_FFT (1)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
#include "py/binary.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objarray.h"
|
||||
#include "compat.h"
|
||||
#include "vectorise.h"
|
||||
|
||||
#ifndef MP_PI
|
||||
|
|
@ -25,11 +24,11 @@
|
|||
|
||||
mp_obj_t vectorise_generic_vector(mp_obj_t o_in, mp_float_t (*f)(mp_float_t)) {
|
||||
// Return a single value, if o_in is not iterable
|
||||
if(mp_obj_is_float(o_in) || mp_obj_is_integer(o_in)) {
|
||||
if(mp_obj_is_float(o_in) || MP_OBJ_IS_INT(o_in)) {
|
||||
return mp_obj_new_float(f(mp_obj_get_float(o_in)));
|
||||
}
|
||||
mp_float_t x;
|
||||
if(mp_obj_is_type(o_in, &ulab_ndarray_type)) {
|
||||
if(MP_OBJ_IS_TYPE(o_in, &ulab_ndarray_type)) {
|
||||
ndarray_obj_t *source = MP_OBJ_TO_PTR(o_in);
|
||||
ndarray_obj_t *ndarray = create_new_ndarray(source->m, source->n, NDARRAY_FLOAT);
|
||||
mp_float_t *dataout = (mp_float_t *)ndarray->array->items;
|
||||
|
|
@ -45,8 +44,8 @@ mp_obj_t vectorise_generic_vector(mp_obj_t o_in, mp_float_t (*f)(mp_float_t)) {
|
|||
ITERATE_VECTOR(mp_float_t, source, dataout);
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(ndarray);
|
||||
} else if(mp_obj_is_type(o_in, &mp_type_tuple) || mp_obj_is_type(o_in, &mp_type_list) ||
|
||||
mp_obj_is_type(o_in, &mp_type_range)) { // i.e., the input is a generic iterable
|
||||
} else if(MP_OBJ_IS_TYPE(o_in, &mp_type_tuple) || MP_OBJ_IS_TYPE(o_in, &mp_type_list) ||
|
||||
MP_OBJ_IS_TYPE(o_in, &mp_type_range)) { // i.e., the input is a generic iterable
|
||||
mp_obj_array_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
ndarray_obj_t *out = create_new_ndarray(1, o->len, NDARRAY_FLOAT);
|
||||
mp_float_t *dataout = (mp_float_t *)out->array->items;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ copyright = '2019, Zoltán Vörös'
|
|||
author = 'Zoltán Vörös'
|
||||
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = '0.31'
|
||||
release = '0.32'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
Introduction
|
||||
============
|
||||
|
||||
In
|
||||
https://micropython-usermod.readthedocs.io/en/latest/usermods_14.html, I
|
||||
mentioned that I have another story, for another day. The day has come,
|
||||
so here is my story.
|
||||
In the `last
|
||||
chapter <https://micropython-usermod.readthedocs.io/en/latest/usermods_15.html>`__
|
||||
of the usermod documentation, I mentioned that I have another story, for
|
||||
another day. The day has come, so here is my story.
|
||||
|
||||
Enter ulab
|
||||
----------
|
||||
|
|
@ -68,9 +68,11 @@ The main points of ``ulab`` are
|
|||
- polynomial fits to numerical data
|
||||
- fast Fourier transforms
|
||||
|
||||
At the time of writing this manual (for version 0.26), the library adds
|
||||
At the time of writing this manual (for version 0.32), the library adds
|
||||
approximately 30 kB of extra compiled code to the micropython
|
||||
(pyboard.v.11) firmware.
|
||||
(pyboard.v.11) firmware. However, if you are tight with flash space, you
|
||||
can easily shave off a couple of kB. See the section on `customising
|
||||
ulab <#Custom_builds>`__.
|
||||
|
||||
Resources and legal matters
|
||||
---------------------------
|
||||
|
|
@ -143,6 +145,35 @@ can always be queried as
|
|||
|
||||
If you find a bug, please, include this number in your report!
|
||||
|
||||
Customising ``ulab``
|
||||
--------------------
|
||||
|
||||
``ulab`` implements a great number of functions, and it is quite
|
||||
possible that you do not need all of them in a particular application.
|
||||
If you want to save some flash space, you can easily exclude arbitrary
|
||||
functions from the firmware. The
|
||||
`https://github.com/v923z/micropython-ulab/blob/master/code/ulab.h <ulab.h>`__
|
||||
header file contains a pre-processor flag for all functions in ``ulab``.
|
||||
The default setting is 1 for each of them, but if you change that to 0,
|
||||
the corresponding function will not be part of the compiled firmware.
|
||||
|
||||
The first couple of lines of the file look like this
|
||||
|
||||
.. code:: c
|
||||
|
||||
// vectorise (all functions) takes approx. 3 kB of flash space
|
||||
#define ULAB_VECTORISE_ACOS (1)
|
||||
#define ULAB_VECTORISE_ACOSH (1)
|
||||
#define ULAB_VECTORISE_ASIN (1)
|
||||
#define ULAB_VECTORISE_ASINH (1)
|
||||
#define ULAB_VECTORISE_ATAN (1)
|
||||
#define ULAB_VECTORISE_ATANH (1)
|
||||
|
||||
In order to simplify navigation in the file, each flag begins with
|
||||
``ULAB_``, continues with the sub-module, where the function itself is
|
||||
implemented, and ends with the function’s name. Each section displays a
|
||||
hint as to how much space you can save by un-setting the flag.
|
||||
|
||||
Basic ndarray operations
|
||||
------------------------
|
||||
|
||||
|
|
@ -166,8 +197,6 @@ Methods of ndarrays
|
|||
|
||||
`.reshape <#.reshape>`__
|
||||
|
||||
`.rawsize\*\* <#.rawsize>`__
|
||||
|
||||
`.transpose <#.transpose>`__
|
||||
|
||||
`.flatten\*\* <#.flatten>`__
|
||||
|
|
@ -395,8 +424,8 @@ Methods of ndarrays
|
|||
.shape
|
||||
~~~~~~
|
||||
|
||||
The ``.shape`` method returns a 2-tuple with the number of rows, and
|
||||
columns.
|
||||
The ``.shape`` method (property) returns a 2-tuple with the number of
|
||||
rows, and columns.
|
||||
|
||||
.. code::
|
||||
|
||||
|
|
@ -406,11 +435,11 @@ columns.
|
|||
|
||||
a = np.array([1, 2, 3, 4], dtype=np.int8)
|
||||
print("a:\n", a)
|
||||
print("shape of a:", a.shape())
|
||||
print("shape of a:", a.shape)
|
||||
|
||||
b= np.array([[1, 2], [3, 4]], dtype=np.int8)
|
||||
print("\nb:\n", b)
|
||||
print("shape of b:", b.shape())
|
||||
print("shape of b:", b.shape)
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
|
|
@ -426,6 +455,74 @@ columns.
|
|||
|
||||
|
||||
|
||||
.size
|
||||
~~~~~
|
||||
|
||||
The ``.size`` method (property) returns an integer with the number of
|
||||
elements in the array.
|
||||
|
||||
.. code::
|
||||
|
||||
# code to be run in micropython
|
||||
|
||||
import ulab as np
|
||||
|
||||
a = np.array([1, 2, 3], dtype=np.int8)
|
||||
print("a:\n", a)
|
||||
print("size of a:", a.size)
|
||||
|
||||
b= np.array([[1, 2], [3, 4]], dtype=np.int8)
|
||||
print("\nb:\n", b)
|
||||
print("size of b:", b.size)
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
a:
|
||||
array([1, 2, 3], dtype=int8)
|
||||
size of a: 3
|
||||
|
||||
b:
|
||||
array([[1, 2],
|
||||
[3, 4]], dtype=int8)
|
||||
size of b: 4
|
||||
|
||||
|
||||
|
||||
|
||||
.itemsize
|
||||
~~~~~~~~~
|
||||
|
||||
The ``.itemsize`` method (property) returns an integer with the siz
|
||||
enumber of elements in the array.
|
||||
|
||||
.. code::
|
||||
|
||||
# code to be run in micropython
|
||||
|
||||
import ulab as np
|
||||
|
||||
a = np.array([1, 2, 3], dtype=np.int8)
|
||||
print("a:\n", a)
|
||||
print("itemsize of a:", a.itemsize)
|
||||
|
||||
b= np.array([[1, 2], [3, 4]], dtype=np.float)
|
||||
print("\nb:\n", b)
|
||||
print("itemsize of b:", b.itemsize)
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
a:
|
||||
array([1, 2, 3], dtype=int8)
|
||||
itemsize of a: 1
|
||||
|
||||
b:
|
||||
array([[1.0, 2.0],
|
||||
[3.0, 4.0]], dtype=float)
|
||||
itemsize of b: 8
|
||||
|
||||
|
||||
|
||||
|
||||
.reshape
|
||||
~~~~~~~~
|
||||
|
||||
|
|
@ -462,41 +559,6 @@ consistent with the old, a ``ValueError`` exception will be raised.
|
|||
|
||||
|
||||
|
||||
.rawsize
|
||||
~~~~~~~~
|
||||
|
||||
The ``rawsize`` method of the ``ndarray`` returns a 5-tuple with the
|
||||
following data
|
||||
|
||||
1. number of rows
|
||||
2. number of columns
|
||||
3. length of the storage (should be equal to the product of 1. and 2.)
|
||||
4. length of the data storage in bytes
|
||||
5. datum size in bytes (1 for ``uint8``/``int8``, 2 for
|
||||
``uint16``/``int16``, and 4, or 8 for ``floats``, see `ndarray, the
|
||||
basic container <#ndarray,-the-basic-container>`__)
|
||||
|
||||
**WARNING:** ``rawsize`` is a ``ulab``-only method; it has no equivalent
|
||||
in ``numpy``.
|
||||
|
||||
.. code::
|
||||
|
||||
# code to be run in micropython
|
||||
|
||||
import ulab as np
|
||||
|
||||
a = np.array([1, 2, 3, 4], dtype=np.float)
|
||||
print("a: \t\t", a)
|
||||
print("rawsize of a: \t", a.rawsize())
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
a: array([1.0, 2.0, 3.0, 4.0], dtype=float)
|
||||
rawsize of a: (1, 4, 4, 16, 4)
|
||||
|
||||
|
||||
|
||||
|
||||
.flatten
|
||||
~~~~~~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,10 @@
|
|||
|
||||
Tue, 11 Feb 2020
|
||||
|
||||
version 0.32.0
|
||||
|
||||
added itemsize, size and shape attributes to ndarrays, and removed rawsize
|
||||
|
||||
Mon, 10 Feb 2020
|
||||
|
||||
version 0.31.0
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": 14,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-10T18:31:42.227494Z",
|
||||
"start_time": "2020-02-10T18:31:42.222100Z"
|
||||
"end_time": "2020-02-11T19:06:35.427133Z",
|
||||
"start_time": "2020-02-11T19:06:35.418598Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
|
|
@ -66,7 +66,7 @@
|
|||
"author = 'Zoltán Vörös'\n",
|
||||
"\n",
|
||||
"# The full version, including alpha/beta/rc tags\n",
|
||||
"release = '0.31'\n",
|
||||
"release = '0.32'\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# -- General configuration ---------------------------------------------------\n",
|
||||
|
|
@ -120,11 +120,11 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 16,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-10T18:49:03.206016Z",
|
||||
"start_time": "2020-02-10T18:49:00.047068Z"
|
||||
"end_time": "2020-02-11T20:30:43.287360Z",
|
||||
"start_time": "2020-02-11T20:30:40.308932Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
|
|
@ -478,7 +478,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In https://micropython-usermod.readthedocs.io/en/latest/usermods_14.html, I mentioned that I have another story, for another day. The day has come, so here is my story.\n",
|
||||
"In the [last chapter](https://micropython-usermod.readthedocs.io/en/latest/usermods_15.html) of the usermod documentation, I mentioned that I have another story, for another day. The day has come, so here is my story.\n",
|
||||
"\n",
|
||||
"## Enter ulab\n",
|
||||
"\n",
|
||||
|
|
@ -506,7 +506,7 @@
|
|||
"- polynomial fits to numerical data\n",
|
||||
"- fast Fourier transforms\n",
|
||||
"\n",
|
||||
"At the time of writing this manual (for version 0.26), the library adds approximately 30 kB of extra compiled code to the micropython (pyboard.v.11) firmware. \n",
|
||||
"At the time of writing this manual (for version 0.32), the library adds approximately 30 kB of extra compiled code to the micropython (pyboard.v.11) firmware. However, if you are tight with flash space, you can easily shave off a couple of kB. See the section on [customising ulab](#Custom_builds).\n",
|
||||
"\n",
|
||||
"## Resources and legal matters\n",
|
||||
"\n",
|
||||
|
|
@ -569,6 +569,29 @@
|
|||
"If you find a bug, please, include this number in your report!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Customising `ulab`\n",
|
||||
"\n",
|
||||
"`ulab` implements a great number of functions, and it is quite possible that you do not need all of them in a particular application. If you want to save some flash space, you can easily exclude arbitrary functions from the firmware. The [https://github.com/v923z/micropython-ulab/blob/master/code/ulab.h](ulab.h) header file contains a pre-processor flag for all functions in `ulab`. The default setting is 1 for each of them, but if you change that to 0, the corresponding function will not be part of the compiled firmware. \n",
|
||||
"\n",
|
||||
"The first couple of lines of the file look like this\n",
|
||||
"\n",
|
||||
"```c\n",
|
||||
"// vectorise (all functions) takes approx. 3 kB of flash space\n",
|
||||
"#define ULAB_VECTORISE_ACOS (1)\n",
|
||||
"#define ULAB_VECTORISE_ACOSH (1)\n",
|
||||
"#define ULAB_VECTORISE_ASIN (1)\n",
|
||||
"#define ULAB_VECTORISE_ASINH (1)\n",
|
||||
"#define ULAB_VECTORISE_ATAN (1)\n",
|
||||
"#define ULAB_VECTORISE_ATANH (1)\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"In order to simplify navigation in the file, each flag begins with `ULAB_`, continues with the sub-module, where the function itself is implemented, and ends with the function's name. Each section displays a hint as to how much space you can save by un-setting the flag."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
|
@ -594,8 +617,6 @@
|
|||
"\n",
|
||||
"[.reshape](#.reshape)\n",
|
||||
"\n",
|
||||
"[.rawsize<sup>**</sup>](#.rawsize)\n",
|
||||
"\n",
|
||||
"[.transpose](#.transpose)\n",
|
||||
"\n",
|
||||
"[.flatten<sup>**</sup>](#.flatten)\n",
|
||||
|
|
@ -845,16 +866,16 @@
|
|||
"source": [
|
||||
"### .shape\n",
|
||||
"\n",
|
||||
"The `.shape` method returns a 2-tuple with the number of rows, and columns."
|
||||
"The `.shape` method (property) returns a 2-tuple with the number of rows, and columns."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 283,
|
||||
"execution_count": 12,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2019-10-16T15:30:33.810628Z",
|
||||
"start_time": "2019-10-16T15:30:33.796088Z"
|
||||
"end_time": "2020-02-11T19:01:40.377272Z",
|
||||
"start_time": "2020-02-11T19:01:40.364448Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
|
|
@ -882,11 +903,111 @@
|
|||
"\n",
|
||||
"a = np.array([1, 2, 3, 4], dtype=np.int8)\n",
|
||||
"print(\"a:\\n\", a)\n",
|
||||
"print(\"shape of a:\", a.shape())\n",
|
||||
"print(\"shape of a:\", a.shape)\n",
|
||||
"\n",
|
||||
"b= np.array([[1, 2], [3, 4]], dtype=np.int8)\n",
|
||||
"print(\"\\nb:\\n\", b)\n",
|
||||
"print(\"shape of b:\", b.shape())"
|
||||
"print(\"shape of b:\", b.shape)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### .size\n",
|
||||
"\n",
|
||||
"The `.size` method (property) returns an integer with the number of elements in the array."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-11T06:32:22.721112Z",
|
||||
"start_time": "2020-02-11T06:32:22.713111Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"a:\n",
|
||||
" array([1, 2, 3], dtype=int8)\n",
|
||||
"size of a: 3\n",
|
||||
"\n",
|
||||
"b:\n",
|
||||
" array([[1, 2],\n",
|
||||
"\t [3, 4]], dtype=int8)\n",
|
||||
"size of b: 4\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%%micropython -unix 1\n",
|
||||
"\n",
|
||||
"import ulab as np\n",
|
||||
"\n",
|
||||
"a = np.array([1, 2, 3], dtype=np.int8)\n",
|
||||
"print(\"a:\\n\", a)\n",
|
||||
"print(\"size of a:\", a.size)\n",
|
||||
"\n",
|
||||
"b= np.array([[1, 2], [3, 4]], dtype=np.int8)\n",
|
||||
"print(\"\\nb:\\n\", b)\n",
|
||||
"print(\"size of b:\", b.size)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### .itemsize\n",
|
||||
"\n",
|
||||
"The `.itemsize` method (property) returns an integer with the siz enumber of elements in the array."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-11T19:05:04.296601Z",
|
||||
"start_time": "2020-02-11T19:05:04.280669Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"a:\n",
|
||||
" array([1, 2, 3], dtype=int8)\n",
|
||||
"itemsize of a: 1\n",
|
||||
"\n",
|
||||
"b:\n",
|
||||
" array([[1.0, 2.0],\n",
|
||||
"\t [3.0, 4.0]], dtype=float)\n",
|
||||
"itemsize of b: 8\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%%micropython -unix 1\n",
|
||||
"\n",
|
||||
"import ulab as np\n",
|
||||
"\n",
|
||||
"a = np.array([1, 2, 3], dtype=np.int8)\n",
|
||||
"print(\"a:\\n\", a)\n",
|
||||
"print(\"itemsize of a:\", a.itemsize)\n",
|
||||
"\n",
|
||||
"b= np.array([[1, 2], [3, 4]], dtype=np.float)\n",
|
||||
"print(\"\\nb:\\n\", b)\n",
|
||||
"print(\"itemsize of b:\", b.itemsize)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -937,54 +1058,6 @@
|
|||
"print('a (1 by 16):', a.reshape((1, 16)))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### .rawsize\n",
|
||||
"\n",
|
||||
"The `rawsize` method of the `ndarray` returns a 5-tuple with the following data\n",
|
||||
"\n",
|
||||
"1. number of rows\n",
|
||||
"2. number of columns\n",
|
||||
"3. length of the storage (should be equal to the product of 1. and 2.)\n",
|
||||
"4. length of the data storage in bytes \n",
|
||||
"5. datum size in bytes (1 for `uint8`/`int8`, 2 for `uint16`/`int16`, and 4, or 8 for `floats`, see [ndarray, the basic container](#ndarray,-the-basic-container))\n",
|
||||
"\n",
|
||||
"**WARNING:** `rawsize` is a `ulab`-only method; it has no equivalent in `numpy`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 510,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2019-10-19T17:44:26.983908Z",
|
||||
"start_time": "2019-10-19T17:44:26.764912Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"a: \t\t array([1.0, 2.0, 3.0, 4.0], dtype=float)\n",
|
||||
"rawsize of a: \t (1, 4, 4, 16, 4)\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%%micropython -unix 1\n",
|
||||
"\n",
|
||||
"import ulab as np\n",
|
||||
"\n",
|
||||
"a = np.array([1, 2, 3, 4], dtype=np.float)\n",
|
||||
"print(\"a: \\t\\t\", a)\n",
|
||||
"print(\"rawsize of a: \\t\", a.rawsize())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
|
|
|||
152
docs/ulab.ipynb
152
docs/ulab.ipynb
|
|
@ -65,11 +65,11 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-10T18:20:10.944642Z",
|
||||
"start_time": "2020-02-10T18:20:10.924517Z"
|
||||
"end_time": "2020-02-11T20:33:18.577747Z",
|
||||
"start_time": "2020-02-11T20:33:18.573974Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
|
|
@ -87,11 +87,11 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-10T18:20:13.006014Z",
|
||||
"start_time": "2020-02-10T18:20:13.002944Z"
|
||||
"end_time": "2020-02-11T20:33:20.962959Z",
|
||||
"start_time": "2020-02-11T20:33:20.959323Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
|
|
@ -137,8 +137,8 @@
|
|||
"execution_count": 4,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-10T18:20:20.164916Z",
|
||||
"start_time": "2020-02-10T18:20:20.148842Z"
|
||||
"end_time": "2020-02-11T20:33:23.430858Z",
|
||||
"start_time": "2020-02-11T20:33:23.371937Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
|
|
@ -328,8 +328,8 @@
|
|||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-10T18:20:23.136432Z",
|
||||
"start_time": "2020-02-10T18:20:23.131323Z"
|
||||
"end_time": "2020-02-11T20:33:26.033162Z",
|
||||
"start_time": "2020-02-11T20:33:26.022590Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
|
|
@ -485,11 +485,11 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 146,
|
||||
"execution_count": 6,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-08T09:29:05.558859Z",
|
||||
"start_time": "2020-02-08T09:29:05.554463Z"
|
||||
"end_time": "2020-02-11T20:33:32.082924Z",
|
||||
"start_time": "2020-02-11T20:33:32.077298Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
|
|
@ -497,7 +497,7 @@
|
|||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"written 2222 bytes to ulab.h\n"
|
||||
"written 2257 bytes to ulab.h\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
@ -571,6 +571,7 @@
|
|||
"#define ULAB_NUMERICAL_FLIP (1)\n",
|
||||
"#define ULAB_NUMERICAL_DIFF (1)\n",
|
||||
"#define ULAB_NUMERICAL_SORT (1)\n",
|
||||
"#define ULAB_NUMERICAL_ARGSORT (1)\n",
|
||||
"\n",
|
||||
"// FFT costs about 2 kB of flash space\n",
|
||||
"#define ULAB_FFT_FFT (1)\n",
|
||||
|
|
@ -3257,11 +3258,11 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 47,
|
||||
"execution_count": 94,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-10T18:53:20.754983Z",
|
||||
"start_time": "2020-02-10T18:53:20.750119Z"
|
||||
"end_time": "2020-02-11T18:55:55.931364Z",
|
||||
"start_time": "2020-02-11T18:55:55.925214Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
|
|
@ -3269,7 +3270,7 @@
|
|||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"written 5176 bytes to ndarray.h\n"
|
||||
"written 5229 bytes to ndarray.h\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
@ -3342,10 +3343,12 @@
|
|||
"mp_obj_t ndarray_unary_op(mp_unary_op_t , mp_obj_t );\n",
|
||||
"\n",
|
||||
"mp_obj_t ndarray_shape(mp_obj_t );\n",
|
||||
"mp_obj_t ndarray_rawsize(mp_obj_t );\n",
|
||||
"mp_obj_t ndarray_size(mp_obj_t );\n",
|
||||
"mp_obj_t ndarray_flatten(size_t , const mp_obj_t *, mp_map_t *);\n",
|
||||
"mp_int_t ndarray_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags);\n",
|
||||
"\n",
|
||||
"void ndarray_attributes(mp_obj_t , qstr , mp_obj_t *);\n",
|
||||
"\n",
|
||||
"#define CREATE_SINGLE_ITEM(outarray, type, typecode, value) do {\\\n",
|
||||
" ndarray_obj_t *tmp = create_new_ndarray(1, 1, (typecode));\\\n",
|
||||
" type *tmparr = (type *)tmp->array->items;\\\n",
|
||||
|
|
@ -3415,11 +3418,11 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"execution_count": 95,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-10T18:25:25.962312Z",
|
||||
"start_time": "2020-02-10T18:25:25.949802Z"
|
||||
"end_time": "2020-02-11T18:56:36.562847Z",
|
||||
"start_time": "2020-02-11T18:56:36.550136Z"
|
||||
},
|
||||
"code_folding": []
|
||||
},
|
||||
|
|
@ -3428,7 +3431,7 @@
|
|||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"written 41633 bytes to ndarray.c\n"
|
||||
"written 41568 bytes to ndarray.c\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
@ -4060,22 +4063,14 @@
|
|||
" return mp_obj_new_tuple(2, tuple);\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mp_obj_t ndarray_rawsize(mp_obj_t self_in) {\n",
|
||||
" // returns a 5-tuple with the \n",
|
||||
" // \n",
|
||||
" // 0. number of rows\n",
|
||||
" // 1. number of columns\n",
|
||||
" // 2. length of the storage (should be equal to the product of 1. and 2.)\n",
|
||||
" // 3. length of the data storage in bytes\n",
|
||||
" // 4. datum size in bytes\n",
|
||||
"mp_obj_t ndarray_size(mp_obj_t self_in) {\n",
|
||||
" ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in);\n",
|
||||
" mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL));\n",
|
||||
" tuple->items[0] = MP_OBJ_NEW_SMALL_INT(self->m);\n",
|
||||
" tuple->items[1] = MP_OBJ_NEW_SMALL_INT(self->n);\n",
|
||||
" tuple->items[2] = MP_OBJ_NEW_SMALL_INT(self->array->len);\n",
|
||||
" tuple->items[3] = MP_OBJ_NEW_SMALL_INT(self->bytes);\n",
|
||||
" tuple->items[4] = MP_OBJ_NEW_SMALL_INT(mp_binary_get_size('@', self->array->typecode, NULL));\n",
|
||||
" return tuple;\n",
|
||||
" return mp_obj_new_int(self->array->len);\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mp_obj_t ndarray_itemsize(mp_obj_t self_in) {\n",
|
||||
" ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in);\n",
|
||||
" return MP_OBJ_NEW_SMALL_INT(mp_binary_get_size('@', self->array->typecode, NULL));\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"mp_obj_t ndarray_flatten(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {\n",
|
||||
|
|
@ -4344,6 +4339,16 @@
|
|||
" ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in);\n",
|
||||
" // buffer_p.get_buffer() returns zero for success, while mp_get_buffer returns true for success\n",
|
||||
" return !mp_get_buffer(self->array, bufinfo, flags);\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"void ndarray_attributes(mp_obj_t self_in, qstr attribute, mp_obj_t *destination) {\n",
|
||||
" if(attribute == MP_QSTR_size) {\n",
|
||||
" destination[0] = ndarray_size(self_in);\n",
|
||||
" } else if(attribute == MP_QSTR_itemsize) {\n",
|
||||
" destination[0] = ndarray_itemsize(self_in);\n",
|
||||
" } else if(attribute == MP_QSTR_shape) {\n",
|
||||
" destination[0] = ndarray_shape(self_in);\n",
|
||||
" }\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
|
|
@ -8689,11 +8694,11 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"execution_count": 7,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-10T18:26:42.212459Z",
|
||||
"start_time": "2020-02-10T18:26:42.206522Z"
|
||||
"end_time": "2020-02-11T20:34:46.008810Z",
|
||||
"start_time": "2020-02-11T20:34:46.001076Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
|
|
@ -8701,7 +8706,7 @@
|
|||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"written 8310 bytes to ulab.c\n"
|
||||
"written 8137 bytes to ulab.c\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
@ -8736,16 +8741,13 @@
|
|||
"#include \"filter.h\"\n",
|
||||
"#include \"numerical.h\"\n",
|
||||
"\n",
|
||||
"STATIC MP_DEFINE_STR_OBJ(ulab_version_obj, \"0.31.0\");\n",
|
||||
"STATIC MP_DEFINE_STR_OBJ(ulab_version_obj, \"0.32.0\");\n",
|
||||
"\n",
|
||||
"MP_DEFINE_CONST_FUN_OBJ_1(ndarray_shape_obj, ndarray_shape);\n",
|
||||
"MP_DEFINE_CONST_FUN_OBJ_1(ndarray_rawsize_obj, ndarray_rawsize);\n",
|
||||
"MP_DEFINE_CONST_FUN_OBJ_KW(ndarray_flatten_obj, 1, ndarray_flatten);\n",
|
||||
"\n",
|
||||
"STATIC const mp_rom_map_elem_t ulab_ndarray_locals_dict_table[] = {\n",
|
||||
" { MP_ROM_QSTR(MP_QSTR_shape), MP_ROM_PTR(&ndarray_shape_obj) },\n",
|
||||
" { MP_ROM_QSTR(MP_QSTR_rawsize), MP_ROM_PTR(&ndarray_rawsize_obj) },\n",
|
||||
" { MP_ROM_QSTR(MP_QSTR_flatten), MP_ROM_PTR(&ndarray_flatten_obj) }, \n",
|
||||
" { MP_ROM_QSTR(MP_QSTR_flatten), MP_ROM_PTR(&ndarray_flatten_obj) },\n",
|
||||
" #if ULAB_LINALG_TRANSPOSE\n",
|
||||
" { MP_ROM_QSTR(MP_QSTR_transpose), MP_ROM_PTR(&linalg_transpose_obj) },\n",
|
||||
" #endif\n",
|
||||
|
|
@ -8768,6 +8770,7 @@
|
|||
" .binary_op = ndarray_binary_op,\n",
|
||||
" .buffer_p = { .get_buffer = ndarray_get_buffer, },\n",
|
||||
" .locals_dict = (mp_obj_dict_t*)&ulab_ndarray_locals_dict,\n",
|
||||
" .attr = ndarray_attributes,\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"STATIC const mp_map_elem_t ulab_globals_table[] = {\n",
|
||||
|
|
@ -8855,7 +8858,7 @@
|
|||
" #if ULAB_VECTORISE_SIN\n",
|
||||
" { MP_OBJ_NEW_QSTR(MP_QSTR_sin), (mp_obj_t)&vectorise_sin_obj },\n",
|
||||
" #endif\n",
|
||||
" #if ULAB_VECTORISE_\n",
|
||||
" #if ULAB_VECTORISE_SINH\n",
|
||||
" { MP_OBJ_NEW_QSTR(MP_QSTR_sinh), (mp_obj_t)&vectorise_sinh_obj },\n",
|
||||
" #endif\n",
|
||||
" #if ULAB_VECTORISE_SQRT\n",
|
||||
|
|
@ -8864,7 +8867,7 @@
|
|||
" #if ULAB_VECTORISE_TAN\n",
|
||||
" { MP_OBJ_NEW_QSTR(MP_QSTR_tan), (mp_obj_t)&vectorise_tan_obj },\n",
|
||||
" #endif\n",
|
||||
" #if ULAB_VECTORISE_TAHN\n",
|
||||
" #if ULAB_VECTORISE_TANH\n",
|
||||
" { MP_OBJ_NEW_QSTR(MP_QSTR_tanh), (mp_obj_t)&vectorise_tanh_obj },\n",
|
||||
" #endif\n",
|
||||
" #if ULAB_NUMERICAL_LINSPACE\n",
|
||||
|
|
@ -9028,11 +9031,11 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"execution_count": 87,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-10T18:38:17.217214Z",
|
||||
"start_time": "2020-02-10T18:38:16.985221Z"
|
||||
"end_time": "2020-02-11T18:47:50.796938Z",
|
||||
"start_time": "2020-02-11T18:47:50.497781Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
|
|
@ -9056,8 +9059,8 @@
|
|||
"execution_count": null,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-10T18:52:42.290540Z",
|
||||
"start_time": "2020-02-10T18:52:39.726501Z"
|
||||
"end_time": "2020-02-11T18:57:44.969887Z",
|
||||
"start_time": "2020-02-11T18:57:26.383775Z"
|
||||
},
|
||||
"scrolled": true
|
||||
},
|
||||
|
|
@ -9066,6 +9069,35 @@
|
|||
"!make USER_C_MODULES=../../../ulab CFLAGS_EXTRA=-DMODULE_ULAB_ENABLED=1 all"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 92,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-11T18:55:17.045304Z",
|
||||
"start_time": "2020-02-11T18:55:17.034858Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"8 3\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%%micropython -unix 1\n",
|
||||
"\n",
|
||||
"import ulab\n",
|
||||
"\n",
|
||||
"a = ulab.array([1, 2, 3])\n",
|
||||
"print(a.itemsize, a.size)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
|
@ -9119,11 +9151,11 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 45,
|
||||
"execution_count": 100,
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2020-02-10T18:46:01.354625Z",
|
||||
"start_time": "2020-02-10T18:46:01.346144Z"
|
||||
"end_time": "2020-02-11T18:57:50.102055Z",
|
||||
"start_time": "2020-02-11T18:57:50.096070Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
|
|
@ -9138,6 +9170,12 @@
|
|||
"source": [
|
||||
"%%writefile ../../../ulab/docs/ulab-change-log.md\n",
|
||||
"\n",
|
||||
"Tue, 11 Feb 2020\n",
|
||||
"\n",
|
||||
"version 0.32.0\n",
|
||||
"\n",
|
||||
" added itemsize, size and shape attributes to ndarrays, and removed rawsize\n",
|
||||
"\n",
|
||||
"Mon, 10 Feb 2020\n",
|
||||
"\n",
|
||||
"version 0.31.0\n",
|
||||
|
|
|
|||
Loading…
Reference in a new issue