
    uki=                    ,   d dl mZ d dlmZ d dlmZ d dlZd dlZd dlZ	d dl
mZ d dl
mZ d dlmZ d dlmZmZmZ d d	lmZmZ d d
lmZ ddZddZddZ	 	 d	 	 	 	 	 ddZddZ	 	 	 	 d	 	 	 	 	 	 	 ddZ	 	 d	 	 	 	 	 ddZ	 	 	 	 d	 	 	 	 	 	 	 ddZ ddZ!y)    )annotations)Sequence)partialN)lax)numpy)fft)promote_dtypes_complexpromote_dtypes_inexactensure_arraylike)canonicalize_axiscanonicalize_axis_tuple)Arrayc                x    t        | |      \  }}t        j                  dt        j                  z  |z  |z        S )Ny             )r	   jnpexpnppi)NkN_arrs      M/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/jax/_src/scipy/fft.py_W4r       s3    #Aq)(%	!E)	**    c           	         t        j                  | d d d|      }t        j                  t        j                  | dd d|      |f      }t        j                  ||g|      S N      )r   slice_in_dimrevconcatenate)xaxisv0v1s       r   _dct_interleaver%   $   sT    
4q$/"
wws1dAt4tg>"	"b4	((r   c                   t        j                  t        j                  dd| j                        t        j                  | j                  |   dz
  fd| j                        gd      }t        j
                  |t        | j                        D cg c]
  }||k7  s	| c}      }| t        j                  || j                  |   z        z  S c c}w )N)r      r   r   r   )	r   r    fulldtypeshapeexpand_dimsrangendimsqrt)outr"   factoras       r   _dct_ortho_normr2   )   s    ??CHHT1cii8#((CIIdOVWDWCY[\^a^g^g:hiklm&??6uSXX#L!!t)A#LM&	sxx401	11 $Ms   
C
C
c                   t        d|       } |dk7  rt        d      ||dvrt        d|d      t        || j                        }|pt        j                  | t        j                  d| j                        t        | j                        D cg c]  }d||k(  r|| j                  |   z
  nddf  c}      } | j                  |   }t        | |      }t        j                  ||      }t        j                  t        j                   ||j"                  j                  	      t        | j                        D cg c]
  }||k7  s	| c}      }	|t%        ||	      z  }
d|
j"                  z  }
|d
k(  rt'        |
|      }
|
S c c}w c c}w )a  Computes the discrete cosine transform of the input

  JAX implementation of :func:`scipy.fft.dct`.

  Args:
    x: array
    type: integer, default = 2. Currently only type 2 is supported.
    n: integer, default = x.shape[axis]. The length of the transform.
      If larger than ``x.shape[axis]``, the input will be zero-padded, if
      smaller, the input will be truncated.
    axis: integer, default=-1. The axis along which the dct will be performed.
    norm: string. The normalization mode: one of ``[None, "backward", "ortho"]``.
      The default is ``None``, which is equivalent to ``"backward"``.

  Returns:
    array containing the discrete cosine transform of x

  See Also:
    - :func:`jax.scipy.fft.dctn`: multidimensional DCT
    - :func:`jax.scipy.fft.idct`: inverse DCT
    - :func:`jax.scipy.fft.idctn`: multidimensional inverse DCT

  Examples:
    >>> x = jax.random.normal(jax.random.key(0), (3, 3))
    >>> with jnp.printoptions(precision=2, suppress=True):
    ...   print(jax.scipy.fft.dct(x))
    [[ 6.43  3.56 -2.86]
     [-1.75  1.55 -1.4 ]
     [ 1.33 -2.01 -0.82]]

    When ``n`` smaller than ``x.shape[axis]``

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...   print(jax.scipy.fft.dct(x, n=2))
    [[ 7.3  -0.57]
     [ 0.19 -0.36]
     [-0.   -1.4 ]]

    When ``n`` smaller than ``x.shape[axis]`` and ``axis=0``

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...   print(jax.scipy.fft.dct(x, n=2, axis=0))
    [[ 3.09  4.4  -2.81]
     [ 2.41  2.62  0.76]]

    When ``n`` larger than ``x.shape[axis]`` and ``axis=1``

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...   print(jax.scipy.fft.dct(x, n=4, axis=1))
    [[ 6.43  4.88  0.04 -3.3 ]
     [-1.75  0.73  1.01 -2.18]
     [ 1.33 -1.05 -2.34 -0.07]]
  idctnr   Only DCT type 2 is implemented.backwardorthozjax.scipy.fft.dct: norm= is not implementedr   r"   r)   r8   )r   NotImplementedError
