Compare commits

...

18 commits

Author SHA1 Message Date
Jeff Epler
b1ca98e813
Merge pull request #7 from jepler/merge-upstream-1
predefine all ulab configurables to enabled
2020-02-11 09:27:35 -06:00
ef4cbfe825 predefine all ulab configurables to enabled 2020-02-11 09:26:57 -06:00
Jeff Epler
5261b0e404
Merge pull request #6 from jepler/merge-upstream-1
Merge upstream
2020-02-11 09:17:38 -06:00
d316e65804 merge upstream 2020-02-11 09:10:33 -06:00
Jeff Epler
2e320f488d
Merge pull request #5 from jepler/trim-readme
Trim README to just the basics
2020-02-07 08:04:35 -06:00
fb89d90fa1
Trim README to just the basics 2020-02-07 08:03:16 -06:00
Jeff Epler
d13a58e5f0
Merge pull request #4 from jepler/fix-convolve-build
fix build of convolve on circuitpython
2020-02-06 15:54:26 -06:00
Jeff Epler
a03ef91904 fix build of convolve on circuitpython 2020-02-06 15:53:49 -06:00
Jeff Epler
5216acfb6f
Merge pull request #3 from jepler/convolve-circuitpython
Convolve (for circuitpython)
2020-02-06 12:46:26 -06:00
Jeff Epler
19e86f85c8 Merge branch 'convolve' into HEAD 2020-02-06 12:44:23 -06:00
Jeff Epler
e7db2173b1
Merge pull request #2 from jepler/docs-build
ulab.rst: Fix so it can be processed by sphinx in circuitpython
2020-02-04 13:47:44 -06:00
3aa8897b90 ulab.rst: Fix so it can be processed by sphinx in circuitpython 2020-02-04 13:45:59 -06:00
Jeff Epler
467386584f
Merge pull request #1 from jepler/master
Prepare ulab to be incorporated into circuitpython as an extmod
2020-02-04 11:37:20 -06:00
cfbf5f4e84 remove files that should not be tracked 2020-02-04 11:35:36 -06:00
b4974825c6 Merge remote-tracking branch 'upstream/master' into HEAD 2020-02-04 11:28:29 -06:00
50957ec120 ndarray: Fix compile error 2020-02-04 10:31:38 -06:00
Andrew Gatherer
e7243ce38a added __init__ files 2020-01-01 16:18:52 -06:00
Andrew Gatherer
58ee495e6b initial edit to CP 2019-12-31 09:18:23 -06:00
25 changed files with 1099 additions and 2084 deletions

View file

