Skip to content

Commit 8c444ef

Browse files
committed
Merge remote-tracking branch 'origin/master' into circuitpython9
2 parents 9c9e953 + a05ec05 commit 8c444ef

File tree

12 files changed

+354
-10
lines changed

12 files changed

+354
-10
lines changed

code/ndarray.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1646,7 +1646,7 @@ ndarray_obj_t *ndarray_from_mp_obj(mp_obj_t obj, uint8_t other_type) {
16461646
mp_float_t *array = (mp_float_t *)ndarray->array;
16471647
array[0] = mp_obj_get_float(obj);
16481648
} else if(mp_obj_is_bool(obj)) {
1649-
ndarray = ndarray_new_linear_array(1, NDARRAY_BOOLEAN);
1649+
ndarray = ndarray_new_linear_array(1, NDARRAY_BOOL);
16501650
uint8_t *array = (uint8_t *)ndarray->array;
16511651
if(obj == mp_const_true) {
16521652
*array = 1;
@@ -1857,6 +1857,12 @@ mp_obj_t ndarray_binary_op(mp_binary_op_t _op, mp_obj_t lobj, mp_obj_t robj) {
18571857
return ndarray_binary_power(lhs, rhs, ndim, shape, lstrides, rstrides);
18581858
break;
18591859
#endif
1860+
#if NDARRAY_HAS_BINARY_OP_OR | NDARRAY_HAS_BINARY_OP_XOR | NDARRAY_HAS_BINARY_OP_AND
1861+
case MP_BINARY_OP_OR:
1862+
case MP_BINARY_OP_XOR:
1863+
case MP_BINARY_OP_AND:
1864+
return ndarray_binary_logical(lhs, rhs, ndim, shape, lstrides, rstrides, op);
1865+
#endif
18601866
#if NDARRAY_HAS_BINARY_OP_FLOOR_DIVIDE
18611867
case MP_BINARY_OP_FLOOR_DIVIDE:
18621868
COMPLEX_DTYPE_NOT_IMPLEMENTED(lhs->dtype);

code/ndarray_operators.c

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,194 @@ mp_obj_t ndarray_binary_power(ndarray_obj_t *lhs, ndarray_obj_t *rhs,
857857
}
858858
#endif /* NDARRAY_HAS_BINARY_OP_POWER */
859859

860+
#if NDARRAY_HAS_BINARY_OP_OR | NDARRAY_HAS_BINARY_OP_XOR | NDARRAY_HAS_BINARY_OP_AND
861+
mp_obj_t ndarray_binary_logical(ndarray_obj_t *lhs, ndarray_obj_t *rhs,
862+
uint8_t ndim, size_t *shape, int32_t *lstrides, int32_t *rstrides, mp_binary_op_t op) {
863+
864+
#if ULAB_SUPPORTS_COMPLEX
865+
if((lhs->dtype == NDARRAY_COMPLEX) || (rhs->dtype == NDARRAY_COMPLEX) || (lhs->dtype == NDARRAY_FLOAT) || (rhs->dtype == NDARRAY_FLOAT)) {
866+
mp_raise_TypeError(translate("operation not supported for the input types"));
867+
}
868+
#else
869+
if((lhs->dtype == NDARRAY_FLOAT) || (rhs->dtype == NDARRAY_FLOAT)) {
870+
mp_raise_TypeError(translate("operation not supported for the input types"));
871+
}
872+
#endif
873+
874+
// bail out, if both inputs are of 16-bit types, but differ in sign;
875+
// numpy promotes the result to int32
876+
if(((lhs->dtype == NDARRAY_INT16) && (rhs->dtype == NDARRAY_UINT16)) ||
877+
((lhs->dtype == NDARRAY_UINT16) && (rhs->dtype == NDARRAY_INT16))) {
878+
mp_raise_TypeError(translate("dtype of int32 is not supported"));
879+
}
880+
881+
ndarray_obj_t *results = NULL;
882+
uint8_t *larray = (uint8_t *)lhs->array;
883+
uint8_t *rarray = (uint8_t *)rhs->array;
884+
885+
886+
switch(op) {
887+
case MP_BINARY_OP_XOR:
888+
if(lhs->dtype == NDARRAY_UINT8) {
889+
if(rhs->dtype == NDARRAY_UINT8) {
890+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT8);
891+
if(lhs->boolean & rhs->boolean) {
892+
results->boolean = 1;
893+
}
894+
BINARY_LOOP(results, uint8_t, uint8_t, uint8_t, larray, lstrides, rarray, rstrides, ^);
895+
} else if(rhs->dtype == NDARRAY_INT8) {
896+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
897+
BINARY_LOOP(results, int16_t, uint8_t, int8_t, larray, lstrides, rarray, rstrides, ^);
898+
} else if(rhs->dtype == NDARRAY_UINT16) {
899+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
900+
BINARY_LOOP(results, uint16_t, uint8_t, uint16_t, larray, lstrides, rarray, rstrides, ^);
901+
} else if(rhs->dtype == NDARRAY_INT16) {
902+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
903+
BINARY_LOOP(results, int16_t, uint8_t, int16_t, larray, lstrides, rarray, rstrides, ^);
904+
}
905+
} else if(lhs->dtype == NDARRAY_INT8) {
906+
if(rhs->dtype == NDARRAY_INT8) {
907+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT8);
908+
BINARY_LOOP(results, int8_t, int8_t, int8_t, larray, lstrides, rarray, rstrides, ^);
909+
} else if(rhs->dtype == NDARRAY_UINT16) {
910+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
911+
BINARY_LOOP(results, int16_t, int8_t, uint16_t, larray, lstrides, rarray, rstrides, ^);
912+
} else if(rhs->dtype == NDARRAY_INT16) {
913+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
914+
BINARY_LOOP(results, int16_t, int8_t, int16_t, larray, lstrides, rarray, rstrides, ^);
915+
} else {
916+
return ndarray_binary_op(MP_BINARY_OP_XOR, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs));
917+
}
918+
} else if(lhs->dtype == NDARRAY_UINT16) {
919+
if(rhs->dtype == NDARRAY_UINT16) {
920+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
921+
BINARY_LOOP(results, uint16_t, uint16_t, uint16_t, larray, lstrides, rarray, rstrides, ^);
922+
} else if(rhs->dtype == NDARRAY_INT16) {
923+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
924+
BINARY_LOOP(results, mp_float_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, ^);
925+
} else {
926+
return ndarray_binary_op(MP_BINARY_OP_XOR, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs));
927+
}
928+
} else if(lhs->dtype == NDARRAY_INT16) {
929+
if(rhs->dtype == NDARRAY_INT16) {
930+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
931+
BINARY_LOOP(results, int16_t, int16_t, int16_t, larray, lstrides, rarray, rstrides, ^);
932+
} else {
933+
return ndarray_binary_op(MP_BINARY_OP_XOR, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs));
934+
}
935+
}
936+
break;
937+
938+
case MP_BINARY_OP_OR:
939+
if(lhs->dtype == NDARRAY_UINT8) {
940+
if(rhs->dtype == NDARRAY_UINT8) {
941+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT8);
942+
if(lhs->boolean & rhs->boolean) {
943+
results->boolean = 1;
944+
}
945+
BINARY_LOOP(results, uint8_t, uint8_t, uint8_t, larray, lstrides, rarray, rstrides, |);
946+
} else if(rhs->dtype == NDARRAY_INT8) {
947+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
948+
BINARY_LOOP(results, int16_t, uint8_t, int8_t, larray, lstrides, rarray, rstrides, |);
949+
} else if(rhs->dtype == NDARRAY_UINT16) {
950+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
951+
BINARY_LOOP(results, uint16_t, uint8_t, uint16_t, larray, lstrides, rarray, rstrides, |);
952+
} else if(rhs->dtype == NDARRAY_INT16) {
953+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
954+
BINARY_LOOP(results, int16_t, uint8_t, int16_t, larray, lstrides, rarray, rstrides, |);
955+
}
956+
} else if(lhs->dtype == NDARRAY_INT8) {
957+
if(rhs->dtype == NDARRAY_INT8) {
958+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT8);
959+
BINARY_LOOP(results, int8_t, int8_t, int8_t, larray, lstrides, rarray, rstrides, |);
960+
} else if(rhs->dtype == NDARRAY_UINT16) {
961+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
962+
BINARY_LOOP(results, int16_t, int8_t, uint16_t, larray, lstrides, rarray, rstrides, |);
963+
} else if(rhs->dtype == NDARRAY_INT16) {
964+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
965+
BINARY_LOOP(results, int16_t, int8_t, int16_t, larray, lstrides, rarray, rstrides, |);
966+
} else {
967+
return ndarray_binary_op(MP_BINARY_OP_OR, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs));
968+
}
969+
} else if(lhs->dtype == NDARRAY_UINT16) {
970+
if(rhs->dtype == NDARRAY_UINT16) {
971+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
972+
BINARY_LOOP(results, uint16_t, uint16_t, uint16_t, larray, lstrides, rarray, rstrides, |);
973+
} else if(rhs->dtype == NDARRAY_INT16) {
974+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
975+
BINARY_LOOP(results, mp_float_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, |);
976+
} else {
977+
return ndarray_binary_op(MP_BINARY_OP_OR, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs));
978+
}
979+
} else if(lhs->dtype == NDARRAY_INT16) {
980+
if(rhs->dtype == NDARRAY_INT16) {
981+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
982+
BINARY_LOOP(results, int16_t, int16_t, int16_t, larray, lstrides, rarray, rstrides, |);
983+
} else {
984+
return ndarray_binary_op(MP_BINARY_OP_OR, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs));
985+
}
986+
}
987+
break;
988+
989+
case MP_BINARY_OP_AND:
990+
if(lhs->dtype == NDARRAY_UINT8) {
991+
if(rhs->dtype == NDARRAY_UINT8) {
992+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT8);
993+
if(lhs->boolean & rhs->boolean) {
994+
results->boolean = 1;
995+
}
996+
BINARY_LOOP(results, uint8_t, uint8_t, uint8_t, larray, lstrides, rarray, rstrides, &);
997+
} else if(rhs->dtype == NDARRAY_INT8) {
998+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
999+
BINARY_LOOP(results, int16_t, uint8_t, int8_t, larray, lstrides, rarray, rstrides, &);
1000+
} else if(rhs->dtype == NDARRAY_UINT16) {
1001+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
1002+
BINARY_LOOP(results, uint16_t, uint8_t, uint16_t, larray, lstrides, rarray, rstrides, &);
1003+
} else if(rhs->dtype == NDARRAY_INT16) {
1004+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
1005+
BINARY_LOOP(results, int16_t, uint8_t, int16_t, larray, lstrides, rarray, rstrides, &);
1006+
}
1007+
} else if(lhs->dtype == NDARRAY_INT8) {
1008+
if(rhs->dtype == NDARRAY_INT8) {
1009+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT8);
1010+
BINARY_LOOP(results, int8_t, int8_t, int8_t, larray, lstrides, rarray, rstrides, &);
1011+
} else if(rhs->dtype == NDARRAY_UINT16) {
1012+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
1013+
BINARY_LOOP(results, int16_t, int8_t, uint16_t, larray, lstrides, rarray, rstrides, &);
1014+
} else if(rhs->dtype == NDARRAY_INT16) {
1015+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
1016+
BINARY_LOOP(results, int16_t, int8_t, int16_t, larray, lstrides, rarray, rstrides, &);
1017+
} else {
1018+
return ndarray_binary_op(MP_BINARY_OP_AND, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs));
1019+
}
1020+
} else if(lhs->dtype == NDARRAY_UINT16) {
1021+
if(rhs->dtype == NDARRAY_UINT16) {
1022+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
1023+
BINARY_LOOP(results, uint16_t, uint16_t, uint16_t, larray, lstrides, rarray, rstrides, &);
1024+
} else if(rhs->dtype == NDARRAY_INT16) {
1025+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
1026+
BINARY_LOOP(results, mp_float_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, &);
1027+
} else {
1028+
return ndarray_binary_op(MP_BINARY_OP_AND, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs));
1029+
}
1030+
} else if(lhs->dtype == NDARRAY_INT16) {
1031+
if(rhs->dtype == NDARRAY_INT16) {
1032+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
1033+
BINARY_LOOP(results, int16_t, int16_t, int16_t, larray, lstrides, rarray, rstrides, &);
1034+
} else {
1035+
return ndarray_binary_op(MP_BINARY_OP_AND, MP_OBJ_FROM_PTR(rhs), MP_OBJ_FROM_PTR(lhs));
1036+
}
1037+
}
1038+
break;
1039+
default:
1040+
return MP_OBJ_NULL; // op not supported
1041+
break;
1042+
}
1043+
return MP_OBJ_FROM_PTR(results);
1044+
}
1045+
1046+
#endif /* NDARRAY_HAS_BINARY_OP_OR | NDARRAY_HAS_BINARY_OP_XOR | NDARRAY_HAS_BINARY_OP_AND */
1047+
8601048
#if NDARRAY_HAS_INPLACE_ADD || NDARRAY_HAS_INPLACE_MULTIPLY || NDARRAY_HAS_INPLACE_SUBTRACT
8611049
mp_obj_t ndarray_inplace_ams(ndarray_obj_t *lhs, ndarray_obj_t *rhs, int32_t *rstrides, uint8_t optype) {
8621050

code/ndarray_operators.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ mp_obj_t ndarray_binary_more(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t
1717
mp_obj_t ndarray_binary_power(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *);
1818
mp_obj_t ndarray_binary_subtract(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *);
1919
mp_obj_t ndarray_binary_true_divide(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *);
20+
mp_obj_t ndarray_binary_logical(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *, mp_binary_op_t );
2021
mp_obj_t ndarray_binary_floor_divide(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *);
2122

2223
mp_obj_t ndarray_inplace_ams(ndarray_obj_t *, ndarray_obj_t *, int32_t *, uint8_t );

code/ulab.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#include "user/user.h"
3434
#include "utils/utils.h"
3535

36-
#define ULAB_VERSION 6.3.5
36+
#define ULAB_VERSION 6.4.1
3737
#define xstr(s) str(s)
3838
#define str(s) #s
3939

code/ulab.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@
9797
#define NDARRAY_HAS_BINARY_OP_ADD (1)
9898
#endif
9999

100+
#ifndef NDARRAY_HAS_BINARY_OP_AND
101+
#define NDARRAY_HAS_BINARY_OP_AND (1)
102+
#endif
103+
100104
#ifndef NDARRAY_HAS_BINARY_OP_EQUAL
101105
#define NDARRAY_HAS_BINARY_OP_EQUAL (1)
102106
#endif
@@ -129,6 +133,10 @@
129133
#define NDARRAY_HAS_BINARY_OP_NOT_EQUAL (1)
130134
#endif
131135

136+
#ifndef NDARRAY_HAS_BINARY_OP_OR
137+
#define NDARRAY_HAS_BINARY_OP_OR (1)
138+
#endif
139+
132140
#ifndef NDARRAY_HAS_BINARY_OP_POWER
133141
#define NDARRAY_HAS_BINARY_OP_POWER (1)
134142
#endif
@@ -141,6 +149,10 @@
141149
#define NDARRAY_HAS_BINARY_OP_TRUE_DIVIDE (1)
142150
#endif
143151

152+
#ifndef NDARRAY_HAS_BINARY_OP_XOR
153+
#define NDARRAY_HAS_BINARY_OP_XOR (1)
154+
#endif
155+
144156
#ifndef NDARRAY_HAS_INPLACE_OPS
145157
#define NDARRAY_HAS_INPLACE_OPS (1)
146158
#endif

docs/ulab-change-log.md

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
Thu, 10 Aug 2023
2+
3+
version 6.4.1
4+
5+
```
6+
fix BOOLEAN issue, which would cause numpy.where funciton abnormally on RP2040(#643)
7+
```
8+
9+
Thu, 20 Jul 2023
10+
11+
version 6.4.0
12+
13+
implement AND, OR, and XOR binary operators
14+
115
Sat, 1 Jul 2023
216

317
version 6.3.5
@@ -25,13 +39,13 @@ version 6.3.1
2539
version 6.3.0
2640

2741
add bitwise operators
28-
42+
2943
Wed, 17 May 2023
3044

3145
version 6.1.1
3246

3347
fix ndarray subscription, when value is NULL
34-
48+
3549
Tue, 16 May 2023
3650

3751
version 6.1.0
@@ -49,7 +63,7 @@ Sun, 7 May 2023
4963
version 6.0.12
5064

5165
ndarray_from_mp_obj correctly treats Boolean arguments
52-
66+
5367
Sat, 6 May 2023
5468

5569
version 6.0.11
@@ -61,19 +75,19 @@ Sat, 6 May 2023
6175
version 6.0.10
6276

6377
fix binary division
64-
78+
6579
Sun, 21 Jan 2023
6680

6781
version 6.0.6
6882

6983
raise proper exception in arange
70-
84+
7185
Sun, 21 Jan 2023
7286

7387
version 6.0.7
7488

7589
treat empty arrays in sort_complex correctly
76-
90+
7791
Sun, 21 Jan 2023
7892

7993
version 6.0.5
@@ -85,7 +99,7 @@ Sun, 15 Jan 2023
8599
version 6.0.4
86100

87101
fix dot function
88-
102+
89103
Sat, 14 Jan 2023
90104

91105
version 6.0.3
@@ -221,7 +235,7 @@ version 4.2.0
221235
Wed, 12 Jan 2022
222236

223237
version 4.2.0
224-
238+
225239
implement numpy.save, numpy.load
226240

227241
Wed, 12 Jan 2022

tests/2d/numpy/and.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
try:
2+
from ulab import numpy as np
3+
except ImportError:
4+
import numpy as np
5+
6+
dtypes = (np.uint8, np.int8, np.uint16, np.int16)
7+
8+
for dtype_a in dtypes:
9+
a = np.array(range(5), dtype=dtype_a)
10+
for dtype_b in dtypes:
11+
b = np.array(range(250, 255), dtype=dtype_b)
12+
try:
13+
print('a & b: ', a & b)
14+
except Exception as e:
15+
print(e)
16+
17+
b = np.array([False, True, False, True, False], dtype=np.bool)
18+
try:
19+
print('a & b (bool): ', a & b)
20+
except Exception as e:
21+
print(e)

tests/2d/numpy/and.py.exp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
a & b: array([0, 1, 0, 1, 4], dtype=uint8)
2+
a & b: array([0, 1, 0, 1, 4], dtype=int16)
3+
a & b: array([0, 1, 0, 1, 4], dtype=uint16)
4+
a & b: array([0, 1, 0, 1, 4], dtype=int16)
5+
a & b (bool): array([0, 1, 0, 1, 0], dtype=uint8)
6+
a & b: array([0, 1, 0, 1, 4], dtype=int16)
7+
a & b: array([0, 1, 0, 1, 4], dtype=int8)
8+
a & b: array([0, 1, 0, 1, 4], dtype=int16)
9+
a & b: array([0, 1, 0, 1, 4], dtype=int16)
10+
a & b (bool): array([0, 1, 0, 1, 0], dtype=int16)
11+
a & b: array([0, 1, 0, 1, 4], dtype=uint16)
12+
a & b: array([0, 1, 0, 1, 4], dtype=int16)
13+
a & b: array([0, 1, 0, 1, 4], dtype=uint16)
14+
dtype of int32 is not supported
15+
a & b (bool): array([0, 1, 0, 1, 0], dtype=uint16)
16+
a & b: array([0, 1, 0, 1, 4], dtype=int16)
17+
a & b: array([0, 1, 0, 1, 4], dtype=int16)
18+
dtype of int32 is not supported
19+
a & b: array([0, 1, 0, 1, 4], dtype=int16)
20+
a & b (bool): array([0, 1, 0, 1, 0], dtype=int16)

0 commit comments

Comments
 (0)