ValueErrorr   r-   r   padr   arrayr)   r,   r*   r%   jnp_fftr   r+   arangerealr   r2   )r!   typenr"   normr1   r   vVr   r/   s              r   dctrH   2   sa   n w"!	QY
?
@@	$&;;
04)3FG
HH	4	($]399Q(-) !t)Q&A> )	*A ggdm!a!kk!$!	oocjj!&&,,7U166]9`VW[_V_!9`a!	C1I#	CHH#	W_
#t
$C	*) :as   #F<
F
F
c           	     t   t        t        t        | j                        |      \  }}| j                  |   | j                  |   }}t        t        | |      |      }t        j                  ||      }t        j                  t        j                  ||j                        t        | j                        D 	cg c]
  }	|	|k7  s	|	 c}	      }
t        j                  t        j                  ||j                        t        | j                        D 	cg c]
  }	|	|k7  s	|	 c}	      }t        ||
      t        ||      |z  t        ||       t        j                  t        j                   ||      d|      z  z   z  }d|j"                  z  }|dk(  rt%        t%        ||      |      S |S c c}	w c c}	w )	N)num_dims)axesr;   r:   r   )shiftr"   r   r8   )mapr   r   r-   r*   r%   r@   fftnr   r+   r   rA   r)   r,   r   rollfliprB   r2   )r!   rK   rE   axis1axis2N1N2rF   rG   r1   k1k2r/   s                r   _dct2rW      sO   W.@$G,%775>1775>b"oa/7!ll14 !
szz"AGG4#(=?aAJ?A"
szz"AGG4#(=?aAJ?A"Bs2r{QR"!RWAX`ahm8n)nno#	CHH#	W_?36>>	* @?s   :
F0
F0

F5
!F5
c                H   t        d|       } |dk7  rt        d      ||dvrt        d|d      |	 t        |      }t        || j                        }t        |      dk(  rt        | ||d	   nd|d	   |
      S |t        t        ||            }t        | j                        D cg c]   }d	||v r||   | j                   |   z
  nd	d	f" }}t#        j$                  | t'        j(                  d	| j*                        |      } t        |      dk(  rt-        | ||      S t        d	t        |      d      D cg c]
  }|||dz     c}D ]  }	t/        | |	|      }  | S # t        $ r, t        |t              rJ t        j                  |      g}Y Vw xY wc c}w c c}w )a  Computes the multidimensional discrete cosine transform of the input

  JAX implementation of :func:`scipy.fft.dctn`.

  Args:
    x: array
    type: integer, default = 2. Currently only type 2 is supported.
    s: integer or sequence of integers. Specifies the shape of the result. If not
      specified, it will default to the shape of ``x`` along the specified ``axes``.
    axes: integer or sequence of integers. Specifies the axes along which the
      transform will be computed.
    norm: string. The normalization mode: one of ``[None, "backward", "ortho"]``.
      The default is ``None``, which is equivalent to ``"backward"``.

  Returns:
    array containing the discrete cosine transform of x

  See Also:
    - :func:`jax.scipy.fft.dct`: one-dimensional DCT
    - :func:`jax.scipy.fft.idct`: one-dimensional inverse DCT
    - :func:`jax.scipy.fft.idctn`: multidimensional inverse DCT

  Examples:

    ``jax.scipy.fft.dctn`` computes the transform along both the axes by default
    when ``axes`` argument is ``None``.

    >>> x = jax.random.normal(jax.random.key(0), (3, 3))
    >>> with jnp.printoptions(precision=2, suppress=True):
    ...   print(jax.scipy.fft.dctn(x))
    [[ 12.01   6.2  -10.17]
     [  8.84   9.65  -3.54]
     [ 11.25  -1.54  -0.88]]

    When ``s=[2]``, dimension of the transform along ``axis 0`` will be ``2``
    and dimension along ``axis 1`` will be same as that of input.

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...   print(jax.scipy.fft.dctn(x, s=[2]))
    [[ 9.36 10.22 -8.53]
     [11.57  2.85 -2.06]]

    When ``s=[2]`` and ``axes=[1]``, dimension of the transform along ``axis 1`` will
    be ``2`` and dimension along ``axis 0`` will  be same as that of input.
    Also when ``axes=[1]``, transform will be computed only along ``axis 1``.

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...   print(jax.scipy.fft.dctn(x, s=[2], axes=[1]))
    [[ 7.3  -0.57]
     [ 0.19 -0.36]
     [-0.   -1.4 ]]

    When ``s=[2, 4]``, shape of the transform will be ``(2, 4)``.

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...   print(jax.scipy.fft.dctn(x, s=[2, 4]))
    [[  9.36  11.23   2.12 -10.97]
     [ 11.57   5.86  -1.37  -1.58]]
  r4   r   r5   Nr6   zjax.scipy.fft.dctn: norm=r9   r   r   rD   r"   rE   )rK   rE   )r   r<   r=   list	TypeError
