Compare commits

...

2 commits

Author SHA1 Message Date
Zoltán Vörös
c878cac3fa add build to requirements 2023-05-13 17:51:14 +02:00
Zoltán Vörös
1c61334af6 add bitwise operators 2023-05-12 21:39:26 +02:00
18 changed files with 660 additions and 5 deletions

View file

@ -12,6 +12,7 @@ SRC_USERMOD += $(USERMODULES_DIR)/ndarray.c
SRC_USERMOD += $(USERMODULES_DIR)/numpy/ndarray/ndarray_iter.c
SRC_USERMOD += $(USERMODULES_DIR)/ndarray_properties.c
SRC_USERMOD += $(USERMODULES_DIR)/numpy/approx.c
SRC_USERMOD += $(USERMODULES_DIR)/numpy/bitwise.c
SRC_USERMOD += $(USERMODULES_DIR)/numpy/compare.c
SRC_USERMOD += $(USERMODULES_DIR)/numpy/carray/carray.c
SRC_USERMOD += $(USERMODULES_DIR)/numpy/carray/carray_tools.c

431
code/numpy/bitwise.c Normal file
View file

@ -0,0 +1,431 @@
/*
* This file is part of the micropython-ulab project,
*
* https://github.com/v923z/micropython-ulab
*
* The MIT License (MIT)
*
* Copyright (c) 2023 Zoltán Vörös
*
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "py/obj.h"
#include "py/runtime.h"
#include "bitwise.h"
#if ULAB_NUMPY_HAS_BITWISE_AND
ndarray_obj_t *bitwise_bitwise_and_loop(ndarray_obj_t *lhs, ndarray_obj_t *rhs, uint8_t ndim, size_t *shape, int32_t *lstrides, int32_t *rstrides) {
// AND is commutative, so simply swap the order, if a particular combination has already been inspected
ndarray_obj_t *results = NULL;
uint8_t *larray = (uint8_t *)lhs->array;
uint8_t *rarray = (uint8_t *)rhs->array;
if(lhs->dtype == NDARRAY_UINT8) {
if(rhs->dtype == NDARRAY_UINT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT8);
BINARY_LOOP(results, uint8_t, uint8_t, uint8_t, larray, lstrides, rarray, rstrides, &);
} else if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint8_t, int8_t, larray, lstrides, rarray, rstrides, &);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, uint8_t, uint16_t, larray, lstrides, rarray, rstrides, &);
} else if(rhs->dtype == NDARRAY_INT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint8_t, int16_t, larray, lstrides, rarray, rstrides, &);
}
} else if(lhs->dtype == NDARRAY_INT8) {
if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT8);
BINARY_LOOP(results, int8_t, int8_t, int8_t, larray, lstrides, rarray, rstrides, &);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, int8_t, uint16_t, larray, lstrides, rarray, rstrides, &);
} else if(rhs->dtype == NDARRAY_INT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int8_t, int16_t, larray, lstrides, rarray, rstrides, &);
} else {
return bitwise_bitwise_and_loop(rhs, lhs, ndim, shape, rstrides, lstrides);
}
} else if(lhs->dtype == NDARRAY_UINT16) {
if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, uint16_t, uint16_t, larray, lstrides, rarray, rstrides, &);
} else if(rhs->dtype == NDARRAY_INT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, &);
} else {
return bitwise_bitwise_and_loop(rhs, lhs, ndim, shape, rstrides, lstrides);
}
} else if(lhs->dtype == NDARRAY_INT16) {
if(rhs->dtype == NDARRAY_INT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int16_t, int16_t, larray, lstrides, rarray, rstrides, &);
} else {
return bitwise_bitwise_and_loop(rhs, lhs, ndim, shape, rstrides, lstrides);
}
}
return results;
}
#endif
#if ULAB_NUMPY_HAS_BITWISE_OR
ndarray_obj_t *bitwise_bitwise_or_loop(ndarray_obj_t *lhs, ndarray_obj_t *rhs, uint8_t ndim, size_t *shape, int32_t *lstrides, int32_t *rstrides) {
// OR is commutative, so simply swap the order, if a particular combination has already been inspected
ndarray_obj_t *results = NULL;
uint8_t *larray = (uint8_t *)lhs->array;
uint8_t *rarray = (uint8_t *)rhs->array;
if(lhs->dtype == NDARRAY_UINT8) {
if(rhs->dtype == NDARRAY_UINT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT8);
BINARY_LOOP(results, uint8_t, uint8_t, uint8_t, larray, lstrides, rarray, rstrides, |);
} else if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint8_t, int8_t, larray, lstrides, rarray, rstrides, |);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, uint8_t, uint16_t, larray, lstrides, rarray, rstrides, |);
} else if(rhs->dtype == NDARRAY_INT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint8_t, int16_t, larray, lstrides, rarray, rstrides, |);
}
} else if(lhs->dtype == NDARRAY_INT8) {
if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT8);
BINARY_LOOP(results, int8_t, int8_t, int8_t, larray, lstrides, rarray, rstrides, |);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, int8_t, uint16_t, larray, lstrides, rarray, rstrides, |);
} else if(rhs->dtype == NDARRAY_INT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int8_t, int16_t, larray, lstrides, rarray, rstrides, |);
} else {
return bitwise_bitwise_or_loop(rhs, lhs, ndim, shape, rstrides, lstrides);
}
} else if(lhs->dtype == NDARRAY_UINT16) {
if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, uint16_t, uint16_t, larray, lstrides, rarray, rstrides, |);
} else if(rhs->dtype == NDARRAY_INT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, |);
} else {
return bitwise_bitwise_or_loop(rhs, lhs, ndim, shape, rstrides, lstrides);
}
} else if(lhs->dtype == NDARRAY_INT16) {
if(rhs->dtype == NDARRAY_INT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int16_t, int16_t, larray, lstrides, rarray, rstrides, |);
} else {
return bitwise_bitwise_or_loop(rhs, lhs, ndim, shape, rstrides, lstrides);
}
}
return results;
}
#endif
#if ULAB_NUMPY_HAS_BITWISE_XOR
ndarray_obj_t *bitwise_bitwise_xor_loop(ndarray_obj_t *lhs, ndarray_obj_t *rhs, uint8_t ndim, size_t *shape, int32_t *lstrides, int32_t *rstrides) {
// OR is commutative, so simply swap the order, if a particular combination has already been inspected
ndarray_obj_t *results = NULL;
uint8_t *larray = (uint8_t *)lhs->array;
uint8_t *rarray = (uint8_t *)rhs->array;
if(lhs->dtype == NDARRAY_UINT8) {
if(rhs->dtype == NDARRAY_UINT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT8);
BINARY_LOOP(results, uint8_t, uint8_t, uint8_t, larray, lstrides, rarray, rstrides, ^);
} else if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint8_t, int8_t, larray, lstrides, rarray, rstrides, ^);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, uint8_t, uint16_t, larray, lstrides, rarray, rstrides, ^);
} else if(rhs->dtype == NDARRAY_INT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint8_t, int16_t, larray, lstrides, rarray, rstrides, ^);
}
} else if(lhs->dtype == NDARRAY_INT8) {
if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT8);
BINARY_LOOP(results, int8_t, int8_t, int8_t, larray, lstrides, rarray, rstrides, ^);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, int8_t, uint16_t, larray, lstrides, rarray, rstrides, ^);
} else if(rhs->dtype == NDARRAY_INT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int8_t, int16_t, larray, lstrides, rarray, rstrides, ^);
} else {
return bitwise_bitwise_xor_loop(rhs, lhs, ndim, shape, rstrides, lstrides);
}
} else if(lhs->dtype == NDARRAY_UINT16) {
if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, uint16_t, uint16_t, larray, lstrides, rarray, rstrides, ^);
} else if(rhs->dtype == NDARRAY_INT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, ^);
} else {
return bitwise_bitwise_xor_loop(rhs, lhs, ndim, shape, rstrides, lstrides);
}
} else if(lhs->dtype == NDARRAY_INT16) {
if(rhs->dtype == NDARRAY_INT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int16_t, int16_t, larray, lstrides, rarray, rstrides, ^);
} else {
return bitwise_bitwise_xor_loop(rhs, lhs, ndim, shape, rstrides, lstrides);
}
}
return results;
}
#endif
#if ULAB_NUMPY_HAS_LEFT_SHIFT
ndarray_obj_t *bitwise_left_shift_loop(ndarray_obj_t *lhs, ndarray_obj_t *rhs, uint8_t ndim, size_t *shape, int32_t *lstrides, int32_t *rstrides) {
ndarray_obj_t *results = NULL;
uint8_t *larray = (uint8_t *)lhs->array;
uint8_t *rarray = (uint8_t *)rhs->array;
if(lhs->dtype == NDARRAY_UINT8) {
if(rhs->dtype == NDARRAY_UINT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT8);
BINARY_LOOP(results, uint8_t, uint8_t, uint8_t, larray, lstrides, rarray, rstrides, <<);
} else if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint8_t, int8_t, larray, lstrides, rarray, rstrides, <<);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, uint8_t, uint16_t, larray, lstrides, rarray, rstrides, <<);
} else {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint8_t, int16_t, larray, lstrides, rarray, rstrides, <<);
}
} else if(lhs->dtype == NDARRAY_INT8) {
if(rhs->dtype == NDARRAY_UINT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int8_t, uint8_t, larray, lstrides, rarray, rstrides, <<);
} else if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT8);
BINARY_LOOP(results, int8_t, int8_t, int8_t, larray, lstrides, rarray, rstrides, <<);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, int8_t, uint16_t, larray, lstrides, rarray, rstrides, <<);
} else {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int8_t, int16_t, larray, lstrides, rarray, rstrides, <<);
}
} else if(lhs->dtype == NDARRAY_UINT16) {
if(rhs->dtype == NDARRAY_UINT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, uint16_t, uint8_t, larray, lstrides, rarray, rstrides, <<);
} else if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT8);
BINARY_LOOP(results, int8_t, int8_t, int8_t, larray, lstrides, rarray, rstrides, <<);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, uint16_t, uint16_t, larray, lstrides, rarray, rstrides, <<);
} else {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, <<);
}
} else if(lhs->dtype == NDARRAY_INT16) {
if(rhs->dtype == NDARRAY_UINT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int16_t, uint8_t, larray, lstrides, rarray, rstrides, <<);
} else if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int16_t, int8_t, larray, lstrides, rarray, rstrides, <<);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, uint16_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, <<);
} else {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int16_t, int16_t, larray, lstrides, rarray, rstrides, <<);
}
}
return results;
}
#endif
#if ULAB_NUMPY_HAS_RIGHT_SHIFT
ndarray_obj_t *bitwise_right_shift_loop(ndarray_obj_t *lhs, ndarray_obj_t *rhs, uint8_t ndim, size_t *shape, int32_t *lstrides, int32_t *rstrides) {
ndarray_obj_t *results = NULL;
uint8_t *larray = (uint8_t *)lhs->array;
uint8_t *rarray = (uint8_t *)rhs->array;
if(lhs->dtype == NDARRAY_UINT8) {
if(rhs->dtype == NDARRAY_UINT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT8);
BINARY_LOOP(results, uint8_t, uint8_t, uint8_t, larray, lstrides, rarray, rstrides, >>);
} else if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint8_t, int8_t, larray, lstrides, rarray, rstrides, >>);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, uint8_t, uint16_t, larray, lstrides, rarray, rstrides, >>);
} else {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint8_t, int16_t, larray, lstrides, rarray, rstrides, >>);
}
} else if(lhs->dtype == NDARRAY_INT8) {
if(rhs->dtype == NDARRAY_UINT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int8_t, uint8_t, larray, lstrides, rarray, rstrides, >>);
} else if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT8);
BINARY_LOOP(results, int8_t, int8_t, int8_t, larray, lstrides, rarray, rstrides, >>);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, int8_t, uint16_t, larray, lstrides, rarray, rstrides, >>);
} else {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int8_t, int16_t, larray, lstrides, rarray, rstrides, >>);
}
} else if(lhs->dtype == NDARRAY_UINT16) {
if(rhs->dtype == NDARRAY_UINT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, uint16_t, uint8_t, larray, lstrides, rarray, rstrides, >>);
} else if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT8);
BINARY_LOOP(results, int8_t, int8_t, int8_t, larray, lstrides, rarray, rstrides, >>);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
BINARY_LOOP(results, uint16_t, uint16_t, uint16_t, larray, lstrides, rarray, rstrides, >>);
} else {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, >>);
}
} else if(lhs->dtype == NDARRAY_INT16) {
if(rhs->dtype == NDARRAY_UINT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int16_t, uint8_t, larray, lstrides, rarray, rstrides, >>);
} else if(rhs->dtype == NDARRAY_INT8) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int16_t, int8_t, larray, lstrides, rarray, rstrides, >>);
} else if(rhs->dtype == NDARRAY_UINT16) {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, uint16_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, >>);
} else {
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
BINARY_LOOP(results, int16_t, int16_t, int16_t, larray, lstrides, rarray, rstrides, >>);
}
}
return results;
}
#endif
mp_obj_t *bitwise_binary_operators(mp_obj_t x1, mp_obj_t x2, uint8_t optype) {
ndarray_obj_t *lhs = ndarray_from_mp_obj(x1, 0);
ndarray_obj_t *rhs = ndarray_from_mp_obj(x2, 0);
#if ULAB_SUPPORTS_COMPLEX
if((lhs->dtype == NDARRAY_FLOAT) || (rhs->dtype == NDARRAY_FLOAT) || (lhs->dtype == NDARRAY_COMPLEX) || (rhs->dtype == NDARRAY_COMPLEX)) {
mp_raise_ValueError(translate("not supported for input types"));
}
#else
if((lhs->dtype == NDARRAY_FLOAT) || (rhs->dtype == NDARRAY_FLOAT)) {
mp_raise_ValueError(translate("not supported for input types"));
}
#endif
uint8_t ndim = 0;
size_t *shape = m_new(size_t, ULAB_MAX_DIMS);
int32_t *lstrides = m_new0(int32_t, ULAB_MAX_DIMS);
int32_t *rstrides = m_new0(int32_t, ULAB_MAX_DIMS);
if(!ndarray_can_broadcast(lhs, rhs, &ndim, shape, lstrides, rstrides)) {
m_del(size_t, shape, ULAB_MAX_DIMS);
m_del(int32_t, lstrides, ULAB_MAX_DIMS);
m_del(int32_t, rstrides, ULAB_MAX_DIMS);
mp_raise_ValueError(translate("operands could not be broadcast together"));
}
ndarray_obj_t *results = NULL;
switch(optype) {
#if ULAB_NUMPY_HAS_BITWISE_AND
case BITWISE_AND:
results = bitwise_bitwise_and_loop(lhs, rhs, ndim, shape, lstrides, rstrides);
break;
#endif
#if ULAB_NUMPY_HAS_BITWISE_OR
case BITWISE_OR:
results = bitwise_bitwise_or_loop(lhs, rhs, ndim, shape, lstrides, rstrides);
break;
#endif
#if ULAB_NUMPY_HAS_BITWISE_XOR
case BITWISE_XOR:
results = bitwise_bitwise_xor_loop(lhs, rhs, ndim, shape, lstrides, rstrides);
break;
#endif
#if ULAB_NUMPY_HAS_LEFT_SHIFT
case BITWISE_LEFT_SHIFT:
results = bitwise_left_shift_loop(lhs, rhs, ndim, shape, lstrides, rstrides);
break;
#endif
#if ULAB_NUMPY_HAS_RIGHT_SHIFT
case BITWISE_RIGHT_SHIFT:
results = bitwise_right_shift_loop(lhs, rhs, ndim, shape, lstrides, rstrides);
break;
#endif
default:
break;
}
m_del(size_t, shape, ULAB_MAX_DIMS);
m_del(int32_t, lstrides, ULAB_MAX_DIMS);
m_del(int32_t, rstrides, ULAB_MAX_DIMS);
return MP_OBJ_FROM_PTR(results);
}
#if ULAB_NUMPY_HAS_BITWISE_AND
mp_obj_t bitwise_bitwise_and(mp_obj_t x1, mp_obj_t x2) {
return bitwise_binary_operators(x1, x2, BITWISE_AND);
}
MP_DEFINE_CONST_FUN_OBJ_2(bitwise_bitwise_and_obj, bitwise_bitwise_and);
#endif
#if ULAB_NUMPY_HAS_BITWISE_OR
mp_obj_t bitwise_bitwise_or(mp_obj_t x1, mp_obj_t x2) {
return bitwise_binary_operators(x1, x2, BITWISE_OR);
}
MP_DEFINE_CONST_FUN_OBJ_2(bitwise_bitwise_or_obj, bitwise_bitwise_or);
#endif
#if ULAB_NUMPY_HAS_BITWISE_XOR
mp_obj_t bitwise_bitwise_xor(mp_obj_t x1, mp_obj_t x2) {
return bitwise_binary_operators(x1, x2, BITWISE_XOR);
}
MP_DEFINE_CONST_FUN_OBJ_2(bitwise_bitwise_xor_obj, bitwise_bitwise_xor);
#endif
#if ULAB_NUMPY_HAS_LEFT_SHIFT
mp_obj_t bitwise_left_shift(mp_obj_t x1, mp_obj_t x2) {
return bitwise_binary_operators(x1, x2, BITWISE_LEFT_SHIFT);
}
MP_DEFINE_CONST_FUN_OBJ_2(left_shift_obj, bitwise_left_shift);
#endif
#if ULAB_NUMPY_HAS_RIGHT_SHIFT
mp_obj_t bitwise_right_shift(mp_obj_t x1, mp_obj_t x2) {
return bitwise_binary_operators(x1, x2, BITWISE_RIGHT_SHIFT);
}
MP_DEFINE_CONST_FUN_OBJ_2(right_shift_obj, bitwise_right_shift);
#endif

32
code/numpy/bitwise.h Normal file
View file

@ -0,0 +1,32 @@
/*
* This file is part of the micropython-ulab project,
*
* https://github.com/v923z/micropython-ulab
*
* The MIT License (MIT)
*
* Copyright (c) 2023 Zoltán Vörös
*/
#ifndef _BITWISE_
#define _BITWISE_
#include "../ulab.h"
#include "../ndarray.h"
enum BITWISE_FUNCTION_TYPE {
BITWISE_AND,
BITWISE_OR,
BITWISE_XOR,
BITWISE_LEFT_SHIFT,
BITWISE_RIGHT_SHIFT,
};
MP_DECLARE_CONST_FUN_OBJ_2(bitwise_bitwise_and_obj);
MP_DECLARE_CONST_FUN_OBJ_2(bitwise_bitwise_or_obj);
MP_DECLARE_CONST_FUN_OBJ_2(bitwise_bitwise_xor_obj);
MP_DECLARE_CONST_FUN_OBJ_2(left_shift_obj);
MP_DECLARE_CONST_FUN_OBJ_2(right_shift_obj);
#endif /* _BITWISE_ */

