o
    X۷i?                     @  s   d dl m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Zejed	d
 dD dd
 dD  dZdd Zd ddZd!ddZd"ddZdd Zdd Zd!ddZd"ddZdS )#    )annotationsN)get_typename)_normalize_axis_index)lfilter)
axis_sliceaxis_assignaxis_reverse)collapse_2dapply_iir_sosa
  
#include <cupy/math_constants.h>
#include <cupy/carray.cuh>
#include <cupy/float16.cuh>  // TODO(seberg): Add this via type_headers?

template<typename T>
__device__ T _compute_symiirorder2_fwd_hc(
        const int k, const T cs, const T r, const T omega) {
    T base;

    if(k < 0) {
        return 0;
    }

    if(omega == 0.0) {
        base = cs * pow(r, ((T) k)) * (k + 1);
    } else if(omega == M_PI) {
        base = cs * pow(r, ((T) k)) * (k + 1) * (1 - 2 * (k % 2));
    } else {
        base = (cs * pow(r, ((T) k)) * sin(omega * (k + 1)) /
                sin(omega));
    }
    return base;
}

template<typename T>
__global__ void compute_symiirorder2_fwd_sc(
        const int n, const int off, const T* cs_ptr, const T* r_ptr,
        const T* omega_ptr, const double precision, bool* valid, T* out) {

    int idx = blockDim.x * blockIdx.x + threadIdx.x;
    if(idx + off >= n) {
        return;
    }

    const T cs = cs_ptr[0];
    const T r = r_ptr[0];
    const T omega = omega_ptr[0];

    T val = _compute_symiirorder2_fwd_hc<T>(idx + off + 1, cs, r, omega);
    T err = val * val;

    out[idx] = val;
    valid[idx] = err <= precision;
}

template<typename T>
__device__ T _compute_symiirorder2_bwd_hs(
        const int ki, const T cs, const T rsq, const T omega) {
    T c0;
    T gamma;

    T cssq = cs * cs;
    int k = abs(ki);
    T rsupk = pow(rsq, ((T) k) / ((T) 2.0));


    if(omega == 0.0) {
        c0 = (1 + rsq) / ((1 - rsq) * (1 - rsq) * (1 - rsq)) * cssq;
        gamma = (1 - rsq) / (1 + rsq);
        return c0 * rsupk * (1 + gamma * k);
    }

    if(omega == M_PI) {
        c0 = (1 + rsq) / ((1 - rsq) * (1 - rsq) * (1 - rsq)) * cssq;
        gamma = (1 - rsq) / (1 + rsq) * (1 - 2 * (k % 2));
        return c0 * rsupk * (1 + gamma * k);
    }

    c0 = (cssq * (1.0 + rsq) / (1.0 - rsq) /
                (1 - 2 * rsq * cos(2 * omega) + rsq * rsq));
    gamma = (1.0 - rsq) / (1.0 + rsq) / tan(omega);
    return c0 * rsupk * (cos(omega * k) + gamma * sin(omega * k));
}

template<typename T>
__global__ void compute_symiirorder2_bwd_sc(
        const int n, const int off, const int l_off, const int r_off,
        const T* cs_ptr, const T* rsq_ptr, const T* omega_ptr,
        const double precision, bool* valid, T* out) {

    int idx = blockDim.x * blockIdx.x + threadIdx.x;
    if(idx + off >= n) {
        return;
    }

    const T cs = cs_ptr[0];
    const T rsq = rsq_ptr[0];
    const T omega = omega_ptr[0];

    T v1 = _compute_symiirorder2_bwd_hs<T>(idx + l_off + off, cs, rsq, omega);
    T v2 = _compute_symiirorder2_bwd_hs<T>(idx + r_off + off, cs, rsq, omega);

    T diff = v1 + v2;
    T err = diff * diff;
    out[idx] = diff;
    valid[idx] = err <= precision;
}
c                 C     g | ]}d | dqS )zcompute_symiirorder2_bwd_sc<> .0tr   r   Q/home/ubuntu/vllm_env/lib/python3.10/site-packages/cupyx/scipy/signal/_splines.py
<listcomp>t       r   )floatdoublec                 C  r   )zcompute_symiirorder2_fwd_sc<r   r   r   r   r   r   r   v   r   )codename_expressionsc                 G  s>   dd |D }d |}|r| d| dn|}| |}|S )Nc                 S  s   g | ]}t |jqS r   )r   dtype)r   argr   r   r   r   {   s    z$_get_module_func.<locals>.<listcomp>z, <r   )joinget_function)module	func_nametemplate_argsargs_dtypestemplatekernel_namekernelr   r   r   _get_module_funcz   s
   

