o
    Yi
                     @   s  d Z ddlZddlmZ ddlmZmZmZ ddlZ	ddl
Z
ddlmZmZ ddlmZ ddlmZ ddlmZmZmZmZmZ dd	lmZmZmZmZ dd
lmZ dd Z dd Z!dd Z"dd Z#e
j$%dddefddZ&dd Z'e
j$%dg dde(fddZ)dd Z*e
j$%d g d!d"ed# fd$d%Z+d&d' Z,d(d) Z-d*d+ Z.d,d- Z/d.d/ Z0d0d1 Z1e
j$%d2d3g d4fd5g d4fd6g d7fd8g d9fgd:efd;d<Z2e
j$%d=d>d?ge
j$%dd@dAge
j$%d:d3d8gd:efdBdCZ3dDdE Z4e
j$%d=dFdGgd=e(fdHdIZ5e
j$%dJe6dKdLdM Z7e
j$%dNg dOdNe(fdPdQZ8e
j$%dRdAdSgdTdU Z9dVdW Z:dXdY Z;dZd[ Z<d\d] Z=e
j$%d:d^d:efd_d`Z>e
j$%dadbdae(dB fdcddZ?e
j$%deg dfd=e(dge(dhe(fdidjZ@e
j$%dkdldmdn ZAdodp ZBe
j$%dqg dre
j$%dseedte(dge(dhe(due(fdvdwZCe
j$%dxdye
j$%dzd{e
j$%d|d}e
j$%d~ddxe(dze(d|e(d~eDfddZEdS )aA  Unit tests for module `_short_time_fft`.

This file's structure loosely groups the tests into the following sequential
categories:

1. Test function `_calc_dual_canonical_window`.
2. Test for invalid parameters and exceptions in `ShortTimeFFT` (until the
    `test_from_window` function).
3. Test algorithmic properties of STFT/ISTFT. Some tests were ported from
   ``test_spectral.py``.

Notes
-----
* Mypy 0.990 does interpret the line::

        from scipy.stats import norm as normal_distribution

  incorrectly (but the code works), hence a ``type: ignore`` was appended.
    N)product)castget_argsLiteral)xp_assert_closexp_assert_equal)fftshift)norm)
get_windowwelchstftistftspectrogram)FFT_MODE_TYPE_calc_dual_canonical_windowShortTimeFFTPAD_TYPE)gaussianc                  C   s0   t dddd} t| d}t|d}t||  dS )zTest dual window calculation with a round trip to verify duality.

    Note that this works only for canonical window pairs (having minimal
    energy) like a Gaussian.

    The window is the same as in the example of `from ShortTimeFFT.from_dual`.
    3   
   T)stdsymN)r   r   r   )wind_winwin2 r   M/tmp/pip-target-1s0edx8b/lib/python/scipy/signal/tests/test_short_time_fft.py*test__calc_dual_canonical_window_roundtrip$   s   

r   c                   C   s   t jtdd ttdd W d   n1 sw   Y  t jtdd ttg dd W d   n1 s;w   Y  t jtdd ttjdtd	d
 W d   dS 1 s]w   Y  dS )z6Raise all exceptions in `_calc_dual_canonical_window`.z!hop=5 is larger than window len.*match      Nz.* Transform not invertible!)g?皙?g333333?r   z"Parameter 'win' cannot be of int.*dtype   )pytestraises
ValueErrorr   nponesarrayintr   r   r   r   +test__calc_dual_canonical_window_exceptions2   s   "r-   c                
   C   s  t jtdd ttdddd W d   n1 sw   Y  t jtdd ttdtjd	d
gddd W d   n1 sBw   Y  t jtdd ttdddd W d   n1 scw   Y  t jtdd ttdddd W d   n1 sw   Y  t jtdd ttdd	dtdd W d   n1 sw   Y  t jtdd ttd
d	dttjd	d
gd W d   dS 1 sw   Y  dS )z]Verify that exceptions get raised on invalid parameters when
    instantiating ShortTimeFFT. z1Parameter win must be 1d, but win.shape=\(2, 2\)!r      r/   r    r%   hopfsNz&Parameter win must have finite entriesr/      z'Parameter hop=0 is not an integer >= 1!r   z)Parameter hop=2.0 is not an integer >= 1!       @z2dual_win.shape=\(5,\) must equal win.shape=\(4,\)!r!   )r1   r2   dual_winz*Parameter dual_win must be a finite array!)	r&   r'   r(   r   r)   r*   r+   infnanr   r   r   r   #test_invalid_initializer_parameters?   s(    "r8   c                  C   s  t tdddd} tjtdd d| _W d   n1 sw   Y  tjtd	d d| _W d   n1 s9w   Y  tjtd
d d| _W d   n1 sSw   Y  tjtdd d| _W d   n1 smw   Y  tjtdd d| _	W d   n1 sw   Y  tjtdd | 
d W d   n1 sw   Y  tjtdd d| _W d   n1 sw   Y  tjtdd d| j	 | _W d   n1 sw   Y  tjtdd | jtdddddd}t| W d   n	1 sw   Y  tjtdd | jtddd W d   n	1 s%w   Y  tjtdd | jtdtjd W d   n	1 sHw   Y  tjtdd | ddd W d   n	1 sgw   Y  tjtd d | jt| jdfddd! W d   n	1 sw   Y  tjtd"d | td# W d   n	1 sw   Y  tjtd$d | t| jdf W d   n	1 sw   Y  tjtd%d | jt| jd&fdd' W d   n	1 sw   Y  tjtd(d | jt| jd&fddd) W d   n	1 sw   Y  tjtd*d | jddd+ W d   n	1 s:w   Y  tjtd,d d-| _| jdd. W d   dS 1 s\w   Y  dS )/zwVerify that exceptions get raised when setting properties or calling
    method of ShortTimeFFT to/with invalid values.   r    r%   r0   z(Sampling interval T=-1 must be positive!r   Nz*Sampling frequency fs=-1 must be positive!zSfft_mode='invalid_typ' not in \('twosided', 'centered', 'onesided', 'onesided2X'\)!invalid_typz7For scaling is None, fft_mode='onesided2X' is invalid.*
onesided2Xz9Attribute mfft=7 needs to be at least the window length.*   zscaling='invalid' not in.*invalidzphase_shift=3.0 has the unit .*g      @z*-mfft < phase_shift < mfft does not hold.*r/   z!Parameter padding='invalid' not.*   r   )k_offp0p1paddingz)Trend type must be 'linear' or 'constant')detrz2Parameter detr=nan is not a str, function or None!z Invalid Parameter p0=0, p1=200.*d      z&f_axis=0 may not be equal to t_axis=0!)t_axisf_axisz3S.shape\[f_axis\]=2 must be equal to self.f_pts=5.*r.   z5S.shape\[t_axis\]=1 needs to have at least 2 slices.*z'.*\(k1=100\) <= \(k_max=12\) is false!$r3   k1z6\(k1=1\) - \(k0=0\) = 1 has to be at least.* length 4!)k0rJ   z3Parameter axes_seq='invalid' not in \['tf', 'ft'\]!)naxes_seqz"Attribute fft_mode=twosided must.*twosided)rL   )r   r)   r*   r&   r'   r(   Tr2   fft_modemfftscale_tophase_shift	_x_sliceszerosnextstft_detrendr7   p_ranger   f_ptsextent)SFTgr   r   r   "test_exceptions_properties_methodsX   sx   
$r]   m)onesidedr<   c                 C   sN  t jtd|  dd ttdd dd| d W d	   n1 s#w   Y  ttdd ddd
d}t jtd|  dd | |_W d	   n1 sNw   Y  ttdddddd}t jtdd |tdd  W d	   n1 s{w   Y  d|_t jtdd |tdd  W d	   d	S 1 sw   Y  d	S )zVerify that one-sided spectra are not allowed with complex-valued
    windows or with complex-valued signals.

    The reason being, the `rfft` function only accepts real-valued input.
    z#One-sided spectra, i.e., fft_mode='z'.*r   r9                 ?r    r%   r1   r2   rP   NrN   psdr_   r1   r2   rR   rP   z)Complex-valued `x` not allowed for self.*r<   )r&   r'   r(   r   r)   r*   rP   r   )r^   r[   r   r   r   $test_exceptions_fft_mode_complex_win   s&   

"rd   c                  C   s   t tdddd} d| _tt | j}W d   n1 s w   Y  tt | td W d   n1 s=w   Y  tt | 	td W d   dS 1 s[w   Y  dS )zBEnsure exception gets raised when property `fft_mode` is invalid. r9   r    r%   r0   r;   N)
r   r)   r*   	_fft_moder&   r'   RuntimeErrorf	_fft_func
_ifft_func)r[   _r   r   r   "test_invalid_fft_mode_RuntimeError   s   "rk   zwin_params, Nx)))r   r4   	   )triangr=   ))kaiser      @rl   ))exponentialN      ?rl   )ro   rl   Nxc              
      s(  t | |ddd}}t | |dd}t|d|dddd	}t|}||j }tj| |||ddddd
}tj| |||ddddd
}	t|j|j t|	j|t	t
|d |   dD ]9  fdd|||	fD \}
}}||
ks}J d  d| d  d|
 ||
ksJ d  d| d  d|
 qXdS )zVerify that `from_window()` handles parameters correctly.

    The window parameterizations are documented in the `get_window` docstring.
    F)fftbinsg      0@Tr3   rN   rb   r%   )r1   r2   rP   rR   rS   )symmetric_winrP   rR   rS   r/   )r1   rO   rP   rQ   scalingrS   c                 3   s    | ]}t | V  qd S )N)getattr).0SFT_n_r   r   	<genexpr>   s    z#test_from_window.<locals>.<genexpr>zSFT1.=z does not equal SFT0.zSFT2.N)r
   r   lenr1   from_windowr   r   r   r)   sqrtsum)
win_paramsrr   w_symr2   w_perSFT0npersegnoverlapSFT1SFT2v0v1v2r   ry   r   test_from_window   s,   


"(*r   c                  C   sP   t ddddddd} ttdfi | }tj|jfi | }t|j|j dS )zVerify the duality of `win` and `dual_win`.

    Note that this test does not work for arbitrary windows, since dual windows
    are not unique. It always works for invertible STFTs if the windows do not
    overlap.
    r    r%   rN   r9   Nr/   )r1   r2   rP   rQ   rR   rS   )dictr   r)   r*   	from_dualr5   r   r   )kwr   r   r   r   r   test_dual_win_roundtrip   s   r   zscale_to, fac_psd, fac_mag))N      ?      ?)	magnituder4   r%   )rb   r%         ?rR   r   rb   c           
      C   s   t tdd dd| d}|j|ksJ |j|ksJ |j|ks"J |j|ks)J tjg d}||}||j ||j }}|d |j	|t
|d}t|| |d |j	|t
|d}	t|	| d	S )
zVerify scaling calculations.

    * Verify passing `scale_to`parameter  to ``__init__().
    * Roundtrip while changing scaling factor.
    r    r/   r%   r1   r2   rR   )r   r   r=   r   r   r   r   r   rI   rb   N)r   r)   r*   fac_psdfac_magnitudefftirfftr   rR   r   r}   r   )
rR   r   fac_magr[   xSxSx_magSx_psdx_magx_psdr   r   r   test_scaling   s   




r   c                  C   s   t tdd dddd} | d | jdksJ | jdks J | jdks'J | d | jdks3J | jdks:J | jd	ksAJ | d td
dD ](\}}t tdd dddd} | j	 }| t
td
 | t| j||  qKdS )zVerify `scale_to()` method.r    r/   r%   Nr   r   r4   rb   r   r   )r9   r    )r   r)   r*   rR   ru   r   r   zipr5   copyr   r   r   )r[   scales_facr5   r   r   r   test_scale_to  s    



r   c               	   C   s  t tdddd} tjg dg dgtd}g dg d	gg d
g dggg dg d	gg dg dggg dg dgg dg dggg dg dgg dg dggd}| D ]1\}}| jt|dddtt|d}tdd |D }tj	|tj
d}t||d| dd qZd S )!zVerify padding.

    The reference arrays were taken from  the docstrings of `zero_ext`,
    `const_ext`, `odd_ext()`, and `even_ext()` from the _array_tools module.
    r!   r    r%   r0   )r%   r/   r3   r    r!   )r   r%   r    rl   r?   r#   )r   r   r%   r/   r3   )r   r   r   r%   r    )r3   r    r!   r   r   )r    rl   r?   r   r   )r%   r%   r%   r/   r3   )r3   r    r!   r!   r!   )r    rl   r?   r?   r?   )r3   r/   r%   r/   r3   )r    r%   r   r%   r    )r3   r    r!   r    r3   )r    rl   r?   rl   r    )r:   r   r%   r/   r3   )r:   r   r%   r    )r3   r    r!      r=   )r    rl   r?         )rU   edgeevenoddr   r/   rC   c                 S   s   g | ]}|  qS r   )r   )rw   y_r   r   r   
<listcomp>8  s    z)test_x_slices_padding.<locals>.<listcomp>zFailed 'z
' padding.err_msgN)r   r)   r*   r+   floatitemsrT   r   r   asarrayfloat64r   )r[   r   dp_xxgenyyr   r   r   test_x_slices_padding&  s*    r   c                  C   s@   t tdddd} | jsJ t tdddd} | jrJ dS )zVerify `invertible` property. r9   r    r%   r0   rl   N)r   r)   r*   
invertibler[   r   r   r   test_invertible=  s   
r   c                  C   s   t tdddd} | jdksJ | jdksJ | jdksJ | jdks&J | ddks/J | dd	ks8J | dd
ksAJ t	j
tdd | d W d   n1 sXw   Y  t	j
tdd | d W d   dS 1 suw   Y  dS )z=Ensure that minimum and maximum values of slices are correct.r9   r    r%   r0   r   r   )r    r%   r   r?   )r    r/   z^Parameter n must ber   r3   N)r   r)   r*   p_mink_minlower_border_endp_maxk_maxupper_border_beginr&   r'   r(   _post_paddingr   r   r   r   test_border_valuesE  s   "r   c                  C   s  t g d} t| ddd}|jdksJ tt | ddd}|ddks(J |ddks1J |d	d
ks:J |dd
ksCJ |dd
ksLJ d|_tt	 |
d}W d   n1 sdw   Y  tt	 |j}W d   dS 1 s}w   Y  dS )zLEnsure that the border calculations are correct for windows with
    zeros. )r   r   r   r   r   r   r   rq   r%   r0   )r   r      r    )r?   r%   r!   r   )$   r/         r:   N)r)   r+   r   r   flipr   _hopr&   r'   rf   r   r   )wr[   rj   r   r   r   test_border_values_exoticU  s    "r   c                  C   s   t tdddd} | jdksJ | jdksJ | jdksJ td| d| j }t| 	d| t| 	dd	d
|d	d
  d| _| jdksKJ | jdksRJ d| _| jdks\J | jdkscJ dS )z1Verify that the times of the slices are correct. r9   r    r/   r0   r   r4   r   r   r%   r3   r   r   N)
r   r)   r*   rO   r2   delta_taranger   r   t)r[   t_stftr   r   r   test_tj  s   r   zfft_mode, fr_   )        rq   r4   r<   rN   )r   rq   r4                centered)r   r   r   rq   r4   rP   c                 C   s(   t tddd| dd}t|j| dS )z)Verify the frequency values property `f`.r!   r    rb   )r1   r2   rP   rR   N)r   r)   r*   r   rg   )rP   rg   r[   r   r   r   test_f{  s   r   rL   r      r!   r   c                 C   s
  t t||||d}|| d }|| d |j }||jd  ||jd  }}|jd }|jd |j }	||jd  |	|jd  }
}|| dd||||	fksVJ || dd||	||fkseJ || dd|||
|fkstJ || dd|
|||fksJ d	S )
z.Ensure that the `extent()` method is correct. ra   r   r:   r/   tfFftTN)r   r)   r*   r   r   rg   delta_frZ   )rL   r^   rP   r[   t0t1t0ct1cf0f1f0cf1cr   r   r   test_extent  s   
"r   c                  C   s~   t tdddd} tdtd}}| || |}}t| ||jd |jd   t| ||||	   dS )z2Verify spectrogram and cross-spectrogram methods. r9   r    r%   r0   r   r/   N)
r   r)   r*   r   r   r   r   realimagconj)r[   r   yXYr   r   r   test_spectrogram  s
    r   r9   rl   c                 C   sr  t jd t j| }t | d}}tttd| | d | d gg dd|  d d| d | d gd}t|	  D ]=\}}}}|d	krI|du rIq:t
||| ||||d
}	|	|}
|	|
}t||j|dd|d|d|d| d q:t
||dd}	d|	_tt |	| W d   n1 sw   Y  tt |	| W d   dS 1 sw   Y  dS )z^Test roundtrip `ifft_func(fft_func(x)) == x` for all permutations of
    relevant parameters. i$ r    Nr%   r/   )Nr   rb   r   )rP   rQ   ru   rS   r<   )r2   rP   rQ   rR   rS   z!_fft_func() roundtrip failed for zf_typ=z, mfft=z
, scaling=z, phase_shift=r   r2   invalid_fft)r)   randomseedrandr*   r   r   r   r   valuesr   rh   ri   r   astyper$   re   r&   r'   rf   )rL   x0r   h_nppf_typrQ   ru   rS   r[   X0x1r   r   r   test_fft_func_roundtrip  s<   

"r   i   c                 C   s  d}t dd}}t |}d|| < t||dddd}||}||d }|j|d| dd	}|j||d dd	}	||d |j }
|jd |j }t	|ddd|
f |ddd|
f d
| d t	|	dd|df |dd||	j
d  df d
| d t |ddd|
f |dd|
df |	ddd|f  |	dd|df f}t	||dd
| d ||d|}t	||dd
| d ||d|d }t	|d|d  |dd
| d |||d |}t	||d d |dd
| d dS )z:Roundtrip for an impulse being at different positions `i`.r   r9   r3   r%   N)r1   r2   rR   rS   r/   rU   r   zi=r   g:0yE>atolr   r   )r)   r*   rU   r   r   nearest_k_pr   r   r   r   shapehstackr   )r   rL   r   r   r   r[   r   n_qSx0Sx1q0_ubq1_leSx01r   y0y1r   r   r   test_impulse_roundtrip  s4   

40&"&r  r1   )r%   r=   r9   c                 C   s   t jd t dd }d|t|d d< t|| dd}dt jd	 }||}|j|t|d
}t	||dd| d d dS )z6An asymmetric window could uncover indexing problems. iK[  r?   r9   r%   r/   Nr   r   @   rI   z%Roundtrip for asymmetric window with z hop= failed!r   )
r)   r   r   r   r}   r   randnr   r   r   )r1   r   r[   r   r   r   r   r   r    test_asymmetric_window_roundtrip  s   

r  m_numr=   c                 C   s&  t t| | d dd}t| d }t|}||}|j||d}t||d|dd|  d d	 tj	t
d
|d  dd ||dd  W d   n1 sVw   Y  tj	t
d|jd d  d|jd  dd |j|ddddf |d W d   dS 1 sw   Y  dS )z/Verify that the shortest allowed signal works. r/   r%   r   rI   z#Roundtrip minimal length signal (n=)z for z sample window failed!r   z	len\(x\)=z must be >= ceil.*r   Nr:   zS.shape\[t_axis\]=z needs to have at least z slices)r   r)   r*   mathceilr   r   r   r&   r'   r(   r  )r  r[   rL   r   r   r   r   r   r   test_minimal_length_signal  s    


 "r  c                  C   s*  t tdddd} | jdksJ d| j| jdks%J d| jd	| jd
ks3J d| jd| j\}}|dksDJ d|d|dksPJ d|dd}| | }dkscJ d|d| | }dkstJ d|d| 	|\}}|dksJ d|d|dksJ d|ddS ) aH  Verify example in "Sliding Windows" subsection from the "User Guide".

    In :ref:`tutorial_stft_sliding_win` (file ``signal.rst``) of the
    :ref:`user_guide` the behavior the border behavior of
    ``ShortTimeFFT(np.ones(6), 2, fs=1)`` with a 50 sample signal is discussed.
    This test verifies the presented indexes.
    r   r/   r%   r   r3   z(Slice middle is not 3 but SFT.m_num_mid=r:   zLowest slice SFT.p_min=z
 is not -1zLowest slice sample SFT.p_min=z
 is not -5zFirst unaffected slice p_lb=z	 is not 2r!   zFirst unaffected sample k_lb=z	 is not 52      zLast slice p_max=z must be 277   zLast sample k_max=z must be 55r   zFirst upper border slice p_ub=z must be 24-   zFirst upper border slice k_ub=z must be 45N)
r   r)   r*   	m_num_midr   r   r   r   r   r   )r[   k_lbp_lbrL   r   r   k_ubp_ubr   r   r   test_tutorial_stft_sliding_win  s   
""r   c               	   C   s\  d\} }t ||  }t dt j d |d|d    }d\}}dd|  f}t|| |||d	d
d\}}}	t|	dd}
tj|| ||dddd}||}t|
|ddddf  tt	|dddf 
 t	|dddf  fd t|	| |||d	d
d\}}|j||d}t||d ksJ t|d| | t|| t||t	|d  dS )zVerify STFT example in "Comparison with Legacy Implementation" from the
    "User Guide".

    In :ref:`tutorial_stft_legacy_stft` (file ``signal.rst``) of the
    :ref:`user_guide` the legacy and the new implementation are compared.
    rF   i                 @F   r"   r/   r  (   r   {Gz?Fspectrum)return_onesidedru   r   axesr   r   NrP   rR   rS   r:   r%   )g<>g(!Gڪ>)input_onesidedru   rI   rl   )r)   r   exppir   r   r   r~   r   absminmaxr   r}   r   )r2   Nt_zzr   r   r   f0_ur   Sz0_uSz0r[   Sz1t0_rz0_rz1_rr   r   r   test_tutorial_stft_legacy_stft!  s4   $
0

r<  c                  C   s   d\} }t ||  }t dt j d |d|d    }d\}}dd|  f}t|| |||d	d
ddd	\}}}	t|t|	dd}
}tj|| ||ddd	d}|j|d|| |j	 |d d}|j
|d|| |j	 |d d}t|| t|
|j t|| d	S )zVerify spectrogram example in "Comparison with Legacy Implementation"
    from the "User Guide".

    In :ref:`tutorial_stft_legacy_stft` (file ``signal.rst``) of the
    :ref:`user_guide` the legacy and the new implementation are compared.
    r!  r"  r#  r"   r/   r$  r   r&  NFr'  complex)detrendr(  ru   moder   r)  r   r   r+  )rA   rB   k_offset)r)   r   r-  r.  r   r   r   r~   r   r1   r   r   rg   )r2   r2  r3  r4  r   r   r   f2_ut2Sz2_uf2Sz2r[   Sz3t3r   r   r   %test_tutorial_stft_legacy_spectrogramJ  s&   $  
rH  c               
   C   sV  d} t tdd d| d}tj| tjd}||}||jd ddd|jd f}t|d	d
}dt	|j
jj }tdD ]h}t|t| dddf|}|j||d}t|t|d| |j|| |d}	t|	||d |j|| ||jd d}
t|
||d t||dfd|f}t|t|d| |j|| |dd}t|||d q@dS )zJVerify correctness of four-dimensional signal by permuting its
    shape. r   r9   r3   r0   r#   r   r%   r:   )r   r:   )r:   r   r/   r    axis)rJ   rH   r   rJ   rH   rG   )rJ   rG   rH   N)r   r)   r*   r   r   r   reshaper  moveaxisfinfor   r$   
resolutionrangerollr   r   ndim)rL   r[   r   r  SxTr   r   r   Syyb0yb1SyTybTr   r   r   test_permute_axesk  s(   
 rZ  )rN   r   r_   r<   c           	      C   s   d}t jd| d t jdd|d}ttddddd| d}|j|dd	}|j||dd
d}t||	|j
dd tt|jd t|jd D ]3\}}|j||dd|ddf |d}t|||dd|f 	|j
dd| d| d| d d qIdS )zTest roundtrip of a multidimensional input signal versus its components.

    This test can uncover potential problems with `fftshift()`.
    rl   r    r/   r#   hannr%   r   rc   rI  r:   rL  zMultidim. roundtrip failed!r   r   NrI   z"Multidim. roundtrip for component zx[z, :, z] and fft_mode=r  )r)   r   r   rM  r   r
   r   r   r   r   r$   r   rQ  r  )	rP   rL   r   r[   r   r   r   jr   r   r   r   test_roundtrip_multidimensional  s    "&"r]  rS   )r   r    Nc                 C   sp   d}t jddddd| d}tjd| td	d|}||}|j||d
}t||dt	|j
jj dd dS )zTest roundtrip of a 2 channel input signal with `mfft` set with different
    values for `phase_shift`

    Tests for Issue https://github.com/scipy/scipy/issues/21671
    r   r[  r%      r=   r?   )r2   r   r   rQ   rS   r/   r#   rI   z2-dim. roundtrip failed!r   N)r   r~   r)   r   r   rM  r   r   r   rO  r   r$   rP  )rS   rL   r[   r   r   r   r   r   r   test_roundtrip_two_dimensional  s   

r_  zwindow, n, nperseg, noverlap))boxcarrE   r   r   )r`  rE   r   rl   )bartlette   r      )r[           )tukeyr     re  r  )r[  rd  re     )r`  rE   r   r3   )ra  rb  r   %   )r[  rd  re     )rg  ri  re     )r[  rd  re  r!   r   r   c                 C   s  t jd t| |}t||| dddd}dt j| dt j|  }||}|j|t|d}t	||d	d
 dt j| }	||	}
|j|
t|d}t	|	
t j|dd
 |	
t j}||}|j|t|d}|j}t	||
t jdd
 t	|jt |jdd
 dS )zRoundtrip test adapted from `test_spectral.TestSTFT`.

    The parameters are taken from the methods test_roundtrip_real(),
    test_roundtrip_nola_not_cola(), test_roundtrip_float32(),
    test_roundtrip_complex().
    i$ r%   rN   N)r2   rP   rS   r   y              $@rI   z#Roundtrip for complex values failedr   z!Roundtrip for float values failedz(Roundtrip for 32 Bit float values failed)r)   r   r   r
   r   r  r   r   r}   r   r   
complex128float32r   r   
zeros_like)windowrL   r   r   r   r[   r4  Szz1r   r   r   x32Sx32x32_1x32_1_rr   r   r   test_roundtrip_windows  s2   
 



rx  signal_type)r   r=  c                 C   s   t jd t dt dt jd }t|dddd}d	t jd
 }| dkr-|d|  }||}|j	|t
|d}t|t j|dd dS )zTest roundtrip for complex-valued window function

    The purpose of this test is to check if the dual window is calculated
    correctly for complex-valued windows.
    i r"  r   r9   r3   r%   rN   )r2   rP   r      r=  rI   z*Roundtrip for complex-valued window failedr   N)r)   r   r   r-  linspacer.  r   r  r   r   r}   r   r   rn  )ry  r   r[   r4  rr  rs  r   r   r   test_roundtrip_complex_window  s   

r|  c            	   	   C   s   t jd} d}d}d\}}t| ||||\}}tj||||dddd}|j| d	d
t| | |j |d d}t	|j
| t	t j|dd| dS )zCompare `welch` function with stft mean.

    Ported from `TestSpectrogram.test_average_all_segments` from file
    ``test__spectral.py``.
    rd  rq   )rh  r   )r?   r/   r<   rb   Nr+  constantr   r/   )rD   rA   rB   r@  r:   rI  )r)   r   r  r   r   r~   r   r}   r1   r   rg   mean)	r   r2   rq  r   r   fwPwr[   Pr   r   r   test_average_all_segments  s   
r  z"window, N, nperseg, noverlap, mfft))r[  rd  re  rf  i   )r[  rd  re  rf  i  )r`  rE   r   r   !   )rg  ri  re  r  rd  )r`  rb  r   r   N)r[    re  rf  N)r`  rE   r   r   N)r`  rE   r   rl   NrC   r2  rQ   c                 C   s   t j|dd}|tdtj d  }tj| d||d|d}|j||d}	|j|	|d	}
t	|
|
tjd
| dd |j||d}|j||d	}t	||dd| d d dS )an  Test the parameter 'padding' of `stft` with roundtrips.

    The STFT parametrizations were taken from the methods
    `test_roundtrip_padded_FFT`, `test_roundtrip_padded_signal` and
    `test_roundtrip_boundary_extension` from class `TestSTFT` in  file
    ``test_spectral.py``. Note that the ShortTimeFFT does not need the
    concept of "boundary extension".
    i]  )sizerandom_stater`   r    r%   rN   )rP   rQ   r   rI   zFailed real roundtrip with 'z	' paddingr   zFailed complex roundtrip with z 'N)normal_distributionrvsr)   r-  r.  r   r~   r   r   r   r   rn  )rq  r2  r   r   rQ   rC   r   r4  r[   r   r   rr  rs  r   r   r   test_stft_padding_roundtrip  s   