@ -1,62 +1,12 @@
# micropython-ulab # circuitpython-ulab
ulab is a numpy-like array manipulation library for micropython. ulab is a numpy-like array manipulation library for micropython.
The module is written in C, defines compact containers for numerical The module is written in C, defines compact containers for numerical
data, and is fast. data, and is fast.
Documentation can be found under https://micropython-ulab.readthedocs.io/en/latest/ ulab will be incorporated in builds of most CircuitPython supported
The source for the manual is in https://github.com/v923z/micropython-ulab/blob/master/docs/ulab-manual.ipynb, devices, so there's usually no need to use the files here directly.
while developer help is in https://github.com/v923z/micropython-ulab/blob/master/docs/ulab.ipynb. If you've encountered a problem with circuitpython-ulab, please
file an issue [in the circuitpython issue tracker](https://github.com/adafruit/circuitpython).
# Firmware circuitpython-ulab is based on [micropython-ulab](https://github.com/v923z/micropython-ulab).
Firmware for pyboard.v.1.1, and PYBD_SF6 is updated once in a while, and can be downloaded
from https://github.com/v923z/micropython-ulab/releases.
## Compiling
If you want to try the latest version of `ulab`, or your hardware is
different to pyboard.v.1.1, or PYBD_SF6, the firmware can be compiled
from the source by following these steps:
First, you have to clone the micropython repository by running
```
git clone https://github.com/micropython/micropython.git
```
on the command line. This will create a new repository with the name `micropython`. Staying there, clone the `ulab` repository with
```
git clone https://github.com/v923z/micropython-ulab.git ulab
```
Then you have to include `ulab` in the compilation process by editing `mpconfigport.h` of the directory of the port for which you want to compile, so, still on the command line, navigate to `micropython/ports/unix`, or `micropython/ports/stm32`, or whichever port is your favourite, and edit the `mpconfigport.h` file there. All you have to do is add a single line at the end:
```
#define MODULE_ULAB_ENABLED (1)
```
This line will inform the compiler that you want `ulab` in the resulting firmware. If you don't have the cross-compiler installed, your might want to do that now, for instance on Linux by executing
```
sudo apt-get install gcc-arm-none-eabi
```
If that was successful, you can try to run the make command in the port's directory as
```
make BOARD=PYBV11 USER_C_MODULES=../../../ulab all
```
which will prepare the firmware for pyboard.v.11. Similarly,
```
make BOARD=PYBD_SF6 USER_C_MODULES=../../../ulab all
```
will compile for the SF6 member of the PYBD series. Provided that you managed to compile the firmware, you would upload that by running
either
```
dfu-util --alt 0 -D firmware.dfu
```
or
```
python pydfu.py -u firmware.dfu
```
In case you got stuck somewhere in the process, a bit more detailed instructions can be found under https://github.com/micropython/micropython/wiki/Getting-Started, and https://github.com/micropython/micropython/wiki/Pyboard-Firmware-Update.

193
code/__init__.c Normal file
View file

@ -0,0 +1,193 @@
/*
* This file is part of the micropython-ulab project,
*
* https://github.com/v923z/micropython-ulab
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Zoltán Vörös
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "py/runtime.h"
#include "py/binary.h"
#include "py/obj.h"
#include "py/objarray.h"
#include "shared-bindings/ulab/ndarray.h"
#include "shared-bindings/ulab/linalg.h"
#include "shared-bindings/ulab/vectorise.h"
#include "shared-bindings/ulab/poly.h"
#include "shared-bindings/ulab/fft.h"
#include "shared-bindings/ulab/numerical.h"
#define ULAB_VERSION 0.262
typedef struct _mp_obj_float_t {
mp_obj_base_t base;
mp_float_t value;
} mp_obj_float_t;
mp_obj_float_t ulab_version = {{&mp_type_float}, ULAB_VERSION};
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);
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_asbytearray_obj, ndarray_asbytearray);
MP_DEFINE_CONST_FUN_OBJ_1(linalg_transpose_obj, linalg_transpose);
MP_DEFINE_CONST_FUN_OBJ_2(linalg_reshape_obj, linalg_reshape);
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_size_obj, 1, linalg_size);
MP_DEFINE_CONST_FUN_OBJ_1(linalg_inv_obj, linalg_inv);
MP_DEFINE_CONST_FUN_OBJ_2(linalg_dot_obj, linalg_dot);
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_zeros_obj, 0, linalg_zeros);
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_ones_obj, 0, linalg_ones);
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_eye_obj, 0, linalg_eye);
MP_DEFINE_CONST_FUN_OBJ_1(linalg_det_obj, linalg_det);
MP_DEFINE_CONST_FUN_OBJ_1(linalg_eig_obj, linalg_eig);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_acos_obj, vectorise_acos);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_acosh_obj, vectorise_acosh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_asin_obj, vectorise_asin);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_asinh_obj, vectorise_asinh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_atan_obj, vectorise_atan);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_atanh_obj, vectorise_atanh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_ceil_obj, vectorise_ceil);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_cos_obj, vectorise_cos);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_erf_obj, vectorise_erf);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_erfc_obj, vectorise_erfc);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_exp_obj, vectorise_exp);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_expm1_obj, vectorise_expm1);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_floor_obj, vectorise_floor);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_gamma_obj, vectorise_gamma);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_lgamma_obj, vectorise_lgamma);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_log_obj, vectorise_log);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_log10_obj, vectorise_log10);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_log2_obj, vectorise_log2);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_sin_obj, vectorise_sin);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_sinh_obj, vectorise_sinh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_sqrt_obj, vectorise_sqrt);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_tan_obj, vectorise_tan);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_tanh_obj, vectorise_tanh);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_linspace_obj, 2, numerical_linspace);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_sum_obj, 1, numerical_sum);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_mean_obj, 1, numerical_mean);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_std_obj, 1, numerical_std);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_min_obj, 1, numerical_min);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_max_obj, 1, numerical_max);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_argmin_obj, 1, numerical_argmin);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_argmax_obj, 1, numerical_argmax);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_roll_obj, 2, numerical_roll);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_flip_obj, 1, numerical_flip);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_diff_obj, 1, numerical_diff);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_sort_obj, 1, numerical_sort);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_sort_inplace_obj, 1, numerical_sort_inplace);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_argsort_obj, 1, numerical_argsort);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(poly_polyval_obj, poly_polyval);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poly_polyfit_obj, 2, 3, poly_polyfit);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fft_fft_obj, 1, 2, fft_fft);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fft_ifft_obj, 1, 2, fft_ifft);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fft_spectrum_obj, 1, 2, fft_spectrum);
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_asbytearray), MP_ROM_PTR(&ndarray_asbytearray_obj) },
{ MP_ROM_QSTR(MP_QSTR_transpose), MP_ROM_PTR(&linalg_transpose_obj) },
{ MP_ROM_QSTR(MP_QSTR_reshape), MP_ROM_PTR(&linalg_reshape_obj) },
{ MP_ROM_QSTR(MP_QSTR_sort), MP_ROM_PTR(&numerical_sort_inplace_obj) },
};
STATIC MP_DEFINE_CONST_DICT(ulab_ndarray_locals_dict, ulab_ndarray_locals_dict_table);
const mp_obj_type_t ulab_ndarray_type = {
{ &mp_type_type },
.name = MP_QSTR_ndarray,
.print = ndarray_print,
.make_new = ndarray_make_new,
.subscr = ndarray_subscr,
.getiter = ndarray_getiter,
.unary_op = ndarray_unary_op,
.binary_op = ndarray_binary_op,
.locals_dict = (mp_obj_dict_t*)&ulab_ndarray_locals_dict,
};
STATIC const mp_map_elem_t ulab_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ulab) },
{ MP_ROM_QSTR(MP_QSTR___version__), MP_ROM_PTR(&ulab_version) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_array), (mp_obj_t)&ulab_ndarray_type },
{ MP_OBJ_NEW_QSTR(MP_QSTR_size), (mp_obj_t)&linalg_size_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_inv), (mp_obj_t)&linalg_inv_obj },
{ MP_ROM_QSTR(MP_QSTR_dot), (mp_obj_t)&linalg_dot_obj },
{ MP_ROM_QSTR(MP_QSTR_zeros), (mp_obj_t)&linalg_zeros_obj },
{ MP_ROM_QSTR(MP_QSTR_ones), (mp_obj_t)&linalg_ones_obj },
{ MP_ROM_QSTR(MP_QSTR_eye), (mp_obj_t)&linalg_eye_obj },
{ MP_ROM_QSTR(MP_QSTR_det), (mp_obj_t)&linalg_det_obj },
{ MP_ROM_QSTR(MP_QSTR_eig), (mp_obj_t)&linalg_eig_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_acos), (mp_obj_t)&vectorise_acos_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_acosh), (mp_obj_t)&vectorise_acosh_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_asin), (mp_obj_t)&vectorise_asin_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_asinh), (mp_obj_t)&vectorise_asinh_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_atan), (mp_obj_t)&vectorise_atan_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_atanh), (mp_obj_t)&vectorise_atanh_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ceil), (mp_obj_t)&vectorise_ceil_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_cos), (mp_obj_t)&vectorise_cos_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_erf), (mp_obj_t)&vectorise_erf_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_erfc), (mp_obj_t)&vectorise_erfc_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_exp), (mp_obj_t)&vectorise_exp_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_expm1), (mp_obj_t)&vectorise_expm1_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_floor), (mp_obj_t)&vectorise_floor_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_gamma), (mp_obj_t)&vectorise_gamma_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_lgamma), (mp_obj_t)&vectorise_lgamma_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_log), (mp_obj_t)&vectorise_log_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_log10), (mp_obj_t)&vectorise_log10_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_log2), (mp_obj_t)&vectorise_log2_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sin), (mp_obj_t)&vectorise_sin_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sinh), (mp_obj_t)&vectorise_sinh_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sqrt), (mp_obj_t)&vectorise_sqrt_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_tan), (mp_obj_t)&vectorise_tan_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_tanh), (mp_obj_t)&vectorise_tanh_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_linspace), (mp_obj_t)&numerical_linspace_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sum), (mp_obj_t)&numerical_sum_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_mean), (mp_obj_t)&numerical_mean_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_std), (mp_obj_t)&numerical_std_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_min), (mp_obj_t)&numerical_min_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_max), (mp_obj_t)&numerical_max_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_argmin), (mp_obj_t)&numerical_argmin_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_argmax), (mp_obj_t)&numerical_argmax_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_roll), (mp_obj_t)&numerical_roll_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_flip), (mp_obj_t)&numerical_flip_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_diff), (mp_obj_t)&numerical_diff_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sort), (mp_obj_t)&numerical_sort_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_argsort), (mp_obj_t)&numerical_argsort_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_polyval), (mp_obj_t)&poly_polyval_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_polyfit), (mp_obj_t)&poly_polyfit_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_fft), (mp_obj_t)&fft_fft_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ifft), (mp_obj_t)&fft_ifft_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_spectrum), (mp_obj_t)&fft_spectrum_obj },
// class constants
{ MP_ROM_QSTR(MP_QSTR_uint8), MP_ROM_INT(NDARRAY_UINT8) },
{ MP_ROM_QSTR(MP_QSTR_int8), MP_ROM_INT(NDARRAY_INT8) },
{ MP_ROM_QSTR(MP_QSTR_uint16), MP_ROM_INT(NDARRAY_UINT16) },
{ MP_ROM_QSTR(MP_QSTR_int16), MP_ROM_INT(NDARRAY_INT16) },
{ MP_ROM_QSTR(MP_QSTR_float), MP_ROM_INT(NDARRAY_FLOAT) },
};
STATIC MP_DEFINE_CONST_DICT (
mp_module_ulab_globals,
ulab_globals_table
);
const mp_obj_module_t ulab_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_ulab_globals,
};
MP_REGISTER_MODULE(MP_QSTR_ulab, ulab_user_cmodule, MODULE_ULAB_ENABLED);

8
code/__init__.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ULAB___INIT___H
#define MICROPY_INCLUDED_SHARED_BINDINGS_ULAB___INIT___H
#include "py/obj.h"
// Nothing now.
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ULAB___INIT___H

230
code/compat.h Normal file
View file

@ -0,0 +1,230 @@
#ifndef MICROPY_INCLUDED_ULAB_COMPAT_H
#define MICROPY_INCLUDED_ULAB_COMPAT_H
#pragma GCC diagnostic ignored "-Wshadow"
#define mp_obj_is_type(obj, type) MP_OBJ_IS_TYPE(obj, type)
#define mp_obj_is_int(obj) MP_OBJ_IS_INT(obj)
#define MP_ROM_NONE (MP_ROM_PTR(&mp_const_none_obj))
#define MP_ROM_FALSE (mp_const_false)
#define MP_ROM_TRUE (mp_const_true)
#ifndef ULAB_FFT_FFT
#define ULAB_FFT_FFT (1)
#endif
#ifndef ULAB_FFT_IFFT
#define ULAB_FFT_IFFT (1)
#endif
#ifndef ULAB_FFT_SPECTRUM
#define ULAB_FFT_SPECTRUM (1)
#endif
#ifndef ULAB_FILTER_CONVOLVE
#define ULAB_FILTER_CONVOLVE (1)
#endif
#ifndef ULAB_LINALG_DET
#define ULAB_LINALG_DET (1)
#endif
#ifndef ULAB_LINALG_DOT
#define ULAB_LINALG_DOT (1)
#endif
#ifndef ULAB_LINALG_EIG
#define ULAB_LINALG_EIG (1)
#endif
#ifndef ULAB_LINALG_EYE
#define ULAB_LINALG_EYE (1)
#endif
#ifndef ULAB_LINALG_INV
#define ULAB_LINALG_INV (1)
#endif
#ifndef ULAB_LINALG_ONES
#define ULAB_LINALG_ONES (1)
#endif
#ifndef ULAB_LINALG_RESHAPE
#define ULAB_LINALG_RESHAPE (1)
#endif
#ifndef ULAB_LINALG_SIZE
#define ULAB_LINALG_SIZE (1)
#endif
#ifndef ULAB_LINALG_TRANSPOSE
#define ULAB_LINALG_TRANSPOSE (1)
#endif
#ifndef ULAB_LINALG_ZEROS
#define ULAB_LINALG_ZEROS (1)
#endif
#ifndef ULAB_NUMERICAL_ARGMAX
#define ULAB_NUMERICAL_ARGMAX (1)
#endif
#ifndef ULAB_NUMERICAL_ARGMIN
#define ULAB_NUMERICAL_ARGMIN (1)
#endif
#ifndef ULAB_NUMERICAL_ARGSORT
#define ULAB_NUMERICAL_ARGSORT (1)
#endif
#ifndef ULAB_NUMERICAL_DIFF
#define ULAB_NUMERICAL_DIFF (1)
#endif
#ifndef ULAB_NUMERICAL_FLIP
#define ULAB_NUMERICAL_FLIP (1)
#endif
#ifndef ULAB_NUMERICAL_LINSPACE
#define ULAB_NUMERICAL_LINSPACE (1)
#endif
#ifndef ULAB_NUMERICAL_MAX
#define ULAB_NUMERICAL_MAX (1)
#endif
#ifndef ULAB_NUMERICAL_MEAN
#define ULAB_NUMERICAL_MEAN (1)
#endif
#ifndef ULAB_NUMERICAL_MIN
#define ULAB_NUMERICAL_MIN (1)
#endif
#ifndef ULAB_NUMERICAL_ROLL
#define ULAB_NUMERICAL_ROLL (1)
#endif
#ifndef ULAB_NUMERICAL_SORT
#define ULAB_NUMERICAL_SORT (1)
#endif
#ifndef ULAB_NUMERICAL_STD
#define ULAB_NUMERICAL_STD (1)
#endif
#ifndef ULAB_NUMERICAL_SUM
#define ULAB_NUMERICAL_SUM (1)
#endif
#ifndef ULAB_POLY_POLYFIT
#define ULAB_POLY_POLYFIT (1)
#endif
#ifndef ULAB_POLY_POLYVAL
#define ULAB_POLY_POLYVAL (1)
#endif
#ifndef ULAB_VECTORISE_
#define ULAB_VECTORISE_ (1)
#endif
#ifndef ULAB_VECTORISE_ACOS
#define ULAB_VECTORISE_ACOS (1)
#endif
#ifndef ULAB_VECTORISE_ACOSH
#define ULAB_VECTORISE_ACOSH (1)
#endif
#ifndef ULAB_VECTORISE_ASIN
#define ULAB_VECTORISE_ASIN (1)
#endif
#ifndef ULAB_VECTORISE_ASINH
#define ULAB_VECTORISE_ASINH (1)
#endif
#ifndef ULAB_VECTORISE_ATAN
#define ULAB_VECTORISE_ATAN (1)
#endif
#ifndef ULAB_VECTORISE_ATANH
#define ULAB_VECTORISE_ATANH (1)
#endif
#ifndef ULAB_VECTORISE_CEIL
#define ULAB_VECTORISE_CEIL (1)
#endif
#ifndef ULAB_VECTORISE_COS
#define ULAB_VECTORISE_COS (1)
#endif
#ifndef ULAB_VECTORISE_ERF
#define ULAB_VECTORISE_ERF (1)
#endif
#ifndef ULAB_VECTORISE_ERFC
#define ULAB_VECTORISE_ERFC (1)
#endif
#ifndef ULAB_VECTORISE_EXP
#define ULAB_VECTORISE_EXP (1)
#endif
#ifndef ULAB_VECTORISE_EXPM1
#define ULAB_VECTORISE_EXPM1 (1)
#endif
#ifndef ULAB_VECTORISE_FLOOR
#define ULAB_VECTORISE_FLOOR (1)
#endif
#ifndef ULAB_VECTORISE_GAMMA
#define ULAB_VECTORISE_GAMMA (1)
#endif
#ifndef ULAB_VECTORISE_LGAMMA
#define ULAB_VECTORISE_LGAMMA (1)
#endif
#ifndef ULAB_VECTORISE_LOG
#define ULAB_VECTORISE_LOG (1)
#endif
#ifndef ULAB_VECTORISE_LOG10
#define ULAB_VECTORISE_LOG10 (1)
#endif
#ifndef ULAB_VECTORISE_LOG2
#define ULAB_VECTORISE_LOG2 (1)
#endif
#ifndef ULAB_VECTORISE_SIN
#define ULAB_VECTORISE_SIN (1)
#endif
#ifndef ULAB_VECTORISE_SINH
#define ULAB_VECTORISE_SINH (1)
#endif
#ifndef ULAB_VECTORISE_SQRT
#define ULAB_VECTORISE_SQRT (1)
#endif
#ifndef ULAB_VECTORISE_TAHN
#define ULAB_VECTORISE_TAHN (1)
#endif
#ifndef ULAB_VECTORISE_TAN
#define ULAB_VECTORISE_TAN (1)
#endif
#ifndef ULAB_VECTORISE_TANH
#define ULAB_VECTORISE_TANH (1)
#endif
#endif // MICROPY_INCLUDED_ULAB_COMPAT_H

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -17,11 +16,10 @@
#include "py/binary.h" #include "py/binary.h"
#include "py/obj.h" #include "py/obj.h"
#include "py/objarray.h" #include "py/objarray.h"
#include "compat.h"
#include "ndarray.h" #include "ndarray.h"
#include "fft.h" #include "fft.h"
#if ULAB_FFT_FFT || ULAB_FFT_IFFT || ULAB_FFT_SPECTRUM
enum FFT_TYPE { enum FFT_TYPE {
FFT_FFT, FFT_FFT,
FFT_IFFT, FFT_IFFT,
@ -78,11 +76,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) { 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")); mp_raise_NotImplementedError(translate("FFT is defined for ndarrays only"));
} }
if(n_args == 2) { 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")); mp_raise_NotImplementedError(translate("FFT is defined for ndarrays only"));
} }
} }
@ -146,7 +144,6 @@ mp_obj_t fft_fft_ifft_spectrum(size_t n_args, mp_obj_t arg_re, mp_obj_t arg_im,
} }
} }
#if ULAB_FFT_FFT
mp_obj_t fft_fft(size_t n_args, const mp_obj_t *args) { mp_obj_t fft_fft(size_t n_args, const mp_obj_t *args) {
if(n_args == 2) { if(n_args == 2) {
return fft_fft_ifft_spectrum(n_args, args[0], args[1], FFT_FFT); return fft_fft_ifft_spectrum(n_args, args[0], args[1], FFT_FFT);
@ -155,10 +152,6 @@ mp_obj_t fft_fft(size_t n_args, const mp_obj_t *args) {
} }
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fft_fft_obj, 1, 2, fft_fft);
#endif
#if ULAB_FFT_IFFT
mp_obj_t fft_ifft(size_t n_args, const mp_obj_t *args) { mp_obj_t fft_ifft(size_t n_args, const mp_obj_t *args) {
if(n_args == 2) { if(n_args == 2) {
return fft_fft_ifft_spectrum(n_args, args[0], args[1], FFT_IFFT); return fft_fft_ifft_spectrum(n_args, args[0], args[1], FFT_IFFT);
@ -167,10 +160,6 @@ mp_obj_t fft_ifft(size_t n_args, const mp_obj_t *args) {
} }
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fft_ifft_obj, 1, 2, fft_ifft);
#endif
#if ULAB_FFT_SPECTRUM
mp_obj_t fft_spectrum(size_t n_args, const mp_obj_t *args) { mp_obj_t fft_spectrum(size_t n_args, const mp_obj_t *args) {
if(n_args == 2) { if(n_args == 2) {
return fft_fft_ifft_spectrum(n_args, args[0], args[1], FFT_SPECTRUM); return fft_fft_ifft_spectrum(n_args, args[0], args[1], FFT_SPECTRUM);
@ -178,8 +167,3 @@ mp_obj_t fft_spectrum(size_t n_args, const mp_obj_t *args) {
return fft_fft_ifft_spectrum(n_args, args[0], mp_const_none, FFT_SPECTRUM); return fft_fft_ifft_spectrum(n_args, args[0], mp_const_none, FFT_SPECTRUM);
} }
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fft_spectrum_obj, 1, 2, fft_spectrum);
#endif
#endif

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -6,12 +5,11 @@
* *
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2019-2020 Zoltán Vörös * Copyright (c) 2019 Zoltán Vörös
*/ */
#ifndef _FFT_ #ifndef _FFT_
#define _FFT_ #define _FFT_
#include "ulab.h"
#ifndef MP_PI #ifndef MP_PI
#define MP_PI MICROPY_FLOAT_CONST(3.14159265358979323846) #define MP_PI MICROPY_FLOAT_CONST(3.14159265358979323846)
@ -19,19 +17,7 @@
#define SWAP(t, a, b) { t tmp = a; a = b; b = tmp; } #define SWAP(t, a, b) { t tmp = a; a = b; b = tmp; }
#if ULAB_FFT_FFT
mp_obj_t fft_fft(size_t , const mp_obj_t *); mp_obj_t fft_fft(size_t , const mp_obj_t *);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(fft_fft_obj);
#endif
#if ULAB_FFT_IFFT
mp_obj_t fft_ifft(size_t , const mp_obj_t *); mp_obj_t fft_ifft(size_t , const mp_obj_t *);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(fft_ifft_obj);
#endif
#if ULAB_FFT_SPECTRUM
mp_obj_t fft_spectrum(size_t , const mp_obj_t *); mp_obj_t fft_spectrum(size_t , const mp_obj_t *);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(fft_spectrum_obj);
#endif
#endif #endif

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -14,10 +13,9 @@
#include <string.h> #include <string.h>
#include "py/obj.h" #include "py/obj.h"
#include "py/runtime.h" #include "py/runtime.h"
#include "py/misc.h" #include "compat.h"
#include "filter.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) { 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[] = { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_a, 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_ROM_NONE } },
@ -35,10 +33,6 @@ mp_obj_t filter_convolve(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
ndarray_obj_t *c = MP_OBJ_TO_PTR(args[1].u_obj); ndarray_obj_t *c = MP_OBJ_TO_PTR(args[1].u_obj);
int len_a = a->array->len; int len_a = a->array->len;
int len_c = c->array->len; int len_c = c->array->len;
// deal with linear arrays only
if(a->m*a->n != len_a || c->m*c->n != len_c) {
mp_raise_TypeError(translate("convolve arguments must be linear arrays"));
}
if(len_a == 0 || len_c == 0) { if(len_a == 0 || len_c == 0) {
mp_raise_TypeError(translate("convolve arguments must not be empty")); mp_raise_TypeError(translate("convolve arguments must not be empty"));
} }
@ -54,13 +48,8 @@ mp_obj_t filter_convolve(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
for(int n=bot_n; n<top_n; n++) { for(int n=bot_n; n<top_n; n++) {
int idx_c = len_c - n - 1; int idx_c = len_c - n - 1;
int idx_a = n+k; int idx_a = n+k;
mp_float_t ai = (mp_float_t)0, ci = (mp_float_t)0; mp_float_t ai = idx_a >= 0 && idx_a < len_a ? ndarray_get_float_value(a->array->items, c->array->typecode, idx_a) : (mp_float_t)0;
if(idx_a >= 0 && idx_a < len_a) { mp_float_t ci = idx_c >= 0 && idx_c < len_c ? ndarray_get_float_value(c->array->items, c->array->typecode, idx_c) : (mp_float_t)0;
ai = ndarray_get_float_value(a->array->items, a->array->typecode, idx_a);
}
if(idx_c >= 0 && idx_c < len_c) {
ci = ndarray_get_float_value(c->array->items, c->array->typecode, idx_c);
}
accum += ai * ci; accum += ai * ci;
} }
*outptr++ = accum; *outptr++ = accum;
@ -68,6 +57,3 @@ mp_obj_t filter_convolve(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
return out; return out;
} }
MP_DEFINE_CONST_FUN_OBJ_KW(filter_convolve_obj, 2, filter_convolve);
#endif

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -12,12 +11,8 @@
#ifndef _FILTER_ #ifndef _FILTER_
#define _FILTER_ #define _FILTER_
#include "ulab.h"
#include "ndarray.h" #include "ndarray.h"
#if ULAB_FILTER_CONVOLVE
mp_obj_t filter_convolve(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t filter_convolve(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(filter_convolve_obj);
#endif
#endif #endif

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -15,9 +14,9 @@
#include "py/obj.h" #include "py/obj.h"
#include "py/runtime.h" #include "py/runtime.h"
#include "py/misc.h" #include "py/misc.h"
#include "compat.h"
#include "linalg.h" #include "linalg.h"
#if ULAB_LINALG_TRANSPOSE
mp_obj_t linalg_transpose(mp_obj_t self_in) { mp_obj_t linalg_transpose(mp_obj_t self_in) {
ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in); ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in);
// the size of a single item in the array // the size of a single item in the array
@ -50,13 +49,9 @@ mp_obj_t linalg_transpose(mp_obj_t self_in) {
return mp_const_none; return mp_const_none;
} }
MP_DEFINE_CONST_FUN_OBJ_1(linalg_transpose_obj, linalg_transpose);
#endif
#if ULAB_LINALG_RESHAPE
mp_obj_t linalg_reshape(mp_obj_t self_in, mp_obj_t shape) { mp_obj_t linalg_reshape(mp_obj_t self_in, mp_obj_t shape) {
ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in); 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")); mp_raise_ValueError(translate("shape must be a 2-tuple"));
} }
@ -76,10 +71,6 @@ mp_obj_t linalg_reshape(mp_obj_t self_in, mp_obj_t shape) {
return MP_OBJ_FROM_PTR(self); return MP_OBJ_FROM_PTR(self);
} }
MP_DEFINE_CONST_FUN_OBJ_2(linalg_reshape_obj, linalg_reshape);
#endif
#if ULAB_LINALG_SIZE
mp_obj_t linalg_size(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { 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[] = { 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 } },
@ -89,13 +80,13 @@ mp_obj_t linalg_size(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; 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); 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")); mp_raise_TypeError(translate("size is defined for ndarrays only"));
} else { } else {
ndarray_obj_t *ndarray = MP_OBJ_TO_PTR(args[0].u_obj); ndarray_obj_t *ndarray = MP_OBJ_TO_PTR(args[0].u_obj);
if(args[1].u_obj == mp_const_none) { if(args[1].u_obj == mp_const_none) {
return mp_obj_new_int(ndarray->array->len); 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); uint8_t ax = mp_obj_get_int(args[1].u_obj);
if(ax == 0) { if(ax == 0) {
if(ndarray->m == 1) { if(ndarray->m == 1) {
@ -118,10 +109,6 @@ mp_obj_t linalg_size(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
} }
} }
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_size_obj, 1, linalg_size);
#endif
#if ULAB_LINALG_INV || ULAB_POLY_POLYFIT
bool linalg_invert_matrix(mp_float_t *data, size_t N) { bool linalg_invert_matrix(mp_float_t *data, size_t N) {
// returns true, of the inversion was successful, // returns true, of the inversion was successful,
// false, if the matrix is singular // false, if the matrix is singular
@ -163,16 +150,14 @@ bool linalg_invert_matrix(mp_float_t *data, size_t N) {
m_del(mp_float_t, unit, N*N); m_del(mp_float_t, unit, N*N);
return true; return true;
} }
#endif
#if ULAB_LINALG_INV
mp_obj_t linalg_inv(mp_obj_t o_in) { 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 // 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")); mp_raise_TypeError(translate("only ndarrays can be inverted"));
} }
ndarray_obj_t *o = MP_OBJ_TO_PTR(o_in); 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")); mp_raise_TypeError(translate("only ndarray objects can be inverted"));
} }
if(o->m != o->n) { if(o->m != o->n) {
@ -199,15 +184,8 @@ mp_obj_t linalg_inv(mp_obj_t o_in) {
return MP_OBJ_FROM_PTR(inverted); return MP_OBJ_FROM_PTR(inverted);
} }
MP_DEFINE_CONST_FUN_OBJ_1(linalg_inv_obj, linalg_inv);
#endif
#if ULAB_LINALG_DOT
mp_obj_t linalg_dot(mp_obj_t _m1, mp_obj_t _m2) { mp_obj_t linalg_dot(mp_obj_t _m1, mp_obj_t _m2) {
// TODO: should the results be upcast? // TODO: should the results be upcast?
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); ndarray_obj_t *m1 = MP_OBJ_TO_PTR(_m1);
ndarray_obj_t *m2 = MP_OBJ_TO_PTR(_m2); ndarray_obj_t *m2 = MP_OBJ_TO_PTR(_m2);
if(m1->n != m2->m) { if(m1->n != m2->m) {
@ -232,10 +210,6 @@ mp_obj_t linalg_dot(mp_obj_t _m1, mp_obj_t _m2) {
return MP_OBJ_FROM_PTR(out); return MP_OBJ_FROM_PTR(out);
} }
MP_DEFINE_CONST_FUN_OBJ_2(linalg_dot_obj, linalg_dot);
#endif
#if ULAB_LINALG_ZEROS || ULAB_LINALG_ONES
mp_obj_t linalg_zeros_ones(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, uint8_t kind) { mp_obj_t linalg_zeros_ones(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, uint8_t kind) {
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} } , { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} } ,
@ -246,14 +220,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); 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; 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")); mp_raise_TypeError(translate("input argument must be an integer or a 2-tuple"));
} }
ndarray_obj_t *ndarray = NULL; 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); size_t n = mp_obj_get_int(args[0].u_obj);
ndarray = create_new_ndarray(1, n, dtype); 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); mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(args[0].u_obj);
if(tuple->len != 2) { if(tuple->len != 2) {
mp_raise_TypeError(translate("input argument must be an integer or a 2-tuple")); mp_raise_TypeError(translate("input argument must be an integer or a 2-tuple"));
@ -269,25 +243,15 @@ mp_obj_t linalg_zeros_ones(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw
} }
return MP_OBJ_FROM_PTR(ndarray); return MP_OBJ_FROM_PTR(ndarray);
} }
#endif
#if ULAB_LINALG_ZEROS
mp_obj_t linalg_zeros(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_obj_t linalg_zeros(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
return linalg_zeros_ones(n_args, pos_args, kw_args, 0); return linalg_zeros_ones(n_args, pos_args, kw_args, 0);
} }
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_zeros_obj, 0, linalg_zeros);
#endif
#if ULAB_LINALG_ONES
mp_obj_t linalg_ones(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_obj_t linalg_ones(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
return linalg_zeros_ones(n_args, pos_args, kw_args, 1); return linalg_zeros_ones(n_args, pos_args, kw_args, 1);
} }
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_ones_obj, 0, linalg_ones);
#endif
#if ULAB_LINALG_EYE
mp_obj_t linalg_eye(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { 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[] = { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
@ -311,16 +275,16 @@ mp_obj_t linalg_eye(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
ndarray_obj_t *ndarray = create_new_ndarray(m, n, dtype); ndarray_obj_t *ndarray = create_new_ndarray(m, n, dtype);
mp_obj_t one = mp_obj_new_int(1); mp_obj_t one = mp_obj_new_int(1);
size_t i = 0; size_t i = 0;
if((k >= 0) && (k < n)) { if((k >= 0) && (abs(k) < n)) {
while(k < n) { while(abs(k) < n) {
mp_binary_set_val_array(dtype, ndarray->array->items, i*n+k, one); mp_binary_set_val_array(dtype, ndarray->array->items, i*n+k, one);
k++; k++;
i++; i++;
} }
} else if((k < 0) && (-k < m)) { } else if((k < 0) && (abs(k) < m)) {
k = -k; k = -k;
i = 0; i = 0;
while(k < m) { while(abs(k) < m) {
mp_binary_set_val_array(dtype, ndarray->array->items, k*n+i, one); mp_binary_set_val_array(dtype, ndarray->array->items, k*n+i, one);
k++; k++;
i++; i++;
@ -329,12 +293,8 @@ mp_obj_t linalg_eye(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
return MP_OBJ_FROM_PTR(ndarray); return MP_OBJ_FROM_PTR(ndarray);
} }
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_eye_obj, 0, linalg_eye);
#endif
#if ULAB_LINALG_DET
mp_obj_t linalg_det(mp_obj_t oin) { 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")); mp_raise_TypeError(translate("function defined for ndarrays only"));
} }
ndarray_obj_t *in = MP_OBJ_TO_PTR(oin); ndarray_obj_t *in = MP_OBJ_TO_PTR(oin);
@ -370,12 +330,8 @@ mp_obj_t linalg_det(mp_obj_t oin) {
return mp_obj_new_float(det); return mp_obj_new_float(det);
} }
MP_DEFINE_CONST_FUN_OBJ_1(linalg_det_obj, linalg_det);
#endif
#if ULAB_LINALG_EIG
mp_obj_t linalg_eig(mp_obj_t oin) { 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")); mp_raise_TypeError(translate("function defined for ndarrays only"));
} }
ndarray_obj_t *in = MP_OBJ_TO_PTR(oin); ndarray_obj_t *in = MP_OBJ_TO_PTR(oin);
@ -500,6 +456,3 @@ mp_obj_t linalg_eig(mp_obj_t oin) {
return tuple; return tuple;
return MP_OBJ_FROM_PTR(eigenvalues); return MP_OBJ_FROM_PTR(eigenvalues);
} }
MP_DEFINE_CONST_FUN_OBJ_1(linalg_eig_obj, linalg_eig);
#endif

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -6,13 +5,12 @@
* *
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2019-2020 Zoltán Vörös * Copyright (c) 2019 Zoltán Vörös
*/ */
#ifndef _LINALG_ #ifndef _LINALG_
#define _LINALG_ #define _LINALG_
#include "ulab.h"
#include "ndarray.h" #include "ndarray.h"
#define SWAP(t, a, b) { t tmp = a; a = b; b = tmp; } #define SWAP(t, a, b) { t tmp = a; a = b; b = tmp; }
@ -25,59 +23,17 @@
#define JACOBI_MAX 20 #define JACOBI_MAX 20
// TODO: transpose, reshape and size should probably be part of ndarray.c
#if ULAB_LINALG_TRANSPOSE
mp_obj_t linalg_transpose(mp_obj_t ); mp_obj_t linalg_transpose(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(linalg_transpose_obj);
#endif
#if ULAB_LINALG_RESHAPE
mp_obj_t linalg_reshape(mp_obj_t , mp_obj_t ); mp_obj_t linalg_reshape(mp_obj_t , mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_2(linalg_reshape_obj);
#endif
#if ULAB_LINALG_SIZE
mp_obj_t linalg_size(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t linalg_size(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(linalg_size_obj);
#endif
#if ULAB_LINALG_INV || ULAB_POLY_POLYFIT
bool linalg_invert_matrix(mp_float_t *, size_t ); bool linalg_invert_matrix(mp_float_t *, size_t );
#endif
#if ULAB_LINALG_INV
mp_obj_t linalg_inv(mp_obj_t ); mp_obj_t linalg_inv(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(linalg_inv_obj);
#endif
#if ULAB_LINALG_DOT
mp_obj_t linalg_dot(mp_obj_t , mp_obj_t ); mp_obj_t linalg_dot(mp_obj_t , mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_2(linalg_dot_obj);
#endif
#if ULAB_LINALG_ZEROS
mp_obj_t linalg_zeros(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t linalg_zeros(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(linalg_zeros_obj);
#endif
#if ULAB_LINALG_ONES
mp_obj_t linalg_ones(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t linalg_ones(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(linalg_ones_obj);
#endif
#if ULAB_LINALG_EYE
mp_obj_t linalg_eye(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t linalg_eye(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(linalg_eye_obj);
#endif
#if ULAB_LINALG_DET
mp_obj_t linalg_det(mp_obj_t ); mp_obj_t linalg_det(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(linalg_det_obj);
#endif
#if ULAB_LINALG_EIG
mp_obj_t linalg_eig(mp_obj_t ); mp_obj_t linalg_eig(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(linalg_eig_obj);
#endif
#endif #endif

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -17,6 +16,7 @@
#include "py/binary.h" #include "py/binary.h"
#include "py/obj.h" #include "py/obj.h"
#include "py/objtuple.h" #include "py/objtuple.h"
#include "compat.h"
#include "ndarray.h" #include "ndarray.h"
// This function is copied verbatim from objarray.c // This function is copied verbatim from objarray.c
@ -64,16 +64,15 @@ void fill_array_iterable(mp_float_t *array, mp_obj_t iterable) {
void ndarray_print_row(const mp_print_t *print, mp_obj_array_t *data, size_t n0, size_t n) { void ndarray_print_row(const mp_print_t *print, mp_obj_array_t *data, size_t n0, size_t n) {
mp_print_str(print, "["); mp_print_str(print, "[");
size_t i;
if(n < PRINT_MAX) { // if the array is short, print everything if(n < PRINT_MAX) { // if the array is short, print everything
mp_obj_print_helper(print, mp_binary_get_val_array(data->typecode, data->items, n0), PRINT_REPR); mp_obj_print_helper(print, mp_binary_get_val_array(data->typecode, data->items, n0), PRINT_REPR);
for(i=1; i<n; i++) { for(size_t i=1; i<n; i++) {
mp_print_str(print, ", "); mp_print_str(print, ", ");
mp_obj_print_helper(print, mp_binary_get_val_array(data->typecode, data->items, n0+i), PRINT_REPR); mp_obj_print_helper(print, mp_binary_get_val_array(data->typecode, data->items, n0+i), PRINT_REPR);
} }
} else { } else {
mp_obj_print_helper(print, mp_binary_get_val_array(data->typecode, data->items, n0), PRINT_REPR); mp_obj_print_helper(print, mp_binary_get_val_array(data->typecode, data->items, n0), PRINT_REPR);
for(i=1; i<3; i++) { for(size_t i=1; i<3; i++) {
mp_print_str(print, ", "); mp_print_str(print, ", ");
mp_obj_print_helper(print, mp_binary_get_val_array(data->typecode, data->items, n0+i), PRINT_REPR); mp_obj_print_helper(print, mp_binary_get_val_array(data->typecode, data->items, n0+i), PRINT_REPR);
} }
@ -165,11 +164,14 @@ STATIC uint8_t ndarray_init_helper(size_t n_args, const mp_obj_t *pos_args, mp_m
return dtype; return dtype;
} }
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_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, n_kw, 1, 2, true); mp_arg_check_num(n_args, kw_args, 1, 2, true);
mp_map_t kw_args; size_t n_kw = 0;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); if (kw_args != 0) {
uint8_t dtype = ndarray_init_helper(n_args, args, &kw_args); n_kw = kw_args->used;
}
mp_map_init_fixed_table(kw_args, n_kw, args + n_args);
uint8_t dtype = ndarray_init_helper(n_args, args, kw_args);
size_t len1, len2=0, i=0; size_t len1, len2=0, i=0;
mp_obj_t len_in = mp_obj_len_maybe(args[0]); mp_obj_t len_in = mp_obj_len_maybe(args[0]);
@ -189,7 +191,8 @@ mp_obj_t ndarray_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
if(len_in != MP_OBJ_NULL) { // indeed, this seems to be an iterable if(len_in != MP_OBJ_NULL) { // indeed, this seems to be an iterable
// Next, we have to check, whether all elements in the outer loop have the same length // Next, we have to check, whether all elements in the outer loop have the same length
if(i > 0) { if(i > 0) {
if(len2 != MP_OBJ_SMALL_INT_VALUE(len_in)) { size_t temp = abs(MP_OBJ_SMALL_INT_VALUE(len_in));
if(len2 != temp) {
mp_raise_ValueError(translate("iterables are not of the same length")); mp_raise_ValueError(translate("iterables are not of the same length"));
} }
} }
@ -216,11 +219,13 @@ mp_obj_t ndarray_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
} }
size_t slice_length(mp_bound_slice_t slice) { size_t slice_length(mp_bound_slice_t slice) {
int32_t len, correction = 1; // TODO: check, whether this is true!
if(slice.step > 0) correction = -1; if(slice.step < 0) {
len = (slice.stop - slice.start + (slice.step + correction)) / slice.step; slice.step = -slice.step;
if(len < 0) return 0; return (slice.start - slice.stop) / slice.step;
return (size_t)len; } else {
return (slice.stop - slice.start) / slice.step;
}
} }
size_t true_length(mp_obj_t bool_list) { size_t true_length(mp_obj_t bool_list) {
@ -230,7 +235,7 @@ size_t true_length(mp_obj_t bool_list) {
mp_obj_t item, iterable = mp_getiter(bool_list, &iter_buf); mp_obj_t item, iterable = mp_getiter(bool_list, &iter_buf);
size_t trues = 0; size_t trues = 0;
while((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { 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 // 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 // to be True/False. Bail out immediately, if the items are not True/False
return 0; return 0;
@ -247,8 +252,8 @@ mp_bound_slice_t generate_slice(mp_uint_t n, mp_obj_t index) {
mp_bound_slice_t slice; 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); 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); uint32_t _index = mp_obj_get_int(index);
if(_index < 0) { if(_index < 0) {
_index += n; _index += n;
} }
@ -351,7 +356,8 @@ mp_obj_t insert_slice_list(ndarray_obj_t *ndarray, size_t m, size_t n,
} else { // columns are indexed by a list } else { // columns are indexed by a list
mp_obj_iter_buf_t column_iter_buf; mp_obj_iter_buf_t column_iter_buf;
mp_obj_t column_item, column_iterable; mp_obj_t column_item, column_iterable;
size_t j = 0, cindex = 0; size_t j = 0;
cindex = 0;
while((row_item = mp_iternext(row_iterable)) != MP_OBJ_STOP_ITERATION) { while((row_item = mp_iternext(row_iterable)) != MP_OBJ_STOP_ITERATION) {
if(mp_obj_is_true(row_item)) { if(mp_obj_is_true(row_item)) {
column_iterable = mp_getiter(column_list, &column_iter_buf); column_iterable = mp_getiter(column_list, &column_iter_buf);
@ -437,7 +443,8 @@ mp_obj_t iterate_slice_list(ndarray_obj_t *ndarray, size_t m, size_t n,
} else { // columns are indexed by a list } else { // columns are indexed by a list
mp_obj_iter_buf_t column_iter_buf; mp_obj_iter_buf_t column_iter_buf;
mp_obj_t column_item, column_iterable; mp_obj_t column_item, column_iterable;
size_t j = 0, cindex = 0; size_t j = 0;
cindex = 0;
while((row_item = mp_iternext(row_iterable)) != MP_OBJ_STOP_ITERATION) { while((row_item = mp_iternext(row_iterable)) != MP_OBJ_STOP_ITERATION) {
if(mp_obj_is_true(row_item)) { if(mp_obj_is_true(row_item)) {
column_iterable = mp_getiter(column_list, &column_iter_buf); column_iterable = mp_getiter(column_list, &column_iter_buf);
@ -461,7 +468,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); mp_bound_slice_t row_slice = simple_slice(0, 0, 1), column_slice = simple_slice(0, 0, 1);
size_t m = 0, n = 0; 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 // we have a row vector, and don't want to assign
column_slice = generate_slice(ndarray->n, index); column_slice = generate_slice(ndarray->n, index);
if(slice_length(column_slice) == 1) { // we were asked for a single item if(slice_length(column_slice) == 1) { // we were asked for a single item
@ -470,7 +477,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 if(ndarray->m == 1) { // we have a row vector
column_slice = generate_slice(ndarray->n, index); column_slice = generate_slice(ndarray->n, index);
row_slice = simple_slice(0, 1, 1); row_slice = simple_slice(0, 1, 1);
@ -496,12 +503,12 @@ mp_obj_t ndarray_get_slice(ndarray_obj_t *ndarray, mp_obj_t index, ndarray_obj_t
if(tuple->len != 2) { if(tuple->len != 2) {
mp_raise_msg(&mp_type_IndexError, translate("too many indices")); mp_raise_msg(&mp_type_IndexError, translate("too many indices"));
} }
if(!(mp_obj_is_type(tuple->items[0], &mp_type_list) || if(!(MP_OBJ_IS_TYPE(tuple->items[0], &mp_type_list) ||
mp_obj_is_type(tuple->items[0], &mp_type_slice) || MP_OBJ_IS_TYPE(tuple->items[0], &mp_type_slice) ||
mp_obj_is_int(tuple->items[0])) || 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_list) ||
mp_obj_is_type(tuple->items[1], &mp_type_slice) || MP_OBJ_IS_TYPE(tuple->items[1], &mp_type_slice) ||
mp_obj_is_int(tuple->items[1]))) { MP_OBJ_IS_INT(tuple->items[1]))) {
mp_raise_msg(&mp_type_IndexError, translate("indices must be integers, slices, or Boolean lists")); 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
@ -541,12 +548,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) if (value == MP_OBJ_SENTINEL) { // return value(s)
return ndarray_get_slice(self, index, NULL); return ndarray_get_slice(self, index, NULL);
} else { // assignment to slices; the value must be an ndarray, or a scalar } else { // assignment to slices; the value must be an ndarray, or a scalar
if(!mp_obj_is_type(value, &ulab_ndarray_type) && if(!MP_OBJ_IS_TYPE(value, &ulab_ndarray_type) &&
!mp_obj_is_int(value) && !mp_obj_is_float(value)) { !MP_OBJ_IS_INT(value) && !mp_obj_is_float(value)) {
mp_raise_ValueError(translate("right hand side must be an ndarray, or a scalar")); mp_raise_ValueError(translate("right hand side must be an ndarray, or a scalar"));
} else { } else {
ndarray_obj_t *values = NULL; 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); values = create_new_ndarray(1, 1, self->array->typecode);
mp_binary_set_val_array(values->array->typecode, values->array->items, 0, value); mp_binary_set_val_array(values->array->typecode, values->array->items, 0, value);
} else if(mp_obj_is_float(value)) { } else if(mp_obj_is_float(value)) {
@ -677,6 +684,11 @@ mp_obj_t ndarray_flatten(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
return self_copy; return self_copy;
} }
mp_obj_t ndarray_asbytearray(mp_obj_t self_in) {
ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in);
return MP_OBJ_FROM_PTR(self->array);
}
// Binary operations // Binary operations
mp_obj_t ndarray_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_t ndarray_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
@ -688,7 +700,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 // TODO: implement in-place operators
mp_obj_t RHS = MP_OBJ_NULL; mp_obj_t RHS = MP_OBJ_NULL;
bool rhs_is_scalar = true; 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); int32_t ivalue = mp_obj_get_int(rhs);
if((ivalue > 0) && (ivalue < 256)) { if((ivalue > 0) && (ivalue < 256)) {
CREATE_SINGLE_ITEM(RHS, uint8_t, NDARRAY_UINT8, ivalue); CREATE_SINGLE_ITEM(RHS, uint8_t, NDARRAY_UINT8, ivalue);
@ -709,7 +721,7 @@ mp_obj_t ndarray_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
rhs_is_scalar = false; rhs_is_scalar = false;
} }
//else //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 // next, the ndarray stuff
ndarray_obj_t *ol = MP_OBJ_TO_PTR(lhs); ndarray_obj_t *ol = MP_OBJ_TO_PTR(lhs);
ndarray_obj_t *or = MP_OBJ_TO_PTR(RHS); ndarray_obj_t *or = MP_OBJ_TO_PTR(RHS);
@ -832,6 +844,11 @@ mp_obj_t ndarray_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
mp_obj_t ndarray_unary_op(mp_unary_op_t op, mp_obj_t self_in) { mp_obj_t ndarray_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in); ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in);
ndarray_obj_t *ndarray = NULL; ndarray_obj_t *ndarray = NULL;
uint8_t *array8u;
int8_t *array8i;
uint16_t *array16u;
int16_t *array16i;
mp_float_t *arraymp;
switch (op) { switch (op) {
case MP_UNARY_OP_LEN: case MP_UNARY_OP_LEN:
if(self->m > 1) { if(self->m > 1) {
@ -848,28 +865,28 @@ mp_obj_t ndarray_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
// we can invert the content byte by byte, there is no need to distinguish // we can invert the content byte by byte, there is no need to distinguish
// between different typecodes // between different typecodes
ndarray = MP_OBJ_TO_PTR(ndarray_copy(self_in)); ndarray = MP_OBJ_TO_PTR(ndarray_copy(self_in));
uint8_t *array = (uint8_t *)ndarray->array->items; array8u = (uint8_t *)ndarray->array->items;
for(size_t i=0; i < self->bytes; i++) array[i] = ~array[i]; for(size_t i=0; i < self->bytes; i++) array8u[i] = ~array8u[i];
return MP_OBJ_FROM_PTR(ndarray); return MP_OBJ_FROM_PTR(ndarray);
break; break;
case MP_UNARY_OP_NEGATIVE: case MP_UNARY_OP_NEGATIVE:
ndarray = MP_OBJ_TO_PTR(ndarray_copy(self_in)); ndarray = MP_OBJ_TO_PTR(ndarray_copy(self_in));
if(self->array->typecode == NDARRAY_UINT8) { if(self->array->typecode == NDARRAY_UINT8) {
uint8_t *array = (uint8_t *)ndarray->array->items; array8u = (uint8_t *)ndarray->array->items;
for(size_t i=0; i < self->array->len; i++) array[i] = -array[i]; for(size_t i=0; i < self->array->len; i++) array8u[i] = -array8u[i];
} else if(self->array->typecode == NDARRAY_INT8) { } else if(self->array->typecode == NDARRAY_INT8) {
int8_t *array = (int8_t *)ndarray->array->items; array8i = (int8_t *)ndarray->array->items;
for(size_t i=0; i < self->array->len; i++) array[i] = -array[i]; for(size_t i=0; i < self->array->len; i++) array8i[i] = -array8i[i];
} else if(self->array->typecode == NDARRAY_UINT16) { } else if(self->array->typecode == NDARRAY_UINT16) {
uint16_t *array = (uint16_t *)ndarray->array->items; array16u = (uint16_t *)ndarray->array->items;
for(size_t i=0; i < self->array->len; i++) array[i] = -array[i]; for(size_t i=0; i < self->array->len; i++) array16u[i] = -array16u[i];
} else if(self->array->typecode == NDARRAY_INT16) { } else if(self->array->typecode == NDARRAY_INT16) {
int16_t *array = (int16_t *)ndarray->array->items; array16i = (int16_t *)ndarray->array->items;
for(size_t i=0; i < self->array->len; i++) array[i] = -array[i]; for(size_t i=0; i < self->array->len; i++) array16i[i] = -array16i[i];
} else { } else {
mp_float_t *array = (mp_float_t *)ndarray->array->items; arraymp = (mp_float_t *)ndarray->array->items;
for(size_t i=0; i < self->array->len; i++) array[i] = -array[i]; for(size_t i=0; i < self->array->len; i++) arraymp[i] = -arraymp[i];
} }
return MP_OBJ_FROM_PTR(ndarray); return MP_OBJ_FROM_PTR(ndarray);
break; break;
@ -882,20 +899,20 @@ mp_obj_t ndarray_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
return ndarray_copy(self_in); return ndarray_copy(self_in);
} }
ndarray = MP_OBJ_TO_PTR(ndarray_copy(self_in)); ndarray = MP_OBJ_TO_PTR(ndarray_copy(self_in));
if((self->array->typecode == NDARRAY_INT8)) { if(self->array->typecode == NDARRAY_INT8) {
int8_t *array = (int8_t *)ndarray->array->items; array8i = (int8_t *)ndarray->array->items;
for(size_t i=0; i < self->array->len; i++) { for(size_t i=0; i < self->array->len; i++) {
if(array[i] < 0) array[i] = -array[i]; if(array8i[i] < 0) array8i[i] = -array8i[i];
} }
} else if((self->array->typecode == NDARRAY_INT16)) { } else if(self->array->typecode == NDARRAY_INT16) {
int16_t *array = (int16_t *)ndarray->array->items; array16i = (int16_t *)ndarray->array->items;
for(size_t i=0; i < self->array->len; i++) { for(size_t i=0; i < self->array->len; i++) {
if(array[i] < 0) array[i] = -array[i]; if(array16i[i] < 0) array16i[i] = -array16i[i];
} }
} else { } else {
mp_float_t *array = (mp_float_t *)ndarray->array->items; arraymp = (mp_float_t *)ndarray->array->items;
for(size_t i=0; i < self->array->len; i++) { for(size_t i=0; i < self->array->len; i++) {
if(array[i] < 0) array[i] = -array[i]; if(arraymp[i] < 0) arraymp[i] = -arraymp[i];
} }
} }
return MP_OBJ_FROM_PTR(ndarray); return MP_OBJ_FROM_PTR(ndarray);
@ -903,9 +920,3 @@ mp_obj_t ndarray_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
default: return MP_OBJ_NULL; // operator not supported default: return MP_OBJ_NULL; // operator not supported
} }
} }
mp_int_t ndarray_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in);
// buffer_p.get_buffer() returns zero for success, while mp_get_buffer returns true for success
return !mp_get_buffer(self->array, bufinfo, flags);
}

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -6,7 +5,7 @@
* *
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2019-2020 Zoltán Vörös * Copyright (c) 2019 Zoltán Vörös
*/ */
#ifndef _NDARRAY_ #ifndef _NDARRAY_
@ -25,11 +24,7 @@
#define FLOAT_TYPECODE 'd' #define FLOAT_TYPECODE 'd'
#endif #endif
#if !CIRCUITPY const mp_obj_type_t ulab_ndarray_type;
#define translate(x) x
#endif
extern const mp_obj_type_t ulab_ndarray_type;
enum NDARRAY_TYPE { enum NDARRAY_TYPE {
NDARRAY_UINT8 = 'B', NDARRAY_UINT8 = 'B',
@ -58,7 +53,7 @@ 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 ); ndarray_obj_t *create_new_ndarray(size_t , size_t , uint8_t );
mp_obj_t ndarray_copy(mp_obj_t ); mp_obj_t ndarray_copy(mp_obj_t );
mp_obj_t ndarray_make_new(const mp_obj_type_t *, size_t , size_t , const mp_obj_t *); mp_obj_t ndarray_make_new(const mp_obj_type_t *, size_t, const mp_obj_t *, mp_map_t *);
mp_obj_t ndarray_subscr(mp_obj_t , mp_obj_t , mp_obj_t ); 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_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_binary_op(mp_binary_op_t , mp_obj_t , mp_obj_t );
@ -67,7 +62,7 @@ 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_shape(mp_obj_t );
mp_obj_t ndarray_rawsize(mp_obj_t ); mp_obj_t ndarray_rawsize(mp_obj_t );
mp_obj_t ndarray_flatten(size_t , const mp_obj_t *, mp_map_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); mp_obj_t ndarray_asbytearray(mp_obj_t );
#define CREATE_SINGLE_ITEM(outarray, type, typecode, value) do {\ #define CREATE_SINGLE_ITEM(outarray, type, typecode, value) do {\
ndarray_obj_t *tmp = create_new_ndarray(1, 1, (typecode));\ ndarray_obj_t *tmp = create_new_ndarray(1, 1, (typecode));\

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -17,6 +16,7 @@
#include "py/runtime.h" #include "py/runtime.h"
#include "py/builtin.h" #include "py/builtin.h"
#include "py/misc.h" #include "py/misc.h"
#include "compat.h"
#include "numerical.h" #include "numerical.h"
enum NUMERICAL_FUNCTION_TYPE { enum NUMERICAL_FUNCTION_TYPE {
@ -29,7 +29,6 @@ enum NUMERICAL_FUNCTION_TYPE {
NUMERICAL_STD, NUMERICAL_STD,
}; };
#if ULAB_NUMERICAL_LINSPACE
mp_obj_t numerical_linspace(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { 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[] = { 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 } },
@ -79,9 +78,6 @@ mp_obj_t numerical_linspace(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
} }
} }
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_linspace_obj, 2, numerical_linspace);
#endif
void axis_sorter(ndarray_obj_t *ndarray, mp_obj_t axis, size_t *m, size_t *n, size_t *N, void axis_sorter(ndarray_obj_t *ndarray, mp_obj_t axis, size_t *m, size_t *n, size_t *N,
size_t *increment, size_t *len, size_t *start_inc) { size_t *increment, size_t *len, size_t *start_inc) {
if(axis == mp_const_none) { // flatten the array if(axis == mp_const_none) { // flatten the array
@ -255,7 +251,6 @@ mp_obj_t numerical_argmin_argmax_ndarray(ndarray_obj_t *ndarray, mp_obj_t axis,
return MP_OBJ_FROM_PTR(results); return MP_OBJ_FROM_PTR(results);
} }
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 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[] = { 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} } ,
@ -310,38 +305,26 @@ mp_obj_t numerical_min(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_arg
return numerical_function(n_args, pos_args, kw_args, NUMERICAL_MIN); return numerical_function(n_args, pos_args, kw_args, NUMERICAL_MIN);
} }
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_min_obj, 1, numerical_min);
mp_obj_t numerical_max(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_obj_t numerical_max(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
return numerical_function(n_args, pos_args, kw_args, NUMERICAL_MAX); return numerical_function(n_args, pos_args, kw_args, NUMERICAL_MAX);
} }
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_max_obj, 1, numerical_max);
mp_obj_t numerical_argmin(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_obj_t numerical_argmin(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
return numerical_function(n_args, pos_args, kw_args, NUMERICAL_ARGMIN); return numerical_function(n_args, pos_args, kw_args, NUMERICAL_ARGMIN);
} }
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_argmin_obj, 1, numerical_argmin);
mp_obj_t numerical_argmax(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_obj_t numerical_argmax(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
return numerical_function(n_args, pos_args, kw_args, NUMERICAL_ARGMAX); return numerical_function(n_args, pos_args, kw_args, NUMERICAL_ARGMAX);
} }
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_argmax_obj, 1, numerical_argmax);
mp_obj_t numerical_sum(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_obj_t numerical_sum(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
return numerical_function(n_args, pos_args, kw_args, NUMERICAL_SUM); return numerical_function(n_args, pos_args, kw_args, NUMERICAL_SUM);
} }
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_sum_obj, 1, numerical_sum);
mp_obj_t numerical_mean(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_obj_t numerical_mean(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
return numerical_function(n_args, pos_args, kw_args, NUMERICAL_MEAN); return numerical_function(n_args, pos_args, kw_args, NUMERICAL_MEAN);
} }
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) { 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[] = { 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 } } ,
@ -370,9 +353,6 @@ mp_obj_t numerical_std(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_arg
return mp_const_none; return mp_const_none;
} }
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) { 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[] = { 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 } },
@ -453,10 +433,6 @@ mp_obj_t numerical_roll(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
} }
} }
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_roll_obj, 2, numerical_roll);
#endif
#if ULAB_NUMERICAL_FLIP
mp_obj_t numerical_flip(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { 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[] = { 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 } },
@ -504,10 +480,6 @@ mp_obj_t numerical_flip(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
return out; return out;
} }
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_flip_obj, 1, numerical_flip);
#endif
#if ULAB_NUMERICAL_DIFF
mp_obj_t numerical_diff(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { 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[] = { 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 } },
@ -576,10 +548,6 @@ mp_obj_t numerical_diff(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
return MP_OBJ_FROM_PTR(out); return MP_OBJ_FROM_PTR(out);
} }
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_diff_obj, 1, numerical_diff);
#endif
#if ULAB_NUMERICAL_SORT
mp_obj_t numerical_sort_helper(mp_obj_t oin, mp_obj_t axis, uint8_t inplace) { 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")); mp_raise_TypeError(translate("sort argument must be an ndarray"));
@ -648,9 +616,6 @@ mp_obj_t numerical_sort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
return numerical_sort_helper(args[0].u_obj, args[1].u_obj, 0); return numerical_sort_helper(args[0].u_obj, args[1].u_obj, 0);
} }
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_sort_obj, 1, numerical_sort);
// method of an ndarray // 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) { 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[] = { static const mp_arg_t allowed_args[] = {
@ -664,10 +629,6 @@ mp_obj_t numerical_sort_inplace(size_t n_args, const mp_obj_t *pos_args, mp_map_
return numerical_sort_helper(args[0].u_obj, args[1].u_obj, 1); return numerical_sort_helper(args[0].u_obj, args[1].u_obj, 1);
} }
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_sort_inplace_obj, 1, numerical_sort_inplace);
#endif
#if ULAB_NUMERICAL_ARGSORT
mp_obj_t numerical_argsort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { 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[] = { 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 } },
@ -737,6 +698,3 @@ mp_obj_t numerical_argsort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw
} }
return MP_OBJ_FROM_PTR(indices); return MP_OBJ_FROM_PTR(indices);
} }
MP_DEFINE_CONST_FUN_OBJ_KW(numerical_argsort_obj, 1, numerical_argsort);
#endif

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -12,80 +11,27 @@
#ifndef _NUMERICAL_ #ifndef _NUMERICAL_
#define _NUMERICAL_ #define _NUMERICAL_
#include "ulab.h"
#include "ndarray.h" #include "ndarray.h"
#if ULAB_NUMERICAL_LINSPACE
mp_obj_t numerical_linspace(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_linspace(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_linspace_obj);
#endif
#if ULAB_NUMERICAL_SUM
mp_obj_t numerical_sum(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_sum(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_sum_obj);
#endif
#if ULAB_NUMERICAL_MEAN
mp_obj_t numerical_mean(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_mean(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_mean_obj);
#endif
#if ULAB_NUMERICAL_STD
mp_obj_t numerical_std(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_std(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_std_obj);
#endif
#if ULAB_NUMERICAL_MIN
mp_obj_t numerical_min(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_min(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_min_obj);
#endif
#if ULAB_NUMERICAL_MAX
mp_obj_t numerical_max(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_max(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_max_obj);
#endif
#if ULAB_NUMERICAL_ARGMIN
mp_obj_t numerical_argmin(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_argmin(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_argmin_obj);
#endif
#if ULAB_NUMERICAL_ARGMAX
mp_obj_t numerical_argmax(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_argmax(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_argmax_obj);
#endif
#if ULAB_NUMERICAL_ROLL
mp_obj_t numerical_roll(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_roll(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_roll_obj);
#endif
// TODO: implement minimum/maximum, and cumsum // TODO: implement minimum/maximum, and cumsum
//mp_obj_t numerical_minimum(mp_obj_t , mp_obj_t ); mp_obj_t numerical_minimum(mp_obj_t , mp_obj_t );
//mp_obj_t numerical_maximum(mp_obj_t , mp_obj_t ); mp_obj_t numerical_maximum(mp_obj_t , mp_obj_t );
//mp_obj_t numerical_cumsum(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_cumsum(size_t , const mp_obj_t *, mp_map_t *);
#if ULAB_NUMERICAL_FLIP
mp_obj_t numerical_flip(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_flip(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_flip_obj);
#endif
#if ULAB_NUMERICAL_DIFF
mp_obj_t numerical_diff(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_diff(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_diff_obj);
#endif
#if ULAB_NUMERICAL_SORT
mp_obj_t numerical_sort(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_sort(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_sort_obj);
mp_obj_t numerical_sort_inplace(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_sort_inplace(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_sort_inplace_obj);
mp_obj_t numerical_argsort(size_t , const mp_obj_t *, mp_map_t *); mp_obj_t numerical_argsort(size_t , const mp_obj_t *, mp_map_t *);
MP_DECLARE_CONST_FUN_OBJ_KW(numerical_argsort_obj);
#endif
#define RUN_ARGMIN(in, out, typein, typeout, len, start, increment, op, pos) do {\ #define RUN_ARGMIN(in, out, typein, typeout, len, start, increment, op, pos) do {\
typein *array = (typein *)(in)->array->items;\ typein *array = (typein *)(in)->array->items;\

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -12,32 +11,31 @@
#include "py/obj.h" #include "py/obj.h"
#include "py/runtime.h" #include "py/runtime.h"
#include "py/objarray.h" #include "py/objarray.h"
#include "compat.h"
#include "ndarray.h" #include "ndarray.h"
#include "linalg.h" #include "linalg.h"
#include "poly.h" #include "poly.h"
#if ULAB_POLY_POLYVAL || ULAB_POLY_POLYFIT
bool object_is_nditerable(mp_obj_t o_in) { bool object_is_nditerable(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) ||
mp_obj_is_type(o_in, &mp_type_tuple) || 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_list) ||
mp_obj_is_type(o_in, &mp_type_range)) { MP_OBJ_IS_TYPE(o_in, &mp_type_range)) {
return true; return true;
} }
return false; return false;
} }
size_t get_nditerable_len(mp_obj_t o_in) { 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); ndarray_obj_t *in = MP_OBJ_TO_PTR(o_in);
return in->array->len; return in->array->len;
} else { } else {
return (size_t)mp_obj_get_int(mp_obj_len_maybe(o_in)); return (size_t)mp_obj_get_int(mp_obj_len_maybe(o_in));
} }
} }
#endif
#if ULAB_POLY_POLYVAL
mp_obj_t poly_polyval(mp_obj_t o_p, mp_obj_t o_x) { mp_obj_t poly_polyval(mp_obj_t o_p, mp_obj_t o_x) {
// TODO: return immediately, if o_p is not an iterable // TODO: return immediately, if o_p is not an iterable
// TODO: there is a bug here: matrices won't work, // TODO: there is a bug here: matrices won't work,
@ -85,10 +83,6 @@ mp_obj_t poly_polyval(mp_obj_t o_p, mp_obj_t o_x) {
return MP_OBJ_FROM_PTR(out); return MP_OBJ_FROM_PTR(out);
} }
MP_DEFINE_CONST_FUN_OBJ_2(poly_polyval_obj, poly_polyval);
#endif
#if ULAB_POLY_POLYFIT
mp_obj_t poly_polyfit(size_t n_args, const mp_obj_t *args) { mp_obj_t poly_polyfit(size_t n_args, const mp_obj_t *args) {
if((n_args != 2) && (n_args != 3)) { if((n_args != 2) && (n_args != 3)) {
mp_raise_ValueError(translate("number of arguments must be 2, or 3")); mp_raise_ValueError(translate("number of arguments must be 2, or 3"));
@ -198,6 +192,3 @@ mp_obj_t poly_polyfit(size_t n_args, const mp_obj_t *args) {
} }
return MP_OBJ_FROM_PTR(beta); return MP_OBJ_FROM_PTR(beta);
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poly_polyfit_obj, 2, 3, poly_polyfit);
#endif

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -6,22 +5,13 @@
* *
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2019-2020 Zoltán Vörös * Copyright (c) 2019 Zoltán Vörös
*/ */
#ifndef _POLY_ #ifndef _POLY_
#define _POLY_ #define _POLY_
#include "ulab.h"
#if ULAB_POLY_POLYVAL
mp_obj_t poly_polyval(mp_obj_t , mp_obj_t ); mp_obj_t poly_polyval(mp_obj_t , mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_2(poly_polyval_obj);
#endif
#if ULAB_POLY_POLYFIT
mp_obj_t poly_polyfit(size_t , const mp_obj_t *); mp_obj_t poly_polyfit(size_t , const mp_obj_t *);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(poly_polyfit_obj);
#endif
#endif #endif

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -18,7 +17,7 @@
#include "py/obj.h" #include "py/obj.h"
#include "py/objarray.h" #include "py/objarray.h"
#include "ulab.h" #include "compat.h"
#include "ndarray.h" #include "ndarray.h"
#include "linalg.h" #include "linalg.h"
#include "vectorise.h" #include "vectorise.h"
@ -27,22 +26,79 @@
#include "filter.h" #include "filter.h"
#include "numerical.h" #include "numerical.h"
STATIC MP_DEFINE_STR_OBJ(ulab_version_obj, "0.31.0"); STATIC MP_DEFINE_STR_OBJ(ulab_version_obj, "0.27.0");
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_shape_obj, ndarray_shape); 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_1(ndarray_rawsize_obj, ndarray_rawsize);
MP_DEFINE_CONST_FUN_OBJ_KW(ndarray_flatten_obj, 1, ndarray_flatten); MP_DEFINE_CONST_FUN_OBJ_KW(ndarray_flatten_obj, 1, ndarray_flatten);
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_asbytearray_obj, ndarray_asbytearray);
MP_DEFINE_CONST_FUN_OBJ_1(linalg_transpose_obj, linalg_transpose);
MP_DEFINE_CONST_FUN_OBJ_2(linalg_reshape_obj, linalg_reshape);
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_size_obj, 1, linalg_size);
MP_DEFINE_CONST_FUN_OBJ_1(linalg_inv_obj, linalg_inv);
MP_DEFINE_CONST_FUN_OBJ_2(linalg_dot_obj, linalg_dot);
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_zeros_obj, 0, linalg_zeros);
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_ones_obj, 0, linalg_ones);
MP_DEFINE_CONST_FUN_OBJ_KW(linalg_eye_obj, 0, linalg_eye);
MP_DEFINE_CONST_FUN_OBJ_1(linalg_det_obj, linalg_det);
MP_DEFINE_CONST_FUN_OBJ_1(linalg_eig_obj, linalg_eig);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_acos_obj, vectorise_acos);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_acosh_obj, vectorise_acosh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_asin_obj, vectorise_asin);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_asinh_obj, vectorise_asinh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_atan_obj, vectorise_atan);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_atanh_obj, vectorise_atanh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_ceil_obj, vectorise_ceil);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_cos_obj, vectorise_cos);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_erf_obj, vectorise_erf);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_erfc_obj, vectorise_erfc);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_exp_obj, vectorise_exp);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_expm1_obj, vectorise_expm1);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_floor_obj, vectorise_floor);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_gamma_obj, vectorise_gamma);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_lgamma_obj, vectorise_lgamma);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_log_obj, vectorise_log);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_log10_obj, vectorise_log10);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_log2_obj, vectorise_log2);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_sin_obj, vectorise_sin);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_sinh_obj, vectorise_sinh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_sqrt_obj, vectorise_sqrt);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_tan_obj, vectorise_tan);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_tanh_obj, vectorise_tanh);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_linspace_obj, 2, numerical_linspace);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_sum_obj, 1, numerical_sum);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_mean_obj, 1, numerical_mean);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_std_obj, 1, numerical_std);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_min_obj, 1, numerical_min);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_max_obj, 1, numerical_max);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_argmin_obj, 1, numerical_argmin);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_argmax_obj, 1, numerical_argmax);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_roll_obj, 2, numerical_roll);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_flip_obj, 1, numerical_flip);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_diff_obj, 1, numerical_diff);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_sort_obj, 1, numerical_sort);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_sort_inplace_obj, 1, numerical_sort_inplace);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(numerical_argsort_obj, 1, numerical_argsort);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(poly_polyval_obj, poly_polyval);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poly_polyfit_obj, 2, 3, poly_polyfit);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fft_fft_obj, 1, 2, fft_fft);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fft_ifft_obj, 1, 2, fft_ifft);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fft_spectrum_obj, 1, 2, fft_spectrum);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(filter_convolve_obj, 2, filter_convolve);
STATIC const mp_rom_map_elem_t ulab_ndarray_locals_dict_table[] = { 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_shape), MP_ROM_PTR(&ndarray_shape_obj) },
{ MP_ROM_QSTR(MP_QSTR_rawsize), MP_ROM_PTR(&ndarray_rawsize_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_asbytearray), MP_ROM_PTR(&ndarray_asbytearray_obj) },
{ MP_ROM_QSTR(MP_QSTR_transpose), MP_ROM_PTR(&linalg_transpose_obj) }, { MP_ROM_QSTR(MP_QSTR_transpose), MP_ROM_PTR(&linalg_transpose_obj) },
#endif
#if ULAB_LINALG_RESHAPE
{ MP_ROM_QSTR(MP_QSTR_reshape), MP_ROM_PTR(&linalg_reshape_obj) }, { MP_ROM_QSTR(MP_QSTR_reshape), MP_ROM_PTR(&linalg_reshape_obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_sort), MP_ROM_PTR(&numerical_sort_inplace_obj) }, { MP_ROM_QSTR(MP_QSTR_sort), MP_ROM_PTR(&numerical_sort_inplace_obj) },
}; };
@ -57,7 +113,6 @@ const mp_obj_type_t ulab_ndarray_type = {
.getiter = ndarray_getiter, .getiter = ndarray_getiter,
.unary_op = ndarray_unary_op, .unary_op = ndarray_unary_op,
.binary_op = ndarray_binary_op, .binary_op = ndarray_binary_op,
.buffer_p = { .get_buffer = ndarray_get_buffer, },
.locals_dict = (mp_obj_dict_t*)&ulab_ndarray_locals_dict, .locals_dict = (mp_obj_dict_t*)&ulab_ndarray_locals_dict,
}; };
@ -65,156 +120,56 @@ STATIC const mp_map_elem_t ulab_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ulab) }, { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ulab) },
{ MP_ROM_QSTR(MP_QSTR___version__), MP_ROM_PTR(&ulab_version_obj) }, { MP_ROM_QSTR(MP_QSTR___version__), MP_ROM_PTR(&ulab_version_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_array), (mp_obj_t)&ulab_ndarray_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_array), (mp_obj_t)&ulab_ndarray_type },
#if ULAB_LINALG_SIZE
{ MP_OBJ_NEW_QSTR(MP_QSTR_size), (mp_obj_t)&linalg_size_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_size), (mp_obj_t)&linalg_size_obj },
#endif
#if ULAB_LINALG_INV
{ MP_OBJ_NEW_QSTR(MP_QSTR_inv), (mp_obj_t)&linalg_inv_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_inv), (mp_obj_t)&linalg_inv_obj },
#endif
#if ULAB_LINALG_DOT
{ MP_ROM_QSTR(MP_QSTR_dot), (mp_obj_t)&linalg_dot_obj }, { MP_ROM_QSTR(MP_QSTR_dot), (mp_obj_t)&linalg_dot_obj },
#endif
#if ULAB_LINALG_ZEROS
{ MP_ROM_QSTR(MP_QSTR_zeros), (mp_obj_t)&linalg_zeros_obj }, { MP_ROM_QSTR(MP_QSTR_zeros), (mp_obj_t)&linalg_zeros_obj },
#endif
#if ULAB_LINALG_ONES
{ MP_ROM_QSTR(MP_QSTR_ones), (mp_obj_t)&linalg_ones_obj }, { MP_ROM_QSTR(MP_QSTR_ones), (mp_obj_t)&linalg_ones_obj },
#endif
#if ULAB_LINALG_EYE
{ MP_ROM_QSTR(MP_QSTR_eye), (mp_obj_t)&linalg_eye_obj }, { MP_ROM_QSTR(MP_QSTR_eye), (mp_obj_t)&linalg_eye_obj },
#endif
#if ULAB_LINALG_DET
{ MP_ROM_QSTR(MP_QSTR_det), (mp_obj_t)&linalg_det_obj }, { MP_ROM_QSTR(MP_QSTR_det), (mp_obj_t)&linalg_det_obj },
#endif
#if ULAB_LINALG_EIG
{ MP_ROM_QSTR(MP_QSTR_eig), (mp_obj_t)&linalg_eig_obj }, { MP_ROM_QSTR(MP_QSTR_eig), (mp_obj_t)&linalg_eig_obj },
#endif
#if ULAB_VECTORISE_ACOS
{ MP_OBJ_NEW_QSTR(MP_QSTR_acos), (mp_obj_t)&vectorise_acos_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_acos), (mp_obj_t)&vectorise_acos_obj },
#endif
#if ULAB_VECTORISE_ACOSH
{ MP_OBJ_NEW_QSTR(MP_QSTR_acosh), (mp_obj_t)&vectorise_acosh_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_acosh), (mp_obj_t)&vectorise_acosh_obj },
#endif
#if ULAB_VECTORISE_ASIN
{ MP_OBJ_NEW_QSTR(MP_QSTR_asin), (mp_obj_t)&vectorise_asin_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_asin), (mp_obj_t)&vectorise_asin_obj },
#endif
#if ULAB_VECTORISE_ASINH
{ MP_OBJ_NEW_QSTR(MP_QSTR_asinh), (mp_obj_t)&vectorise_asinh_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_asinh), (mp_obj_t)&vectorise_asinh_obj },
#endif
#if ULAB_VECTORISE_ATAN
{ MP_OBJ_NEW_QSTR(MP_QSTR_atan), (mp_obj_t)&vectorise_atan_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_atan), (mp_obj_t)&vectorise_atan_obj },
#endif
#if ULAB_VECTORISE_ATANH
{ MP_OBJ_NEW_QSTR(MP_QSTR_atanh), (mp_obj_t)&vectorise_atanh_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_atanh), (mp_obj_t)&vectorise_atanh_obj },
#endif
#if ULAB_VECTORISE_CEIL
{ MP_OBJ_NEW_QSTR(MP_QSTR_ceil), (mp_obj_t)&vectorise_ceil_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_ceil), (mp_obj_t)&vectorise_ceil_obj },
#endif
#if ULAB_VECTORISE_COS
{ MP_OBJ_NEW_QSTR(MP_QSTR_cos), (mp_obj_t)&vectorise_cos_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_cos), (mp_obj_t)&vectorise_cos_obj },
#endif
#if ULAB_VECTORISE_ERF
{ MP_OBJ_NEW_QSTR(MP_QSTR_erf), (mp_obj_t)&vectorise_erf_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_erf), (mp_obj_t)&vectorise_erf_obj },
#endif
#if ULAB_VECTORISE_ERFC
{ MP_OBJ_NEW_QSTR(MP_QSTR_erfc), (mp_obj_t)&vectorise_erfc_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_erfc), (mp_obj_t)&vectorise_erfc_obj },
#endif
#if ULAB_VECTORISE_EXP
{ MP_OBJ_NEW_QSTR(MP_QSTR_exp), (mp_obj_t)&vectorise_exp_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_exp), (mp_obj_t)&vectorise_exp_obj },
#endif
#if ULAB_VECTORISE_EXPM1
{ MP_OBJ_NEW_QSTR(MP_QSTR_expm1), (mp_obj_t)&vectorise_expm1_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_expm1), (mp_obj_t)&vectorise_expm1_obj },
#endif
#if ULAB_VECTORISE_FLOOR
{ MP_OBJ_NEW_QSTR(MP_QSTR_floor), (mp_obj_t)&vectorise_floor_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_floor), (mp_obj_t)&vectorise_floor_obj },
#endif
#if ULAB_VECTORISE_GAMMA
{ MP_OBJ_NEW_QSTR(MP_QSTR_gamma), (mp_obj_t)&vectorise_gamma_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_gamma), (mp_obj_t)&vectorise_gamma_obj },
#endif
#if ULAB_VECTORISE_LGAMMA
{ MP_OBJ_NEW_QSTR(MP_QSTR_lgamma), (mp_obj_t)&vectorise_lgamma_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_lgamma), (mp_obj_t)&vectorise_lgamma_obj },
#endif
#if ULAB_VECTORISE_LOG
{ MP_OBJ_NEW_QSTR(MP_QSTR_log), (mp_obj_t)&vectorise_log_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_log), (mp_obj_t)&vectorise_log_obj },
#endif
#if ULAB_VECTORISE_LOG10
{ MP_OBJ_NEW_QSTR(MP_QSTR_log10), (mp_obj_t)&vectorise_log10_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_log10), (mp_obj_t)&vectorise_log10_obj },
#endif
#if ULAB_VECTORISE_LOG2
{ MP_OBJ_NEW_QSTR(MP_QSTR_log2), (mp_obj_t)&vectorise_log2_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_log2), (mp_obj_t)&vectorise_log2_obj },
#endif
#if ULAB_VECTORISE_SIN
{ MP_OBJ_NEW_QSTR(MP_QSTR_sin), (mp_obj_t)&vectorise_sin_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sin), (mp_obj_t)&vectorise_sin_obj },
#endif
#if ULAB_VECTORISE_
{ MP_OBJ_NEW_QSTR(MP_QSTR_sinh), (mp_obj_t)&vectorise_sinh_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sinh), (mp_obj_t)&vectorise_sinh_obj },
#endif
#if ULAB_VECTORISE_SQRT
{ MP_OBJ_NEW_QSTR(MP_QSTR_sqrt), (mp_obj_t)&vectorise_sqrt_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sqrt), (mp_obj_t)&vectorise_sqrt_obj },
#endif
#if ULAB_VECTORISE_TAN
{ MP_OBJ_NEW_QSTR(MP_QSTR_tan), (mp_obj_t)&vectorise_tan_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_tan), (mp_obj_t)&vectorise_tan_obj },
#endif
#if ULAB_VECTORISE_TAHN
{ MP_OBJ_NEW_QSTR(MP_QSTR_tanh), (mp_obj_t)&vectorise_tanh_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_tanh), (mp_obj_t)&vectorise_tanh_obj },
#endif
#if ULAB_NUMERICAL_LINSPACE
{ MP_OBJ_NEW_QSTR(MP_QSTR_linspace), (mp_obj_t)&numerical_linspace_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_linspace), (mp_obj_t)&numerical_linspace_obj },
#endif
#if ULAB_NUMERICAL_SUM
{ MP_OBJ_NEW_QSTR(MP_QSTR_sum), (mp_obj_t)&numerical_sum_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sum), (mp_obj_t)&numerical_sum_obj },
#endif
#if ULAB_NUMERICAL_MEAN
{ MP_OBJ_NEW_QSTR(MP_QSTR_mean), (mp_obj_t)&numerical_mean_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_mean), (mp_obj_t)&numerical_mean_obj },
#endif
#if ULAB_NUMERICAL_STD
{ MP_OBJ_NEW_QSTR(MP_QSTR_std), (mp_obj_t)&numerical_std_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_std), (mp_obj_t)&numerical_std_obj },
#endif
#if ULAB_NUMERICAL_MIN
{ MP_OBJ_NEW_QSTR(MP_QSTR_min), (mp_obj_t)&numerical_min_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_min), (mp_obj_t)&numerical_min_obj },
#endif
#if ULAB_NUMERICAL_MAX
{ MP_OBJ_NEW_QSTR(MP_QSTR_max), (mp_obj_t)&numerical_max_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_max), (mp_obj_t)&numerical_max_obj },
#endif
#if ULAB_NUMERICAL_ARGMIN
{ MP_OBJ_NEW_QSTR(MP_QSTR_argmin), (mp_obj_t)&numerical_argmin_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_argmin), (mp_obj_t)&numerical_argmin_obj },
#endif
#if ULAB_NUMERICAL_ARGMAX
{ MP_OBJ_NEW_QSTR(MP_QSTR_argmax), (mp_obj_t)&numerical_argmax_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_argmax), (mp_obj_t)&numerical_argmax_obj },
#endif
#if ULAB_NUMERICAL_ROLL
{ MP_OBJ_NEW_QSTR(MP_QSTR_roll), (mp_obj_t)&numerical_roll_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_roll), (mp_obj_t)&numerical_roll_obj },
#endif
#if ULAB_NUMERICAL_FLIP
{ MP_OBJ_NEW_QSTR(MP_QSTR_flip), (mp_obj_t)&numerical_flip_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_flip), (mp_obj_t)&numerical_flip_obj },
#endif
#if ULAB_NUMERICAL_DIFF
{ MP_OBJ_NEW_QSTR(MP_QSTR_diff), (mp_obj_t)&numerical_diff_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_diff), (mp_obj_t)&numerical_diff_obj },
#endif
#if ULAB_NUMERICAL_SORT
{ MP_OBJ_NEW_QSTR(MP_QSTR_sort), (mp_obj_t)&numerical_sort_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sort), (mp_obj_t)&numerical_sort_obj },
#endif
#if ULAB_NUMERICAL_ARGSORT
{ MP_OBJ_NEW_QSTR(MP_QSTR_argsort), (mp_obj_t)&numerical_argsort_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_argsort), (mp_obj_t)&numerical_argsort_obj },
#endif
#if ULAB_POLY_POLYVAL
{ MP_OBJ_NEW_QSTR(MP_QSTR_polyval), (mp_obj_t)&poly_polyval_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_polyval), (mp_obj_t)&poly_polyval_obj },
#endif
#if ULAB_POLY_POLYFIT
{ MP_OBJ_NEW_QSTR(MP_QSTR_polyfit), (mp_obj_t)&poly_polyfit_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_polyfit), (mp_obj_t)&poly_polyfit_obj },
#endif
#if ULAB_FFT_FFT
{ MP_OBJ_NEW_QSTR(MP_QSTR_fft), (mp_obj_t)&fft_fft_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_fft), (mp_obj_t)&fft_fft_obj },
#endif
#if ULAB_FFT_IFFT
{ MP_OBJ_NEW_QSTR(MP_QSTR_ifft), (mp_obj_t)&fft_ifft_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_ifft), (mp_obj_t)&fft_ifft_obj },
#endif
#if ULAB_FFT_SPECTRUM
{ MP_OBJ_NEW_QSTR(MP_QSTR_spectrum), (mp_obj_t)&fft_spectrum_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_spectrum), (mp_obj_t)&fft_spectrum_obj },
#endif
#if ULAB_FILTER_CONVOLVE
{ MP_OBJ_NEW_QSTR(MP_QSTR_convolve), (mp_obj_t)&filter_convolve_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_convolve), (mp_obj_t)&filter_convolve_obj },
#endif
// class constants // class constants
{ MP_ROM_QSTR(MP_QSTR_uint8), MP_ROM_INT(NDARRAY_UINT8) }, { MP_ROM_QSTR(MP_QSTR_uint8), MP_ROM_INT(NDARRAY_UINT8) },
{ MP_ROM_QSTR(MP_QSTR_int8), MP_ROM_INT(NDARRAY_INT8) }, { MP_ROM_QSTR(MP_QSTR_int8), MP_ROM_INT(NDARRAY_INT8) },

