o
    X۷i,w                     @  s  d Z ddlmZ ddl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 g dZd	d
 Zd6ddZd7ddZejddddZd8ddZ	d9ddZdd ZejddddZdd Z	d:d d!Zeejjd;d"d#Zeejjd;d$d%Zeejjd;d&d'Zeejjd;d(d)Zd8d*d+Z d,d- Z!eejj"d<d.d/Z"eejj#d<d0d1Z#eejj$d<d2d3Z$eejj%d<d4d5Z%dS )=u  Real-to-real transforms

cuFFT does not implement real-to-real FFTs. This module implements forward
and inverse DCT-II and DCT-III transforms using FFTs.

A length N DCT can be computed using a length N FFT and some additional
multiplications and reordering of entries.

The approach taken here is based on the work in [1]_, [2]_ and is discussed in
the freely-available online resources [3]_, [4]_.

The implementation here follows that approach with only minor modification to
match the normalization conventions in SciPy.

The modifications to turn a type II or III DCT to a DST were implemented as
described in [5]_.

.. [1] J. Makhoul, "A fast cosine transform in one and two dimensions," in
    IEEE Transactions on Acoustics, Speech, and Signal Processing, vol. 28,
    no. 1, pp. 27-34, February 1980.

.. [2] M.J. Narasimha and A.M. Peterson, “On the computation of the discrete
    cosine  transform,” IEEE Trans. Commun., vol. 26, no. 6, pp. 934–936, 1978.

.. [3] http://fourier.eng.hmc.edu/e161/lectures/dct/node2.html

.. [4] https://dsp.stackexchange.com/questions/2807/fast-cosine-transform-via-fft

.. [5] X. Shao, S. G. Johnson. Type-II/III DCT/DST algorithms with reduced
    number of arithmetic operations, Signal Processing, Volume 88, Issue 6,
    pp. 1553-1564, 2008.
    )annotationsN)_core)_cook_shape)_fft)	AxisError)dctdctndstdstnidctidctnidstidstnc                 C  s2   | j jdv r
tj}nt| j tj}| j|ddS )NbuiF)copy)dtypekindcupyfloat64promote_typesfloat32astype)xfloat_dtype r   U/home/ubuntu/vllm_env/lib/python3.10/site-packages/cupyx/scipy/fft/_realtransforms.py_promote_dtype1   s   r      c                 C  s^   |dkrdS |dkrdnd}d| |  }|dkrd| }|S |dkr+dt | }|S td)	a]  Normalization factors for DCT/DST I-IV.

    Parameters
    ----------
    n : int
        Data size.
    inorm : {'none', 'sqrt', 'full'}
        When `inorm` is 'none', the scaling factor is 1.0 (unnormalized). When
        `inorm` is 1, scaling by ``1/sqrt(d)`` as needed for an orthogonal
        transform is used. When `inorm` is 2, normalization by ``1/d`` is
        applied. The value of ``d`` depends on both `n` and the `dct_type`.
    dct_type : {1, 2, 3, 4}
        Which type of DCT or DST is being normalized?.

    Returns
    -------
    fct : float
        The normalization factor.
    none   r   r   fullsqrtz)expected inorm = "none", "sqrt" or "full")mathr"   
ValueError)ninormdct_typedeltadfctr   r   r   _get_dct_norm_factor:   s   r+   Fc                 C  s   t dg| j }t ddd||< t|}t dg| j }|d r-t ddd||< t|}nt ddd||< t|}|rKtj| | | |  f|d} | S tj| | | | f|d} | S );Reorder entries to allow computation of DCT/DST-II via FFT.Nr   r   )axis)slicendimtupler   concatenate)r   r%   r.   r	   sl_evensl_oddr   r   r   _reshuffle_dct2[   s   
r5   zR xr, int32 N, R norm_factorzC yzS
    C j(0., -1.);
    y = (R)2.0 * norm_factor * exp(j * (R)(i * M_PI / (2 * N)));)	in_params
out_params	operationc                 C  sb   |du r|}t j|f| jd}t|j||| | jdkr|S dg| j }|||< t|}||S )z@Twiddle & scaling factors for computation of DCT/DST-II via FFT.Nr   r   )r   emptyr   _mult_factor_dct2realr0   r1   reshape)r   r%   r.   norm_factor
n_truncatetmp	tmp_shaper   r   r   _exp_factor_dct2w   s   