r$   c              
   C  sr   t | d d | }|jt j}|jdkr7t |d |k|jt jt||d d | |d | |d}|S )Nr      axis)cupywherer   typenansizer   )	all_validcum_polynoffr(   indiceszir   r   r   _find_initial_cond   s   

r4         c                 C  s|  t || j}| j}| j}| jdkrt| |\} }t|dkr#td|dks+|dkrM| jttju r7d}n| jttj	u rCd}n
dt
| jj  }||9 }tjd|d d | jd	}|| }|t| }	tj||  dd
t| dddd
 }
|	|k}t||
|d }tt|rtdd}|dkrd| jd df}tj|| jd	}t||dd}tjdddd| df }t|}tt| d||| jdd\}}tj||f }| |d  t|d }t||dd}tj|ddd| df }t|}tt|ddd||| jd\}}|dkrtjt||f }n	tjt||f }|dkr<||}t|d|}|jjs<| }|S )Nr&   |z1| must be less than 1.0              ?ư>gMbP?
   r%   r   r'   r   ;Sum to find symmetric boundary conditions did not converge.r&      r>      F)r3   r   	apply_firstepr3   r   )r   ndimshaper	   r)   abs
ValueErrorr   float64float32finfoiexparange	conjugatecumsumr   r4   anyisnanzerosr   r_
atleast_2dr
   c_r   reshapemoveaxisflagsc_contiguouscopy)inputc0z1	precisionr(   input_shape
input_ndimpospow_z1diffr/   r.   r3   zi_shapeall_zicoefy1_outr   r   r   _symiirorder1_nd   sn   








rj   c                 C  s  t |g| j}t |g| j}t |dkrtd|dks#|dkr*t | jj}||9 }t jd| jd | jd}|| }|t 	| }t 
||  | d  }||k}t||| j}	t |	rdtdt jd| f }
|
| j}
tt jd| jd|
| dd |	d	\}}t j|	|f }| |d  |d
  }	t jd| f }
|
| j}
t||
|dd
 ddd
 |	d	\}}t j|ddd
 |	f S )aR  
    Implement a smoothing IIR filter with mirror-symmetric boundary conditions
    using a cascade of first-order sections.  The second section uses a
    reversed sequence.  This implements a system with the following
    transfer function and mirror-symmetric boundary conditions::

                           c0
           H(z) = ---------------------
                   (1-z1/z) (1 - z1 z)

    The resulting signal will have mirror symmetric boundary conditions
    as well.

    Parameters
    ----------
    input : ndarray
        The input signal.
    c0, z1 : scalar
        Parameters in the transfer function.
    precision :
        Specifies the precision for calculating initial conditions
        of the recursive filter based on mirror-symmetric input.

    Returns
    -------
    output : ndarray
        The filtered signal.
    r&   r6   r7   r8   r;   r   r<   Nr3   r%   )r)   asarrayr   rG   rH   rK   
resolutionrM   r-   rN   rO   r4   rQ   rS   astyper   ones)r[   r\   r]   r^   ra   rb   rc   r/   r.   r3   arg   rh   ri   r   r   r   symiirorder1   s8   