r  N_x)rf     rj  re  i9  w_size)rf  re  t_step)r    r  f_c)g      @g      7@c                 C   s  t t d|d | t j }t||dddd}dt |jj }t| |} t | 	t j
}t dt j | | |j }t ||d g}||}	|j|	| d}
|jt t jt |	d	 d d
d }|	jd
 |jksrJ t |jdks|J t || dk sJ t||
|d t j|d dd|j }|	jd |	jjd  }t jt j|dd|j dd|j }t|||d t jd t jd| }||}	|j|	| d}
|	jd
 |jksJ t |jdksJ t || dk sJ t||
|d t j|d dd|j }|	jd |	jjd  }t jt j|dd|j dd|j }t|||d t d	| f}||}	|j|	| d}
|
j|jksIJ dS )as  Test if a `psd`-scaled STFT conserves the L2 norm.

    This test is adapted from MNE-Python [1]_. Besides being battle-tested,
    this test has the benefit of using non-standard window including
    non-positive values and a 2d input signal.

    Since `ShortTimeFFT` requires the signal length `N_x` to be at least the
    window length `w_size`, the parameter `N_x` was changed from
    ``(127, 128, 255, 256, 1337)`` to ``(128, 129, 255, 256, 1337)`` to be
    more useful.

    .. [1] File ``test_stft.py`` of MNE-Python
        https://github.com/mne-tools/mne-python/blob/main/mne/time_frequency/tests/test_stft.py
    r   r  r<   rb   )r2   rP   rR   r/   rq   rI   r   r%   rI  r   rK  r:   iۂ$ N)r)   sinr   r.  r   rO  r$   rP  r1  r   r   rO   r+   r   r   rg   argmaxr   r/  r  rY   allr   r   r   r   r   r   r   r  rU   )r  r  r  r  rq  r[   r   r   r   r   xpmax_freqE_xaX2E_Xr   r   r   test_energy_conservation/  sH    


($
$
r  )F__doc__r  	itertoolsr   typingr   r   r   numpyr)   r&   scipy._lib._array_apir   r   	scipy.fftr   scipy.statsr	   r  scipy.signalr
   r   r   r   r   scipy.signal._short_time_fftr   r   r   r   scipy.signal.windowsr   r   r-   r8   r]   markparametrizerd   rk   r,   r   r   r   r   r   r   r   r   r   r   r   r   r   rQ  r  r  r  r   r<  rH  rZ  r]  r_  rx  r|  r  r  r   r  r   r   r   r   <module>   s    D



	
 
)!"
&