3636
3737# NumPy version and a convenient boolean flag
3838NUMPY_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+ }
39114
40115
41116@runtime_checkable
@@ -2923,15 +2998,14 @@ def chunkwise_logaddexp(inputs, output, offset):
29232998 return blosc2 .lazyudf (chunkwise_logaddexp , (x1 , x2 ), dtype = dtype , shape = x1 .shape )
29242999
29253000
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+ }
29353009
29363010
29373011class Operand :
@@ -2984,92 +3058,12 @@ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
29843058 if method != "__call__" :
29853059 return NotImplemented
29863060
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- }
30613061 if ufunc in local_ufunc_map :
30623062 return local_ufunc_map [ufunc ](* inputs )
30633063
30643064 if ufunc in ufunc_map :
30653065 value = inputs [0 ] if inputs [1 ] is self else inputs [1 ]
30663066 _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 ))
30733067 return blosc2 .LazyExpr (new_op = (value , ufunc_map [ufunc ], self ))
30743068
30753069 if ufunc in ufunc_map_1param :
@@ -3081,8 +3075,6 @@ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
30813075
30823076 def __add__ (self , value : int | float | blosc2 .Array , / ) -> blosc2 .LazyExpr :
30833077 _check_allowed_dtypes (value )
3084- if blosc2 .result_type (value , self ) == blosc2 .bool_ :
3085- return blosc2 .LazyExpr (new_op = (value , "|" , self ))
30863078 return blosc2 .LazyExpr (new_op = (self , "+" , value ))
30873079
30883080 def __iadd__ (self , value : int | float | blosc2 .Array , / ) -> blosc2 .LazyExpr :
@@ -3118,9 +3110,6 @@ def __rsub__(self, value: int | float | blosc2.Array, /) -> blosc2.LazyExpr:
31183110 @is_documented_by (multiply )
31193111 def __mul__ (self , value : int | float | blosc2 .Array , / ) -> blosc2 .LazyExpr :
31203112 _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 ))
31243113 return blosc2 .LazyExpr (new_op = (self , "*" , value ))
31253114
31263115 def __imul__ (self , value : int | float | blosc2 .Array , / ) -> blosc2 .LazyExpr :
0 commit comments