v923z / micropython-ulab Goto Github PK
View Code? Open in Web Editor NEWa numpy-like fast vector module for micropython, circuitpython, and their derivatives
Home Page: https://micropython-ulab.readthedocs.io/en/latest
License: MIT License
a numpy-like fast vector module for micropython, circuitpython, and their derivatives
Home Page: https://micropython-ulab.readthedocs.io/en/latest
License: MIT License
ulab is assuming that MicroPython is built with MICROPY_OBJ_REPR_A
or MICROPY_OBJ_REPR_B
, which store floats as boxed objects instead of as immediate values like smallints. In the code below, the float object is assumed to be boxed:
Lines 29 to 34 in 81acfc7
Feature request: an equivalent to numpy’s clip() function. Sure, same operation can be done in a couple lines of Python, but the speed of occurring entirely in ulab space would be a big plus. Thanks.
Great work!
I want to add your ulab to MaixPy as a submodule, and I come across two problems,
extern const mp_obj_type_t ulab_ndarray_type;
micropython-ulab/code/ndarray.h
Line 27 in 107587d
Lines 110 to 120 in 107587d
py/obj.h
in header files like fft.h
Trying to optimize an inner loop, I've tried to limit the computations by indexing an array with a boolean list. unfortunately, it take waaaay more time for each iteration.
example code on circuitpython :
import ulab
import time
a = ulab.ones(1000)
b = [False]*1000
b[5:10] = [True]*5
start = time.monotonic_ns()
a = a * 2
print('time for a*2 : ', time.monotonic_ns() - start )
start = time.monotonic_ns()
a[5:10] = a[5:10] * 2
print('time for a[5:10]*2 : ', time.monotonic_ns() - start )
start = time.monotonic_ns()
a[b] = a[b] * 2
print('time for a[b] = a[b]*2 :', time.monotonic_ns() - start )
output (timing in ns) :
time for a*2 : 423000
time for a[5:10]*2 : 123000
time for a[b] = a[b]*2 : 4745000
I am testing with : Adafruit CircuitPython 5.0.0-37-geebe76997 on 2020-03-09; Adafruit Monster M4SK with samd51j19
Use Ctrl-D to exit, Ctrl-E for paste mode
>>> import ulab
>>> ulab.dot(ulab.zeros(3), 0)
Segmentation fault
I've encountered a number of these; I think it's where both arguments need to be ndarrays, but it's not caught as an exception but leads to segmentation fault / hardfault instead. Do you want them reported separately as I encounter them? (this is the only one I wrote down so far)
Micropython now supports the PEP 465 syntax for using @
as an infix binary operator for matrix multiplication (following the merge of micropython/micropython#4947). Classes implemented in C will get their binary_op
method called with the MP_BINARY_OP_MAT_MULTIPLY
operator code when the user does this. It would be great if ulab
supported this syntax in the same way that numpy
does, since it makes code much more concise and readable, as well as making numpy
code more directly portable.
@mouryarahul I have opened a new issue for the documentation.
The continuation of the conversation in #17
arctan2
requires two operands, so the implementation should be similar to that of binary operators. The numpy
reference is here: https://docs.scipy.org/doc/numpy/reference/generated/numpy.arctan2.html
This is the place, where suggestions related to new functions/functionality and the like should be brought up.
This is a great package, and I was working through the examples provided in the documentation. I had some trouble replicating the np.mean function. (See output below). I am working on the SF6 hardware on Microptyhon v1.12-43-g54a2584de-dirty using ulab version 0.263
import ulab as np
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print('a: \n', a)
a:
array([[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0],
[7.0, 8.0, 9.0]], dtype=float)
print('sum, flat array: ', np.sum(a))
sum, flat array: 45.0
print('mean, horizontal: ', np.mean(a, axis=1))
mean, horizontal: array([2048.00048828125, 5.387879937997763e-315, 0.0], dtype=float)
print('std, vertical: ', np.std(a, axis=0))
std, vertical: array([7.191838266139812, 5.314304082212256e-315, 0.0], dtype=float)
When subscripting a 1-D array with an integer a single value is returned but when subscripting a 2-D array with two integers the result is a 1x1 array containing the value. For example:
>>> a = np.array(range(6))
>>> a[4]
4.0
>>> b = np.array(range(6)).reshape((2,3))
>>> b[1,1]
array([4.0], dtype=float)
>>> _.shape()
(1, 1)
Note that in numpy
the behaviour of subscripting is simple: dimensions that are indexed with a single value are removed from the result while dimensions that are indexed with a slice or which are not index at all (i.e. there are fewer indices than dimensions) remain. Thus when indexing an array b
with 2 dimensions b[0,0]
returns a single value, b[0,0:1]
returns a 1-D result containing that single value and b[0:1,0:1]
returns a 2-D array containing that value. Ideally ulab
should do the same.
Note that if the design for N-dimensional arrays discussed in #13 is implemented then this will clearly require the implementation of a more generic subscripting system anyway.
I had been download the latest verison ulab,when make it, it showed the error information as follow:
LINK build-PYBV11/firmware.elf
build-PYBV11/code/vectorise.o: In function vectorise_around': vectorise.c:(.text.vectorise_around+0x76): undefined reference to
roundf'
Makefile:597: recipe for target 'build-PYBV11/firmware.elf' failed
make: *** [build-PYBV11/firmware.elf] Error 1
How to solve this issue,Thanks!
This is amazing! I've been trying to build ulab in CircuitPython, which I should be able to do as CP is a fork of micropython, but I've been having a lot of trouble. I'm seeing a lot of issues with shadowed declarations and comparison between signed and unsigned integers. When I attempt to make the board in the appropriate port using:
make BOARD=pybadge USER_C_MODULES=../../../ulab all
I get the following error:
Including User C Module from ../../../ulab/code
QSTR updated
FREEZE ../../frozen/circuitpython-stage/pybadge
../../../ulab/code/ndarray.c: In function 'ndarray_print_row':
../../../ulab/code/ndarray.c:81:20: error: declaration of 'i' shadows a previous local [-Werror=shadow]
for(size_t i=1; i<3; i++) {
^
../../../ulab/code/ndarray.c:66:12: note: shadowed declaration is here
size_t i;
^
../../../ulab/code/ndarray.c: In function 'ndarray_make_new':
../../../ulab/code/ndarray.c:168:30: error: passing argument 2 of 'mp_arg_check_num' makes pointer from integer without a cast [-Werror=int-conversion]
mp_arg_check_num(n_args, n_kw, 1, 2, true);
^~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:80:6: note: expected 'mp_map_t * {aka struct _mp_map_t *}' but argument is of type 'size_t {aka unsigned int}'
void mp_arg_check_num(size_t n_args, mp_map_t *kw_args, size_t n_args_min, size_t n_args_max, bool takes_kw);
^~~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c:176:29: error: passing argument 1 of 'mp_raise_ValueError' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_ValueError("first argument must be an iterable");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:153:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_ValueError(const compressed_string_t *msg);
^~~~~~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c:191:25: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
if(len2 != MP_OBJ_SMALL_INT_VALUE(len_in)) {
^~
../../../ulab/code/ndarray.c:192:41: error: passing argument 1 of 'mp_raise_ValueError' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_ValueError("iterables are not of the same length");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:153:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_ValueError(const compressed_string_t *msg);
^~~~~~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c: In function 'true_length':
../../../ulab/code/ndarray.c:234:13: error: implicit declaration of function 'mp_obj_is_type'; did you mean 'mp_obj_is_true'? [-Werror=implicit-function-declaration]
if(!mp_obj_is_type(item, &mp_type_bool)) {
^~~~~~~~~~~~~~
mp_obj_is_true
../../../ulab/code/ndarray.c:234:13: error: nested extern declaration of 'mp_obj_is_type' [-Werror=nested-externs]
../../../ulab/code/ndarray.c: In function 'generate_slice':
../../../ulab/code/ndarray.c:251:15: error: implicit declaration of function 'mp_obj_is_int'; did you mean 'mp_obj_list_init'? [-Werror=implicit-function-declaration]
} else if(mp_obj_is_int(index)) {
^~~~~~~~~~~~~
mp_obj_list_init
../../../ulab/code/ndarray.c:251:15: error: nested extern declaration of 'mp_obj_is_int' [-Werror=nested-externs]
../../../ulab/code/ndarray.c:256:20: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
if((_index >= n) || (_index < 0)) {
^~
../../../ulab/code/ndarray.c:257:47: error: passing argument 2 of 'mp_raise_msg' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_msg(&mp_type_IndexError, "index is out of bounds");
^~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:151:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg);
^~~~~~~~~~~~
../../../ulab/code/ndarray.c:263:43: error: passing argument 2 of 'mp_raise_msg' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_msg(&mp_type_IndexError, "indices must be integers, slices, or Boolean lists");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:151:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg);
^~~~~~~~~~~~
../../../ulab/code/ndarray.c: In function 'insert_slice_list':
../../../ulab/code/ndarray.c:293:33: error: passing argument 1 of 'mp_raise_ValueError' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_ValueError("could not broadast input array from shape");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:153:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_ValueError(const compressed_string_t *msg);
^~~~~~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c:355:27: error: declaration of 'cindex' shadows a previous local [-Werror=shadow]
size_t j = 0, cindex = 0;
^~~~~~
../../../ulab/code/ndarray.c:296:12: note: shadowed declaration is here
size_t cindex, rindex;
^~~~~~
../../../ulab/code/ndarray.c: In function 'iterate_slice_list':
../../../ulab/code/ndarray.c:380:43: error: passing argument 2 of 'mp_raise_msg' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_msg(&mp_type_IndexError, "empty index range");
^~~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:151:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg);
^~~~~~~~~~~~
../../../ulab/code/ndarray.c:441:27: error: declaration of 'cindex' shadows a previous local [-Werror=shadow]
size_t j = 0, cindex = 0;
^~~~~~
../../../ulab/code/ndarray.c:390:12: note: shadowed declaration is here
size_t cindex, rindex;
^~~~~~
../../../ulab/code/ndarray.c: In function 'ndarray_get_slice':
../../../ulab/code/ndarray.c:498:47: error: passing argument 2 of 'mp_raise_msg' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_msg(&mp_type_IndexError, "too many indices");
^~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:151:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg);
^~~~~~~~~~~~
../../../ulab/code/ndarray.c:506:51: error: passing argument 2 of 'mp_raise_msg' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_msg(&mp_type_IndexError, "indices must be integers, slices, or Boolean lists");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:151:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg);
^~~~~~~~~~~~
../../../ulab/code/ndarray.c: In function 'ndarray_subscr':
../../../ulab/code/ndarray.c:547:33: error: passing argument 1 of 'mp_raise_ValueError' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_ValueError("right hand side must be an ndarray, or a scalar");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:153:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_ValueError(const compressed_string_t *msg);
^~~~~~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c: In function 'ndarray_flatten':
../../../ulab/code/ndarray.c:658:29: error: passing argument 1 of 'mp_raise_ValueError' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_ValueError("flattening order must be either 'C', or 'F'");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:153:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_ValueError(const compressed_string_t *msg);
^~~~~~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c: In function 'ndarray_binary_op':
../../../ulab/code/ndarray.c:723:33: error: passing argument 1 of 'mp_raise_ValueError' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_ValueError("operands could not be broadcast together");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:153:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_ValueError(const compressed_string_t *msg);
^~~~~~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c:826:40: error: passing argument 1 of 'mp_raise_TypeError' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_TypeError("wrong input type");
^~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:155:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_TypeError(const compressed_string_t *msg);
^~~~~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c:834:28: error: passing argument 1 of 'mp_raise_TypeError' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_TypeError("wrong operand type on the right hand side");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:155:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_TypeError(const compressed_string_t *msg);
^~~~~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c: In function 'ndarray_unary_op':
../../../ulab/code/ndarray.c:852:37: error: passing argument 1 of 'mp_raise_ValueError' from incompatible pointer type [-Werror=incompatible-pointer-types]
mp_raise_ValueError("operation is not supported for given type");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../../ulab/code/ndarray.c:15:0:
../../py/runtime.h:153:15: note: expected 'const compressed_string_t * {aka const struct *}' but argument is of type 'const char *'
NORETURN void mp_raise_ValueError(const compressed_string_t *msg);
^~~~~~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c:865:26: error: declaration of 'array' shadows a previous local [-Werror=shadow]
uint8_t *array = (uint8_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:857:22: note: shadowed declaration is here
uint8_t *array = (uint8_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:868:25: error: declaration of 'array' shadows a previous local [-Werror=shadow]
int8_t *array = (int8_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:857:22: note: shadowed declaration is here
uint8_t *array = (uint8_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:871:27: error: declaration of 'array' shadows a previous local [-Werror=shadow]
uint16_t *array = (uint16_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:857:22: note: shadowed declaration is here
uint8_t *array = (uint8_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:874:26: error: declaration of 'array' shadows a previous local [-Werror=shadow]
int16_t *array = (int16_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:857:22: note: shadowed declaration is here
uint8_t *array = (uint8_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:877:29: error: declaration of 'array' shadows a previous local [-Werror=shadow]
mp_float_t *array = (mp_float_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:857:22: note: shadowed declaration is here
uint8_t *array = (uint8_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:892:25: error: declaration of 'array' shadows a previous local [-Werror=shadow]
int8_t *array = (int8_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:857:22: note: shadowed declaration is here
uint8_t *array = (uint8_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:897:26: error: declaration of 'array' shadows a previous local [-Werror=shadow]
int16_t *array = (int16_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:857:22: note: shadowed declaration is here
uint8_t *array = (uint8_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:902:29: error: declaration of 'array' shadows a previous local [-Werror=shadow]
mp_float_t *array = (mp_float_t *)ndarray->array->items;
^~~~~
../../../ulab/code/ndarray.c:857:22: note: shadowed declaration is here
uint8_t *array = (uint8_t *)ndarray->array->items;
^~~~~
cc1: all warnings being treated as errors
make: *** [build-pybadge/code/ndarray.o] Error 1
I am working with version 0.36.0 and I don't seem to be able to access np.mean(), np.std(), np.min(), np.max() and other functions. There seems to be an "AttributeError" 'module' object has no attribute 'mean' "
Some changes had to be made to compile ulab into MicroPython v1.12-93 for the Nucleo-L476RG. After the following changes were made, everything seems to work well. NOTE: I'm new to building custom C modules for MicroPython, and these problems may have been caused by my doing something (or many somethings) incorrectly.
mp_const_none_obj
, mp_const_true_obj
, and mp_const_false_obj
were unrecognized. Replacing macros such as MP_ROM_PTR(&mp_const_none_obj)
with corresponding macros MP_ROM_NONE
, MP_ROM_TRUE
, and MP_ROM_FALSE
allowed successful compilation.
As I intend to compile other external C code as well as ulab, it is appropriate to place the ulab directory one level under the main external C code directory, which I've placed inside the root MicroPython directory (is that a faux pas?). The ulab source files are then only found if moved from the ulab/code
subdirectory to the main ulab
directory. A workaround which seems to work is to move micropython.mk
to the main ulab
directory, leave the source files in ulab/code
, and edit micropython.mk
to specify the location of the source and header files as follows:
USERMODULES_DIR := $(USERMOD_DIR)
# Add all C files to SRC_USERMOD.
SRC_USERMOD += $(USERMODULES_DIR)/code/ndarray.c
SRC_USERMOD += $(USERMODULES_DIR)/code/linalg.c
SRC_USERMOD += $(USERMODULES_DIR)/code/vectorise.c
SRC_USERMOD += $(USERMODULES_DIR)/code/poly.c
SRC_USERMOD += $(USERMODULES_DIR)/code/fft.c
SRC_USERMOD += $(USERMODULES_DIR)/code/numerical.c
SRC_USERMOD += $(USERMODULES_DIR)/code/ulab.c
# We can add our module folder to include paths if needed
# This is not actually needed in this example.
CFLAGS_USERMOD += -I$(USERMODULES_DIR)/code
Instructions from the ulab README as well as the MicroPython external C modules page were used to duct tape this solution together. I suspect that the directory problems are my own doing, but I'm not sure about the compiler not recognizing mp_const_none_obj
, etc.
Happy to supply more details, diffs, patches, or whatever...as soon as I've gone and learned how to generate them correctly.
I'm not sure if I'm doing any mistake, but indexing using boolean list is not working as expected. See below the result:
MicroPython v1.12-167-gf020eac6a-dirty on 2020-03-06; PYBD-SF6W with STM32F767IIK
Type "help()" for more information.
import ulab as np
a = np.array(range(9), dtype=np.float)
print("a:\t", a)
a: array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0], dtype=float)
print("a < 5:\t", a[a < 5])
a < 5: array([], dtype=float)
Is there any workaround? Thanks for your suggestions.
The title says it all. https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.round.html
micropython-ulab/code/ndarray.c
Line 254 in ac3f03c
Might give compilation errors on other platforms. I think it would be a good idea to change the type or at least to add #include<unistd.h>
How can I create an ndarray of shape (w, h, c) from a C array of pixels (uint8_t) ? I can create 1D arrays by implementing getiter and unary_op, do I need to return an iter as the items of the first iter and so on ?
np.array([[1,2]]) should return a two dimensional array with only one element. Accessing said array with array[0] should return [1,2] and it should be passable to arguments such as argsort() which takes in an ndarray. I have not been able to create such an array with ulab. Using reshape() doesn't affect the issue.
Examples:
ulab
import ulab as np
arr = [[1,2]]
arr2 = np.array(arr)
arr2[0]
1.0
numpy
import numpy as np
arr = [[1,2]]
arr2 = np.array(arr)
arr2[0]
Out[1]: array([1, 2])
Since the micropython.mk file has added the following line
CFLAGS_EXTRA = -DMODULE_ULAB_ENABLED=1
There's no need to add #define MODULE_ULAB_ENABLED (1)
in the mpconfigport.h.Or it would make redefined errors while compiling code.
When running ulab
on the ESP32 the dot product function ulab.dot()
yields erroneous results when the inputs are non-square. For instance:
>>> import ulab as np
>>> aa = np.array(range(6)).reshape((2,3))
>>> bb = np.array(range(6)).reshape((3,2))
>>> np.dot(aa,bb)
array([[2.0, 3.0],
[8.0, 15.0]], dtype=float)
>>> np.dot(bb,aa)
array([[3.0, 4.0, 0.0],
[9.0, 14.0, 0.0],
[0.0, 0.0, 0.0]], dtype=float)
While regular binary operators seem to work fine the dot product function behaves very erratically. The fact that it seems to work correctly for square arrays suggest that the problem is likely some transposition of the dimension lengths.
I am having an issue running np.dot(). I am running on PYBD-SF6 using version 0.26.5. It appears that a row matrix times a square matrix works fine. However, when I use dot with a square matrix times a column matrix, the results aren't as expected. It appears to only provide the first element in the expected result (14,32,50)
`MicroPython v1.12-92-gd89ed3e62-dirty on 2020-01-26; PYBD-SF6W with STM32F767IIK
Type "help()" for more information.
import ulab as np
print('you are running ulab version', np.version)
you are running ulab version 0.26.5
a = np.array(([1,2,3],[4,5,6],[7,8,9]))
b = np.array(([1,2,3]))
b.transpose()
c = np.dot(a,b)
c
array([14.0, 0.0, 0.0], dtype=float)
`
I was trying to implement numpy.linalg.norm in the pythonic way, e.g., L0-norm, and got this when doing:
>>> a
array([1.2, 0.0, -1.3, 0.25, 1.45, -0.35, 2.0], dtype=float)
>>> a != 0.
True
>>> a[a != 0.]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: too many indices
I see that there isn't any mention of !=
comparision in the documenation. Is this intensional?
At the moment, I'm achieving L0-norm in two steps:
>>> a = array([1.2, 0.0, -1.3, 0.25, 1.45, -0.35, 2.0], dtype=float)
>>> sum([a < 0.]) + sum([a > 0.])
@v923z Do you suggest some efficient way?
In numpy
, ndarray.transpose()
returns a view of the original array and ndarray.reshape()
returns a view when possible and otherwise they returns a new array. In both cases the array object passed in as the argument is left unaffected. The current ulab
behaviour is to reshape the argument that was passed and return the modified original.
The code for both of these functions will naturally get reworked with the new N-dimensional arrays and views, so this GitHub issue is more a spec for the new code than a plea for fixing the old code.
FWIW, in the code I started writing for ndarray
the "if possible" test for reshape was simple and dumb: reshape
used a view if and only if the input array or view had never been sliced or transposed (which implies that the stride on each dimension is the product of the lengths of all the more deeply nested dimensions). In practice I just kept a flag that was set on creation of new arrays but cleared for new slice or transposes views. Views created by subscripting using only integer indices copied the flag from the parent. In practice this meant that there are some cases that could have used a view but ended up copying because the code to check those cases seemed unnecessarily complex for Micropython.
I'm not sure, is this happening only in my testing! I'm running test on:
MicroPython v1.12-326-g8fff0b0ac on 2020-04-01; PYBD-SF6W with STM32F767IIK
The numerical.sort function is corrupting a certain element in the matrix:
>>> a
array([[6.058420993051577, 2.018588295338188, 6.307303740008193, 6.743567296659661], [3.760399477657426, 1.501626760992716, 1.020398368879967, 1.903483081086812], [5.20075447514754, 0.7655233559988428, 0.2730999062713479, 5.448723074844875], [3.666587663986214, 0.5528238825462162, 7.759826840359533, 9.887756673795574], [3.228270818725618, 1.784248212712498, 5.302361277197747, 6.772730290987155]], dtype=float)
>>> ulab.numerical.sort(a, axis=0)
array([[3.228270818725618, 0.5528238825462162, 0.2730999062713479, 1.903483081086812], [4.550686286587561e-314, 0.7655233559988428, 1.020398368879967, 5.448723074844875], [3.666587663986214, 1.501626760992716, 5.302361277197747, 6.743567296659661], [3.760399477657426, 1.784248212712498, 6.307303740008193, 6.772730290987155], [5.20075447514754, 2.018588295338188, 7.759826840359533, 9.887756673795574]], dtype=float)
Observe that the two elements of zero column has changed abruptly. However, this does happen when axis=1:
>>> ulab.numerical.sort(a, axis=1)
array([[2.018588295338188, 6.058420993051577, 6.307303740008193, 6.743567296659661], [1.020398368879967, 1.501626760992716, 1.903483081086812, 3.760399477657426], [0.2730999062713479, 0.7655233559988428, 5.20075447514754, 5.448723074844875], [0.5528238825462162, 3.666587663986214, 7.759826840359533, 9.887756673795574], [1.784248212712498, 3.228270818725618, 5.302361277197747, 6.772730290987155]], dtype=float)
Can you also verify at your end?
Hi, Glad to find this repo.
Numpy is the base of science analysis in python. So micropython-ulab is a meaningful repo.
And now CNN is very prevent everywhere. So we wrote Planer, Powerful Light Artificial NEuRon. It is a CNN framework based on pure Numpy-like interface (with out any kernel code, just use reshape, transpose, concadinate, dot, and + - * /). I think it can run on with ulab as backend (with no modify or little modify).
I will buy a micropython board to have a try, if I encounter any problem, could you give a support?
I'm attempting to compile ulab
for the PYBD_SF6 from a Mac running macOS 10.13.4.
micropython-ulab
and the current version of micropython.make
in micropython/mpy-cross
make BOARD=PYBD_SF6 CROSS_COMPILE=/usr/local/bin/arm-none-eabi-
in micropython/ports/stm32
, which successfully compiled the "normal" firmware for SF6.make BOARD=PYBD_SF6 CROSS_COMPILE=/usr/local/bin/arm-none-eabi- USER_C_MODULES=../../../ulab all
, compilation fails with the error messages below.Am I doing something wrong here? I'm not an experienced firmware compiler.
CC ../../../ulab/code/ndarray.c
../../../ulab/code/ndarray.c: In function 'ndarray_init_helper':
../../../ulab/code/ndarray.c:157:11: error: 'MP_QSTR_dtype' undeclared (first use in this function); did you mean 'MP_QSTR_type'?
{ MP_QSTR_dtype, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NDARRAY_FLOAT } },
^~~~~~~~~~~~~
MP_QSTR_type
../../../ulab/code/ndarray.c:157:11: note: each undeclared identifier is reported only once for each function it appears in
../../../ulab/code/ndarray.c: In function 'ndarray_flatten':
../../../ulab/code/ndarray.c:648:11: error: 'MP_QSTR_order' undeclared (first use in this function); did you mean 'MP_QSTR_ord'?
{ MP_QSTR_order, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR_C)} },
^~~~~~~~~~~~~
MP_QSTR_ord
../../../ulab/code/ndarray.c:648:11: error: initialization of 'short unsigned int' from 'const mp_arg_t *' {aka 'const struct _mp_arg_t *'} makes integer from pointer without a cast [-Werror=int-conversion]
../../../ulab/code/ndarray.c:648:11: note: (near initialization for 'allowed_args[0].qst')
../../../ulab/code/ndarray.c:648:11: error: initializer element is not constant
../../../ulab/code/ndarray.c:648:11: note: (near initialization for 'allowed_args[0].qst')
In file included from ../../py/mpstate.h:35,
from ../../py/runtime.h:29,
from ../../../ulab/code/ndarray.c:15:
../../../ulab/code/ndarray.c:648:81: error: 'MP_QSTR_C' undeclared (first use in this function); did you mean 'MP_QSTR_r'?
{ MP_QSTR_order, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR_C)} },
^~~~~~~~~
../../py/obj.h:92:56: note: in definition of macro 'MP_OBJ_NEW_QSTR'
#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 2))
^~~
../../../ulab/code/ndarray.c:648:69: note: in expansion of macro 'MP_ROM_QSTR'
{ MP_QSTR_order, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR_C)} },
^~~~~~~~~~~
../../py/obj.h:92:30: error: initializer element is not constant
#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 2))
^
../../py/obj.h:248:24: note: in expansion of macro 'MP_OBJ_NEW_QSTR'
#define MP_ROM_QSTR(q) MP_OBJ_NEW_QSTR(q)
^~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c:648:69: note: in expansion of macro 'MP_ROM_QSTR'
{ MP_QSTR_order, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR_C)} },
^~~~~~~~~~~
../../py/obj.h:92:30: note: (near initialization for 'allowed_args[0].defval.u_rom_obj')
#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 2))
^
../../py/obj.h:248:24: note: in expansion of macro 'MP_OBJ_NEW_QSTR'
#define MP_ROM_QSTR(q) MP_OBJ_NEW_QSTR(q)
^~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c:648:69: note: in expansion of macro 'MP_ROM_QSTR'
{ MP_QSTR_order, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR_C)} },
^~~~~~~~~~~
cc1: all warnings being treated as errors
make: *** [build-PYBD_SF6/code/ndarray.o] Error 1
Add the cross product function https://docs.scipy.org/doc/numpy/reference/generated/numpy.cross.html
Symptom:
ulab.std() sometimes produce nan in the result
ulab version 0.25
Reproduce:
import ulab as np
a = np.array([[109.5894, 117.2053, 69.3245],
[109.5894, 117.1788, 69.3245],
[109.596, 117.1854, 69.3245],
[109.596, 117.1854, 69.3245],
[109.5894, 117.1722, 69.31788],
[109.5894, 117.1921, 69.31788],
[109.5894, 117.1854, 69.31788],
[109.596, 117.1656, 69.31788],
[109.596, 117.1589, 69.31126],
[109.596, 117.1788, 69.30463],
[109.596, 117.1656, 69.29801],
[109.596, 117.1391, 69.29801],
[109.5894, 117.1656, 69.29801],
[109.5828, 117.1523, 69.29801],
[109.5762, 117.1391, 69.29139],
[109.5695, 117.1457, 69.29139],
[109.5762, 117.1457, 69.29139],
[109.5762, 117.1258, 69.28477],
[109.5695, 117.1192, 69.28477],
[109.5695, 117.0861, 69.28477],
[109.5695, 117.0728, 69.27814],
[109.5695, 117.0728, 69.27814],
[109.5695, 117.0861, 69.28477],
[109.5629, 117.0861, 69.29139],
[109.5695, 117.1059, 69.29139],
[109.5695, 117.1126, 69.28477],
[109.5762, 117.1059, 69.28477],
[109.5828, 117.1258, 69.29139],
[109.5762, 117.1457, 69.29139],
[109.5762, 117.1324, 69.29139],
[109.5762, 117.1192, 69.28477],
[109.5762, 117.1192, 69.28477],
[109.5695, 117.1391, 69.28477],
[109.5695, 117.1059, 69.28477],
[109.5762, 117.1457, 69.28477],
[109.5828, 117.1258, 69.28477],
[109.5828, 117.0993, 69.28477],
[109.5828, 117.1457, 69.28477],
[109.5828, 117.1523, 69.29139],
[109.5894, 117.0993, 69.28477],
[109.5828, 117.1059, 69.27814],
[109.5762, 117.1457, 69.27814],
[109.5695, 117.1126, 69.27814],
[109.5695, 117.1192, 69.27814],
[109.5695, 117.1457, 69.28477],
[109.5695, 117.1324, 69.29139],
[109.5695, 117.1192, 69.28477],
[109.5762, 117.1523, 69.29139],
[109.5695, 117.1722, 69.29801],
[109.5695, 117.1523, 69.29801],
[109.5629, 117.1391, 69.29801],
[109.5695, 117.1722, 69.30463],
[109.5762, 117.1391, 69.31126],
[109.5762, 117.0927, 69.30463],
[109.5695, 117.1391, 69.30463],
[109.5695, 117.0927, 69.30463],
[109.5629, 117.053, 69.30463],
[109.5629, 117.0795, 69.30463],
[109.5563, 117.0728, 69.30463],
[109.5497, 117.0265, 69.29801],
[109.5497, 117.0066, 69.29139],
[109.5497, 117.0199, 69.29139],
[109.5497, 116.9868, 69.29139],
[109.5497, 116.9603, 69.29139],
[109.5497, 116.9801, 69.29801],
[109.5497, 116.9603, 69.29801],
[109.543, 116.9404, 69.29139],
[109.543, 116.9338, 69.28477],
[109.5364, 116.9536, 69.28477],
[109.543, 116.9536, 69.29139],
[109.543, 116.9603, 69.29139],
[109.5364, 116.947, 69.29139],
[109.5298, 116.9669, 69.29139],
[109.5298, 116.9801, 69.29139],
[109.5232, 116.947, 69.29139],
[109.5298, 116.9735, 69.29139],
[109.5232, 117.0066, 69.28477],
[109.5165, 117.0, 69.27814],
[109.5099, 116.9868, 69.27152],
[109.5099, 117.0132, 69.27152],
[109.5099, 117.0199, 69.27152],
[109.5099, 116.9735, 69.27152],
[109.5033, 117.0132, 69.2649],
[109.4967, 117.0662, 69.25828],
[109.4967, 117.0265, 69.25828],
[109.4967, 117.0397, 69.25828],
[109.5033, 117.0728, 69.25166],
[109.4967, 117.053, 69.25166],
[109.4967, 117.0, 69.24503],
[109.4967, 117.0331, 69.23841],
[109.4901, 117.0662, 69.23841],
[109.4967, 117.0464, 69.23841],
[109.4901, 117.0728, 69.23841],
[109.4901, 117.0993, 69.23841],
[109.4901, 117.0662, 69.23841],
[109.4967, 117.0199, 69.23841],
[109.4901, 117.053, 69.23841],
[109.4901, 117.053, 69.23841],
[109.4901, 117.0199, 69.23841],
[109.4834, 117.0596, 69.23841]])
print(np.std(a,axis=0))
Result:
array([nan, nan, nan], dtype=float)
Expected result:
array([0.03424415, 0.07198399, 0.02212126], dtype=float)
@v923z I'm not sure if this is intentional?
MicroPython v1.12-337-g312c69949 on 2020-04-06; PYBD-SF6W with STM32F767IIK
Type "help()" for more information.
>>> import ulab as np
>>> np.__version__
'0.41.0'
>>> a = np.array([[4,5,6],[1,2,3],[7,8,9]])
>>> np.numerical.argsort(a, axis=0)
array([[1, 1, 1],
[0, 0, 0],
[2, 2, 2]], dtype=uint16)
>>> a
array([[4.0, 5.0, 6.0],
[1.0, 2.0, 3.0],
[7.0, 8.0, 9.0]], dtype=float)
>>> np.numerical.argsort(a, axis=None)
array([3, 4, 5, 0, 1, 2, 6, 7, 8], dtype=uint16)
>>> a
array([4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 7.0, 8.0, 9.0], dtype=float)
whereas the documentation of ULAB
mentions: "Since during the sorting, only the indices are shuffled, argsort does not modify the input array...". The original array is flattened when axis=None
. The Numpy
behaves as the documentation of ULAB
mentions.
@v923z linalg.dot
seems to have a certain bug:
MicroPython v1.12-368-gbd63c26dd on 2020-04-13; PYBD-SF6W with STM32F767IIK
Type "help()" for more information.
>>> ulab.__version__
'0.41.2'
>>> A
array([[1.0, 2.0],
[3.0, 4.0]], dtype=float)
>>> B
array([[1.0, 2.0, 3.0, 4.0],
[5.0, 6.0, 7.0, 8.0]], dtype=float)
>>> ulab.linalg.dot(A,B)
array([[11.0, 23.0, 14.0, 30.0],
[17.0, 37.0, 20.0, 44.0]], dtype=float)
whereas the correct result from Numpy is:
np.dot(A,B)
array([[11, 14, 17, 20],
[23, 30, 37, 44]])
Seems that it has something to do with way the elements are stored in the array!
Can you reproduce the same at your end?
At the moment, ndarrays must be on the left hand side of a binary operator. Thus
a = np.array([1, 2, 3])
a + 1
works, but
a = np.array([1, 2, 3])
1 + a
fails. A solution involves the implementation of the REVERSE operators in binary_op in ndarray.c
Is this generic C code that could easily build and run on linux, mac, windows?
Or does it only work on microcontrollers? (which ones?)
Hi, I just wanted to say that Ibrahim added your code to the OpenMV Cam.
Thanks!
(Yes, I know this is not the best way to contact you).
MICROPY_FLOAT_IMPL_FLOAT
turns on -Wdouble-promotion
and -fsingle-precision-constant
which causes epsilon literal to be float and an implicit conversion from 'float' to 'double' (to match fabs) warning/error. Maybe fabsf should be used instead...
QSTR not updated
CC ../../extmod/ulab/code/linalg.c
../../extmod/ulab/code/linalg.c: In function 'linalg_invert_matrix':
../../extmod/ulab/code/linalg.c:127:32: error: implicit conversion from 'float' to 'double' to match other operand of binary expression [-Werror=double-promotion]
if(fabs(data[m*(N+1)]) < epsilon) {
^
../../extmod/ulab/code/linalg.c: In function 'linalg_det':
../../extmod/ulab/code/linalg.c:310:35: error: implicit conversion from 'float' to 'double' to match other operand of binary expression [-Werror=double-promotion]
if(fabs(tmp[m*(in->n+1)]) < epsilon) {
^
../../extmod/ulab/code/linalg.c: In function 'linalg_eig':
../../extmod/ulab/code/linalg.c:349:24: error: implicit conversion from 'float' to 'double' to match other operand of binary expression [-Werror=double-promotion]
if(epsilon < fabs(array[m*in->n + n] - array[n*in->n + m])) {
^
cc1: all warnings being treated as errors
If you find that you would need a numpy
function that is not implemented in ulab
, please, open a new issue for each function you want to have implemented. This issue is locked, and cannot be appended to.
Currently ulab
fails to properly displays arrays where the length of one of the dimensions is 1. Furthermore it incorrectly represents the shape of arrays with only one dimension.
To see this consider the following code for regular Python and numpy
:
>>> import numpy as np
>>> aa = np.array(range(3))
>>> aa, aa.shape
(array([0, 1, 2]), (3,))
>>> bb = np.array(range(3)).reshape((1,3))
>>> bb, bb.shape
(array([[0, 1, 2]]), (1, 3))
>>> cc = np.array(range(3)).reshape((3,1))
>>> cc, cc.shape
(array([[0],
[1],
[2]]), (3, 1))
Compare this with the equivalent code in Micropython with ulab
:
>>> import ulab as np
>>> aa = np.array(range(3))
>>> aa, aa.shape()
(array([0.0, 1.0, 2.0], dtype=float), (1, 3))
>>> bb = np.array(range(3)).reshape((1,3))
>>> bb, bb.shape()
(array([0.0, 1.0, 2.0], dtype=float), (1, 3))
>>> cc = np.array(range(3)).reshape((3,1))
>>> cc, cc.shape()
(array([0.0, 1.0, 2.0], dtype=float), (3, 1))
In the aa
case the shape is misrepresented as being two dimensional even though it is printed as one dimensional. In the bb
and cc
cases the shape is correctly displayed but the array is printed as if it were one dimensional.
Two dimensional arrays where the length of both dimensions is greater than one are printed correctly and have the shape correctly represented.
This might simply be an oversight?
I've been playing around with ulab and it's awesome, but I've run into some issues because I can't modify the elements of an ndarray.
For example:
>>> a = 100 * np.linspace(0,10,num=1024)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported types for __mul__: 'int', 'ndarray'
and
>>> for i in range(len(b)):
... b[i] = i
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ValueError: index is out of range
By the way, THANK YOU for making this module. I'm still getting my bearings with mpy and usermods, but your documentation has been very helpful. Hopefully soon I'll have some time to add some of these features in myself.
EDIT: I just tried >>> a = np.linspace(0,10,num=1024) * 100
and it worked, so that's a solid workaround!
As discussed in #21 (comment), add the Cholesky decomposition to linalg
. The numpy
interface is defined in https://docs.scipy.org/doc/numpy-1.17.0/reference/generated/numpy.linalg.cholesky.html
In ulab
, the transpose
method is an in-place operation, i.e., it doesn't return a new array, while numpy
does.
@v923z Hi, I was wondering if there exists already optimized Math and DSP library for ARM uController and found that there is one provided by ARM itself called CMSIS, I guess you may be aware of it. I see that Micropython does use the only device driver part from CMSIS library from ST in the port stm32. I was wondering will it be possible to include CMSIS DSP library into ULAB, e.g. using arm_math.h and others? I'm not sure about the Licencing thing though!
>>> ulab.numerical.argmax([[1,2],[4,3]])
1
>>> ulab.numerical.argmin([[1,2],[4,3]])
0
but
>>> ulab.numerical.argmin(ulab.array([[1,2],[4,3]]))
0
>>> ulab.numerical.argmax(ulab.array([[1,2],[4,3]]))
2
and
>>> numpy.argmin([[1,2],[4,3]])
0
>>> numpy.argmax([[1,2],[4,3]])
2
In numpy
the transpose of an array x
can be accessed using the property x.T
. This is a widely used feature that should be supported.
It should be noted in numpy
the T
property points to the same underlying value set, with the array stride values and dimensions reversed. Unless ulab
changes to track the array strides for all dimensions this may be difficult to replicate.
I'm not sure if this is intentional:
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a[1,1]
array([5.0], dtype=float)
>>> a[1][1]
5.0
why in the first case we get an array while in second case a numeric value? In numpy, both result into a numeric value rather in array container.
ulab on circuitpython:
>>> x = ulab.linspace(0, 10)
>>> ulab.argmax(x)
array([49], dtype=uint16)
numpy:
>>> x = numpy.linspace(0, 10)
>>> numpy.argmax(x)
49
I am able to compile micropython+ulab for the PYBD_SF6 but not for unix.
My batch script is the following:
mkdir build
cd build
git clone https://github.com/micropython/micropython.git
git clone https://github.com/v923z/micropython-ulab.git ulab
cd micropython
git submodule update --init
cd mpy-cross/
make
cd ../ports/stm32
echo '#define MODULE_ULAB_ENABLED (1)' | cat >> mpconfigport.h
make BOARD=PYBD_SF6 CROSS_COMPILE=/usr/local/bin/arm-none-eabi- USER_C_MODULES=../../../ulab all
cd ../unix
echo '#define MODULE_ULAB_ENABLED (1)' | cat >> mpconfigport.h
make USER_C_MODULES=../../../ulab all
When running the above code, I get a functional PUBD_SF6 firmware but the unix make results in 3 -Wparentheses-equality
errors in ulab/code/ndarray.c
:
CC ../../../ulab/code/ndarray.c
../../../ulab/code/ndarray.c:583:20: error: equality comparison with extraneous parentheses [-Werror,-Wparentheses-equality]
if((ndarray->m == 1)) {
~~~~~~~~~~~^~~~
../../../ulab/code/ndarray.c:583:20: note: remove extraneous parentheses around the comparison to silence this warning
if((ndarray->m == 1)) {
~ ^ ~
../../../ulab/code/ndarray.c:583:20: note: use '=' to turn this equality comparison into an assignment
if((ndarray->m == 1)) {
^~
=
../../../ulab/code/ndarray.c:891:39: error: equality comparison with extraneous parentheses [-Werror,-Wparentheses-equality]
if((self->array->typecode == NDARRAY_INT8)) {
~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c:891:39: note: remove extraneous parentheses around the comparison to silence this warning
if((self->array->typecode == NDARRAY_INT8)) {
~ ^ ~
../../../ulab/code/ndarray.c:891:39: note: use '=' to turn this equality comparison into an assignment
if((self->array->typecode == NDARRAY_INT8)) {
^~
=
../../../ulab/code/ndarray.c:896:46: error: equality comparison with extraneous parentheses [-Werror,-Wparentheses-equality]
} else if((self->array->typecode == NDARRAY_INT16)) {
~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
../../../ulab/code/ndarray.c:896:46: note: remove extraneous parentheses around the comparison to silence this warning
} else if((self->array->typecode == NDARRAY_INT16)) {
~ ^ ~
../../../ulab/code/ndarray.c:896:46: note: use '=' to turn this equality comparison into an assignment
} else if((self->array->typecode == NDARRAY_INT16)) {
^~
=
3 errors generated.
make: *** [build/code/ndarray.o] Error 1
If I add -Wno-parentheses-equality
to the CFLAGS
in micropython/ports/unix/Makefile
, I get different errors, in ulab/code/linalg.c
this time:
CC ../../../ulab/code/ndarray.c
CC ../../../ulab/code/linalg.c
../../../ulab/code/linalg.c:127:12: error: using integer absolute value function 'abs' when argument is of floating point type [-Werror,-Wabsolute-value]
if(abs(data[m*(N+1)]) < epsilon) {
^
../../../ulab/code/linalg.c:127:12: note: use function 'fabs' instead
if(abs(data[m*(N+1)]) < epsilon) {
^~~
fabs
../../../ulab/code/linalg.c:310:12: error: using integer absolute value function 'abs' when argument is of floating point type [-Werror,-Wabsolute-value]
if(abs(tmp[m*(in->n+1)]) < epsilon) {
^
../../../ulab/code/linalg.c:310:12: note: use function 'fabs' instead
if(abs(tmp[m*(in->n+1)]) < epsilon) {
^~~
fabs
../../../ulab/code/linalg.c:349:26: error: using integer absolute value function 'abs' when argument is of floating point type [-Werror,-Wabsolute-value]
if(epsilon < abs(array[m*in->n + n] - array[n*in->n + m])) {
^
../../../ulab/code/linalg.c:349:26: note: use function 'fabs' instead
if(epsilon < abs(array[m*in->n + n] - array[n*in->n + m])) {
^~~
fabs
3 errors generated.
make: *** [build/code/linalg.o] Error 1
I suspect this might be due to some quirk of the macOS C compiler, but that's not much more than a random guess.
Is there anything obvious that I'm doing wrong?
I recently updated to version 0.32.0 and notices that the .transpose() function was not available.
`
a = np.zeros((5,3))
a.shape
(5, 3)
a.transpose
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'ndarray' object has no attribute 'transpose'
a.transpose()
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'ndarray' object has no attribute 'transpose'
`
It seems that too few elements are in the result.
>>> np.array([0,1,2,3,4])[::2]
array([0, 2, 4])
vs
>>> ulab.array([0,1,2,3,4])[::2]
array([0.0, 2.0], dtype=float)
Let me know if you'd like me to look into this.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.