rB   r    Tc                 C  sf  || j  k s|| j krtd|dk r|| j 7 }|dur(|dk r(td| dt| |f|fd} | j| }t| | j| ||} |dkrGd	}n|d
krR|rOdnd}n|rVdnd}t||dd}tj| ||dd} t	| |||}	| |	9 } t
| } |dkrtdg| j  }
td|
|< | t|
  tdd 9  < |rtdg| j  }tddd||< | t| } | S )a  Forward DCT/DST-II (or inverse DCT/DST-III) along a single axis

    Parameters
    ----------
    x : cupy.ndarray
        The data to transform.
    n : int
        The size of the transform. If None, ``x.shape[axis]`` is used.
    axis : int
        Axis along which the transform is applied.
    forward : bool
        Set true to indicate that this is a forward DCT-II as opposed to an
        inverse DCT-III (The difference between the two is only in the
        normalization factor).
    norm : {None, 'ortho', 'forward', 'backward'}
        The normalization convention to use.
    dst : bool
        If True, a discrete sine transform is computed rather than the discrete
        cosine transform.
    overwrite_x : bool
        Indicates that it is okay to overwrite x. In practice, the current
        implementation never performs the transform in-place.

    Returns
    -------
    y: cupy.ndarray
        The transformed array.
    axis out of ranger   Nr   invalid number of data points () specifiedR2Rorthor"   forwardr!   r   r   r&   r'   Tr%   r.   overwrite_x      ?r    )r0   r   r$   r   shaper5   r+   r   fftrB   r   r<   r/   r1   r#   r"   )r   r%   r.   rH   normr	   rK   r&   r>   r@   sl0slrevr   r   r   _dct_or_dst_type2   s<   



rR   c           	      C  s   t | }|d d }tdg| j }tddd||< t|}tdg| j }td|||< | t| ||< tdg| j }tddd||< t|}td|d d||< |ra| t|  ||< |S | t| ||< |S )r,   r   r   Nr   r    )r   
empty_liker/   r0   r1   )	yr%   r.   r	   r   n_halfr3   sl_halfr4   r   r   r   _reshuffle_dct3   s"   
rW   zV
    C j(0., 1.);
    y = (R)(2 * N * norm_factor) * exp(j * (R)(i * M_PI / (2 * N)));c                 C  sT   t j|f|d}t|j||| | jdkr|S dg| j }|||< t|}||S )zATwiddle & scaling factors for computation of DCT/DST-III via FFT.r9   r   )r   r:   _mult_factor_dct3r<   r0   r1   r=   )r   r%   r.   r   r>   r@   rA   r   r   r   _exp_factor_dct3   s   

rY   c                 C  s  || j  k s|| j krtd|dk r|| j 7 }|dur(|dk r(td| dt| |f|fd} | j| }|dkrDd	td
 }d}n&|dkrQd	}|rNdnd}n|dksY|du rbd	}|r_dnd}ntd| dt||dd}	t	| tj
}
tdg| j  }td||< |rtdg| j  }tddd||< | t| } |dkrt	| jtj}| j|kr| |} n|s|  } | t|  td
9  < d	}t| |||
|	}| | } | t|  |9  < tj| ||dd} t| } t| |||S )a  Forward DCT/DST-III (or inverse DCT/DST-II) along a single axis.

    Parameters
    ----------
    x : cupy.ndarray
        The data to transform.
    n : int
        The size of the transform. If None, ``x.shape[axis]`` is used.
    axis : int
        Axis along which the transform is applied.
    forward : bool
        Set true to indicate that this is a forward DCT-II as opposed to an
        inverse DCT-III (The difference between the two is only in the
        normalization factor).
    norm : {None, 'ortho', 'forward', 'backward'}
        The normalization convention to use.
    dst : bool
        If True, a discrete sine transform is computed rather than the discrete
        cosine transform.
    overwrite_x : bool
        Indicates that it is okay to overwrite x. In practice, the current
        implementation never performs the transform in-place.

    Returns
    -------
    y: cupy.ndarray
        The transformed array.

    rC   r   Nr   rD   rE   rF   rG   rL   r   r"   rH   r!   r   backwardzInvalid norm value "z-", should be "backward", "ortho" or "forward"   rI   r    TrJ   )r0   r   r$   r   rM   r#   r"   r+   r   r   	complex64r/   r1   r   r   r   r   rY   r   ifftr<   rW   )r   r%   r.   rO   rH   r	   rK   	sl0_scaler&   r>   r   rP   rQ   r   r@   r   r   r   _dct_or_dst_type3   sT    