isinstancer   operatorindexr   r-   lenrH   dictzipr,   r*   r   r>   r   r?   r)   rW   dctn)
r!   rC   srK   rE   nsr1   padsi
axes_blocks
             r   rb   rb      s   ~ w"!	QY
?
@@	$&;;
1D94GH
II]
q'a
 
!qvv	.$Y!^qAMAaDt$q'MM]	c$l	BBG-PQQa2g1
"1a8PDP399Q($/AY!^D)) +03t9a*@AQT!AaC[A ,jQZd+A,	
()  Ax(((>>!
a Q Bs   E" +%F;F"1FFc                   t        d|       } |dk7  rt        d      ||dvrt        d|d      t        || j                        }|pt        j                  | t        j                  d| j                        t        | j                        D cg c]  }d||k(  r|| j                  |   z
  nddf  c}      } | j                  |   }t        |       \  } ||dk(  rt        | |      } t        | |      } t        j                  t        j                  || j                  	      t        | j                        D cg c]
  }||k7  s	| c}      }t!        ||      }| j#                  |j                        } | t!        ||      z  } | dz  |z  } t%        j&                  | |
      } t)        | j*                  |      }	|	S c c}w c c}w )a  Computes the inverse discrete cosine transform of the input

  JAX implementation of :func:`scipy.fft.idct`.

  Args:
    x: array
    type: integer, default = 2. Currently only type 2 is supported.
    n: integer, default = x.shape[axis]. The length of the transform.
      If larger than ``x.shape[axis]``, the input will be zero-padded, if
      smaller, the input will be truncated.
    axis: integer, default=-1. The axis along which the dct will be performed.
    norm: string. The normalization mode: one of ``[None, "backward", "ortho"]``.
      The default is ``None``, which is equivalent to ``"backward"``.

  Returns:
    array containing the inverse discrete cosine transform of x

  See Also:
    - :func:`jax.scipy.fft.dct`: DCT
    - :func:`jax.scipy.fft.dctn`: multidimensional DCT
    - :func:`jax.scipy.fft.idctn`: multidimensional inverse DCT

  Examples:

    >>> x = jax.random.normal(jax.random.key(0), (3, 3))
    >>> with jnp.printoptions(precision=2, suppress=True):
    ...    print(jax.scipy.fft.idct(x))
    [[ 0.78  0.41 -0.39]
     [-0.12  0.31 -0.23]
     [ 0.17 -0.3  -0.11]]

    When ``n`` smaller than ``x.shape[axis]``

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...    print(jax.scipy.fft.idct(x, n=2))
    [[ 1.12 -0.31]
     [ 0.04 -0.08]
     [ 0.05 -0.3 ]]

    When ``n`` smaller than ``x.shape[axis]`` and ``axis=0``

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...    print(jax.scipy.fft.idct(x, n=2, axis=0))
    [[ 0.38  0.57 -0.45]
     [ 0.43  0.44  0.24]]

    When ``n`` larger than ``x.shape[axis]`` and ``axis=0``

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...    print(jax.scipy.fft.idct(x, n=4, axis=0))
    [[ 0.1   0.38 -0.16]
     [ 0.28  0.18 -0.26]
     [ 0.3   0.15 -0.08]
     [ 0.13  0.3   0.29]]

    ``jax.scipy.fft.idct`` can be used to reconstruct ``x`` from the result
    of ``jax.scipy.fft.dct``

    >>> x_dct = jax.scipy.fft.dct(x)
    >>> jnp.allclose(x, jax.scipy.fft.idct(x_dct))
    Array(True, dtype=bool)
  idctr   r5   r6   zjax.scipy.fft.idct: norm=r9   r   r7   r;   r:   )r   r<   r=   r   r-   r   r>   r   r?   r)   r,   r*   r
   r2   r+   rA   r   astyper@   ifft_dct_deinterleaverB   )