View file

@ -1,78 +0,0 @@
/*
* This file is part of the micropython-ulab project,
*
* https://github.com/v923z/micropython-ulab
*
* The MIT License (MIT)
*
* Copyright (c) 2019-2020 Zoltán Vörös
*/
#ifndef __ULAB__
#define __ULAB__
// 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)
#define ULAB_VECTORISE_CEIL (1)
#define ULAB_VECTORISE_COS (1)
#define ULAB_VECTORISE_ERF (1)
#define ULAB_VECTORISE_ERFC (1)
#define ULAB_VECTORISE_EXP (1)
#define ULAB_VECTORISE_EXPM1 (1)
#define ULAB_VECTORISE_FLOOR (1)
#define ULAB_VECTORISE_GAMMA (1)
#define ULAB_VECTORISE_LGAMMA (1)
#define ULAB_VECTORISE_LOG (1)
#define ULAB_VECTORISE_LOG10 (1)
#define ULAB_VECTORISE_LOG2 (1)
#define ULAB_VECTORISE_SIN (1)
#define ULAB_VECTORISE_SINH (1)
#define ULAB_VECTORISE_SQRT (1)
#define ULAB_VECTORISE_TAN (1)
#define ULAB_VECTORISE_TANH (1)
// linalg adds around 6 kB
#define ULAB_LINALG_TRANSPOSE (1)
#define ULAB_LINALG_RESHAPE (1)
#define ULAB_LINALG_SIZE (1)
#define ULAB_LINALG_INV (1)
#define ULAB_LINALG_DOT (1)
#define ULAB_LINALG_ZEROS (1)
#define ULAB_LINALG_ONES (1)
#define ULAB_LINALG_EYE (1)
#define ULAB_LINALG_DET (1)
#define ULAB_LINALG_EIG (1)
// poly is approx. 2.5 kB
#define ULAB_POLY_POLYVAL (1)
#define ULAB_POLY_POLYFIT (1)
//
#define ULAB_NUMERICAL_LINSPACE (1)
#define ULAB_NUMERICAL_SUM (1)
#define ULAB_NUMERICAL_MEAN (1)
#define ULAB_NUMERICAL_STD (1)
#define ULAB_NUMERICAL_MIN (1)
#define ULAB_NUMERICAL_MAX (1)
#define ULAB_NUMERICAL_ARGMIN (1)
#define ULAB_NUMERICAL_ARGMAX (1)
#define ULAB_NUMERICAL_ROLL (1)
#define ULAB_NUMERICAL_FLIP (1)
#define ULAB_NUMERICAL_DIFF (1)
#define ULAB_NUMERICAL_SORT (1)
// FFT costs about 2 kB of flash space
#define ULAB_FFT_FFT (1)
#define ULAB_FFT_IFFT (1)
#define ULAB_FFT_SPECTRUM (1)
// the filter module takes about 0.8 kB of flash space
#define ULAB_FILTER_CONVOLVE (1)
#endif

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -16,6 +15,7 @@
#include "py/binary.h" #include "py/binary.h"
#include "py/obj.h" #include "py/obj.h"
#include "py/objarray.h" #include "py/objarray.h"
#include "compat.h"
#include "vectorise.h" #include "vectorise.h"
#ifndef MP_PI #ifndef MP_PI
@ -61,118 +61,26 @@ mp_obj_t vectorise_generic_vector(mp_obj_t o_in, mp_float_t (*f)(mp_float_t)) {
return mp_const_none; return mp_const_none;
} }
#if ULAB_VECTORISE_ACOS
MATH_FUN_1(acos, acos); MATH_FUN_1(acos, acos);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_acos_obj, vectorise_acos);
#endif
#if ULAB_VECTORISE_ACOSH
MATH_FUN_1(acosh, acosh); MATH_FUN_1(acosh, acosh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_acosh_obj, vectorise_acosh);
#endif
#if ULAB_VECTORISE_ASIN
MATH_FUN_1(asin, asin); MATH_FUN_1(asin, asin);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_asin_obj, vectorise_asin);
#endif
#if ULAB_VECTORISE_ASINH
MATH_FUN_1(asinh, asinh); MATH_FUN_1(asinh, asinh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_asinh_obj, vectorise_asinh);
#endif
#if ULAB_VECTORISE_ATAN
MATH_FUN_1(atan, atan); MATH_FUN_1(atan, atan);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_atan_obj, vectorise_atan);
#endif
#if ULAB_VECTORISE_ATANH
MATH_FUN_1(atanh, atanh); MATH_FUN_1(atanh, atanh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_atanh_obj, vectorise_atanh);
#endif
#if ULAB_VECTORISE_CEIL
MATH_FUN_1(ceil, ceil); MATH_FUN_1(ceil, ceil);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_ceil_obj, vectorise_ceil);
#endif
#if ULAB_VECTORISE_COS
MATH_FUN_1(cos, cos); MATH_FUN_1(cos, cos);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_cos_obj, vectorise_cos);
#endif
#if ULAB_VECTORISE_ERF
MATH_FUN_1(erf, erf); MATH_FUN_1(erf, erf);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_erf_obj, vectorise_erf);
#endif
#if ULAB_VECTORISE_ERFC
MATH_FUN_1(erfc, erfc); MATH_FUN_1(erfc, erfc);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_erfc_obj, vectorise_erfc);
#endif
#if ULAB_VECTORISE_EXP
MATH_FUN_1(exp, exp); MATH_FUN_1(exp, exp);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_exp_obj, vectorise_exp);
#endif
#if ULAB_VECTORISE_EXPM1
MATH_FUN_1(expm1, expm1); MATH_FUN_1(expm1, expm1);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_expm1_obj, vectorise_expm1);
#endif
#if ULAB_VECTORISE_FLOOR
MATH_FUN_1(floor, floor); MATH_FUN_1(floor, floor);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_floor_obj, vectorise_floor);
#endif
#if ULAB_VECTORISE_GAMMA
MATH_FUN_1(gamma, tgamma); MATH_FUN_1(gamma, tgamma);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_gamma_obj, vectorise_gamma);
#endif
#if ULAB_VECTORISE_LGAMMA
MATH_FUN_1(lgamma, lgamma); MATH_FUN_1(lgamma, lgamma);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_lgamma_obj, vectorise_lgamma);
#endif
#if ULAB_VECTORISE_LOG
MATH_FUN_1(log, log); MATH_FUN_1(log, log);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_log_obj, vectorise_log);
#endif
#if ULAB_VECTORISE_LOG10
MATH_FUN_1(log10, log10); MATH_FUN_1(log10, log10);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_log10_obj, vectorise_log10);
#endif
#if ULAB_VECTORISE_LOG2
MATH_FUN_1(log2, log2); MATH_FUN_1(log2, log2);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_log2_obj, vectorise_log2);
#endif
#if ULAB_VECTORISE_SIN
MATH_FUN_1(sin, sin); MATH_FUN_1(sin, sin);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_sin_obj, vectorise_sin);
#endif
#if ULAB_VECTORISE_SINH
MATH_FUN_1(sinh, sinh); MATH_FUN_1(sinh, sinh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_sinh_obj, vectorise_sinh);
#endif
#if ULAB_VECTORISE_SQRT
MATH_FUN_1(sqrt, sqrt); MATH_FUN_1(sqrt, sqrt);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_sqrt_obj, vectorise_sqrt);
#endif
#if ULAB_VECTORISE_TAN
MATH_FUN_1(tan, tan); MATH_FUN_1(tan, tan);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_tan_obj, vectorise_tan);
#endif
#if ULAB_VECTORISE_TANH
MATH_FUN_1(tanh, tanh); MATH_FUN_1(tanh, tanh);
MP_DEFINE_CONST_FUN_OBJ_1(vectorise_tanh_obj, vectorise_tanh);
#endif