r_   c              	   C     | j jdkr t| j|||||}|dt| j|||||  }|S t| } |dkr2t| |||dddS |dkr@t| |||dddS |dv rHtd	t	d
)a  Return the Discrete Cosine Transform of an array, x.

    Parameters
    ----------
    x : cupy.ndarray
        The input array.
    type : {1, 2, 3, 4}, optional
        Type of the DCT (see Notes). Default type is 2. Currently CuPy only
        supports types 2 and 3.
    n : int, optional:
        Length of the transform.  If ``n < x.shape[axis]``, `x` is
        truncated. If ``n > x.shape[axis]``, `x` is zero-padded.
        The default results in ``n = x.shape[axis]``.
    axis : int, optional
        Axis along which the dct is computed; the default is over the
        last axis (i.e., ``axis=-1``).
    norm : {"backward", "ortho", "forward"}, optional
        Normalization mode (see Notes). Default is "backward".
    overwrite_x : bool, optional
        If True, the contents of `x` can be destroyed; the default is False.

    Returns
    -------
    y : cupy.ndarray of real
        The transformed input array.

    See Also
    --------
    :func:`scipy.fft.dct`

    Notes
    -----
    For a single dimension array ``x``, ``dct(x, norm='ortho')`` is equal
    to MATLAB ``dct(x)``.

    For ``norm="ortho"`` both the `dct` and `idct` are scaled by the same
    overall factor in both directions. By default, the transform is also
    orthogonalized which for types 1, 2 and 3 means the transform definition is
    modified to give orthogonality of the DCT matrix (see below).

    For ``norm="backward"``, there is no scaling on `dct` and the `idct` is
    scaled by ``1/N`` where ``N`` is the "logical" size of the DCT. For
    ``norm="forward"`` the ``1/N`` normalization is applied to the forward
    `dct` instead and the `idct` is unnormalized.

    CuPy currently only supports DCT types 2 and 3. 'The' DCT generally
    refers to DCT type 2, and 'the' Inverse DCT generally refers to DCT
    type 3 [1]_. See the :func:`scipy.fft.dct` documentation for a full
    description of each type.

    References
    ----------
    .. [1] Wikipedia, "Discrete cosine transform",
           https://en.wikipedia.org/wiki/Discrete_cosine_transform

    c              ?r   TFr%   r.   rO   rH   r	   r[   r      .Only DCT-II and DCT-III have been implemented.invalid DCT type)
r   r   r   r<   imagr   rR   r_   NotImplementedErrorr$   r   typer%   r.   rO   rK   outr   r   r   r   W  s$   :r   c              	   C  s   | j jdkr t| j|||||}|dt| j|||||  }|S t| } |dkr2t| |||dddS |dkr@t| |||dddS |dv rHtdt	d	)
a  Return the Discrete Sine Transform of an array, x.

    Parameters
    ----------
    x : cupy.ndarray
        The input array.
    type : {1, 2, 3, 4}, optional
        Type of the DST (see Notes). Default type is 2.
    n : int, optional
        Length of the transform.  If ``n < x.shape[axis]``, `x` is
        truncated.  If ``n > x.shape[axis]``, `x` is zero-padded. The
        default results in ``n = x.shape[axis]``.
    axis : int, optional
        Axis along which the dst is computed; the default is over the
        last axis (i.e., ``axis=-1``).
    norm : {"backward", "ortho", "forward"}, optional
        Normalization mode (see Notes). Default is "backward".
    overwrite_x : bool, optional
        If True, the contents of `x` can be destroyed; the default is False.

    Returns
    -------
    dst : cupy.ndarray of real
        The transformed input array.

    See Also
    --------
    :func:`scipy.fft.dst`

    Notes
    -----

    For ``norm="ortho"`` both the `dst` and `idst` are scaled by the same
    overall factor in both directions. By default, the transform is also
    orthogonalized which for types 2 and 3 means the transform definition is
    modified to give orthogonality of the DST matrix (see below).

    For ``norm="backward"``, there is no scaling on the `dst` and the `idst` is
    scaled by ``1/N`` where ``N`` is the "logical" size of the DST.

    See the :func:`scipy.fft.dst` documentation for a full description of each
    type. CuPy currently only supports DST types 2 and 3.
    ra   rb   r   Trc   r[   rd   .Only DST-II and DST-III have been implemented.invalid DST type)