&rq   c                 C  s   d }|dkr|t ||  | d  }n0|t jkr-|t ||  | d  dd| d    }n|t ||  t || d   t | }t | dk d|S )Nr7   r&      r   )r)   powerpisinr*   )kcsromegabaser   r   r   _compute_symiirorder2_fwd_hc  s   
* r{   c                 C  sL  || }t | } t || d }|dkr9d| d| d|  d|   | }d| d|  }|| d||    S |t jkrjd| d| d|  d|   | }d| d|  dd| d    }|| d||    S |d|  d|  dd| t d|   ||   }d| d|  t | }|| t ||  |t ||     S )Ng       @r7   r&   rr   r8   )r)   rG   rs   rt   costanru   )rv   rw   rsqry   cssqrsupkr\   gammar   r   r   _compute_symiirorder2_bwd_hs*  s    
$
$  (r   c                  C  sb  |dkrt d|dks|dkr2| jttju rd}n| jttju r(d}n
dt| jj  }t|| j}| j	}| j}| jdkrJt
| |\} }d}|| }d	| t| }	| }
tdd	| t|  | }t||j}t||j}t||j}||9 }ttd
|}tj|d f|jd}tj|d ftjd}tjd	| jd}t||||}tj}tj}td| j	d d	 |D ]}|d|d f| j	d d	 |||||||f t| ||| }|d d d |j	d  }|dd  d |j	d  }t|r)tj|| dd|d t| dd  }t|d d d |j	d  || j	d |}t|ratj|| dd|d t| dd	  |d t| dd  }t|dd  d |j	d  || j	d |}tttj||f sq nqtttj||f rt dd}|dkrd| j	d df}ttj|ddd|	 |
 f }|| j}tj|| jd}t||d	d}t||dd}t t| d	||| jd\}}|dkrtj!|||f }ntj|||f }ttd|}tj|f|jd}tj|ftjd}t"| }tj}td| j	d d |D ]W}|d|f| j	d d |dd|t||jt||j|||f
 t|||| }tj|d |j	d  | dd}t|d |j	d  || j	d |}tt|sc nqtt|rrt dtj}td| j	d d |D ]Q}|d|f| j#d |dd	|t||jt||j|||f
 t|||| }tj|d |j	d  | dd}t|d |j# || j#|}tt|s nqtt|rt dt||d	d}t||dd}t t|ddd||d\}}|dkrtj!t"|||f }n
tjt"|||f }|dkr/|$|}t%|d|}|j&j's/|( }|S )Nr8   zr must be less than 1.0r7   gdy=r9   r:   r&      rr   compute_symiirorder2_fwd_scr;   r   r%   )r&   r'   r<   r=   r>   r?   rD   compute_symiirorder2_bwd_scrB   rk   ))rH   r   r)   rI   rJ   rK   rL   r   rE   rF   r	   r|   
atleast_1drl   r$   SYMIIR2_MODULEemptybool_rM   r{   r,   ranger   rQ   rO   r4   rP   rS   rT   rn   rR   r   r
   rU   r   r-   rV   rW   rX   rY   rZ   ) r[   rx   ry   r^   r(   r_   r`   block_szr~   a2a3rw   r   rc   r.   starting_diffy0rg   iinput_slicediff_y0diff_y1cum_poly_y0cum_poly_y1rd   sosre   y_fwdrh   r   	rev_inputri   r   r   r   _symiirorder2_nd?  s  
 



 

 



r   c                 C  s   t | |||S )ak  
    Implement a smoothing IIR filter with mirror-symmetric boundary conditions
    using a cascade of second-order sections.  The second section uses a
    reversed sequence.  This implements the following transfer function::

                                  cs^2
         H(z) = ---------------------------------------
                (1 - a2/z - a3/z^2) (1 - a2 z - a3 z^2 )

    where::

          a2 = 2 * r * cos(omega)
          a3 = - r ** 2
          cs = 1 - 2 * r * cos(omega) + r ** 2

    Parameters
    ----------
    input : ndarray
        The input signal.
    r, omega : float
        Parameters in the transfer function.
    precision : float
        Specifies the precision for calculating initial conditions
        of the recursive filter based on mirror-symmetric input.

    Returns
    -------
    output : ndarray
        The filtered signal.
    )r   )r[   rx   ry   r^   r   r   r   symiirorder2  s   r   )r   r%   )r5   r%   )r5   )
__future__r   r)   cupy._core._scalarr   cupy._core.internalr   cupyx.scipy.signal._signaltoolsr   cupyx.scipy.signal._arraytoolsr   r   r   cupyx.scipy.signal._iir_utilsr	   r
   SYMIIR2_KERNEL	RawModuler   r$   r4   rj   rq   r{   r   r   r   r   r   r   r   <module>   s6    d


JF
 