diff --git a/ivy/array/extensions/elementwise.py b/ivy/array/extensions/elementwise.py index 08a3d87fb3d10..b3b37f727753c 100644 --- a/ivy/array/extensions/elementwise.py +++ b/ivy/array/extensions/elementwise.py @@ -240,3 +240,36 @@ def float_power( ivy.array([1., 8., 27., 16., 5.]) """ return ivy.float_power(self._data, x2, out=out) + + def exp2( + self: Union[ivy.Array, float, list, tuple], + /, + *, + out: Optional[ivy.Array] = None, + ) -> ivy.Array: + """ivy.Array instance method variant of ivy.exp2. This method simply + wraps the function, and so the docstring for ivy.exp2 also applies to + this method with minimal changes. + + Parameters + ---------- + self + Array-like input. + out + optional output array, for writing the result to. + + Returns + ------- + ret + Element-wise 2 to the power x. This is a scalar if x is a scalar. + + Examples + -------- + >>> x = ivy.array([1, 2, 3]) + >>> x.exp2() + ivy.array([2., 4., 8.]) + >>> x = [5, 6, 7] + >>> x.exp2() + ivy.array([32., 64., 128.]) + """ + return ivy.exp2(self._data, out=out) diff --git a/ivy/container/extensions/elementwise.py b/ivy/container/extensions/elementwise.py index 3c11e3dbbb28b..8ea98eb3424e6 100644 --- a/ivy/container/extensions/elementwise.py +++ b/ivy/container/extensions/elementwise.py @@ -519,3 +519,87 @@ def float_power( } """ return self.static_float_power(self, x2, out=out) + + @staticmethod + def static_exp2( + x: Union[ivy.Array, ivy.NativeArray, ivy.Container, float, list, tuple], + /, + *, + key_chains: Optional[Union[List[str], Dict[str, str]]] = None, + to_apply: bool = True, + prune_unapplied: bool = False, + map_sequences: bool = False, + out: Optional[ivy.Container] = None, + ) -> ivy.Container: + """ + ivy.Container static method variant of ivy.exp2. This method simply wraps + the function, and so the docstring for ivy.exp2 also applies to this + method with minimal changes. + + Parameters + ---------- + x + container with the base input arrays. + out + optional output container, for writing the result to. + + Returns + ------- + ret + Container including arrays with element-wise 2 to the power + of input arrays elements. + + Examples + -------- + >>> x = ivy.Container(a=ivy.array([1, 2, 3]),\ + b=[5, 6, 7]) + >>> ivy.Container.static_exp2(x) + { + a: ivy.array([2., 4., 8.]) + b: ivy.array([32., 64., 128.]) + } + """ + return ContainerBase.multi_map_in_static_method( + "exp2", + x, + key_chains=key_chains, + to_apply=to_apply, + prune_unapplied=prune_unapplied, + map_sequences=map_sequences, + out=out, + ) + + def exp2( + self: ivy.Container, + /, + *, + out: Optional[ivy.Container] = None, + ) -> ivy.Container: + """ivy.Container instance method variant of ivy.exp2. This method simply + wraps the function, and so the docstring for ivy.exp2 also applies to + this method with minimal changes. + + Parameters + ---------- + self + container with the base input arrays. + out + optional output container, for writing the result to. + + Returns + ------- + ret + Container including arrays with element-wise 2 to the power + of input array elements. + + Examples + -------- + >>> x = ivy.Container(a=ivy.array([1, 2, 3]),\ + b=[5, 6, 7]) + >>> x.exp2() + { + a: ivy.array([2., 4., 8.]) + b: ivy.array([32., 64., 128.]) + } + """ + return self.static_exp2(self, out=out) diff --git a/ivy/functional/backends/jax/extensions/elementwise.py b/ivy/functional/backends/jax/extensions/elementwise.py index 98cbf378a9509..72c50399308d1 100644 --- a/ivy/functional/backends/jax/extensions/elementwise.py +++ b/ivy/functional/backends/jax/extensions/elementwise.py @@ -51,3 +51,12 @@ def float_power( out: Optional[JaxArray] = None, ) -> JaxArray: return jnp.float_power(x1, x2) + + +def exp2( + x: Union[JaxArray, float, list, tuple], + /, + *, + out: Optional[JaxArray] = None, +) -> JaxArray: + return jnp.exp2(x) diff --git a/ivy/functional/backends/numpy/extensions/elementwise.py b/ivy/functional/backends/numpy/extensions/elementwise.py index 334c9f12f83de..19e96ec39f3d0 100644 --- a/ivy/functional/backends/numpy/extensions/elementwise.py +++ b/ivy/functional/backends/numpy/extensions/elementwise.py @@ -102,3 +102,15 @@ def float_power( float_power.support_native_out = True + + +def exp2( + x: Union[np.ndarray, float, list, tuple], + /, + *, + out: Optional[np.ndarray] = None, +) -> np.ndarray: + return np.exp2(x, out=out) + + +exp2.support_native_out = True diff --git a/ivy/functional/backends/tensorflow/extensions/elementwise.py b/ivy/functional/backends/tensorflow/extensions/elementwise.py index 128efe25e32ba..c19206e4eef54 100644 --- a/ivy/functional/backends/tensorflow/extensions/elementwise.py +++ b/ivy/functional/backends/tensorflow/extensions/elementwise.py @@ -83,3 +83,12 @@ def float_power( out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: return tf.experimental.numpy.float_power(x1, x2) + + +def exp2( + x: Union[tf.Tensor, tf.Variable, float, list, tuple], + /, + *, + out: Optional[Union[tf.Tensor, tf.Variable]] = None, +) -> Union[tf.Tensor, tf.Variable]: + return tf.math.pow(2, x, name=None) diff --git a/ivy/functional/backends/torch/extensions/elementwise.py b/ivy/functional/backends/torch/extensions/elementwise.py index 1d224ef380adb..9843e0bee5e45 100644 --- a/ivy/functional/backends/torch/extensions/elementwise.py +++ b/ivy/functional/backends/torch/extensions/elementwise.py @@ -98,3 +98,15 @@ def float_power( float_power.support_native_out = True + + +def exp2( + x: Union[torch.Tensor, float, list, tuple], + /, + *, + out: Optional[torch.Tensor] = None, +) -> torch.Tensor: + return torch.exp2(x, out=out) + + +exp2.support_native_out = True diff --git a/ivy/functional/extensions/elementwise.py b/ivy/functional/extensions/elementwise.py index d227c410e4530..f6b992a2bd26a 100644 --- a/ivy/functional/extensions/elementwise.py +++ b/ivy/functional/extensions/elementwise.py @@ -306,3 +306,38 @@ def float_power( ivy.array([1., 8., 27., 16., 5.]) """ return ivy.current_backend().float_power(x1, x2, out=out) + + +@to_native_arrays_and_back +@handle_out_argument +@handle_nestable +def exp2( + x: Union[ivy.Array, float, list, tuple], + /, + *, + out: Optional[ivy.Array] = None, +) -> ivy.Array: + """Calculate 2**p for all p in the input array. + + Parameters + ---------- + x + Array-like input. + out + optional output array, for writing the result to. + + Returns + ------- + ret + Element-wise 2 to the power x. This is a scalar if x is a scalar. + + Examples + -------- + >>> x = ivy.array([1, 2, 3]) + >>> ivy.exp2(x) + ivy.array([2., 4., 8.]) + >>> x = [5, 6, 7] + >>> ivy.exp2(x) + ivy.array([32., 64., 128.]) + """ + return ivy.current_backend().exp2(x, out=out) diff --git a/ivy_tests/test_ivy/test_functional/test_extensions/test_core/test_elementwise.py b/ivy_tests/test_ivy/test_functional/test_extensions/test_core/test_elementwise.py index 2c9e43e42b6da..942de5412c819 100644 --- a/ivy_tests/test_ivy/test_functional/test_extensions/test_core/test_elementwise.py +++ b/ivy_tests/test_ivy/test_functional/test_extensions/test_core/test_elementwise.py @@ -295,3 +295,42 @@ def test_float_power( x1=np.asarray(x[0], dtype=input_dtype[0]), x2=np.asarray(x[1], dtype=input_dtype[1]) ) + + +# exp2 +@handle_cmd_line_args +@given( + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + min_value=-10, + max_value=10, + min_num_dims=1, + max_num_dims=3, + min_dim_size=1, + max_dim_size=3, + ), + num_positional_args=helpers.num_positional_args(fn_name="exp2"), +) +def test_exp2( + dtype_and_x, + with_out, + as_variable, + num_positional_args, + native_array, + container, + instance_method, + fw, +): + input_dtype, x = dtype_and_x + helpers.test_function( + input_dtypes=input_dtype, + as_variable_flags=as_variable, + with_out=with_out, + num_positional_args=num_positional_args, + native_array_flags=native_array, + container_flags=container, + instance_method=instance_method, + fw=fw, + fn_name="exp2", + x=np.asarray(x[0], dtype=input_dtype[0]), + )