r   r   r	   r<   rh   r   rR   r_   ri   r$   rj   r   r   r   r	     s$   -r	   c              	   C  s   | j jdkr t| j|||||}|dt| j|||||  }|S t| } |dkr1t| |||ddS |dkr>t| |||ddS |dv rFtdt	d	)
a  Return the Inverse Discrete Cosine Transform of an array, x.

    Parameters
    ----------
    x : cupy.ndarray
        The input array.
    type : {1, 2, 3, 4}, optional
        Type of the DCT (see Notes). Default type is 2.
    n : int, optional
        Length of the transform.  If ``n < x.shape[axis]``, `x` is
        truncated.  If ``n > x.shape[axis]``, `x` is zero-padded. The
        default results in ``n = x.shape[axis]``.
    axis : int, optional
        Axis along which the idct is computed; the default is over the
        last axis (i.e., ``axis=-1``).
    norm : {"backward", "ortho", "forward"}, optional
        Normalization mode (see Notes). Default is "backward".
    overwrite_x : bool, optional
        If True, the contents of `x` can be destroyed; the default is False.

    Returns
    -------
    idct : cupy.ndarray of real
        The transformed input array.

    See Also
    --------
    :func:`scipy.fft.idct`

    Notes
    -----
    For a single dimension array `x`, ``idct(x, norm='ortho')`` is equal to
    MATLAB ``idct(x)``.

    For ``norm="ortho"`` both the `dct` and `idct` are scaled by the same
    overall factor in both directions. By default, the transform is also
    orthogonalized which for types 1, 2 and 3 means the transform definition is
    modified to give orthogonality of the IDCT matrix (see `dct` for the full
    definitions).

    'The' IDCT is the IDCT-II, which is the same as the normalized DCT-III
    [1]_. See the :func:`scipy.fft.dct` documentation for a full description of
    each type. CuPy currently only supports DCT types 2 and 3.

    References
    ----------
    .. [1] Wikipedia, "Discrete sine transform",
           https://en.wikipedia.org/wiki/Discrete_sine_transform
    ra   rb   r   F)r%   r.   rO   rH   r[   rd   rf   rg   )