View file

@ -1,4 +1,3 @@
/* /*
* This file is part of the micropython-ulab project, * This file is part of the micropython-ulab project,
* *
@ -6,130 +5,37 @@
* *
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2019-2020 Zoltán Vörös * Copyright (c) 2019 Zoltán Vörös
*/ */
#ifndef _VECTORISE_ #ifndef _VECTORISE_
#define _VECTORISE_ #define _VECTORISE_
#include "ulab.h"
#include "ndarray.h" #include "ndarray.h"
#if ULAB_VECTORISE_ACOS
mp_obj_t vectorise_acos(mp_obj_t ); mp_obj_t vectorise_acos(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_acos_obj);
#endif
#if ULAB_VECTORISE_ACOSH
mp_obj_t vectorise_acosh(mp_obj_t ); mp_obj_t vectorise_acosh(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_acosh_obj);
#endif
#if ULAB_VECTORISE_ASIN
mp_obj_t vectorise_asin(mp_obj_t ); mp_obj_t vectorise_asin(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_asin_obj);
#endif
#if ULAB_VECTORISE_ASINH
mp_obj_t vectorise_asinh(mp_obj_t ); mp_obj_t vectorise_asinh(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_asinh_obj);
#endif
#if ULAB_VECTORISE_ATANH
mp_obj_t vectorise_atan(mp_obj_t ); mp_obj_t vectorise_atan(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_atan_obj);
#endif
#if ULAB_VECTORISE_ATANH
mp_obj_t vectorise_atanh(mp_obj_t ); mp_obj_t vectorise_atanh(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_atanh_obj);
#endif
#if ULAB_VECTORISE_CEIL
mp_obj_t vectorise_ceil(mp_obj_t ); mp_obj_t vectorise_ceil(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_ceil_obj);
#endif
#if ULAB_VECTORISE_COS
mp_obj_t vectorise_cos(mp_obj_t ); mp_obj_t vectorise_cos(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_cos_obj);
#endif
#if ULAB_VECTORISE_ERF
mp_obj_t vectorise_erf(mp_obj_t ); mp_obj_t vectorise_erf(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_erf_obj);
#endif
#if ULAB_VECTORISE_ERFC
mp_obj_t vectorise_erfc(mp_obj_t ); mp_obj_t vectorise_erfc(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_erfc_obj);
#endif
#if ULAB_VECTORISE_EXP
mp_obj_t vectorise_exp(mp_obj_t ); mp_obj_t vectorise_exp(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_exp_obj);
#endif
#if ULAB_VECTORISE_EXPM1
mp_obj_t vectorise_expm1(mp_obj_t ); mp_obj_t vectorise_expm1(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_expm1_obj);
#endif
#if ULAB_VECTORISE_FLOOR
mp_obj_t vectorise_floor(mp_obj_t ); mp_obj_t vectorise_floor(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_floor_obj);
#endif
#if ULAB_VECTORISE_GAMMA
mp_obj_t vectorise_gamma(mp_obj_t ); mp_obj_t vectorise_gamma(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_gamma_obj);
#endif
#if ULAB_VECTORISE_LGAMMA
mp_obj_t vectorise_lgamma(mp_obj_t ); mp_obj_t vectorise_lgamma(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_lgamma_obj);
#endif
#if ULAB_VECTORISE_LOG
mp_obj_t vectorise_log(mp_obj_t ); mp_obj_t vectorise_log(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_log_obj);
#endif
#if ULAB_VECTORISE_LOG10
mp_obj_t vectorise_log10(mp_obj_t ); mp_obj_t vectorise_log10(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_log10_obj);
#endif
#if ULAB_VECTORISE_LOG2
mp_obj_t vectorise_log2(mp_obj_t ); mp_obj_t vectorise_log2(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_log2_obj);
#endif
#if ULAB_VECTORISE_SIN
mp_obj_t vectorise_sin(mp_obj_t ); mp_obj_t vectorise_sin(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_sin_obj);
#endif
#if ULAB_VECTORISE_SINH
mp_obj_t vectorise_sinh(mp_obj_t ); mp_obj_t vectorise_sinh(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_sinh_obj);
#endif
#if ULAB_VECTORISE_SQRT
mp_obj_t vectorise_sqrt(mp_obj_t ); mp_obj_t vectorise_sqrt(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_sqrt_obj);
#endif
#if ULAB_VECTORISE_TAN
mp_obj_t vectorise_tan(mp_obj_t ); mp_obj_t vectorise_tan(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_tan_obj);
#endif
#if ULAB_VECTORISE_TANH
mp_obj_t vectorise_tanh(mp_obj_t ); mp_obj_t vectorise_tanh(mp_obj_t );
MP_DECLARE_CONST_FUN_OBJ_1(vectorise_tanh_obj);
#endif
#define ITERATE_VECTOR(type, source, out) do {\ #define ITERATE_VECTOR(type, source, out) do {\
type *input = (type *)(source)->array->items;\ type *input = (type *)(source)->array->items;\