r!   rC   rD   r"   rE   r1   r   r   w4r/   s
             r   ri   ri      s   @ vq!!	QY
?
@@	$&;;
1D94GH
II	4	($]399Q(-) !t)Q&A> )	*A ggdm!a "!	\TZ'4 Aa!	oocjj!''2aff4[1QRVZQZQ4[\!
1Qx"hhrxx!3q!9o!!eai!ll14 !!&&$'#	*%) 5\s   #F>;
G
G
c                   t        d|       } |dk7  rt        d      ||dvrt        d|d      |	 t        |      }t        || j                        }t        |      dk(  rt        | ||d	   nd|d	   |
      S |t        t        ||            }t        | j                        D cg c]   }d	||v r||   | j                   |   z
  nd	d	f" }}t#        j$                  | t'        j(                  d	| j*                        |      } |D ]  }t        | ||      }  | S # t        $ r, t        |t              rJ t        j                  |      g}Y w xY wc c}w )a	  Computes the multidimensional inverse discrete cosine transform of the input

  JAX implementation of :func:`scipy.fft.idctn`.

  Args:
    x: array
    type: integer, default = 2. Currently only type 2 is supported.
    s: integer or sequence of integers. Specifies the shape of the result. If not
      specified, it will default to the shape of ``x`` along the specified ``axes``.
    axes: integer or sequence of integers. Specifies the axes along which the
      transform will be computed.
    norm: string. The normalization mode: one of ``[None, "backward", "ortho"]``.
      The default is ``None``, which is equivalent to ``"backward"``.

  Returns:
    array containing the inverse discrete cosine transform of x

  See Also:
    - :func:`jax.scipy.fft.dct`: one-dimensional DCT
    - :func:`jax.scipy.fft.dctn`: multidimensional DCT
    - :func:`jax.scipy.fft.idct`: one-dimensional inverse DCT

  Examples:

    ``jax.scipy.fft.idctn`` computes the transform along both the axes by default
    when ``axes`` argument is ``None``.

    >>> x = jax.random.normal(jax.random.key(0), (3, 3))
    >>> with jnp.printoptions(precision=2, suppress=True):
    ...    print(jax.scipy.fft.idctn(x))
    [[ 0.12  0.11 -0.15]
     [ 0.07  0.17 -0.03]
     [ 0.19 -0.07 -0.02]]

    When ``s=[2]``, dimension of the transform along ``axis 0`` will be ``2``
    and dimension along ``axis 1`` will be the same as that of input.

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...  print(jax.scipy.fft.idctn(x, s=[2]))
    [[ 0.15  0.21 -0.18]
     [ 0.24 -0.01 -0.02]]

    When ``s=[2]`` and ``axes=[1]``, dimension of the transform along ``axis 1`` will
    be ``2`` and dimension along ``axis 0`` will  be same as that of input.
    Also when ``axes=[1]``, transform will be computed only along ``axis 1``.

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...  print(jax.scipy.fft.idctn(x, s=[2], axes=[1]))
    [[ 1.12 -0.31]
     [ 0.04 -0.08]
     [ 0.05 -0.3 ]]

    When ``s=[2, 4]``, shape of the transform will be ``(2, 4)``

    >>> with jnp.printoptions(precision=2, suppress=True):
    ...  print(jax.scipy.fft.idctn(x, s=[2, 4]))
    [[ 0.1   0.18  0.07 -0.16]
     [ 0.2   0.06 -0.03 -0.01]]

    ``jax.scipy.fft.idctn`` can be used to reconstruct ``x`` from the result
    of ``jax.scipy.fft.dctn``

    >>> x_dctn = jax.scipy.fft.dctn(x)
    >>> jnp.allclose(x, jax.scipy.fft.idctn(x_dctn))
    Array(True, dtype=bool)
  r4   r   r5   Nr6   zjax.scipy.fft.idctn: norm=r9   r   r   rY   )r"   rE   )r   r<   r=   rZ   r[   r\   r   r]   r^   r   r-   r_   ri   r`   ra   r,   r*   r   r>   r   r?   r)   )	r!   rC   rc   rK   rE   rd   r1   re   r"   s	            r   r4   r4   P  sc   L w"!	QY
