o
    i%                     @   s~   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 dddZ	d	d
 Z
dddZdddZdddZdddZdS )    N)_core)internal)_util)specialFc                 C   s   t jt jg}|s|t jt jg7 }| d u r0|j|v r$t j|j|jd} | S t j|j|d d} | S t| tu rH| |vr>t	dt j|j| d} | S | j|jkrRt	d| S )Ndtypezoutput type not supportedzoutput shape not correct)
cupy	complex64
complex128float32float64r   emptyshapetypeRuntimeError)outputinputcomplex_onlytypes r   Y/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/cupyx/scipy/ndimage/_fourier.py_get_output_fourier
   s"   
	r   c                 C   s*   d| | j f d|| d   }| |S )z>Promote a 1d array to ndim with non-singleton size along axis.)   r   )sizereshape)arrndimaxisnd_shaper   r   r   _reshape_nd   s    
r    r   c                 C   s   | j }t|| }t||}t||d}t| | tt	||j
D ]S\}\}}	||kr?|dkr?tj|	|jjd}
|
| }
ntj|	}
|
j|jjdd}
|
|
9 }
|| d }|
dtj tj | 9 }
tj|
|
d t|
||d	}
||
9 }q#|S )
a  Multidimensional Gaussian shift filter.

    The array is multiplied with the Fourier transform of a (separable)
    Gaussian kernel.

    Args:
        input (cupy.ndarray): The input array.
        sigma (float or sequence of float):  The sigma of the Gaussian kernel.
            If a float, `sigma` is the same for all axes. If a sequence,
            `sigma` has to contain one value for each axis.
        n (int, optional):  If `n` is negative (default), then the input is
            assumed to be the result of a complex fft. If `n` is larger than or
            equal to zero, the input is assumed to be the result of a real fft,
            and `n` gives the length of the array before transformation along
            the real transform direction.
        axis (int, optional): The axis of the real transform (only used when
            ``n > -1``).
        output (cupy.ndarray, optional):
            If given, the result of shifting the input is placed in this array.

    Returns:
        output (cupy.ndarray): The filtered output.
    sigmar   r   Fcopy   outr   r   )r   r   r   _normalize_axis_indexr   _fix_sequence_argr   elementwise_copy	enumeratezipr   r	   arangerealr   fftfftfreqastypenumpypiexpr    )r   r!   nr   r   r   sigmasaxsigmakax_sizer   scaler   r   r   fourier_gaussian#   s$   


r<   c           
      C   s   | j }t|| }t||}t||d}t| | tt	||j
D ]A\}\}}||kr?|dkr?tj||jjd}	|	| }	ntj|}	|	j|jjdd}	|	|9 }	tj|	|	d t|	||d}	||	9 }q#|S )a  Multidimensional uniform shift filter.

    The array is multiplied with the Fourier transform of a box of given size.

    Args:
        input (cupy.ndarray): The input array.
        size (float or sequence of float):  The sigma of the box used for
            filtering. If a float, `size` is the same for all axes. If a
            sequence, `size` has to contain one value for each axis.
        n (int, optional):  If `n` is negative (default), then the input is
            assumed to be the result of a complex fft. If `n` is larger than or
            equal to zero, the input is assumed to be the result of a real fft,
            and `n` gives the length of the array before transformation along
            the real transform direction.
        axis (int, optional): The axis of the real transform (only used when
            ``n > -1``).
        output (cupy.ndarray, optional):
            If given, the result of shifting the input is placed in this array.

    Returns:
        output (cupy.ndarray): The filtered output.
    r   r   r   Fr"   r&   r(   )r   r   r   r)   r   r*   r   r+   r,   r-   r   r	   r.   r/   r   r0   r1   r2   sincr    )
r   r   r6   r   r   r   sizesr8   r:   r   r   r   r   fourier_uniformX   s    


r?   c                 C   s   | j }t|| dd}t||}t||d}t| | tt	||j
D ]H\}\}}	|dkr0q%||krL|dkrLtj|	|jd}
|
dtj | | 9 }
ntj|	}
|
dtj |  }
tj|
|
d t|
||d}
||
9 }q%|S )	aF  Multidimensional Fourier shift filter.

    The array is multiplied with the Fourier transform of a shift operation.

    Args:
        input (cupy.ndarray): The input array. This should be in the Fourier
            domain.
        shift (float or sequence of float):  The size of shift. If a float,
            `shift` is the same for all axes. If a sequence, `shift` has to
            contain one value for each axis.
        n (int, optional):  If `n` is negative (default), then the input is
            assumed to be the result of a complex fft. If `n` is larger than or
            equal to zero, the input is assumed to be the result of a real fft,
            and `n` gives the length of the array before transformation along
            the real transform direction.
        axis (int, optional): The axis of the real transform (only used when
            ``n > -1``).
        output (cupy.ndarray, optional):
            If given, the result of shifting the input is placed in this array.

    Returns:
        output (cupy.ndarray): The shifted output (in the Fourier domain).
    T)r   shiftr   r   y              r&   r(   )r   r   r   r)   r   r*   r   r+   r,   r-   r   r	   r.   r   r3   r4   r0   r1   r5   r    )r   r@   r6   r   r   r   shiftsr8   shiftkr:   r   r   r   r   fourier_shift   s"   
rC   c                 C   s  | j }|dkrt| ||||S |dkrtdt|| }t||}t||d}t	| | d}t
t||jD ]F\}\}}	||krZ|dkrZtj|	|jjd}
|
tj| | 9 }
ntj|	}
|
tj| 9 }
|
j|jjdd}
|
|
9 }
t|
||d	}
||
 }q9tj||d
 |dkrtj||d
 |d9 }|| }n|dkrtj||d
 ||t| 8 }|d9 }||d  }d|d| < || 9 }|S )a   Multidimensional ellipsoid Fourier filter.

    The array is multiplied with the fourier transform of a ellipsoid of
    given sizes.

    Args:
        input (cupy.ndarray): The input array.
        size (float or sequence of float):  The size of the box used for
            filtering. If a float, `size` is the same for all axes. If a
            sequence, `size` has to contain one value for each axis.
        n (int, optional):  If `n` is negative (default), then the input is
            assumed to be the result of a complex fft. If `n` is larger than or
            equal to zero, the input is assumed to be the result of a real fft,
            and `n` gives the length of the array before transformation along
            the real transform direction.
        axis (int, optional): The axis of the real transform (only used when
            ``n > -1``).
        output (cupy.ndarray, optional):
            If given, the result of shifting the input is placed in this array.

    Returns:
        output (cupy.ndarray): The filtered output.
    r      z'Only 1d, 2d and 3d inputs are supportedr   r   r   Fr"   r(   r&      g      ?)r   )r   r?   NotImplementedErrorr   r   r)   r   r*   r   r+   r,   r-   r   r	   r.   r/   r   r3   r4   r0   r1   r2   r    sqrtr   j1sincos)r   r   r6   r   r   r   r>   distancer8   r:   r   r   r   r   fourier_ellipsoid   sB   


rL   )F)r   r   N)r3   r	   r   
cupy._corer   cupyx.scipy.ndimager   cupyx.scipyr   r   r    r<   r?   rC   rL   r   r   r   r   <module>   s    


5
21