Skip to content

Commit

Permalink
Added function fmin (#9053)
Browse files Browse the repository at this point in the history
Co-authored-by: nathzi1505 <[email protected]>
  • Loading branch information
hyadav2k and p3jitnath authored Jan 3, 2023
1 parent 988a31f commit ac04ffd
Show file tree
Hide file tree
Showing 8 changed files with 277 additions and 0 deletions.
40 changes: 40 additions & 0 deletions ivy/array/experimental/elementwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,46 @@ def fmax(
"""
return ivy.fmax(self._data, x2, out=out)

def fmin(
self: ivy.Array,
x2: ivy.Array,
/,
*,
out: Optional[ivy.Array] = None,
) -> ivy.Array:
"""ivy.Array instance method variant of ivy.fmin. This method simply
wraps the function, and so the docstring for ivy.fmin also applies to
this method with minimal changes.
Parameters
----------
self
x1
First input array.
x2
Second input array
out
optional output array, for writing the result to.
Returns
-------
ret
Array with element-wise minimums.
Examples
--------
>>> x1 = ivy.array([2, 3, 4])
>>> x2 = ivy.array([1, 5, 2])
>>> ivy.fmin(x1, x2)
ivy.array([1, 3, 2])
>>> x1 = ivy.array([ivy.nan, 0, ivy.nan])
>>> x2 = ivy.array([0, ivy.nan, ivy.nan])
>>> x1.fmin(x2)
ivy.array([ 0., 0., nan])
"""
return ivy.fmin(self._data, x2, out=out)

def trapz(
self: ivy.Array,
/,
Expand Down
93 changes: 93 additions & 0 deletions ivy/container/experimental/elementwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,99 @@ def fmax(
"""
return self.static_fmax(self, x2, out=out)

@staticmethod
def static_fmin(
x1: Union[ivy.Array, ivy.NativeArray, ivy.Container],
x2: Union[ivy.Array, ivy.NativeArray, ivy.Container],
/,
*,
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.fmin. This method simply wraps
the function, and so the docstring for ivy.fmin also applies to this method
with minimal changes.
Parameters
----------
x1
container with the first input arrays.
x2
container with the second input arrays
out
optional output container, for writing the result to.
Returns
-------
ret
Container including arrays with element-wise minimums.
Examples
--------
>>> x1 = ivy.Container(a=ivy.array([2, 3, 4]),\
b=ivy.array([ivy.nan, 0, ivy.nan]))
>>> x2 = ivy.Container(a=ivy.array([1, 5, 2]),\
b=ivy.array([0, ivy.nan, ivy.nan]))
>>> ivy.Container.static_fmin(x1, x2)
{
a: ivy.array([1, 3, 2]),
b: ivy.array([0., 0., nan])
}
"""
return ContainerBase.cont_multi_map_in_static_method(
"fmin",
x1,
x2,
key_chains=key_chains,
to_apply=to_apply,
prune_unapplied=prune_unapplied,
map_sequences=map_sequences,
out=out,
)

def fmin(
self: ivy.Container,
x2: ivy.Container,
/,
*,
out: Optional[ivy.Container] = None,
) -> ivy.Container:
"""ivy.Container instance method variant of ivy.fmin. This method simply
wraps the function, and so the docstring for ivy.fmin also applies to this
method with minimal changes.
Parameters
----------
self
container with the first input arrays.
x2
container with the second input arrays
out
optional output container, for writing the result to.
Returns
-------
ret
Container including arrays with element-wise minimums.
Examples
--------
>>> x1 = ivy.Container(a=ivy.array([2, 3, 4]),\
b=ivy.array([ivy.nan, 0, ivy.nan]))
>>> x2 = ivy.Container(a=ivy.array([1, 5, 2]),\
b=ivy.array([0, ivy.nan, ivy.nan]))
>>> x1.fmin(x2)
{
a: ivy.array([1, 3, 2]),
b: ivy.array([0., 0., nan])
}
"""
return self.static_fmin(self, x2, out=out)

@staticmethod
def static_float_power(
x1: Union[ivy.Array, ivy.NativeArray, ivy.Container, float, list, tuple],
Expand Down
10 changes: 10 additions & 0 deletions ivy/functional/backends/jax/experimental/elementwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ def fmax(
return jnp.fmax(x1, x2)


def fmin(
x1: JaxArray,
x2: JaxArray,
/,
*,
out: Optional[JaxArray] = None,
) -> JaxArray:
return jnp.fmin(x1, x2)


def trapz(
y: JaxArray,
/,
Expand Down
23 changes: 23 additions & 0 deletions ivy/functional/backends/numpy/experimental/elementwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,29 @@ def fmax(
fmax.support_native_out = True


@_scalar_output_to_0d_array
def fmin(
x1: np.ndarray,
x2: np.ndarray,
/,
*,
out: Optional[np.ndarray] = None,
) -> np.ndarray:
return np.fmin(
x1,
x2,
out=None,
where=True,
casting="same_kind",
order="K",
dtype=None,
subok=True,
)


fmin.support_native_out = True


@_scalar_output_to_0d_array
def trapz(
y: np.ndarray,
Expand Down
17 changes: 17 additions & 0 deletions ivy/functional/backends/tensorflow/experimental/elementwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,23 @@ def fmax(
return ret


def fmin(
x1: Union[tf.Tensor, tf.Variable],
x2: Union[tf.Tensor, tf.Variable],
/,
*,
out: Optional[Union[tf.Tensor, tf.Variable]] = None,
) -> Union[tf.Tensor, tf.Variable]:
temp = tf.constant(float("nan"))
tf.dtypes.cast(x1, tf.float64)
tf.dtypes.cast(x2, tf.float64)
x1 = tf.where(tf.math.is_nan(x1, temp), x2, x1)
x2 = tf.where(tf.math.is_nan(x2, temp), x1, x2)
tf.experimental.numpy.experimental_enable_numpy_behavior()
ret = tf.experimental.numpy.minimum(x1, x2)
return ret


def trapz(
y: Union[tf.Tensor, tf.Variable],
/,
Expand Down
13 changes: 13 additions & 0 deletions ivy/functional/backends/torch/experimental/elementwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,19 @@ def fmax(
fmax.support_native_out = True


def fmin(
x1: torch.Tensor,
x2: torch.Tensor,
/,
*,
out: Optional[torch.Tensor] = None,
) -> torch.Tensor:
return torch.fmin(x1, x2, out=None)


fmin.support_native_out = True


@with_unsupported_dtypes({"1.11.0 and below": ("float16",)}, backend_version)
def sinc(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor:
x = _cast_for_unary_op(x)
Expand Down
43 changes: 43 additions & 0 deletions ivy/functional/ivy/experimental/elementwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,49 @@ def fmax(
return ivy.current_backend().fmax(x1, x2, out=out)


@to_native_arrays_and_back
@handle_out_argument
@handle_nestable
def fmin(
x1: Union[ivy.Array, ivy.NativeArray],
x2: Union[ivy.Array, ivy.NativeArray],
/,
*,
out: Optional[Union[ivy.Array, ivy.NativeArray]] = None,
) -> Union[ivy.Array, ivy.NativeArray]:
"""Computes the element-wise minimums of two arrays. Differs from ivy.minimum
in the case where one of the elements is NaN. ivy.minimum returns the NaN element
while ivy.fmin returns the non-NaN element.
Parameters
----------
x1
First input array.
x2
Second input array.
out
optional output array, for writing the result to.
Returns
-------
ret
Array with element-wise minimums.
Examples
--------
>>> x1 = ivy.array([2, 3, 4])
>>> x2 = ivy.array([1, 5, 2])
>>> ivy.fmin(x1, x2)
ivy.array([1, 3, 2])
>>> x1 = ivy.array([ivy.nan, 0, ivy.nan])
>>> x2 = ivy.array([0, ivy.nan, ivy.nan])
>>> ivy.fmin(x1, x2)
ivy.array([ 0., 0., nan])
"""
return ivy.current_backend().fmin(x1, x2, out=out)


@to_native_arrays_and_back
@handle_out_argument
@handle_nestable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,44 @@ def test_fmax(
)


# fmin
@handle_test(
fn_tree="functional.ivy.experimental.fmax",
dtype_and_x=helpers.dtype_and_values(
available_dtypes=helpers.get_dtypes("float"),
min_value=-10,
max_value=10,
num_arrays=2,
shared_dtype=True,
min_num_dims=1,
max_num_dims=3,
min_dim_size=1,
max_dim_size=3,
allow_nan=True,
),
test_gradients=st.just(False),
)
def test_fmin(
dtype_and_x,
test_flags,
backend_fw,
fn_name,
on_device,
ground_truth_backend,
):
input_dtype, x = dtype_and_x
helpers.test_function(
input_dtypes=input_dtype,
test_flags=test_flags,
on_device=on_device,
fw=backend_fw,
ground_truth_backend=ground_truth_backend,
fn_name=fn_name,
x1=x[0],
x2=x[1],
)


# trapz
@st.composite
def _either_x_dx(draw):
Expand Down

0 comments on commit ac04ffd

Please sign in to comment.