?
@@	$&;;
2TI5HI
JJ]
q'a
 
!qvv	.$Y!^Q]QqT47NN]	c$l	BBG-PQQa2g1
"1a8PDP399Q($/A  &dQT%A&	
(#  Ax(((>>!
a Qs   D +%E1EEc                   	 t        d d d       	t        	 fdt        t         j                              D              }t        	 fdt        t         j                              D              } |   }t        j                   |   f      }t        j                   j                   j                        }t        	fdt        t         j                              D              }t        	fdt        t         j                              D              }|j                  |   j                  |      }|j                  |   j                  |      }|S )Nc              3     K   | ];  }|k(  r0t        d t        j                  j                     dz        d      n = y wr   slicemathceilr*   .0rf   r"   empty_slicer!   s     r   	<genexpr>z$_dct_deinterleave.<locals>.<genexpr>  sB      $
 56IeD$))AGGDM!O,a0;N$   AAc              3     K   | ];  }|k(  r0t        t        j                  j                     d z        dd      n = yw)r   Nr   rq   ru   s     r   rx   z$_dct_deinterleave.<locals>.<genexpr>  sB      $
 56IeDIIaggdmAo&a0;N$ry   r;   c              3  F   K   | ]  }|k(  rt        d d d      n  y w)Nr   rr   rv   rf   r"   rw   s     r   rx   z$_dct_deinterleave.<locals>.<genexpr>  s,      W=>a4ieD$[8W   !c              3  F   K   | ]  }|k(  rt        d dd      n  yw)r   Nr   r|   r}   s     r   rx   z$_dct_deinterleave.<locals>.<genexpr>  s,      T:;19eAtQ+5Tr~   )rr   tupler,   r_   r*   r   r   r   zerosr)   atset)
r!   r"   ix0ix1r#   r$   r/   evensoddsrw   s
   ``       @r   rl   rl     s   dD$'+ $S\"$ 	$# 
 $S\"$ 
$# 	v"
wwqvw"		!'')#
 WBGAGGBUW W%	 T?DS\?RT 
T$			2	#t#	*r   )r   intr   r   returnr   )r!   r   r"   r   r   r   )r/   r   r"   r   r   r   )r   NN)r!   r   rC   r   rD   z
int | Noner"   r   rE   
str | Noner   r   )r!   r   rK   zSequence[int]rE   r   r   r   )r   NNN)r!   r   rC   r   rc   Sequence[int] | NonerK   r   rE   r   r   r   )"
__future__r   collections.abcr   	functoolsr   rs   r]   r   r   jax._srcr   r   jax._src.numpyr   r@   jax._src.numpy.utilr	   r
   r   jax._src.utilr   r   jax._src.typingr   r   r%   r2   rH   rW   rb   ri   r4   rl    r   r   <module>r      s   # $      ! )F F D !+)
2 26+/LL(L49L^   !!%&* ] ]#] ] &+]@ 37,0\\)\5:\~ !""&'+!a!a$a a ',aHr   