Skip to content

Commit

Permalink
added ifftn to ivy functional api (#17397)
Browse files Browse the repository at this point in the history
Co-authored-by: Kareem Morsy <kreem.morsy@hotmail.com>
  • Loading branch information
akshatvishu and KareemMAX authored Jun 22, 2023
1 parent 770111b commit 05cd6af
Show file tree
Hide file tree
Showing 9 changed files with 642 additions and 1 deletion.
67 changes: 67 additions & 0 deletions ivy/data_classes/array/experimental/layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -957,3 +957,70 @@ def fft2(
0. +0.j , 0. +0.j ]])
"""
return ivy.fft2(self._data, s=s, dim=dim, norm=norm, out=out)

def ifftn(
self: ivy.Array,
s: Optional[Union[int, Tuple[int, ...]]] = None,
axes: Optional[Union[int, Tuple[int, ...]]] = None,
*,
norm: str = "backward",
out: Optional[ivy.Array] = None,
) -> ivy.Array:
"""
Compute the N-dimensional inverse discrete Fourier Transform.
Parameters
----------
x
Input array of complex numbers.
s
sequence of ints, optional
Shape (length of transformed axis) of the output (`s[0]` refers to axis 0,
`s[1]` to axis 1, etc.). If given shape is smaller than that of the input,
the input is cropped. If larger, input is padded with zeros. If `s` is not
given, shape of input along axes specified by axes is used.
axes
axes over which to compute the IFFT. If not given, last `len(s)` axes are
used, or all axes if `s` is also not specified. Repeated indices in axes
means inverse transform over that axis is performed multiple times.
norm
Optional argument, "backward", "ortho" or "forward". Defaults to be
"backward".
"backward" indicates no normalization.
"ortho" indicates normalization by 1/sqrt(n).
"forward" indicates normalization by 1/n.
out
Optional output array, for writing the result to. It must have a shape that
the inputs broadcast to.
Returns
-------
ret
The truncated or zero-padded input, transformed along the axes indicated
by axes, or by a combination of s or x, as explained in the parameters
section above.
Examples
--------
>>> x = ivy.array([[0.24730653+0.90832391j, 0.49495562+0.9039565j,
0.98193269+0.49560517j],
[0.93280757+0.48075343j, 0.28526384+0.3351205j,
0.2343787 +0.83528011j],
[0.18791352+0.30690572j, 0.82115787+0.96195183j,
0.44719226+0.72654048j]])
>>> y = ivy.ifftn(x)
>>> print(y)
ivy.array([[ 0.51476765+0.66160417j, -0.04319742-0.05411636j,
-0.015561 -0.04216015j],
[ 0.06310689+0.05347854j, -0.13392983+0.16052352j,
-0.08371392+0.17252843j],
[-0.0031429 +0.05421245j, -0.10446617-0.17747098j,
0.05344324+0.07972424j]])
>>> b = ivy.ifftn(x, s=[2, 1], axes=[0, 1], norm='ortho')
>>> print(b)
ivy.array([[ 0.8344667 +0.98222595j],
[-0.48472244+0.30233797j]])
"""
return ivy.ifftn(self._data, s=s, axes=axes, norm=norm, out=out)
116 changes: 116 additions & 0 deletions ivy/data_classes/container/experimental/layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1907,3 +1907,119 @@ def adaptive_avg_pool2d(
prune_unapplied=prune_unapplied,
map_sequences=map_sequences,
)

@staticmethod
def static_ifftn(
x: ivy.Container,
s: Optional[Union[int, Tuple[int, ...]]] = None,
axes: Optional[Union[int, Tuple[int, ...]]] = None,
*,
norm: str = "backward",
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 static method variant of ivy.ifftn.
This method simply wraps the function, and so the docstring for
ivy.ifftn also applies to this method with minimal changes.
Parameters
----------
x
Input array of complex numbers.
s
sequence of ints, optional
Shape (length of transformed axis) of the output (`s[0]` refers to axis 0,
`s[1]` to axis 1, etc.). If given shape is smaller than that of the input,
the input is cropped. If larger, input is padded with zeros. If `s` is not
given, shape of input along axes specified by axes is used.
axes
axes over which to compute the IFFT. If not given, last `len(s)` axes are
used, or all axes if `s` is also not specified. Repeated indices in axes
means inverse transform over that axis is performed multiple times.
norm
Optional argument, "backward", "ortho" or "forward".
Defaults to be "backward".
"backward" indicates no normalization.
"ortho" indicates normalization by 1/sqrt(n).
"forward" indicates normalization by 1/n.
out
Optional output array, for writing the result to. It must have a shape that
the inputs broadcast to.
Returns
-------
ret
The truncated or zero-padded input, transformed along the axes indicated
by axes, or by a combination of s or x, as explained in the parameters
section above.
"""
return ContainerBase.cont_multi_map_in_function(
"ifftn",
x,
s=s,
axes=axes,
norm=norm,
key_chains=key_chains,
to_apply=to_apply,
prune_unapplied=prune_unapplied,
map_sequences=map_sequences,
out=out,
)