View file

@ -22,7 +22,7 @@ copyright = '2019, Zoltán Vörös'
author = 'Zoltán Vörös' author = 'Zoltán Vörös'
# The full version, including alpha/beta/rc tags # The full version, including alpha/beta/rc tags
release = '0.31' release = '0.26'
# -- General configuration --------------------------------------------------- # -- General configuration ---------------------------------------------------

View file

@ -172,6 +172,8 @@ Methods of ndarrays
`.flatten\*\* <#.flatten>`__ `.flatten\*\* <#.flatten>`__
`.asbytearray <#.asbytearray>`__
Matrix methods Matrix methods
-------------- --------------
@ -237,10 +239,10 @@ FFT routines
`spectrum\*\* <#spectrum>`__ `spectrum\*\* <#spectrum>`__
Filter functions Filter routines
---------------- ---------------
`convolve <#convolve>`__ `convolve\* <#convolve>`__
ndarray, the basic container ndarray, the basic container
============================ ============================
@ -538,6 +540,83 @@ verbatim copy of the contents.
.asbytearray
~~~~~~~~~~~~
The contents of an ``ndarray`` can be accessed directly by calling the
``.asbytearray`` method. This will simply return a pointer to the
underlying flat ``array`` object, which can then be manipulated
directly.
**WARNING:** ``asbytearray`` is a ``ulab``-only method; it has no
equivalent in ``numpy``.
In the example below, note the difference between ``a``, and ``buffer``:
while both are designated as an array, you recognise the micropython
array from the fact that it prints the typecode (``b`` in this
particular case). The ``ndarray``, on the other hand, prints out the
``dtype`` (``int8`` here).
.. code::
# code to be run in micropython
import ulab as np
a = np.array([1, 2, 3, 4], dtype=np.int8)
print('a: ', a)
buffer = a.asbytearray()
print("array content:", buffer)
buffer[1] = 123
print("array content:", buffer)
.. parsed-literal::
a: array([1, 2, 3, 4], dtype=int8)
array content: array('b', [1, 2, 3, 4])
array content: array('b', [1, 123, 3, 4])
This in itself wouldnt be very interesting, but since ``buffer`` is a
proper micropython ``array``, we can pass it to functions that can
employ the buffer protocol. E.g., all the ``ndarray`` facilities can be
applied to the results of timed ADC conversions.
.. code::
# code to be run in micropython
import pyb
import ulab as np
n = 100
adc = pyb.ADC(pyb.Pin.board.X19)
tim = pyb.Timer(6, freq=10)
a = np.array([0]*n, dtype=np.uint8)
buffer = a.asbytearray()
adc.read_timed(buffer, tim)
print("ADC results:\t", a)
print("mean of results:\t", np.mean(a))
print("std of results:\t", np.std(a))
.. parsed-literal::
ADC results: array([48, 2, 2, ..., 0, 0, 0], dtype=uint8)
mean of results: 1.22
std of results: 4.744639
Likewise, data can be read directly into ``ndarray``\ s from other
interfaces, e.g., SPI, I2C etc, and also, by laying bare the
``ndarray``, we can pass results of ``ulab`` computations to anything
that can read from a buffer.
.transpose .transpose
~~~~~~~~~~ ~~~~~~~~~~
@ -967,10 +1046,6 @@ take the following snippet from the micropython manual:
return result return result
return new_func return new_func
.. parsed-literal::
.. code:: .. code::
@ -1973,6 +2048,7 @@ spaced numbers between 0, and two pi, and sort them:
print('b: ', b) print('b: ', b)
sort_time(b) sort_time(b)
print('\nb sorted:\n', b) print('\nb sorted:\n', b)
argsort argsort
------- -------
@ -2837,6 +2913,33 @@ As such, ``spectrum`` is really just a shorthand for
spectrum calculated the lazy way: array([187.8641, 315.3125, 347.8804, ..., 84.4587, 347.8803, 315.3124], dtype=float) spectrum calculated the lazy way: array([187.8641, 315.3125, 347.8804, ..., 84.4587, 347.8803, 315.3124], dtype=float)
Filter routines
===============
numpy:
https://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html
convolve
--------
Returns the discrete, linear convolution of two one-dimensional sequences.
Only the ``full`` mode is supported, and the ``mode`` named parameter is not accepted.
Note that all other modes can be had by slicing a ``full`` result.
.. code::
# code to be run in micropython
import ulab as np
x = np.array((1,2,3))
y = np.array((1,10,100,1000))
print(np.convolve(x, y))
.. parsed-literal::
array([1.0, 12.0, 123.0, 1230.0, 2300.0, 3000.0], dtype=float)
Computation and storage costs Computation and storage costs
----------------------------- -----------------------------
@ -2907,48 +3010,13 @@ By combining the two observations above, if you place the first signal,
combined signal, then the Fourier transforms of the two components can combined signal, then the Fourier transforms of the two components can
be recovered as be recovered as
:raw-latex:`\begin{eqnarray} | :math:`Y_1(k) = \frac{1}{2}\left(Y(k) + Y^*(N-k)\right)`
Y_1(k) &=& \frac{1}{2}\left(Y(k) + Y^*(N-k)\right) | :math:`Y_2(k) = -\frac{i}{2}\left(Y(k) - Y^*(N-k)\right)`
\\
Y_2(k) &=& -\frac{i}{2}\left(Y(k) - Y^*(N-k)\right) where :math:`N` is the length of :math:`y_1`, and
\end{eqnarray}` where :math:`N` is the length of :math:`y_1`, and
:math:`Y_1, Y_2`, and :math:`Y`, respectively, are the Fourier :math:`Y_1, Y_2`, and :math:`Y`, respectively, are the Fourier
transforms of :math:`y_1, y_2`, and :math:`y = y_1 + iy_2`. transforms of :math:`y_1, y_2`, and :math:`y = y_1 + iy_2`.
Filter routines
===============
numpy:
https://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html
convolve
--------
Returns the discrete, linear convolution of two one-dimensional
sequences.
Only the ``full`` mode is supported, and the ``mode`` named parameter is
not accepted. Note that all other modes can be had by slicing a ``full``
result.
.. code::
# code to be run in micropython
import ulab as np
x = np.array((1,2,3))
y = np.array((1,10,100,1000))
print(np.convolve(x, y))
.. parsed-literal::
array([1.0, 12.0, 123.0, 1230.0, 2300.0, 3000.0], dtype=float)
Extending ulab Extending ulab
============== ==============

