From 5279de73abddf75f702622661346a79f39896aea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20V=C3=B6r=C3=B6s?= Date: Fri, 21 Jul 2023 21:57:31 +0200 Subject: [PATCH 1/2] implement AND, OR, XOR binary operators (#639) * implement AND, OR, XOR binary operators * fix unterminated if * add missing linebreak * add more linebreaks * remove leading linebreak --- code/ndarray.c | 6 ++ code/ndarray_operators.c | 188 ++++++++++++++++++++++++++++++++++++++ code/ndarray_operators.h | 1 + code/ulab.c | 2 +- code/ulab.h | 12 +++ docs/ulab-change-log.md | 6 ++ tests/2d/numpy/and.py | 21 +++++ tests/2d/numpy/and.py.exp | 20 ++++ tests/2d/numpy/or.py | 21 +++++ tests/2d/numpy/or.py.exp | 20 ++++ tests/2d/numpy/xor.py | 21 +++++ tests/2d/numpy/xor.py.exp | 20 ++++ 12 files changed, 337 insertions(+), 1 deletion(-) create mode 100644 tests/2d/numpy/and.py create mode 100644 tests/2d/numpy/and.py.exp create mode 100644 tests/2d/numpy/or.py create mode 100644 tests/2d/numpy/or.py.exp create mode 100644 tests/2d/numpy/xor.py create mode 100644 tests/2d/numpy/xor.py.exp diff --git a/code/ndarray.c b/code/ndarray.c index 45418be2..dd4161f1 100644 --- a/code/ndarray.c +++ b/code/ndarray.c @@ -1949,6 +1949,12 @@ mp_obj_t ndarray_binary_op(mp_binary_op_t _op, mp_obj_t lobj, mp_obj_t robj) { return ndarray_binary_power(lhs, rhs, ndim, shape, lstrides, rstrides); break; #endif + #if NDARRAY_HAS_BINARY_OP_OR | NDARRAY_HAS_BINARY_OP_XOR | NDARRAY_HAS_BINARY_OP_AND + case MP_BINARY_OP_OR: + case MP_BINARY_OP_XOR: + case MP_BINARY_OP_AND: + return ndarray_binary_logical(lhs, rhs, ndim, shape, lstrides, rstrides, op); + #endif #if NDARRAY_HAS_BINARY_OP_FLOOR_DIVIDE case MP_BINARY_OP_FLOOR_DIVIDE: COMPLEX_DTYPE_NOT_IMPLEMENTED(lhs->dtype); diff --git a/code/ndarray_operators.c b/code/ndarray_operators.c index 3983dabc..f96f981f 100644 --- a/code/ndarray_operators.c +++ b/code/ndarray_operators.c @@ -857,6 +857,194 @@ mp_obj_t ndarray_binary_power(ndarray_obj_t *lhs, ndarray_obj_t *rhs, } #endif /* NDARRAY_HAS_BINARY_OP_POWER */ +#if NDARRAY_HAS_BINARY_OP_OR | NDARRAY_HAS_BINARY_OP_XOR | NDARRAY_HAS_BINARY_OP_AND +mp_obj_t ndarray_binary_logical(ndarray_obj_t *lhs, ndarray_obj_t *rhs, + uint8_t ndim, size_t *shape, int32_t *lstrides, int32_t *rstrides, mp_binary_op_t op) { + + #if ULAB_SUPPORTS_COMPLEX + if((lhs->dtype == NDARRAY_COMPLEX) || (rhs->dtype == NDARRAY_COMPLEX) || (lhs->dtype == NDARRAY_FLOAT) || (rhs->dtype == NDARRAY_FLOAT)) { + mp_raise_TypeError(translate("operation not supported for the input types")); + } + #else + if((lhs->dtype == NDARRAY_FLOAT) || (rhs->dtype == NDARRAY_FLOAT)) { + mp_raise_TypeError(translate("operation not supported for the input types")); + } + #endif + + // bail out, if both inputs are of 16-bit types, but differ in sign; + // numpy promotes the result to int32 + if(((lhs->dtype == NDARRAY_INT16) && (rhs->dtype == NDARRAY_UINT16)) || + ((lhs->dtype == NDARRAY_UINT16) && (rhs->dtype == NDARRAY_INT16))) { + mp_raise_TypeError(translate("dtype of int32 is not supported")); + } + + ndarray_obj_t *results = NULL; + uint8_t *larray = (uint8_t *)lhs->array; + uint8_t *rarray = (uint8_t *)rhs->array; + + + switch(op) { + case MP_BINARY_OP_XOR: + if(lhs->dtype == NDARRAY_UINT8) { + if(rhs->dtype == NDARRAY_UINT8) { + results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT8); + if(lhs->boolean & rhs->boolean) { + results->boolean = 1; + } + 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_INT16); + BINARY_LOOP(results, int16_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 ndarray_binary_op(MP_BINARY_OP_XOR, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs)); + } + } 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_FLOAT); + BINARY_LOOP(results, mp_float_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, ^); + } else { + return ndarray_binary_op(MP_BINARY_OP_XOR, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs)); + } + } 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 ndarray_binary_op(MP_BINARY_OP_XOR, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs)); + } + } + break; + + case MP_BINARY_OP_OR: + if(lhs->dtype == NDARRAY_UINT8) { + if(rhs->dtype == NDARRAY_UINT8) { + results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT8); + if(lhs->boolean & rhs->boolean) { + results->boolean = 1; + } + 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_INT16); + BINARY_LOOP(results, int16_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 ndarray_binary_op(MP_BINARY_OP_OR, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs)); + } + } 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_FLOAT); + BINARY_LOOP(results, mp_float_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, |); + } else { + return ndarray_binary_op(MP_BINARY_OP_OR, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs)); + } + } 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 ndarray_binary_op(MP_BINARY_OP_OR, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs)); + } + } + break; + + case MP_BINARY_OP_AND: + if(lhs->dtype == NDARRAY_UINT8) { + if(rhs->dtype == NDARRAY_UINT8) { + results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT8); + if(lhs->boolean & rhs->boolean) { + results->boolean = 1; + } + 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_INT16); + BINARY_LOOP(results, int16_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 ndarray_binary_op(MP_BINARY_OP_AND, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs)); + } + } 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_FLOAT); + BINARY_LOOP(results, mp_float_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, &); + } else { + return ndarray_binary_op(MP_BINARY_OP_AND, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs)); + } + } 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 ndarray_binary_op(MP_BINARY_OP_AND, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs)); + } + } + break; + default: + return MP_OBJ_NULL; // op not supported + break; + } + return MP_OBJ_FROM_PTR(results); +} + +#endif /* NDARRAY_HAS_BINARY_OP_OR | NDARRAY_HAS_BINARY_OP_XOR | NDARRAY_HAS_BINARY_OP_AND */ + #if NDARRAY_HAS_INPLACE_ADD || NDARRAY_HAS_INPLACE_MULTIPLY || NDARRAY_HAS_INPLACE_SUBTRACT mp_obj_t ndarray_inplace_ams(ndarray_obj_t *lhs, ndarray_obj_t *rhs, int32_t *rstrides, uint8_t optype) { diff --git a/code/ndarray_operators.h b/code/ndarray_operators.h index b8f080fa..f0f3c89d 100644 --- a/code/ndarray_operators.h +++ b/code/ndarray_operators.h @@ -17,6 +17,7 @@ mp_obj_t ndarray_binary_more(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t mp_obj_t ndarray_binary_power(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *); mp_obj_t ndarray_binary_subtract(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *); mp_obj_t ndarray_binary_true_divide(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *); +mp_obj_t ndarray_binary_logical(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *, mp_binary_op_t ); mp_obj_t ndarray_binary_floor_divide(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *); mp_obj_t ndarray_inplace_ams(ndarray_obj_t *, ndarray_obj_t *, int32_t *, uint8_t ); diff --git a/code/ulab.c b/code/ulab.c index d731aac4..f8e35bb9 100644 --- a/code/ulab.c +++ b/code/ulab.c @@ -33,7 +33,7 @@ #include "user/user.h" #include "utils/utils.h" -#define ULAB_VERSION 6.3.5 +#define ULAB_VERSION 6.4.0 #define xstr(s) str(s) #define str(s) #s diff --git a/code/ulab.h b/code/ulab.h index b063bcac..26df82fb 100644 --- a/code/ulab.h +++ b/code/ulab.h @@ -97,6 +97,10 @@ #define NDARRAY_HAS_BINARY_OP_ADD (1) #endif +#ifndef NDARRAY_HAS_BINARY_OP_AND +#define NDARRAY_HAS_BINARY_OP_AND (1) +#endif + #ifndef NDARRAY_HAS_BINARY_OP_EQUAL #define NDARRAY_HAS_BINARY_OP_EQUAL (1) #endif @@ -129,6 +133,10 @@ #define NDARRAY_HAS_BINARY_OP_NOT_EQUAL (1) #endif +#ifndef NDARRAY_HAS_BINARY_OP_OR +#define NDARRAY_HAS_BINARY_OP_OR (1) +#endif + #ifndef NDARRAY_HAS_BINARY_OP_POWER #define NDARRAY_HAS_BINARY_OP_POWER (1) #endif @@ -141,6 +149,10 @@ #define NDARRAY_HAS_BINARY_OP_TRUE_DIVIDE (1) #endif +#ifndef NDARRAY_HAS_BINARY_OP_XOR +#define NDARRAY_HAS_BINARY_OP_XOR (1) +#endif + #ifndef NDARRAY_HAS_INPLACE_OPS #define NDARRAY_HAS_INPLACE_OPS (1) #endif diff --git a/docs/ulab-change-log.md b/docs/ulab-change-log.md index 9dea370b..ad4021a4 100644 --- a/docs/ulab-change-log.md +++ b/docs/ulab-change-log.md @@ -1,3 +1,9 @@ +Thu, 20 Jul 2023 + +version 6.4.0 + + implement AND, OR, and XOR binary operators + Sat, 1 Jul 2023 version 6.3.5 diff --git a/tests/2d/numpy/and.py b/tests/2d/numpy/and.py new file mode 100644 index 00000000..0c881a19 --- /dev/null +++ b/tests/2d/numpy/and.py @@ -0,0 +1,21 @@ +try: + from ulab import numpy as np +except ImportError: + import numpy as np + +dtypes = (np.uint8, np.int8, np.uint16, np.int16) + +for dtype_a in dtypes: + a = np.array(range(5), dtype=dtype_a) + for dtype_b in dtypes: + b = np.array(range(250, 255), dtype=dtype_b) + try: + print('a & b: ', a & b) + except Exception as e: + print(e) + + b = np.array([False, True, False, True, False], dtype=np.bool) + try: + print('a & b (bool): ', a & b) + except Exception as e: + print(e) diff --git a/tests/2d/numpy/and.py.exp b/tests/2d/numpy/and.py.exp new file mode 100644 index 00000000..43a7cd1d --- /dev/null +++ b/tests/2d/numpy/and.py.exp @@ -0,0 +1,20 @@ +a & b: array([0, 1, 0, 1, 4], dtype=uint8) +a & b: array([0, 1, 0, 1, 4], dtype=int16) +a & b: array([0, 1, 0, 1, 4], dtype=uint16) +a & b: array([0, 1, 0, 1, 4], dtype=int16) +a & b (bool): array([0, 1, 0, 1, 0], dtype=uint8) +a & b: array([0, 1, 0, 1, 4], dtype=int16) +a & b: array([0, 1, 0, 1, 4], dtype=int8) +a & b: array([0, 1, 0, 1, 4], dtype=int16) +a & b: array([0, 1, 0, 1, 4], dtype=int16) +a & b (bool): array([0, 1, 0, 1, 0], dtype=int16) +a & b: array([0, 1, 0, 1, 4], dtype=uint16) +a & b: array([0, 1, 0, 1, 4], dtype=int16) +a & b: array([0, 1, 0, 1, 4], dtype=uint16) +dtype of int32 is not supported +a & b (bool): array([0, 1, 0, 1, 0], dtype=uint16) +a & b: array([0, 1, 0, 1, 4], dtype=int16) +a & b: array([0, 1, 0, 1, 4], dtype=int16) +dtype of int32 is not supported +a & b: array([0, 1, 0, 1, 4], dtype=int16) +a & b (bool): array([0, 1, 0, 1, 0], dtype=int16) diff --git a/tests/2d/numpy/or.py b/tests/2d/numpy/or.py new file mode 100644 index 00000000..5788843e --- /dev/null +++ b/tests/2d/numpy/or.py @@ -0,0 +1,21 @@ +try: + from ulab import numpy as np +except ImportError: + import numpy as np + +dtypes = (np.uint8, np.int8, np.uint16, np.int16) + +for dtype_a in dtypes: + a = np.array(range(5), dtype=dtype_a) + for dtype_b in dtypes: + b = np.array(range(250, 255), dtype=dtype_b) + try: + print('a | b: ', a | b) + except Exception as e: + print(e) + + b = np.array([False, True, False, True, False], dtype=np.bool) + try: + print('a | b (bool): ', a | b) + except Exception as e: + print(e) \ No newline at end of file diff --git a/tests/2d/numpy/or.py.exp b/tests/2d/numpy/or.py.exp new file mode 100644 index 00000000..d3395dd3 --- /dev/null +++ b/tests/2d/numpy/or.py.exp @@ -0,0 +1,20 @@ +a | b: array([250, 251, 254, 255, 254], dtype=uint8) +a | b: array([-6, -5, -2, -1, -2], dtype=int16) +a | b: array([250, 251, 254, 255, 254], dtype=uint16) +a | b: array([250, 251, 254, 255, 254], dtype=int16) +a | b (bool): array([0, 1, 2, 3, 4], dtype=uint8) +a | b: array([250, 251, 254, 255, 254], dtype=int16) +a | b: array([-6, -5, -2, -1, -2], dtype=int8) +a | b: array([250, 251, 254, 255, 254], dtype=int16) +a | b: array([250, 251, 254, 255, 254], dtype=int16) +a | b (bool): array([0, 1, 2, 3, 4], dtype=int16) +a | b: array([250, 251, 254, 255, 254], dtype=uint16) +a | b: array([-6, -5, -2, -1, -2], dtype=int16) +a | b: array([250, 251, 254, 255, 254], dtype=uint16) +dtype of int32 is not supported +a | b (bool): array([0, 1, 2, 3, 4], dtype=uint16) +a | b: array([250, 251, 254, 255, 254], dtype=int16) +a | b: array([-6, -5, -2, -1, -2], dtype=int16) +dtype of int32 is not supported +a | b: array([250, 251, 254, 255, 254], dtype=int16) +a | b (bool): array([0, 1, 2, 3, 4], dtype=int16) diff --git a/tests/2d/numpy/xor.py b/tests/2d/numpy/xor.py new file mode 100644 index 00000000..f571dce3 --- /dev/null +++ b/tests/2d/numpy/xor.py @@ -0,0 +1,21 @@ +try: + from ulab import numpy as np +except ImportError: + import numpy as np + +dtypes = (np.uint8, np.int8, np.uint16, np.int16) + +for dtype_a in dtypes: + a = np.array(range(5), dtype=dtype_a) + for dtype_b in dtypes: + b = np.array(range(250, 255), dtype=dtype_b) + try: + print('a ^ b: ', a ^ b) + except Exception as e: + print(e) + + b = np.array([False, True, False, True, False], dtype=np.bool) + try: + print('a ^ b (bool): ', a ^ b) + except Exception as e: + print(e) \ No newline at end of file diff --git a/tests/2d/numpy/xor.py.exp b/tests/2d/numpy/xor.py.exp new file mode 100644 index 00000000..d6352d1a --- /dev/null +++ b/tests/2d/numpy/xor.py.exp @@ -0,0 +1,20 @@ +a ^ b: array([250, 250, 254, 254, 250], dtype=uint8) +a ^ b: array([-6, -6, -2, -2, -6], dtype=int16) +a ^ b: array([250, 250, 254, 254, 250], dtype=uint16) +a ^ b: array([250, 250, 254, 254, 250], dtype=int16) +a ^ b (bool): array([0, 0, 2, 2, 4], dtype=uint8) +a ^ b: array([250, 250, 254, 254, 250], dtype=int16) +a ^ b: array([-6, -6, -2, -2, -6], dtype=int8) +a ^ b: array([250, 250, 254, 254, 250], dtype=int16) +a ^ b: array([250, 250, 254, 254, 250], dtype=int16) +a ^ b (bool): array([0, 0, 2, 2, 4], dtype=int16) +a ^ b: array([250, 250, 254, 254, 250], dtype=uint16) +a ^ b: array([-6, -6, -2, -2, -6], dtype=int16) +a ^ b: array([250, 250, 254, 254, 250], dtype=uint16) +dtype of int32 is not supported +a ^ b (bool): array([0, 0, 2, 2, 4], dtype=uint16) +a ^ b: array([250, 250, 254, 254, 250], dtype=int16) +a ^ b: array([-6, -6, -2, -2, -6], dtype=int16) +dtype of int32 is not supported +a ^ b: array([250, 250, 254, 254, 250], dtype=int16) +a ^ b (bool): array([0, 0, 2, 2, 4], dtype=int16) From a05ec05351260cf48fefc347265b8d8bf29c03f1 Mon Sep 17 00:00:00 2001 From: Xuebin Ruan <39629131+qqice@users.noreply.github.com> Date: Thu, 10 Aug 2023 16:25:19 +0800 Subject: [PATCH 2/2] Fix #643 (#645) * Fix #643 * Update to version 6.4.1 --- code/ndarray.c | 2 +- code/ulab.c | 2 +- docs/ulab-change-log.md | 24 ++++++++++++++++-------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/code/ndarray.c b/code/ndarray.c index dd4161f1..e7aeb88c 100644 --- a/code/ndarray.c +++ b/code/ndarray.c @@ -1738,7 +1738,7 @@ ndarray_obj_t *ndarray_from_mp_obj(mp_obj_t obj, uint8_t other_type) { mp_float_t *array = (mp_float_t *)ndarray->array; array[0] = mp_obj_get_float(obj); } else if(mp_obj_is_bool(obj)) { - ndarray = ndarray_new_linear_array(1, NDARRAY_BOOLEAN); + ndarray = ndarray_new_linear_array(1, NDARRAY_BOOL); uint8_t *array = (uint8_t *)ndarray->array; if(obj == mp_const_true) { *array = 1; diff --git a/code/ulab.c b/code/ulab.c index f8e35bb9..7487144b 100644 --- a/code/ulab.c +++ b/code/ulab.c @@ -33,7 +33,7 @@ #include "user/user.h" #include "utils/utils.h" -#define ULAB_VERSION 6.4.0 +#define ULAB_VERSION 6.4.1 #define xstr(s) str(s) #define str(s) #s diff --git a/docs/ulab-change-log.md b/docs/ulab-change-log.md index ad4021a4..ff921249 100644 --- a/docs/ulab-change-log.md +++ b/docs/ulab-change-log.md @@ -1,3 +1,11 @@ +Thu, 10 Aug 2023 + +version 6.4.1 + +``` +fix BOOLEAN issue, which would cause numpy.where funciton abnormally on RP2040(#643) +``` + Thu, 20 Jul 2023 version 6.4.0 @@ -31,13 +39,13 @@ version 6.3.1 version 6.3.0 add bitwise operators - + Wed, 17 May 2023 version 6.1.1 fix ndarray subscription, when value is NULL - + Tue, 16 May 2023 version 6.1.0 @@ -55,7 +63,7 @@ Sun, 7 May 2023 version 6.0.12 ndarray_from_mp_obj correctly treats Boolean arguments - + Sat, 6 May 2023 version 6.0.11 @@ -67,19 +75,19 @@ Sat, 6 May 2023 version 6.0.10 fix binary division - + Sun, 21 Jan 2023 version 6.0.6 raise proper exception in arange - + Sun, 21 Jan 2023 version 6.0.7 treat empty arrays in sort_complex correctly - + Sun, 21 Jan 2023 version 6.0.5 @@ -91,7 +99,7 @@ Sun, 15 Jan 2023 version 6.0.4 fix dot function - + Sat, 14 Jan 2023 version 6.0.3 @@ -227,7 +235,7 @@ version 4.2.0 Wed, 12 Jan 2022 version 4.2.0 - + implement numpy.save, numpy.load Wed, 12 Jan 2022