r   r   r   r<   rh   r   r_   rR   ri   r$   rj   r   r   r   r     s   3r   c              	   C  r`   )a>  Return the Inverse Discrete Sine Transform of an array, x.

    Parameters
    ----------
    x : cupy.ndarray
        The input array.
    type : {1, 2, 3, 4}, optional
        Type of the DST (see Notes). Default type is 2.
    n : int, optional
        Length of the transform. If ``n < x.shape[axis]``, `x` is
        truncated.  If ``n > x.shape[axis]``, `x` is zero-padded. The
        default results in ``n = x.shape[axis]``.
    axis : int, optional
        Axis along which the idst is computed; the default is over the
        last axis (i.e., ``axis=-1``).
    norm : {"backward", "ortho", "forward"}, optional
        Normalization mode (see Notes). Default is "backward".
    overwrite_x : bool, optional
        If True, the contents of `x` can be destroyed; the default is False.

    Returns
    -------
    idst : cupy.ndarray of real
        The transformed input array.

    See Also
    --------
    :func:`scipy.fft.idst`

    Notes
    -----
    For full details of the DST types and normalization modes, as well as
    references, see :func:`scipy.fft.dst`.
    ra   rb   r   FTrc   r[   rd   rm   rn   )
r   r   r   r<   rh   r   r_   rR   ri   r$   rj   r   r   r   r   7  s$   $r   c              
   C  sX   t | tjr	| f} z
dd | D } W | S  ty+ } z|pd}t| d|d}~ww )z-Convert ``x`` to an iterable sequence of int.c                 S  s   g | ]}t |qS r   )operatorindex.0ar   r   r   
<listcomp>{      z$_iterable_of_int.<locals>.<listcomp>valuez) must be a scalar or iterable of integersN)
isinstancenumbersNumber	TypeErrorr$   )r   nameer   r   r   _iterable_of_intu  s   r}   c                   s4  |du }|du }|s5t |d} fdd|D }t fdd|D r'tdtt|t|kr5td|sot |d	}t|}|rLt||krLtd
|rb| jkrWtdt jt|  j} fddt||D }n|r|t j	}t j}n	 fdd|D }tdd |D rtd| d||fS )z3Handles shape and axes arguments for nd transforms.Naxesc                   s"   g | ]}|d k r| j  n|qS )r   r0   rq   r   r   r   rt     s   " z+_init_nd_shape_and_axes.<locals>.<listcomp>c                 3  s"    | ]}| j kp|d k V  qdS )r   Nr   rq   r   r   r   	<genexpr>  s     z*_init_nd_shape_and_axes.<locals>.<genexpr>z$axes exceeds dimensionality of inputzall axes must be uniquerM   zBwhen given, axes and shape arguments have to be of the same lengthz)shape requires more axes than are presentc                   s&   g | ]\}}|d kr j | n|qS )r    rM   )rr   srs   r   r   r   rt     s   & c                   s   g | ]} j | qS r   r   rq   r   r   r   rt     ru   c                 s  s    | ]}|d k V  qdS )r   Nr   )rr   r   r   r   r   r     s    rD   rE   )
r}   anyr$   lensetr0   rangeziplistrM   )r   rM   r~   noshapenoaxesnshaper   r   r   _init_nd_shape_and_axes  s<   




r   c           
   	   C     | j jdkr t| j|||||}|dt| j|||||  }|S t| ||\}}t| } t|dkr4| S t||D ]\}}	t	| |||	||d} q9| S )a  Compute a multidimensional Discrete Cosine Transform.

    Parameters
    ----------
    x : cupy.ndarray
        The input array.
    type : {1, 2, 3, 4}, optional
        Type of the DCT (see Notes). Default type is 2.
    s : int or array_like of ints or None, optional
        The shape of the result. If both `s` and `axes` (see below) are None,
        `s` is ``x.shape``; if `s` is None but `axes` is not None, then `s` is
        ``numpy.take(x.shape, axes, axis=0)``.
        If ``s[i] > x.shape[i]``, the ith dimension is padded with zeros.
        If ``s[i] < x.shape[i]``, the ith dimension is truncated to length
        ``s[i]``.
        If any element of `s` is -1, the size of the corresponding dimension of
        `x` is used.
    axes : int or array_like of ints or None, optional
        Axes over which the DCT is computed. If not given, the last ``len(s)``
        axes are used, or all axes if `s` is also not specified.
    norm : {"backward", "ortho", "forward"}, optional
        Normalization mode (see Notes). Default is "backward".
    overwrite_x : bool, optional
        If True, the contents of `x` can be destroyed; the default is False.

    Returns
    -------
    y : cupy.ndarray of real
        The transformed input array.

    See Also
    --------
    :func:`scipy.fft.dctn`

    Notes
    -----
    For full details of the DCT types and normalization modes, as well as
    references, see `dct`.
    ra   rb   r   rk   r%   r.   rO   rK   )
r   r   r   r<   rh   r   r   r   r   r   
r   rk   r   r~   rO   rK   rl   rM   r%   r.   r   r   r   r        )r   c           
   	   C  r   )a  Compute a multidimensional Discrete Cosine Transform.

    Parameters
    ----------
    x : cupy.ndarray
        The input array.
    type : {1, 2, 3, 4}, optional
        Type of the DCT (see Notes). Default type is 2.
    s : int or array_like of ints or None, optional
        The shape of the result. If both `s` and `axes` (see below) are None,
        `s` is ``x.shape``; if `s` is None but `axes` is not None, then `s` is
        ``numpy.take(x.shape, axes, axis=0)``.
        If ``s[i] > x.shape[i]``, the ith dimension is padded with zeros.
        If ``s[i] < x.shape[i]``, the ith dimension is truncated to length
        ``s[i]``.
        If any element of `s` is -1, the size of the corresponding dimension of
        `x` is used.
    axes : int or array_like of ints or None, optional
        Axes over which the IDCT is computed. If not given, the last ``len(s)``
        axes are used, or all axes if `s` is also not specified.
    norm : {"backward", "ortho", "forward"}, optional
        Normalization mode (see Notes). Default is "backward".
    overwrite_x : bool, optional
        If True, the contents of `x` can be destroyed; the default is False.

    Returns
    -------
    y : cupy.ndarray of real
        The transformed input array.

    See Also
    --------
    :func:`scipy.fft.idctn`

    Notes
    -----
    For full details of the IDCT types and normalization modes, as well as
    references, see :func:`scipy.fft.idct`.
    ra   rb   r   r   )
r   r   r   r<   rh   r   r   r   r   r   r   r   r   r   r     r   r   c           
   	   C  r   )a  Compute a multidimensional Discrete Sine Transform.

    Parameters
    ----------
    x : cupy.ndarray
        The input array.
    type : {1, 2, 3, 4}, optional
        Type of the DST (see Notes). Default type is 2.
    s : int or array_like of ints or None, optional
        The shape of the result. If both `s` and `axes` (see below) are None,
        `s` is ``x.shape``; if `s` is None but `axes` is not None, then `s` is
        ``numpy.take(x.shape, axes, axis=0)``.
        If ``s[i] > x.shape[i]``, the ith dimension is padded with zeros.
        If ``s[i] < x.shape[i]``, the ith dimension is truncated to length
        ``s[i]``.
        If any element of `s` is -1, the size of the corresponding dimension of
        `x` is used.
    axes : int or array_like of ints or None, optional
        Axes over which the DST is computed. If not given, the last ``len(s)``
        axes are used, or all axes if `s` is also not specified.
    norm : {"backward", "ortho", "forward"}, optional
        Normalization mode (see Notes). Default is "backward".
    overwrite_x : bool, optional
        If True, the contents of `x` can be destroyed; the default is False.

    Returns
    -------
    y : cupy.ndarray of real
        The transformed input array.

    See Also
    --------
    :func:`scipy.fft.dstn`

    Notes
    -----
    For full details of the DST types and normalization modes, as well as
    references, see :func:`scipy.fft.dst`.
    ra   rb   r   r   )
r   r   r
   r<   rh   r   r   r   r   r	   r   r   r   r   r
   '  r   r
   c           
   	   C  r   )a  Compute a multidimensional Discrete Sine Transform.

    Parameters
    ----------
    x : cupy.ndarray
        The input array.
    type : {1, 2, 3, 4}, optional
        Type of the DST (see Notes). Default type is 2.
    s : int or array_like of ints or None, optional
        The shape of the result. If both `s` and `axes` (see below) are None,
        `s` is ``x.shape``; if `s` is None but `axes` is not None, then `s` is
        ``numpy.take(x.shape, axes, axis=0)``.
        If ``s[i] > x.shape[i]``, the ith dimension is padded with zeros.
        If ``s[i] < x.shape[i]``, the ith dimension is truncated to length
        ``s[i]``.
        If any element of `s` is -1, the size of the corresponding dimension of
        `x` is used.
    axes : int or array_like of ints or None, optional
        Axes over which the IDST is computed. If not given, the last ``len(s)``
        axes are used, or all axes if `s` is also not specified.
    norm : {"backward", "ortho", "forward"}, optional
        Normalization mode (see Notes). Default is "backward".
    overwrite_x : bool, optional
        If True, the contents of `x` can be destroyed; the default is False.

    Returns
    -------
    y : cupy.ndarray of real
        The transformed input array.

    See Also
    --------
    :func:`scipy.fft.idstn`

    Notes
    -----
    For full details of the IDST types and normalization modes, as well as
    references, see :func:`scipy.fft.idst`.
    ra   rb   r   r   )
r   r   r   r<   rh   r   r   r   r   r   r   r   r   r   r   c  r   r   )r   )F)N)Nr    TNFF)Nr    NTFF)r   Nr    NF)r   NNNF)&__doc__
__future__r   r#   rx   ro   r   r   cupy.fft._fftr   cupyx.scipy.fftr   cupy.exceptionsr   __all__r   r+   r5   ElementwiseKernelr;   rB   rR   rW   rX   rY   r_   _implements
_scipy_fftr   r	   r   r   r}   r   r   r   r
   r   r   r   r   r   <module>   sb     
	
!
	
G	
YQDH
=*;;;