added function pointer tools
This commit is contained in:
parent
148c948fa4
commit
b7c135faf7
9 changed files with 153 additions and 51 deletions
|
|
@ -20,6 +20,8 @@
|
|||
#include "py/binary.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objarray.h"
|
||||
|
||||
#include "../ulab_tools.h"
|
||||
#include "fft.h"
|
||||
|
||||
#if ULAB_FFT_MODULE
|
||||
|
|
@ -101,8 +103,10 @@ mp_obj_t fft_fft_ifft_spectrum(size_t n_args, mp_obj_t arg_re, mp_obj_t arg_im,
|
|||
mp_float_t *data_re = (mp_float_t *)out_re->array;
|
||||
|
||||
uint8_t *array = (uint8_t *)re->array;
|
||||
mp_float_t (*func)(void *) = ndarray_get_float_function(re->dtype);
|
||||
|
||||
for(size_t i=0; i < len; i++) {
|
||||
*data_re++ = ndarray_get_float_value(array, re->dtype);
|
||||
*data_re++ = func(array);
|
||||
array += re->strides[ULAB_MAX_DIMS - 1];
|
||||
}
|
||||
data_re -= len;
|
||||
|
|
@ -120,8 +124,9 @@ mp_obj_t fft_fft_ifft_spectrum(size_t n_args, mp_obj_t arg_re, mp_obj_t arg_im,
|
|||
mp_raise_ValueError(translate("real and imaginary parts must be of equal length"));
|
||||
}
|
||||
array = (uint8_t *)im->array;
|
||||
func = ndarray_get_float_function(im->dtype);
|
||||
for(size_t i=0; i < len; i++) {
|
||||
*data_im++ = ndarray_get_float_value(array, im->dtype);
|
||||
*data_im++ = func(array);
|
||||
array += im->strides[ULAB_MAX_DIMS - 1];
|
||||
}
|
||||
data_im -= len;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ USERMODULES_DIR := $(USERMOD_DIR)
|
|||
|
||||
# Add all C files to SRC_USERMOD.
|
||||
SRC_USERMOD += $(USERMODULES_DIR)/ndarray_operators.c
|
||||
SRC_USERMOD += $(USERMODULES_DIR)/ulab_tools.c
|
||||
SRC_USERMOD += $(USERMODULES_DIR)/ndarray.c
|
||||
SRC_USERMOD += $(USERMODULES_DIR)/ulab_create.c
|
||||
SRC_USERMOD += $(USERMODULES_DIR)/linalg/linalg.c
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
#include "py/binary.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objtuple.h"
|
||||
|
||||
#include "ulab_tools.h"
|
||||
#include "ndarray.h"
|
||||
#include "ndarray_operators.h"
|
||||
|
||||
|
|
@ -283,38 +285,6 @@ void mp_obj_slice_indices(mp_obj_t self_in, mp_int_t length, mp_bound_slice_t *r
|
|||
}
|
||||
#endif
|
||||
|
||||
mp_float_t ndarray_get_float_index(void *data, uint8_t typecode, size_t index) {
|
||||
// Returns a float value from an arbitrary data type
|
||||
// The value in question is supposed to be located at the head of the pointer
|
||||
if(typecode == NDARRAY_UINT8) {
|
||||
return (mp_float_t)((uint8_t *)data)[index];
|
||||
} else if(typecode == NDARRAY_INT8) {
|
||||
return (mp_float_t)((int8_t *)data)[index];
|
||||
} else if(typecode == NDARRAY_UINT16) {
|
||||
return (mp_float_t)((uint16_t *)data)[index];
|
||||
} else if(typecode == NDARRAY_INT16) {
|
||||
return (mp_float_t)((int16_t *)data)[index];
|
||||
} else {
|
||||
return (mp_float_t)((mp_float_t *)data)[index];
|
||||
}
|
||||
}
|
||||
|
||||
mp_float_t ndarray_get_float_value(void *data, uint8_t typecode) {
|
||||
// Returns a float value from an arbitrary data type
|
||||
// The value in question is supposed to be located at the head of the pointer
|
||||
if(typecode == NDARRAY_UINT8) {
|
||||
return (mp_float_t)(*(uint8_t *)data);
|
||||
} else if(typecode == NDARRAY_INT8) {
|
||||
return (mp_float_t)(*(int8_t *)data);
|
||||
} else if(typecode == NDARRAY_UINT16) {
|
||||
return (mp_float_t)(*(uint16_t *)data);
|
||||
} else if(typecode == NDARRAY_INT16) {
|
||||
return (mp_float_t)(*(int16_t *)data);
|
||||
} else {
|
||||
return *((mp_float_t *)data);
|
||||
}
|
||||
}
|
||||
|
||||
void ndarray_fill_array_iterable(mp_float_t *array, mp_obj_t iterable) {
|
||||
mp_obj_iter_buf_t x_buf;
|
||||
mp_obj_t x_item, x_iterable = mp_getiter(iterable, &x_buf);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/builtin.h"
|
||||
#include "py/misc.h"
|
||||
|
||||
#include "../ulab_tools.h"
|
||||
#include "numerical.h"
|
||||
|
||||
#if ULAB_NUMERICAL_MODULE
|
||||
|
|
@ -209,8 +211,9 @@ static mp_obj_t numerical_argmin_argmax_ndarray(ndarray_obj_t *ndarray, mp_obj_t
|
|||
|
||||
if(axis == mp_const_none) {
|
||||
// work with the flattened array
|
||||
mp_float_t (*func)(void *) = ndarray_get_float_function(ndarray->dtype);
|
||||
uint8_t *array = (uint8_t *)ndarray->array;
|
||||
mp_float_t best_value = ndarray_get_float_value(array, ndarray->dtype);
|
||||
mp_float_t best_value = func(array);
|
||||
mp_float_t value;
|
||||
size_t index = 0, best_index = 0;
|
||||
|
||||
|
|
@ -228,7 +231,7 @@ static mp_obj_t numerical_argmin_argmax_ndarray(ndarray_obj_t *ndarray, mp_obj_t
|
|||
#endif
|
||||
size_t l = 0;
|
||||
do {
|
||||
value = ndarray_get_float_value(array, ndarray->dtype);
|
||||
value = func(array);
|
||||
if((optype == NUMERICAL_ARGMAX) || (optype == NUMERICAL_MAX)) {
|
||||
if(best_value < value) {
|
||||
best_value = value;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/objarray.h"
|
||||
#include "../linalg/linalg.h"
|
||||
|
||||
#include "../ulab_tools.h"
|
||||
#include "poly.h"
|
||||
|
||||
#if ULAB_POLY_MODULE
|
||||
|
|
@ -178,6 +180,8 @@ mp_obj_t poly_polyval(mp_obj_t o_p, mp_obj_t o_x) {
|
|||
ndarray = ndarray_new_dense_ndarray(source->ndim, source->shape, NDARRAY_FLOAT);
|
||||
mp_float_t *array = (mp_float_t *)ndarray->array;
|
||||
|
||||
mp_float_t (*func)(void *) = ndarray_get_float_function(source->dtype);
|
||||
|
||||
// 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
|
||||
|
|
@ -195,7 +199,7 @@ mp_obj_t poly_polyval(mp_obj_t o_p, mp_obj_t o_x) {
|
|||
size_t l = 0;
|
||||
do {
|
||||
mp_float_t y = p[0];
|
||||
mp_float_t _x = ndarray_get_float_value(sarray, source->dtype);
|
||||
mp_float_t _x = func(sarray);
|
||||
for(uint8_t m=0; m < plen-1; m++) {
|
||||
y *= _x;
|
||||
y += p[m+1];
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
#include "user/user.h"
|
||||
#include "vector/vectorise.h"
|
||||
|
||||
#define ULAB_VERSION 1.2.0
|
||||
#define ULAB_VERSION 1.2.2
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
#if ULAB_NUMPY_COMPATIBILITY
|
||||
|
|
|
|||
92
code/ulab_tools.c
Normal file
92
code/ulab_tools.c
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* This file is part of the micropython-ulab project,
|
||||
*
|
||||
* https://github.com/v923z/micropython-ulab
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Zoltán Vörös
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "ulab.h"
|
||||
#include "ndarray.h"
|
||||
#include "ulab_tools.h"
|
||||
|
||||
// The following five functions return a float from a void type
|
||||
// The value in question is supposed to be located at the head of the pointer
|
||||
|
||||
mp_float_t ndarray_get_float_uint8(void *data) {
|
||||
// Returns a float value from an uint8_t type
|
||||
return (mp_float_t)(*(uint8_t *)data);
|
||||
}
|
||||
|
||||
mp_float_t ndarray_get_float_int8(void *data) {
|
||||
// Returns a float value from an int8_t type
|
||||
return (mp_float_t)(*(int8_t *)data);
|
||||
}
|
||||
|
||||
mp_float_t ndarray_get_float_uint16(void *data) {
|
||||
// Returns a float value from an uint16_t type
|
||||
return (mp_float_t)(*(uint16_t *)data);
|
||||
}
|
||||
|
||||
mp_float_t ndarray_get_float_int16(void *data) {
|
||||
// Returns a float value from an int16_t type
|
||||
return (mp_float_t)(*(int16_t *)data);
|
||||
}
|
||||
|
||||
|
||||
mp_float_t ndarray_get_float_float(void *data) {
|
||||
// Returns a float value from an mp_float_t type
|
||||
return *((mp_float_t *)data);
|
||||
}
|
||||
|
||||
// returns a single function pointer, depending on the dtype
|
||||
void *ndarray_get_float_function(uint8_t dtype) {
|
||||
if(dtype == NDARRAY_UINT8) {
|
||||
return ndarray_get_float_uint8;
|
||||
} else if(dtype == NDARRAY_INT8) {
|
||||
return ndarray_get_float_int8;
|
||||
} else if(dtype == NDARRAY_UINT16) {
|
||||
return ndarray_get_float_uint16;
|
||||
} else if(dtype == NDARRAY_INT16) {
|
||||
return ndarray_get_float_int16;
|
||||
} else {
|
||||
return ndarray_get_float_float;
|
||||
}
|
||||
}
|
||||
|
||||
mp_float_t ndarray_get_float_index(void *data, uint8_t dtype, size_t index) {
|
||||
// returns a single float value from an array located at index
|
||||
if(dtype == NDARRAY_UINT8) {
|
||||
return (mp_float_t)((uint8_t *)data)[index];
|
||||
} else if(dtype == NDARRAY_INT8) {
|
||||
return (mp_float_t)((int8_t *)data)[index];
|
||||
} else if(dtype == NDARRAY_UINT16) {
|
||||
return (mp_float_t)((uint16_t *)data)[index];
|
||||
} else if(dtype == NDARRAY_INT16) {
|
||||
return (mp_float_t)((int16_t *)data)[index];
|
||||
} else {
|
||||
return (mp_float_t)((mp_float_t *)data)[index];
|
||||
}
|
||||
}
|
||||
|
||||
mp_float_t ndarray_get_float_value(void *data, uint8_t dtype) {
|
||||
// Returns a float value from an arbitrary data type
|
||||
// The value in question is supposed to be located at the head of the pointer
|
||||
if(dtype == NDARRAY_UINT8) {
|
||||
return (mp_float_t)(*(uint8_t *)data);
|
||||
} else if(dtype == NDARRAY_INT8) {
|
||||
return (mp_float_t)(*(int8_t *)data);
|
||||
} else if(dtype == NDARRAY_UINT16) {
|
||||
return (mp_float_t)(*(uint16_t *)data);
|
||||
} else if(dtype == NDARRAY_INT16) {
|
||||
return (mp_float_t)(*(int16_t *)data);
|
||||
} else {
|
||||
return *((mp_float_t *)data);
|
||||
}
|
||||
}
|
||||
21
code/ulab_tools.h
Normal file
21
code/ulab_tools.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* This file is part of the micropython-ulab project,
|
||||
*
|
||||
* https://github.com/v923z/micropython-ulab
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Zoltán Vörös
|
||||
*/
|
||||
|
||||
#ifndef _TOOLS_
|
||||
#define _TOOLS_
|
||||
|
||||
mp_float_t ndarray_get_float_uint8(void *);
|
||||
mp_float_t ndarray_get_float_int8(void *);
|
||||
mp_float_t ndarray_get_float_uint16(void *);
|
||||
mp_float_t ndarray_get_float_int16(void *);
|
||||
mp_float_t ndarray_get_float_float(void *);
|
||||
void *ndarray_get_float_function(uint8_t );
|
||||
|
||||
#endif
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
#include "py/binary.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objarray.h"
|
||||
#include "../ulab_tools.h"
|
||||
#include "vectorise.h"
|
||||
|
||||
#if ULAB_VECTORISE_MODULE
|
||||
|
|
@ -137,6 +138,8 @@ mp_obj_t vectorise_around(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_
|
|||
mp_float_t *narray = (mp_float_t *)ndarray->array;
|
||||
uint8_t *sarray = (uint8_t *)source->array;
|
||||
|
||||
mp_float_t (*func)(void *) = ndarray_get_float_function(source->dtype);
|
||||
|
||||
#if ULAB_MAX_DIMS > 3
|
||||
size_t i = 0;
|
||||
do {
|
||||
|
|
@ -151,7 +154,7 @@ mp_obj_t vectorise_around(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_
|
|||
#endif
|
||||
size_t l = 0;
|
||||
do {
|
||||
mp_float_t f = ndarray_get_float_value(sarray, source->dtype);
|
||||
mp_float_t f = func(sarray);
|
||||
*narray++ = MICROPY_FLOAT_C_FUN(round)(f * mul) / mul;
|
||||
sarray += source->strides[ULAB_MAX_DIMS - 1];
|
||||
l++;
|
||||
|
|
@ -219,6 +222,9 @@ mp_obj_t vectorise_arctan2(mp_obj_t y, mp_obj_t x) {
|
|||
ndarray_obj_t *results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
|
||||
mp_float_t *rarray = (mp_float_t *)results->array;
|
||||
|
||||
mp_float_t (*funcx)(void *) = ndarray_get_float_function(ndarray_x->dtype);
|
||||
mp_float_t (*funcy)(void *) = ndarray_get_float_function(ndarray_y->dtype);
|
||||
|
||||
#if ULAB_MAX_DIMS > 3
|
||||
size_t i = 0;
|
||||
do {
|
||||
|
|
@ -233,8 +239,8 @@ mp_obj_t vectorise_arctan2(mp_obj_t y, mp_obj_t x) {
|
|||
#endif
|
||||
size_t l = 0;
|
||||
do {
|
||||
mp_float_t _x = ndarray_get_float_value(xarray, ndarray_x->dtype);
|
||||
mp_float_t _y = ndarray_get_float_value(yarray, ndarray_y->dtype);
|
||||
mp_float_t _x = funcx(xarray);
|
||||
mp_float_t _y = funcy(yarray);
|
||||
*rarray++ = MICROPY_FLOAT_C_FUN(atan2)(_y, _x);
|
||||
xarray += xstrides[ULAB_MAX_DIMS - 1];
|
||||
yarray += ystrides[ULAB_MAX_DIMS - 1];
|
||||
|
|
|
|||
Loading…
Reference in a new issue