@@ -1928,6 +1928,38 @@ def __ndx_rlogaddexp__(self, x1: TyArrayBase | int | float, /) -> TyArrayFloatin
19281928 return safe_cast (TyArrayFloating , (x1 .exp () + x2 .exp ()).log ())
19291929 return NotImplemented
19301930
1931+ @overload
1932+ def __add__ (self : Self , other : Self | int | float ) -> Self : ...
1933+ @overload
1934+ def __add__ (self , other : TyArrayNumber | int | float ) -> TyArrayNumber : ...
1935+ @overload
1936+ def __add__ (self , other : TyArrayBase | PyScalar ) -> TyArrayBase : ...
1937+ def __add__ (self , other : TyArrayBase | PyScalar ) -> TyArrayBase :
1938+ return super ().__add__ (other )
1939+
1940+ @overload
1941+ def __sub__ (self : Self , other : Self | int | float ) -> Self : ...
1942+ @overload
1943+ def __sub__ (self , other : TyArrayNumber | int | float ) -> TyArrayNumber : ...
1944+ @overload
1945+ def __sub__ (self , other : TyArrayBase | PyScalar ) -> TyArrayBase : ...
1946+ def __sub__ (self , other : TyArrayBase | PyScalar ) -> TyArrayBase :
1947+ return super ().__sub__ (other )
1948+
1949+ @overload
1950+ def __mul__ (self : Self , other : Self | int | float ) -> Self : ...
1951+ @overload
1952+ def __mul__ (self , other : TyArrayBase | PyScalar ) -> TyArrayBase : ...
1953+ def __mul__ (self , other : TyArrayBase | PyScalar ) -> TyArrayBase :
1954+ return super ().__mul__ (other )
1955+
1956+ @overload
1957+ def __truediv__ (self : Self , other : Self | int | float ) -> Self : ...
1958+ @overload
1959+ def __truediv__ (self , other : TyArrayBase | PyScalar ) -> TyArrayBase : ...
1960+ def __truediv__ (self , other : TyArrayBase | PyScalar ) -> TyArrayBase :
1961+ return super ().__truediv__ (other )
1962+
19311963 def ceil (self ) -> Self :
19321964 return type (self )(op .ceil (self ._var ))
19331965
@@ -2073,6 +2105,14 @@ def cosh(self) -> Self:
20732105 def exp (self ) -> Self :
20742106 return type (self )(op .exp (self ._var ))
20752107
2108+ def expm1 (self ) -> Self :
2109+ # expm1(x) = (u - 1) * x / log(u) with u = exp(x); == x where u == 1.
2110+ # Analog of Goldberg's log1p (see below).
2111+ u = self .exp ()
2112+ d = u - 1.0
2113+ tail = (d == - 1.0 ) | u .isinf ()
2114+ return where (u == 1.0 , self , where (tail , d , d * self / u .log ()))
2115+
20762116 def log (self ) -> Self :
20772117 return type (self )(op .log (self ._var ))
20782118
@@ -2084,6 +2124,16 @@ def log10(self) -> Self:
20842124 res = self .log () / float (np .log (10 ))
20852125 return safe_cast (type (self ), res )
20862126
2127+ def log1p (self ) -> Self :
2128+ # log1p(x) = log(u) * x / (u - 1) with u = 1 + x; == x where u == 1.
2129+ # Goldberg, "What Every Computer Scientist Should Know About
2130+ # Floating-Point Arithmetic", Theorem 4:
2131+ # https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
2132+ u = self + 1.0
2133+ d = u - 1.0
2134+ short_circuit = (u == 1.0 ) | (self .isinf () & (self > 0.0 ))
2135+ return where (short_circuit , self , u .log () * (self / d ))
2136+
20872137 def sin (self ) -> Self :
20882138 return type (self )(op .sin (self ._var ))
20892139
0 commit comments