36
36
37
37
# NumPy version and a convenient boolean flag
38
38
NUMPY_GE_2_0 = np .__version__ >= "2.0"
39
+ # handle different numpy versions
40
+ if NUMPY_GE_2_0 : # array-api compliant
41
+ nplshift = np .bitwise_left_shift
42
+ nprshift = np .bitwise_right_shift
43
+ npbinvert = np .bitwise_invert
44
+ else : # not array-api compliant
45
+ nplshift = np .left_shift
46
+ nprshift = np .right_shift
47
+ npbinvert = np .bitwise_not
48
+
49
+ # These functions in ufunc_map in ufunc_map_1param are implemented in numexpr and so we call
50
+ # those instead (since numexpr uses multithreading it is faster)
51
+ ufunc_map = {
52
+ np .add : "+" ,
53
+ np .subtract : "-" ,
54
+ np .multiply : "*" ,
55
+ np .divide : "/" ,
56
+ np .true_divide : "/" ,
57
+ np .floor_divide : "//" ,
58
+ np .power : "**" ,
59
+ np .less : "<" ,
60
+ np .less_equal : "<=" ,
61
+ np .greater : ">" ,
62
+ np .greater_equal : ">=" ,
63
+ np .equal : "==" ,
64
+ np .not_equal : "!=" ,
65
+ np .bitwise_and : "&" ,
66
+ np .bitwise_or : "|" ,
67
+ np .bitwise_xor : "^" ,
68
+ np .arctan2 : "arctan2" ,
69
+ nplshift : "<<" , # nplshift selected above according to numpy version
70
+ nprshift : ">>" , # nprshift selected above according to numpy version
71
+ np .remainder : "%" ,
72
+ np .nextafter : "nextafter" ,
73
+ np .copysign : "copysign" ,
74
+ np .hypot : "hypot" ,
75
+ np .maximum : "maximum" ,
76
+ np .minimum : "minimum" ,
77
+ }
78
+
79
+ # implemented in numexpr
80
+ ufunc_map_1param = {
81
+ np .sqrt : "sqrt" ,
82
+ np .sin : "sin" ,
83
+ np .cos : "cos" ,
84
+ np .tan : "tan" ,
85
+ np .arcsin : "arcsin" ,
86
+ np .arccos : "arccos" ,
87
+ np .arctan : "arctan" ,
88
+ np .sinh : "sinh" ,
89
+ np .cosh : "cosh" ,
90
+ np .tanh : "tanh" ,
91
+ np .arcsinh : "arcsinh" ,
92
+ np .arccosh : "arccosh" ,
93
+ np .arctanh : "arctanh" ,
94
+ np .exp : "exp" ,
95
+ np .expm1 : "expm1" ,
96
+ np .log : "log" ,
97
+ np .log10 : "log10" ,
98
+ np .log1p : "log1p" ,
99
+ np .log2 : "log2" ,
100
+ np .abs : "abs" ,
101
+ np .conj : "conj" ,
102
+ np .real : "real" ,
103
+ np .imag : "imag" ,
104
+ npbinvert : "~" , # npbinvert selected above according to numpy version
105
+ np .isnan : "isnan" ,
106
+ np .isfinite : "isfinite" ,
107
+ np .isinf : "isinf" ,
108
+ np .floor : "floor" ,
109
+ np .ceil : "ceil" ,
110
+ np .trunc : "trunc" ,
111
+ np .signbit : "signbit" ,
112
+ np .round : "round" ,
113
+ }
39
114
40
115
41
116
@runtime_checkable
@@ -2923,15 +2998,14 @@ def chunkwise_logaddexp(inputs, output, offset):
2923
2998
return blosc2 .lazyudf (chunkwise_logaddexp , (x1 , x2 ), dtype = dtype , shape = x1 .shape )
2924
2999
2925
3000
2926
- # handle different numpy versions
2927
- if NUMPY_GE_2_0 : # array-api compliant
2928
- nplshift = np .bitwise_left_shift
2929
- nprshift = np .bitwise_right_shift
2930
- npbinvert = np .bitwise_invert
2931
- else : # not array-api compliant
2932
- nplshift = np .left_shift
2933
- nprshift = np .right_shift
2934
- npbinvert = np .bitwise_not
3001
+ # implemented in python-blosc2
3002
+ local_ufunc_map = {
3003
+ np .logaddexp : logaddexp ,
3004
+ np .logical_not : logical_not ,
3005
+ np .logical_and : logical_and ,
3006
+ np .logical_or : logical_or ,
3007
+ np .logical_xor : logical_xor ,
3008
+ }
2935
3009
2936
3010
2937
3011
class Operand :
@@ -2984,92 +3058,12 @@ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
2984
3058
if method != "__call__" :
2985
3059
return NotImplemented
2986
3060
2987
- # These functions in ufunc_map in ufunc_map_1param are implemented in numexpr and so we call
2988
- # those instead (since numexpr uses multithreading it is faster)
2989
- ufunc_map = {
2990
- np .add : "+" ,
2991
- np .subtract : "-" ,
2992
- np .multiply : "*" ,
2993
- np .divide : "/" ,
2994
- np .true_divide : "/" ,
2995
- np .floor_divide : "//" ,
2996
- np .power : "**" ,
2997
- np .less : "<" ,
2998
- np .less_equal : "<=" ,
2999
- np .greater : ">" ,
3000
- np .greater_equal : ">=" ,
3001
- np .equal : "==" ,
3002
- np .not_equal : "!=" ,
3003
- np .bitwise_and : "&" ,
3004
- np .bitwise_or : "|" ,
3005
- np .bitwise_xor : "^" ,
3006
- np .arctan2 : "arctan2" ,
3007
- nplshift : "<<" , # nplshift selected above according to numpy version
3008
- nprshift : ">>" , # nprshift selected above according to numpy version
3009
- np .remainder : "%" ,
3010
- np .nextafter : "nextafter" ,
3011
- np .copysign : "copysign" ,
3012
- np .hypot : "hypot" ,
3013
- np .maximum : "maximum" ,
3014
- np .minimum : "minimum" ,
3015
- }
3016
-
3017
- # implemented in numexpr
3018
- ufunc_map_1param = {
3019
- np .sqrt : "sqrt" ,
3020
- np .sin : "sin" ,
3021
- np .cos : "cos" ,
3022
- np .tan : "tan" ,
3023
- np .arcsin : "arcsin" ,
3024
- np .arccos : "arccos" ,
3025
- np .arctan : "arctan" ,
3026
- np .sinh : "sinh" ,
3027
- np .cosh : "cosh" ,
3028
- np .tanh : "tanh" ,
3029
- np .arcsinh : "arcsinh" ,
3030
- np .arccosh : "arccosh" ,
3031
- np .arctanh : "arctanh" ,
3032
- np .exp : "exp" ,
3033
- np .expm1 : "expm1" ,
3034
- np .log : "log" ,
3035
- np .log10 : "log10" ,
3036
- np .log1p : "log1p" ,
3037
- np .log2 : "log2" ,
3038
- np .abs : "abs" ,
3039
- np .conj : "conj" ,
3040
- np .real : "real" ,
3041
- np .imag : "imag" ,
3042
- npbinvert : "~" , # npbinvert selected above according to numpy version
3043
- np .isnan : "isnan" ,
3044
- np .isfinite : "isfinite" ,
3045
- np .isinf : "isinf" ,
3046
- np .floor : "floor" ,
3047
- np .ceil : "ceil" ,
3048
- np .trunc : "trunc" ,
3049
- np .signbit : "signbit" ,
3050
- np .round : "round" ,
3051
- }
3052
-
3053
- # implemented in python-blosc2
3054
- local_ufunc_map = {
3055
- np .logaddexp : logaddexp ,
3056
- np .logical_not : logical_not ,
3057
- np .logical_and : logical_and ,
3058
- np .logical_or : logical_or ,
3059
- np .logical_xor : logical_xor ,
3060
- }
3061
3061
if ufunc in local_ufunc_map :
3062
3062
return local_ufunc_map [ufunc ](* inputs )
3063
3063
3064
3064
if ufunc in ufunc_map :
3065
3065
value = inputs [0 ] if inputs [1 ] is self else inputs [1 ]
3066
3066
_check_allowed_dtypes (value )
3067
- # catch special case of multiplying two bools (not implemented in numexpr)
3068
- if ufunc_map [ufunc ] == "*" and blosc2 .result_type (value , self ) == blosc2 .bool_ :
3069
- return blosc2 .LazyExpr (new_op = (value , "&" , self ))
3070
- # catch special case of adding two bools (not implemented in numexpr)
3071
- if ufunc_map [ufunc ] == "+" and blosc2 .result_type (value , self ) == blosc2 .bool_ :
3072
- return blosc2 .LazyExpr (new_op = (value , "|" , self ))
3073
3067
return blosc2 .LazyExpr (new_op = (value , ufunc_map [ufunc ], self ))
3074
3068
3075
3069
if ufunc in ufunc_map_1param :
@@ -3081,8 +3075,6 @@ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
3081
3075
3082
3076
def __add__ (self , value : int | float | blosc2 .Array , / ) -> blosc2 .LazyExpr :
3083
3077
_check_allowed_dtypes (value )
3084
- if blosc2 .result_type (value , self ) == blosc2 .bool_ :
3085
- return blosc2 .LazyExpr (new_op = (value , "|" , self ))
3086
3078
return blosc2 .LazyExpr (new_op = (self , "+" , value ))
3087
3079
3088
3080
def __iadd__ (self , value : int | float | blosc2 .Array , / ) -> blosc2 .LazyExpr :
@@ -3118,9 +3110,6 @@ def __rsub__(self, value: int | float | blosc2.Array, /) -> blosc2.LazyExpr:
3118
3110
@is_documented_by (multiply )
3119
3111
def __mul__ (self , value : int | float | blosc2 .Array , / ) -> blosc2 .LazyExpr :
3120
3112
_check_allowed_dtypes (value )
3121
- # catch special case of multiplying two bools (not implemented in numexpr)
3122
- if blosc2 .result_type (value , self ) == blosc2 .bool_ :
3123
- return blosc2 .LazyExpr (new_op = (value , "&" , self ))
3124
3113
return blosc2 .LazyExpr (new_op = (self , "*" , value ))
3125
3114
3126
3115
def __imul__ (self , value : int | float | blosc2 .Array , / ) -> blosc2 .LazyExpr :
0 commit comments