View file

@ -1,28 +1,3 @@
Mon, 10 Feb 2020
version 0.31.0
removed asbytearray, and added buffer protocol to ndarrays, fixed bad error in filter.c
Sun, 09 Feb 2020
version 0.30.2
fixed slice_length in ndarray.c
Sat, 08 Feb 2020
version 0.30.1
fixed typecode error, added variable inspection, and replaced ternary operators in filter.c
Fri, 07 Feb 2020
version 0.30.0
ulab functions can arbitrarily be excluded from the firmware via the ulab.h configuration file
Thu, 06 Feb 2020 Thu, 06 Feb 2020
version 0.27.0 version 0.27.0

View file

@ -24,11 +24,11 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "execution_count": 23,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2020-02-10T18:31:42.227494Z", "end_time": "2019-11-05T16:01:28.817558Z",
"start_time": "2020-02-10T18:31:42.222100Z" "start_time": "2019-11-05T16:01:28.810704Z"
} }
}, },
"outputs": [ "outputs": [
@ -66,7 +66,7 @@
"author = 'Zoltán Vörös'\n", "author = 'Zoltán Vörös'\n",
"\n", "\n",
"# The full version, including alpha/beta/rc tags\n", "# The full version, including alpha/beta/rc tags\n",
"release = '0.31'\n", "release = '0.26'\n",
"\n", "\n",
"\n", "\n",
"# -- General configuration ---------------------------------------------------\n", "# -- General configuration ---------------------------------------------------\n",
@ -120,11 +120,10 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": null,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2020-02-10T18:49:03.206016Z", "start_time": "2019-11-06T17:37:29.723Z"
"start_time": "2020-02-10T18:49:00.047068Z"
} }
}, },
"outputs": [], "outputs": [],
@ -293,11 +292,11 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 3,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2020-02-10T18:34:14.611085Z", "end_time": "2019-11-04T20:57:36.730820Z",
"start_time": "2020-02-10T18:34:14.607299Z" "start_time": "2019-11-04T20:57:36.723446Z"
} }
}, },
"outputs": [], "outputs": [],
@ -311,11 +310,11 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 4,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2020-02-10T18:34:15.995782Z", "end_time": "2019-11-04T20:57:38.576560Z",
"start_time": "2020-02-10T18:34:15.975187Z" "start_time": "2019-11-04T20:57:38.521927Z"
} }
}, },
"outputs": [], "outputs": [],
@ -600,6 +599,8 @@
"\n", "\n",
"[.flatten<sup>**</sup>](#.flatten)\n", "[.flatten<sup>**</sup>](#.flatten)\n",
"\n", "\n",
"[.asbytearray](#.asbytearray)\n",
"\n",
"## Matrix methods\n", "## Matrix methods\n",
"\n", "\n",
"[size](#size)\n", "[size](#size)\n",
@ -658,11 +659,7 @@
"\n", "\n",
"[ifft<sup>**</sup>](#ifft)\n", "[ifft<sup>**</sup>](#ifft)\n",
"\n", "\n",
"[spectrum<sup>**</sup>](#spectrum)\n", "[spectrum<sup>**</sup>](#spectrum)"
"\n",
"## Filter functions\n",
"\n",
"[convolve](#convolve)"
] ]
}, },
{ {
@ -1038,6 +1035,109 @@
"print(\"b flattened (F): \\t\", b.flatten(order='F'))" "print(\"b flattened (F): \\t\", b.flatten(order='F'))"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### .asbytearray\n",
"\n",
"The contents of an `ndarray` can be accessed directly by calling the `.asbytearray` method. This will simply return a pointer to the underlying flat `array` object, which can then be manipulated directly.\n",
"\n",
"**WARNING:** `asbytearray` is a `ulab`-only method; it has no equivalent in `numpy`.\n",
"\n",
"In the example below, note the difference between `a`, and `buffer`: while both are designated as an array, you recognise the micropython array from the fact that it prints the typecode (`b` in this particular case). The `ndarray`, on the other hand, prints out the `dtype` (`int8` here)."
]
},
{
"cell_type": "code",
"execution_count": 211,
"metadata": {
"ExecuteTime": {
"end_time": "2019-11-01T14:25:39.008074Z",
"start_time": "2019-11-01T14:25:38.876546Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a: array([1, 2, 3, 4], dtype=int8)\n",
"array content: array('b', [1, 2, 3, 4])\n",
"array content: array('b', [1, 123, 3, 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.int8)\n",
"print('a: ', a)\n",
"buffer = a.asbytearray()\n",
"print(\"array content:\", buffer)\n",
"buffer[1] = 123\n",
"print(\"array content:\", buffer)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This in itself wouldn't be very interesting, but since `buffer` is a proper micropython `array`, we can pass it to functions that can employ the buffer protocol. E.g., all the `ndarray` facilities can be applied to the results of timed ADC conversions."
]
},
{
"cell_type": "code",
"execution_count": 563,
"metadata": {
"ExecuteTime": {
"end_time": "2019-10-20T07:29:00.153589Z",
"start_time": "2019-10-20T07:28:50.210383Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ADC results:\t array([48, 2, 2, ..., 0, 0, 0], dtype=uint8)\n",
"mean of results:\t 1.22\n",
"std of results:\t 4.744639\n",
"\n"
]
}
],
"source": [
"%%micropython -pyboard 1\n",
"\n",
"import pyb\n",
"import ulab as np\n",
"\n",
"n = 100\n",
"\n",
"adc = pyb.ADC(pyb.Pin.board.X19)\n",
"tim = pyb.Timer(6, freq=10)\n",
"\n",
"a = np.array([0]*n, dtype=np.uint8)\n",
"buffer = a.asbytearray()\n",
"adc.read_timed(buffer, tim)\n",
"\n",
"print(\"ADC results:\\t\", a)\n",
"print(\"mean of results:\\t\", np.mean(a))\n",
"print(\"std of results:\\t\", np.std(a))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Likewise, data can be read directly into `ndarray`s from other interfaces, e.g., SPI, I2C etc, and also, by laying bare the `ndarray`, we can pass results of `ulab` computations to anything that can read from a buffer."
]
},
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
@ -4168,56 +4268,6 @@
"where $N$ is the length of $y_1$, and $Y_1, Y_2$, and $Y$, respectively, are the Fourier transforms of $y_1, y_2$, and $y = y_1 + iy_2$." "where $N$ is the length of $y_1$, and $Y_1, Y_2$, and $Y$, respectively, are the Fourier transforms of $y_1, y_2$, and $y = y_1 + iy_2$."
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Filter routines"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"numpy: https://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html\n",
"\n",
"## convolve\n",
"Returns the discrete, linear convolution of two one-dimensional sequences.\n",
"\n",
"Only the ``full`` mode is supported, and the ``mode`` named parameter is not accepted. Note that all other modes can be had by slicing a ``full`` result."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"ExecuteTime": {
"end_time": "2020-02-10T18:46:06.538207Z",
"start_time": "2020-02-10T18:46:06.525851Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"array([1.0, 12.0, 123.0, 1230.0, 2300.0, 3000.0], dtype=float)\n",
"\n",
"\n"
]
}
],
"source": [
"%%micropython -unix 1\n",
"\n",
"import ulab as np\n",
"\n",
"x = np.array((1,2,3))\n",
"y = np.array((1,10,100,1000))\n",
"\n",
"print(np.convolve(x, y))"
]
},
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},

File diff suppressed because it is too large Load diff