
    `iZ                         d Z ddlZddlZddlmc mc mZ ddlm	Z	m
Z
mZmZmZ ddlmZ d Zd ZdZ ej        edd	d
g          Zd Z	 	 	 	 	 	 	 	 	 	 	 	 ddZd Zd Zd ZdS )a  
Spectral analysis functions and utilities.

Some of the functions defined here were ported directly from CuSignal under
terms of the MIT license, under the following notice:

Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
    N)odd_exteven_extzero_ext	const_ext_as_strided)
get_windowc                 4    t          j        |           j        S N)cupydtypename)r   s    u/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/cupyx/scipy/signal/_spectral_impl.py_get_raw_typenamer   &   s    :e!!    c                     d |D             }d                     |          }|r| d| n|}|                     |          }|S )Nc                 6    g | ]}t          |j                  S  )r   r   ).0args     r   
<listcomp>z(_get_module_func_raw.<locals>.<listcomp>+   s#    IIIC$SY//IIIr   _)joinget_function)module	func_nametemplate_argsargs_dtypestemplatekernel_namekernels          r   _get_module_func_rawr!   *   s[    II=IIIKxx$$H/<KY+++++)K  --FMr   a>  

///////////////////////////////////////////////////////////////////////////////
//                            LOMBSCARGLE                                    //
///////////////////////////////////////////////////////////////////////////////

template<typename T>
__device__ void _cupy_lombscargle_float( const int x_shape,
                                         const int freqs_shape,
                                         const T *__restrict__ x,
                                         const T *__restrict__ y,
                                         const T *__restrict__ freqs,
                                         T *__restrict__ pgram,
                                         const T *__restrict__ y_dot ) {

    const int tx { static_cast<int>( blockIdx.x * blockDim.x + threadIdx.x ) };
    const int stride { static_cast<int>( blockDim.x * gridDim.x ) };

    T yD {};
    if ( y_dot[0] == 0 ) {
        yD = 1.0f;
    } else {
        yD = 2.0f / y_dot[0];
    }

    for ( int tid = tx; tid < freqs_shape; tid += stride ) {

        T freq { freqs[tid] };

        T xc {};
        T xs {};
        T cc {};
        T ss {};
        T cs {};
        T c {};
        T s {};

        for ( int j = 0; j < x_shape; j++ ) {
            sincosf( freq * x[j], &s, &c );
            xc += y[j] * c;
            xs += y[j] * s;
            cc += c * c;
            ss += s * s;
            cs += c * s;
        }

        T c_tau {};
        T s_tau {};
        T tau { atan2f( 2.0f * cs, cc - ss ) / ( 2.0f * freq ) };
        sincosf( freq * tau, &s_tau, &c_tau );
        T c_tau2 { c_tau * c_tau };
        T s_tau2 { s_tau * s_tau };
        T cs_tau { 2.0f * c_tau * s_tau };

        pgram[tid] = ( 0.5f * ( ( ( c_tau * xc + s_tau * xs ) *
                                  ( c_tau * xc + s_tau * xs ) /
                                  ( c_tau2 * cc + cs_tau * cs + s_tau2 * ss ) ) +
                                ( ( c_tau * xs - s_tau * xc ) *
                                  ( c_tau * xs - s_tau * xc ) /
                                  ( c_tau2 * ss - cs_tau * cs + s_tau2 * cc ) ) ) ) *
                     yD;
    }
}

extern "C" __global__ void __launch_bounds__( 512 ) _cupy_lombscargle_float32(
        const int x_shape, const int freqs_shape, const float *__restrict__ x,
        const float *__restrict__ y, const float *__restrict__ freqs,
        float *__restrict__ pgram, const float *__restrict__ y_dot ) {
    _cupy_lombscargle_float<float>( x_shape, freqs_shape, x, y,
                                    freqs, pgram, y_dot );
}

template<typename T>
__device__ void _cupy_lombscargle_double( const int x_shape,
                                          const int freqs_shape,
                                          const T *__restrict__ x,
                                          const T *__restrict__ y,
                                          const T *__restrict__ freqs,
                                          T *__restrict__ pgram,
                                          const T *__restrict__ y_dot ) {

    const int tx { static_cast<int>( blockIdx.x * blockDim.x + threadIdx.x ) };
    const int stride { static_cast<int>( blockDim.x * gridDim.x ) };

    T yD {};
    if ( y_dot[0] == 0 ) {
        yD = 1.0;
    } else {
        yD = 2.0 / y_dot[0];
    }

    for ( int tid = tx; tid < freqs_shape; tid += stride ) {

        T freq { freqs[tid] };

        T xc {};
        T xs {};
        T cc {};
        T ss {};
        T cs {};
        T c {};
        T s {};

        for ( int j = 0; j < x_shape; j++ ) {

            sincos( freq * x[j], &s, &c );
            xc += y[j] * c;
            xs += y[j] * s;
            cc += c * c;
            ss += s * s;
            cs += c * s;
        }

        T c_tau {};
        T s_tau {};
        T tau { atan2( 2.0 * cs, cc - ss ) / ( 2.0 * freq ) };
        sincos( freq * tau, &s_tau, &c_tau );
        T c_tau2 { c_tau * c_tau };
        T s_tau2 { s_tau * s_tau };
        T cs_tau { 2.0 * c_tau * s_tau };

        pgram[tid] = ( 0.5 * ( ( ( c_tau * xc + s_tau * xs ) *
                                 ( c_tau * xc + s_tau * xs ) /
                                 ( c_tau2 * cc + cs_tau * cs + s_tau2 * ss ) ) +
                               ( ( c_tau * xs - s_tau * xc ) *
                                 ( c_tau * xs - s_tau * xc ) /
                                 ( c_tau2 * ss - cs_tau * cs + s_tau2 * cc ) ) ) ) *
                     yD;
    }
}

extern "C" __global__ void __launch_bounds__( 512 ) _cupy_lombscargle_float64(
        const int x_shape, const int freqs_shape, const double *__restrict__ x,
        const double *__restrict__ y, const double *__restrict__ freqs,
        double *__restrict__ pgram, const double *__restrict__ y_dot ) {

    _cupy_lombscargle_double<double>( x_shape, freqs_shape, x, y, freqs,
                                      pgram, y_dot );
}
)z
-std=c++11_cupy_lombscargle_float32_cupy_lombscargle_float64)codeoptionsname_expressionsc                     t           j                                        }|j        d         dz  }d}t	          t
          d|           }| j        d         |j        d         | ||||f}	 ||f|f|	           d S )NMultiProcessorCount   i   _cupy_lombscargler   )r   cudaDevice
attributesr!   LOMBSCARGLE_MODULEshape)
xyfreqspgramy_dot	device_id
num_blocksblock_szlombscargle_kernelargss
             r   _lombscargler:      s    	  ""I%&;<rAJH-/4 4 GAJA1eUEBD
}xk488888r         ?hannconstantTdensitypsdFc           	      >  
 |dvrt          d| d          t          t          t          t          dd}||vrBt          d                    |t          |                                                              || u }|s|dk    rt          d          t          
          
t          j
        |           } |s5t          j
        |          }t          j        | |t          j                  }nt          j        | t          j                  }|st          | j                  }t          |j                  }|                    
           |                    
           	 t          j        t          j        |          t          j        |                    j        }n# t           $ r t          d	          w xY w|rV| j        d
k    rJt          j        | j                  t          j        | j                  t          j        | j                  fS nn| j        d
k    s|j        d
k    rX|t%          | j        
         |j        
         g          fz   }t          j        t          j        |          d
          }|||fS | j        dk    rc
dk    r]t          j        | 
t+          | j                            } |s3|j        dk    r(t          j        |
t+          |j                            }|s| j        d         |j        d         k    r| j        d         |j        d         k     r\t          | j                  }|j        d         | j        d         z
  |d<   t          j        | t          j        |          fd          } n[t          |j                  }| j        d         |j        d         z
  |d<   t          j        |t          j        |          fd          }|$t          |          }|dk     rt          d          t1          ||| j        d                   \  }}||}n$||k     rt          d          t          |          }||dz  }nt          |          }||k    rt          d          ||z
  }|,||         } || |dz  d          } |s |||dz  d          }|r| j        d         |z
   |z  |z  }t          | j        dd                   |gz   }t          j        | t          j        |          fd          } |sJt          |j        dd                   |gz   }t          j        |t          j        |          fd          }sd }n%t3          d          sfd}n
dk    r
fd}n}t          j        |t          j                  |k    r|                    |          }|	dk    rd|||z                                  z  z  }n3|	dk    rd|                                dz  z  }nt          d|	z            |dk    rt          j        |          }|rZt          j        |           rd}t=          j        d           n1d}|s*t          j        |          rd}t=          j        d           nd}|dk    r$t          j         !                    |d|z            }n)|dk    r#t          j         "                    |d|z            }tG          | ||||||          } |s-tG          |||||||          }!t          j$        |           |!z  } n|dk    rt          j$        |           | z  } | |z  } |dk    r4|dk    r.|dz  r| dddfxx         dz  cc<   n| dddfxx         dz  cc<   t          j%        |dz  | j        d         |dz  z
  dz   ||z
            tM          |          z  }"||"|dz  |z  z  }"|                     |          } |r|dk    r| j'        } 
d
k     r
dz  
t          j        | d
          } ||"| fS ) a  
    Calculate various forms of windowed FFTs for PSD, CSD, etc.

    This is a helper function that implements the commonality between
    the stft, psd, csd, and spectrogram functions. It is not designed to
    be called externally. The windows are not averaged over; the result
    from each window is returned.

    Parameters
    ---------
    x : array_like
        Array or sequence containing the data to be analyzed.
    y : array_like
        Array or sequence containing the data to be analyzed. If this is
        the same object in memory as `x` (i.e. ``_spectral_helper(x,
        x, ...)``), the extra computations are spared.
    fs : float, optional
        Sampling frequency of the time series. Defaults to 1.0.
    window : str or tuple or array_like, optional
        Desired window to use. If `window` is a string or tuple, it is
        passed to `get_window` to generate the window values, which are
        DFT-even by default. See `get_window` for a list of windows and
        required parameters. If `window` is array_like it will be used
        directly as the window and its length must be nperseg. Defaults
        to a Hann window.
    nperseg : int, optional
        Length of each segment. Defaults to None, but if window is str or
        tuple, is set to 256, and if window is array_like, is set to the
        length of the window.
    noverlap : int, optional
        Number of points to overlap between segments. If `None`,
        ``noverlap = nperseg // 2``. Defaults to `None`.
    nfft : int, optional
        Length of the FFT used, if a zero padded FFT is desired. If
        `None`, the FFT length is `nperseg`. Defaults to `None`.
    detrend : str or function or `False`, optional
        Specifies how to detrend each segment. If `detrend` is a
        string, it is passed as the `type` argument to the `detrend`
        function. If it is a function, it takes a segment and returns a
        detrended segment. If `detrend` is `False`, no detrending is
        done. Defaults to 'constant'.
    return_onesided : bool, optional
        If `True`, return a one-sided spectrum for real data. If
        `False` return a two-sided spectrum. Defaults to `True`, but for
        complex data, a two-sided spectrum is always returned.
    scaling : { 'density', 'spectrum' }, optional
        Selects between computing the cross spectral density ('density')
        where `Pxy` has units of V**2/Hz and computing the cross
        spectrum ('spectrum') where `Pxy` has units of V**2, if `x`
        and `y` are measured in V and `fs` is measured in Hz.
        Defaults to 'density'
    axis : int, optional
        Axis along which the FFTs are computed; the default is over the
        last axis (i.e. ``axis=-1``).
    mode: str {'psd', 'stft'}, optional
        Defines what kind of return values are expected. Defaults to
        'psd'.
    boundary : str or None, optional
        Specifies whether the input signal is extended at both ends, and
        how to generate the new values, in order to center the first
        windowed segment on the first input point. This has the benefit
        of enabling reconstruction of the first input point when the
        employed window function starts at zero. Valid options are
        ``['even', 'odd', 'constant', 'zeros', None]``. Defaults to
        `None`.
    padded : bool, optional
        Specifies whether the input signal is zero-padded at the end to
        make the signal fit exactly into an integer number of window
        segments, so that all of the signal is included in the output.
        Defaults to `False`. Padding occurs after boundary extension, if
        `boundary` is not `None`, and `padded` is `True`.

    Returns
    -------
    freqs : ndarray
        Array of sample frequencies.
    t : ndarray
        Array of times corresponding to each data segment
    result : ndarray
        Array of output data, contents dependent on *mode* kwarg.

    Notes
    -----
    Adapted from matplotlib.mlab

    )r@   stftzUnknown value for mode z!, must be one of: {'psd', 'stft'}N)evenoddr=   zerosNz2Unknown boundary option '{0}', must be one of: {1}r@   z'x and y must be equal if mode is 'stft'z%x and y cannot be broadcast together.r   r?      z"nperseg must be a positive integer)input_lengthz.nfft must be greater than or equal to nperseg.   z#noverlap must be less than nperseg.)axisc                     | S r
   r   )ds    r   detrend_funcz&_spectral_helper.<locals>.detrend_func  s    Hr   __call__c                 2    t          j        | d          S )Nr?   )typerI   )	filteringdetrend)rK   rQ   s    r   rL   z&_spectral_helper.<locals>.detrend_func  s    $QW2>>>>r   c                     t          j        | d          }  |           } t          j        | t          | j                            S )Nr?   )r   rollaxislenr/   )rK   rI   rQ   s    r   rL   z&_spectral_helper.<locals>.detrend_func  s?    aT**A

A=D#ag,,777r   r>   r;   spectrumzUnknown scaling: %rrB   twosidedz9Input data is complex, switching to return_onesided=Falseonesided.)(
ValueErrorr   r   r   r   formatlistkeysintr   asarrayresult_type	complex64r/   pop	broadcastemptysizeminrS   ndimrT   concatenaterE   _triage_segmentshasattrastypesumsqrtiscomplexobjwarningswarnfftfftfreqrfftfreq_fft_helperconjarangefloatreal)#r0   r1   fswindownpersegnoverlapnfftrQ   return_onesidedscalingrI   modeboundarypaddedboundary_funcs	same_dataoutdtypexouteryouter
outershapeoutshapeemptyout	pad_shapewinnstepext_funcnaddzeros_shaperL   scalesidesr2   resultresult_ytimes#          `  `                        r   _spectral_helperr      s	   L ?""d   
 
 	
  N ~%%@GG$~224455 
 
 	
 QI DBCCCt99D 	QA 7LOO#Aq$.99#At~66 
Fagag

4

4	F
6""DJv$6$68 88= J 	F 	F 	FDEEE	F  06Q;;
17##TZ%8%8$*QW:M:MO O  6Q;;!&A++!S!'$-)G%H%H$JJH}TZ%9%92tDDHXx//vzz2::as17||44A 9!M!T3qw<<88  	E72;!'"+%%wr{QWR[(( MM	 !agbk 9	"$aI)>)>%?DD MM	 !agbk 9	"$aI)>)>%?DDg,,Q;;ABBB $FG!'"+NNNLC|	IJJJ4yya<x==7>???hE !(+HQ12... 	3GqLr222A H '"+'(50G;173B3<((D61aK!8!89CCC 	Hqwss|,,v5K !TZ%<%<!=BGGGA  	 	 	 	 Wj)) 	? 	? 	? 	? 	? 	? 
	8 	8 	8 	8 	8 	8 	8 T^,,88jj"")rS3YOO---.	J		cggii1n$.8999v~~	%   Q 	EM(   
 E $Q'' &EM0  
 
  q2v..	*		!!$B// Cw$NNF ,q#|&$? ?6""X-	6""V+
eOF
tu}}!8 	#37OOOq OOOO 3"9";!QWR[7Q;.2Gh4F b		D 1""]]8$$F  TV^^ axx	 ]62t,,F$s   %>F$ $F>c                    t          | t                    st          | t                    rE|d}||k    r*t          j        d                    ||                     |}t          | |          }nt          j        |           }t          |j
                  dk    rt          d          ||j
        d         k     rt          d          ||j
        d         }n"| ||j
        d         k    rt          d	          ||fS )
a  
    Parses window and nperseg arguments for spectrogram and _spectral_helper.
    This is a helper function, not meant to be called externally.

    Parameters
    ----------
    window : string, tuple, or ndarray
        If window is specified by a string or tuple and nperseg is not
        specified, nperseg is set to the default of 256 and returns a window of
        that length.
        If instead the window is array_like and nperseg is not specified, then
        nperseg is set to the length of the window. A ValueError is raised if
        the user supplies both an array_like window and a value for nperseg but
        nperseg does not equal the length of the window.

    nperseg : int
        Length of each segment

    input_length: int
        Length of input signal, i.e. x.shape[-1]. Used to test for errors.

    Returns
    -------
    win : ndarray
        window. If function was called with string or tuple than this will hold
        the actual array used as a window.

    nperseg : int
        Length of each segment. If window is str or tuple, nperseg is set to
        256. If window is array_like, nperseg is set to the length of the
        6
        window.
    N   zLnperseg = {0:d} is greater than input length  = {1:d}, using nperseg = {1:d}rF   zwindow must be 1-Dr?   z"window is longer than input signalr   z>value specified for nperseg is different from length of window)
isinstancestrtuplerm   rn   rY   r   r   r]   rT   r/   rX   )rx   ry   rG   r   s       r   rg   rg     s   H &# *VU";"; ?G\!!M228&,2O2O   #G))l6""sy>>Q1222#)B-''ABBB?ilGG #)A,&& -   <r   c                    |dk    r|dk    r| dt           j        f         }ni||z
  }| j        dd         | j        d         |z
  |z  |fz   }	| j        dd         || j        d         z  | j        d         fz   }
t	          | |	|
          } ||          }||z  }|dk    rt           j        j        }n|j        }t           j        j        } |||          }|S )	a/  
    Calculate windowed FFT, for internal use by
    cusignal.spectral_analysis.spectral._spectral_helper

    This is a helper function that does the main FFT calculation for
    `_spectral helper`. All input validation is performed there, and the
    data axis is assumed to be the last axis of x. It is not designed to
    be called externally. The windows are not averaged over; the result
    from each window is returned.

    Returns
    -------
    result : ndarray
        Array of FFT data

    Notes
    -----
    Adapted from matplotlib.mlab

    rF   r   .Nr?   )r/   stridesrV   )n)r   newaxisr/   r   r   ro   rv   rfft)r0   r   rL   ry   rz   r{   r   r   stepr/   r   funcs               r   rr   rr   W  s    , !||A3$% !x!7D @'JJ)CRC.D19R=$8!)B-#HHQeW=== \&!!F 6\F 
x|x}T&D!!!FMr   c                     dt          j        d| dz
  dz  dz             z  }dt          j        d|dz   z  d|z  z
            z   S )a.  
    Returns the bias of the median of a set of periodograms relative to
    the mean.

    See arXiv:gr-qc/0509116 Appendix B for details.

    Parameters
    ----------
    n : int
        Numbers of periodograms being averaged.

    Returns
    -------
    bias : float
        Calculated bias.
    rH   r;   rF   )r   rt   rj   )r   ii_2s     r   _median_biasr     sN    " t{3Q1q 0111Dtxtax(3:56666r   )r;   r<   NNNr=   Tr>   r?   r@   NF)__doc__rm   r   cupyx.scipy.signal._signaltoolsscipysignal_signaltoolsrP   cupyx.scipy.signal._arraytoolsr   r   r   r   r   #cupyx.scipy.signal.windows._windowsr   r   r!   LOMBSCARGLE_KERNEL	RawModuler.   r:   r   rg   rr   r   r   r   r   <module>r      sy   6   3 3 3 3 3 3 3 3 3 3 3 39 9 9 9 9 9 9 9 9 9 9 9 9 9 : : : : : :" " "  K \ $T^	_1134 4 4 	9 	9 	9 			B B B BJ
= = =@. . .b7 7 7 7 7r   