def ifftn(
self: ivy.Container,
s: Optional[Union[int, Tuple[int, ...]]] = None,
axes: Optional[Union[int, Tuple[int, ...]]] = None,
*,
norm: str = "backward",
out: Optional[ivy.Array] = None,
):
"""
ivy.Container static method variant of ivy.ifftn.
This method simply wraps the function, and so the docstring for
ivy.ifftn also applies to this method with minimal changes.
Parameters
----------
x
Input array of complex numbers.
s
sequence of ints, optional
Shape (length of transformed axis) of the output (`s[0]` refers to axis 0,
`s[1]` to axis 1, etc.). If given shape is smaller than that of the input,
the input is cropped. If larger, input is padded with zeros. If `s` is not
given, shape of input along axes specified by axes is used.
axes
axes over which to compute the IFFT. If not given, last `len(s)` axes are
used, or all axes if `s` is also not specified. Repeated indices in axes
means inverse transform over that axis is performed multiple times.
norm
Optional argument, "backward", "ortho" or "forward".
Defaults to be "backward".
"backward" indicates no normalization.
"ortho" indicates normalization by 1/sqrt(n).
"forward" indicates normalization by 1/n.
out
Optional output array, for writing the result to. It must have a shape that
the inputs broadcast to.
Returns
-------
ret
Container containing the transformed inputs
"""
return self.static_ifftn(
self,
s=s,
axes=axes,
norm=norm,
out=out,
)
13 changes: 12 additions & 1 deletion ivy/functional/backends/jax/experimental/layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,17 @@ def fft2(
return jnp.fft.fft2(x, s, dim, norm).astype(jnp.complex128)



def ifftn(
x: JaxArray,
s: Optional[Union[int, Tuple[int]]] = None,
axes: Optional[Union[int, Tuple[int]]] = None,
*,
norm: str = "backward",
out: Optional[JaxArray] = None,
) -> JaxArray:
return jnp.fft.ifftn(x, s, axes, norm)

@with_unsupported_dtypes(
{"0.4.12 and below": ("bfloat16", "float16", "complex")}, backend_version
)
Expand All @@ -786,4 +797,4 @@ def embedding(
embeddings = jnp.where(
norms < -max_norm, embeddings * -max_norm / norms, embeddings
)
return embeddings

11 changes: 11 additions & 0 deletions ivy/functional/backends/numpy/experimental/layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,16 @@ def fft2(
return np.fft.fft2(x, s, dim, norm).astype(np.complex128)


def ifftn(
x: np.ndarray,
s: Optional[Union[int, Tuple[int]]] = None,
axes: Optional[Union[int, Tuple[int]]] = None,
*,
norm: str = "backward",
out: Optional[np.ndarray] = None,
) -> np.ndarray:
return np.fft.ifftn(x, s, axes, norm).astype(x.dtype)

@with_unsupported_dtypes({"1.25.0 and below": ("complex",)}, backend_version)
def embedding(
weights: np.ndarray,
Expand All @@ -911,3 +921,4 @@ def embedding(
norms < -max_norm, embeddings * -max_norm / norms, embeddings
)
return embeddings

11 changes: 11 additions & 0 deletions ivy/functional/backends/paddle/experimental/layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,14 @@ def interpolate(
antialias: Optional[bool] = False,
):
raise IvyNotImplementedException()


def ifftn(
x: paddle.Tensor,
s: Optional[Union[int, Tuple[int]]] = None,
axes: Optional[Union[int, Tuple[int]]] = None,
*,
norm: Optional[str] = "backward",
out: Optional[paddle.Tensor] = None,
) -> paddle.Tensor:
return paddle.fft.ifftn(x, s, axes, norm)
Loading

0 comments on commit 05cd6af

Please sign in to comment.