View file

@ -18,6 +18,7 @@
#include "numpy.h"
#include "approx.h"
#include "bitwise.h"
#include "carray/carray.h"
#include "compare.h"
#include "create.h"
@ -164,7 +165,6 @@ static const mp_rom_map_elem_t ulab_numpy_globals_table[] = {
#if ULAB_NUMPY_HAS_ZEROS
{ MP_ROM_QSTR(MP_QSTR_zeros), MP_ROM_PTR(&create_zeros_obj) },
#endif
// functions of the compare sub-module
#if ULAB_NUMPY_HAS_CLIP
{ MP_ROM_QSTR(MP_QSTR_clip), MP_ROM_PTR(&compare_clip_obj) },
#endif
@ -189,10 +189,25 @@ static const mp_rom_map_elem_t ulab_numpy_globals_table[] = {
#if ULAB_NUMPY_HAS_NONZERO
{ MP_ROM_QSTR(MP_QSTR_nonzero), MP_ROM_PTR(&compare_nonzero_obj) },
#endif
#if ULAB_NUMPY_HAS_WHERE
{ MP_ROM_QSTR(MP_QSTR_where), MP_ROM_PTR(&compare_where_obj) },
#endif
// bitwise operators
#if ULAB_NUMPY_HAS_BITWISE_AND
{ MP_ROM_QSTR(MP_QSTR_bitwise_and), MP_ROM_PTR(&bitwise_bitwise_and_obj) },
#endif
#if ULAB_NUMPY_HAS_BITWISE_OR
{ MP_ROM_QSTR(MP_QSTR_bitwise_or), MP_ROM_PTR(&bitwise_bitwise_or_obj) },
#endif
#if ULAB_NUMPY_HAS_BITWISE_XOR
{ MP_ROM_QSTR(MP_QSTR_bitwise_xor), MP_ROM_PTR(&bitwise_bitwise_xor_obj) },
#endif
#if ULAB_NUMPY_HAS_LEFT_SHIFT
{ MP_ROM_QSTR(MP_QSTR_left_shift), MP_ROM_PTR(&left_shift_obj) },
#endif
#if ULAB_NUMPY_HAS_RIGHT_SHIFT
{ MP_ROM_QSTR(MP_QSTR_right_shift), MP_ROM_PTR(&right_shift_obj) },
#endif
// functions of the filter sub-module
#if ULAB_NUMPY_HAS_CONVOLVE
{ MP_ROM_QSTR(MP_QSTR_convolve), MP_ROM_PTR(&filter_convolve_obj) },

View file

@ -33,7 +33,7 @@
#include "user/user.h"
#include "utils/utils.h"
#define ULAB_VERSION 6.0.12
#define ULAB_VERSION 6.1.0
#define xstr(s) str(s)
#define str(s) #s

View file

@ -165,6 +165,27 @@
#define NDARRAY_HAS_INPLACE_TRUE_DIVIDE (1)
#endif
// bitwise operators
#ifndef ULAB_NUMPY_HAS_BITWISE_AND
#define ULAB_NUMPY_HAS_BITWISE_AND (1)
#endif
#ifndef ULAB_NUMPY_HAS_BITWISE_OR
#define ULAB_NUMPY_HAS_BITWISE_OR (1)
#endif
#ifndef ULAB_NUMPY_HAS_BITWISE_XOR
#define ULAB_NUMPY_HAS_BITWISE_XOR (1)
#endif
#ifndef ULAB_NUMPY_HAS_LEFT_SHIFT
#define ULAB_NUMPY_HAS_LEFT_SHIFT (1)
#endif
#ifndef ULAB_NUMPY_HAS_RIGHT_SHIFT
#define ULAB_NUMPY_HAS_RIGHT_SHIFT (1)
#endif
// the ndarray unary operators
#ifndef NDARRAY_HAS_UNARY_OPS
#define NDARRAY_HAS_UNARY_OPS (1)

View file

@ -1,3 +1,9 @@
Fri, 12 May 2023
version 6.1.0
add bitwise operators
Sun, 7 May 2023
version 6.0.12

View file

@ -15,5 +15,4 @@ myst-parser
# For stubs and annotations
adafruit-circuitpython-typing
build

View file

@ -0,0 +1,14 @@
try:
from ulab import numpy as np
except:
import numpy as np
dtypes = (np.uint8, np.int8, np.uint16, np.int16)
for dtype1 in dtypes:
x1 = np.array(range(5), dtype=dtype1)
for dtype2 in dtypes:
x2 = np.array(range(5, 0, -1), dtype=dtype2)
print(np.bitwise_and(x1, x2))

View file

@ -0,0 +1,16 @@
array([0, 0, 2, 2, 0], dtype=uint8)
array([0, 0, 2, 2, 0], dtype=int16)
array([0, 0, 2, 2, 0], dtype=uint16)
array([0, 0, 2, 2, 0], dtype=int16)
array([0, 0, 2, 2, 0], dtype=int16)
array([0, 0, 2, 2, 0], dtype=int8)
array([0, 0, 2, 2, 0], dtype=uint16)
array([0, 0, 2, 2, 0], dtype=int16)
array([0, 0, 2, 2, 0], dtype=uint16)
array([0, 0, 2, 2, 0], dtype=uint16)
array([0, 0, 2, 2, 0], dtype=uint16)
array([0, 0, 2, 2, 0], dtype=int16)
array([0, 0, 2, 2, 0], dtype=int16)
array([0, 0, 2, 2, 0], dtype=int16)
array([0, 0, 2, 2, 0], dtype=int16)
array([0, 0, 2, 2, 0], dtype=int16)

View file

@ -0,0 +1,14 @@
try:
from ulab import numpy as np
except:
import numpy as np
dtypes = (np.uint8, np.int8, np.uint16, np.int16)
for dtype1 in dtypes:
x1 = np.array(range(5), dtype=dtype1)
for dtype2 in dtypes:
x2 = np.array(range(5, 0, -1), dtype=dtype2)
print(np.bitwise_or(x1, x2))

View file

@ -0,0 +1,16 @@
array([5, 5, 3, 3, 5], dtype=uint8)
array([5, 5, 3, 3, 5], dtype=int16)
array([5, 5, 3, 3, 5], dtype=uint16)
array([5, 5, 3, 3, 5], dtype=int16)
array([5, 5, 3, 3, 5], dtype=int16)
array([5, 5, 3, 3, 5], dtype=int8)
array([5, 5, 3, 3, 5], dtype=uint16)
array([5, 5, 3, 3, 5], dtype=int16)
array([5, 5, 3, 3, 5], dtype=uint16)
array([5, 5, 3, 3, 5], dtype=uint16)
array([5, 5, 3, 3, 5], dtype=uint16)
array([5, 5, 3, 3, 5], dtype=int16)
array([5, 5, 3, 3, 5], dtype=int16)
array([5, 5, 3, 3, 5], dtype=int16)
array([5, 5, 3, 3, 5], dtype=int16)
array([5, 5, 3, 3, 5], dtype=int16)

View file

@ -0,0 +1,14 @@
try:
from ulab import numpy as np
except:
import numpy as np
dtypes = (np.uint8, np.int8, np.uint16, np.int16)
for dtype1 in dtypes:
x1 = np.array(range(5), dtype=dtype1)
for dtype2 in dtypes:
x2 = np.array(range(5, 0, -1), dtype=dtype2)
print(np.bitwise_xor(x1, x2))

View file

@ -0,0 +1,16 @@
array([5, 5, 1, 1, 5], dtype=uint8)
array([5, 5, 1, 1, 5], dtype=int16)
array([5, 5, 1, 1, 5], dtype=uint16)
array([5, 5, 1, 1, 5], dtype=int16)
array([5, 5, 1, 1, 5], dtype=int16)
array([5, 5, 1, 1, 5], dtype=int8)
array([5, 5, 1, 1, 5], dtype=uint16)
array([5, 5, 1, 1, 5], dtype=int16)
array([5, 5, 1, 1, 5], dtype=uint16)
array([5, 5, 1, 1, 5], dtype=uint16)
array([5, 5, 1, 1, 5], dtype=uint16)
array([5, 5, 1, 1, 5], dtype=int16)
array([5, 5, 1, 1, 5], dtype=int16)
array([5, 5, 1, 1, 5], dtype=int16)
array([5, 5, 1, 1, 5], dtype=int16)
array([5, 5, 1, 1, 5], dtype=int16)

View file

@ -0,0 +1,14 @@
try:
from ulab import numpy as np
except:
import numpy as np
dtypes = (np.uint8, np.int8, np.uint16, np.int16)
for dtype1 in dtypes:
x1 = np.array(range(5), dtype=dtype1)
for dtype2 in dtypes:
x2 = np.array(range(5, 0, -1), dtype=dtype2)
print(np.left_shift(x1, x2))

View file

@ -0,0 +1,16 @@
array([0, 16, 16, 12, 8], dtype=uint8)
array([0, 16, 16, 12, 8], dtype=int16)
array([0, 16, 16, 12, 8], dtype=uint16)
array([0, 16, 16, 12, 8], dtype=int16)
array([0, 16, 16, 12, 8], dtype=int16)
array([0, 16, 16, 12, 8], dtype=int8)
array([0, 16, 16, 12, 8], dtype=uint16)
array([0, 16, 16, 12, 8], dtype=int16)
array([0, 16, 16, 12, 8], dtype=uint16)
array([0, 16, 16, 12, 8], dtype=int8)
array([0, 16, 16, 12, 8], dtype=uint16)
array([0, 16, 16, 12, 8], dtype=int16)
array([0, 16, 16, 12, 8], dtype=int16)
array([0, 16, 16, 12, 8], dtype=int16)
array([0, 16, 16, 12, 8], dtype=int16)
array([0, 16, 16, 12, 8], dtype=int16)

View file

@ -0,0 +1,14 @@
try:
from ulab import numpy as np
except:
import numpy as np
dtypes = (np.uint8, np.int8, np.uint16, np.int16)
for dtype1 in dtypes:
x1 = np.array(range(5), dtype=dtype1)
for dtype2 in dtypes:
x2 = np.array(range(5, 0, -1), dtype=dtype2)
print(np.right_shift(x1, x2))

View file

@ -0,0 +1,16 @@
array([0, 0, 0, 0, 2], dtype=uint8)
array([0, 0, 0, 0, 2], dtype=int16)
array([0, 0, 0, 0, 2], dtype=uint16)
array([0, 0, 0, 0, 2], dtype=int16)
array([0, 0, 0, 0, 2], dtype=int16)
array([0, 0, 0, 0, 2], dtype=int8)
array([0, 0, 0, 0, 2], dtype=uint16)
array([0, 0, 0, 0, 2], dtype=int16)
array([0, 0, 0, 0, 2], dtype=uint16)
array([0, 0, 0, 0, 2], dtype=int8)
array([0, 0, 0, 0, 2], dtype=uint16)
array([0, 0, 0, 0, 2], dtype=int16)
array([0, 0, 0, 0, 2], dtype=int16)
array([0, 0, 0, 0, 2], dtype=int16)
array([0, 0, 0, 0, 2], dtype=int16)
array([0, 0, 0, 0, 2], dtype=int16)