
    (ph1Z                         S SK rS SK JrJrJrJrJrJrJrJ	r	J
r
JrJrJrJrJr  / SQrSS jrSS jr  SS jrSSS.S	 jjrSS
 jrSS jrS rS\4S jrg)    N)asarrayzerosplacenanmodpiextractlogsqrtexpcossinpolyvalpolyint)sawtoothsquare
gausspulsechirp
sweep_polyunit_impulsec                 r   [        U 5      [        U5      p [        X U -
  -   5      n[        XU-
  -   5      n U R                  R                  S;   a  U R                  R                  nOSn[        U R                  U5      nUS:  US:  -  n[        XE[        5        [        U S[        -  5      nSU-
  XbS-  [        -  :  -  n[        Xv5      n[        Xr5      n	[        XGU[        U	-  -  S-
  5        SU-
  SU-
  -  n
[        X5      n[        X5      n	[        XJ[        U	S-   -  U-
  [        SU	-
  -  -  5        U$ )a<  
Return a periodic sawtooth or triangle waveform.

The sawtooth waveform has a period ``2*pi``, rises from -1 to 1 on the
interval 0 to ``width*2*pi``, then drops from 1 to -1 on the interval
``width*2*pi`` to ``2*pi``. `width` must be in the interval [0, 1].

Note that this is not band-limited.  It produces an infinite number
of harmonics, which are aliased back and forth across the frequency
spectrum.

Parameters
----------
t : array_like
    Time.
width : array_like, optional
    Width of the rising ramp as a proportion of the total cycle.
    Default is 1, producing a rising ramp, while 0 produces a falling
    ramp.  `width` = 0.5 produces a triangle wave.
    If an array, causes wave shape to change over time, and must be the
    same length as t.

Returns
-------
y : ndarray
    Output array containing the sawtooth waveform.

Examples
--------
A 5 Hz waveform sampled at 500 Hz for 1 second:

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> t = np.linspace(0, 1, 500)
>>> plt.plot(t, signal.sawtooth(2 * np.pi * 5 * t))

fFdDd   r      )
r   dtypecharr   shaper   r   r   r   r	   )twidthwytypeymask1tmodmask2tsubwsubmask3s              J/var/www/html/venv/lib/python3.13/site-packages/scipy/signal/_waveforms.pyr   r      s-   N 1:wu~qUAUAww||xagguA Uq1uE	!C q!b&>D Y4a%"*,-E5D5D	!DBI&*+
 Y1u9%E5D5D	!R4!8_t+a$h@AH    c                    [        U 5      [        U5      p [        X U -
  -   5      n[        XU-
  -   5      n U R                  R                  S;   a  U R                  R                  nOSn[        U R                  U5      nUS:  US:  -  n[        XE[        5        [        U S[        -  5      nSU-
  XbS-  [        -  :  -  n[        XGS5        SU-
  SU-
  -  n[        XHS5        U$ )a  
Return a periodic square-wave waveform.

The square wave has a period ``2*pi``, has value +1 from 0 to
``2*pi*duty`` and -1 from ``2*pi*duty`` to ``2*pi``. `duty` must be in
the interval [0,1].

Note that this is not band-limited.  It produces an infinite number
of harmonics, which are aliased back and forth across the frequency
spectrum.

Parameters
----------
t : array_like
    The input time array.
duty : array_like, optional
    Duty cycle.  Default is 0.5 (50% duty cycle).
    If an array, causes wave shape to change over time, and must be the
    same length as t.

Returns
-------
y : ndarray
    Output array containing the square waveform.

Examples
--------
A 5 Hz waveform sampled at 500 Hz for 1 second:

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> t = np.linspace(0, 1, 500, endpoint=False)
>>> plt.plot(t, signal.square(2 * np.pi * 5 * t))
>>> plt.ylim(-2, 2)

A pulse-width modulated sine wave:

>>> plt.figure()
>>> sig = np.sin(2 * np.pi * t)
>>> pwm = signal.square(2 * np.pi * 30 * t, duty=(sig + 1)/2)
>>> plt.subplot(2, 1, 1)
>>> plt.plot(t, sig)
>>> plt.subplot(2, 1, 2)
>>> plt.plot(t, pwm)
>>> plt.ylim(-1.5, 1.5)

r   r   r   r   r   )	r   r   r   r   r   r   r   r   r   )	r    dutyr"   r#   r$   r%   r&   r'   r*   s	            r+   r   r   X   s    b 1:wt}qUAUAww||xagguA Uq1uE	!C q!b&>DY4a%"*,-E	!A Y1u9%E	!BHr,   Fc                    US:  a  [        SUS S35      eUS::  a  [        SUS S35      eUS:  a  [        SUS S35      e[        S	US
-  5      n[        U-  U-  S-  * S[        U5      -  -  n[	        U [
        5      (       aI  U S:X  a8  US:  a  [        S5      e[        S	US
-  5      n	[        [        U	5      * U-  5      $ [        S5      e[        U* U -  U -  5      n
U
[        S[        -  U-  U -  5      -  nU
[        S[        -  U-  U -  5      -  nU(       d	  U(       d  U$ U(       d
  U(       a  X4$ U(       a
  U(       d  X4$ U(       a  U(       a  XU
4$ gg)av  
Return a Gaussian modulated sinusoid:

    ``exp(-a t^2) exp(1j*2*pi*fc*t).``

If `retquad` is True, then return the real and imaginary parts
(in-phase and quadrature).
If `retenv` is True, then return the envelope (unmodulated signal).
Otherwise, return the real part of the modulated sinusoid.

Parameters
----------
t : ndarray or the string 'cutoff'
    Input array.
fc : float, optional
    Center frequency (e.g. Hz).  Default is 1000.
bw : float, optional
    Fractional bandwidth in frequency domain of pulse (e.g. Hz).
    Default is 0.5.
bwr : float, optional
    Reference level at which fractional bandwidth is calculated (dB).
    Default is -6.
tpr : float, optional
    If `t` is 'cutoff', then the function returns the cutoff
    time for when the pulse amplitude falls below `tpr` (in dB).
    Default is -60.
retquad : bool, optional
    If True, return the quadrature (imaginary) as well as the real part
    of the signal.  Default is False.
retenv : bool, optional
    If True, return the envelope of the signal.  Default is False.

Returns
-------
yI : ndarray
    Real part of signal.  Always returned.
yQ : ndarray
    Imaginary part of signal.  Only returned if `retquad` is True.
yenv : ndarray
    Envelope of signal.  Only returned if `retenv` is True.

Examples
--------
Plot real component, imaginary component, and envelope for a 5 Hz pulse,
sampled at 100 Hz for 2 seconds:

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> t = np.linspace(-1, 1, 2 * 100, endpoint=False)
>>> i, q, e = signal.gausspulse(t, fc=5, retquad=True, retenv=True)
>>> plt.plot(t, i, t, q, t, e, '--')

r   zCenter frequency (fc=z.2fz) must be >=0.zFractional bandwidth (bw=z) must be > 0.z#Reference level for bandwidth (bwr=z) must be < 0 dBg      $@g      4@r   g      @cutoffz.Reference level for time cutoff must be < 0 dBz'If `t` is a string, it must be 'cutoff'N)

ValueErrorpowr   r
   
isinstancestrr   r   r   r   )r    fcbwbwrtprretquadretenvrefatrefyenvyIyQs                r+   r   r      s   p 
Av0CGHH	Qw4RHNKLL
ax>s3i H* * + 	+
 dC$J
C r'B,1	c#h/A!S= ax  "- . .tS4Z(DT
Q''FGGrAvz?D	AFRK!O$	$B	AFRK!O$	$B6	vxvv6t| wr,   )complexc                    [        XX#XF5      [        R                  " U5      -   nU(       a  [        R                  " SU-  5      $ [        R                  " U5      $ )a  Frequency-swept cosine generator.

In the following, 'Hz' should be interpreted as 'cycles per unit';
there is no requirement here that the unit is one second.  The
important distinction is that the units of rotation are cycles, not
radians. Likewise, `t` could be a measurement of space instead of time.

Parameters
----------
t : array_like
    Times at which to evaluate the waveform.
f0 : float
    Frequency (e.g. Hz) at time t=0.
t1 : float
    Time at which `f1` is specified.
f1 : float
    Frequency (e.g. Hz) of the waveform at time `t1`.
method : {'linear', 'quadratic', 'logarithmic', 'hyperbolic'}, optional
    Kind of frequency sweep.  If not given, `linear` is assumed.  See
    Notes below for more details.
phi : float, optional
    Phase offset, in degrees. Default is 0.
vertex_zero : bool, optional
    This parameter is only used when `method` is 'quadratic'.
    It determines whether the vertex of the parabola that is the graph
    of the frequency is at t=0 or t=t1.
complex : bool, optional
    This parameter creates a complex-valued analytic signal instead of a
    real-valued signal. It allows the use of complex baseband (in communications
    domain). Default is False.

    .. versionadded:: 1.15.0

Returns
-------
y : ndarray
    A numpy array containing the signal evaluated at `t` with the requested
    time-varying frequency.  More precisely, the function returns
    ``exp(1j*phase + 1j*(pi/180)*phi) if complex else cos(phase + (pi/180)*phi)``
    where `phase` is the integral (from 0 to `t`) of ``2*pi*f(t)``.
    The instantaneous frequency ``f(t)`` is defined below.

See Also
--------
sweep_poly

Notes
-----
There are four possible options for the parameter `method`, which have a (long)
standard form and some allowed abbreviations. The formulas for the instantaneous
frequency :math:`f(t)` of the generated signal are as follows:

1. Parameter `method` in ``('linear', 'lin', 'li')``:

   .. math::
       f(t) = f_0 + \beta\, t           \quad\text{with}\quad
       \beta = \frac{f_1 - f_0}{t_1}

   Frequency :math:`f(t)` varies linearly over time with a constant rate
   :math:`\beta`.

2. Parameter `method` in ``('quadratic', 'quad', 'q')``:

   .. math::
        f(t) =
        \begin{cases}
          f_0 + \beta\, t^2          & \text{if vertex_zero is True,}\\
          f_1 + \beta\, (t_1 - t)^2  & \text{otherwise,}
        \end{cases}
        \quad\text{with}\quad
        \beta = \frac{f_1 - f_0}{t_1^2}

   The graph of the frequency f(t) is a parabola through :math:`(0, f_0)` and
   :math:`(t_1, f_1)`.  By default, the vertex of the parabola is at
   :math:`(0, f_0)`. If `vertex_zero` is ``False``, then the vertex is at
   :math:`(t_1, f_1)`.
   To use a more general quadratic function, or an arbitrary
   polynomial, use the function `scipy.signal.sweep_poly`.

3. Parameter `method` in ``('logarithmic', 'log', 'lo')``:

   .. math::
        f(t) = f_0  \left(\frac{f_1}{f_0}\right)^{t/t_1}

   :math:`f_0` and :math:`f_1` must be nonzero and have the same sign.
   This signal is also known as a geometric or exponential chirp.

4. Parameter `method` in ``('hyperbolic', 'hyp')``:

   .. math::
          f(t) = \frac{\alpha}{\beta\, t + \gamma} \quad\text{with}\quad
          \alpha = f_0 f_1 t_1, \ \beta = f_0 - f_1, \ \gamma = f_1 t_1

   :math:`f_0` and :math:`f_1` must be nonzero.


Examples
--------
For the first example, a linear chirp ranging from 6 Hz to 1 Hz over 10 seconds is
plotted:

>>> import numpy as np
>>> from matplotlib.pyplot import tight_layout
>>> from scipy.signal import chirp, square, ShortTimeFFT
>>> from scipy.signal.windows import gaussian
>>> import matplotlib.pyplot as plt
...
>>> N, T = 1000, 0.01  # number of samples and sampling interval for 10 s signal
>>> t = np.arange(N) * T  # timestamps
...
>>> x_lin = chirp(t, f0=6, f1=1, t1=10, method='linear')
...
>>> fg0, ax0 = plt.subplots()
>>> ax0.set_title(r"Linear Chirp from $f(0)=6\,$Hz to $f(10)=1\,$Hz")
>>> ax0.set(xlabel="Time $t$ in Seconds", ylabel=r"Amplitude $x_\text{lin}(t)$")
>>> ax0.plot(t, x_lin)
>>> plt.show()

The following four plots each show the short-time Fourier transform of a chirp
ranging from 45 Hz to 5 Hz with different values for the parameter `method`
(and `vertex_zero`):

>>> x_qu0 = chirp(t, f0=45, f1=5, t1=N*T, method='quadratic', vertex_zero=True)
>>> x_qu1 = chirp(t, f0=45, f1=5, t1=N*T, method='quadratic', vertex_zero=False)
>>> x_log = chirp(t, f0=45, f1=5, t1=N*T, method='logarithmic')
>>> x_hyp = chirp(t, f0=45, f1=5, t1=N*T, method='hyperbolic')
...
>>> win = gaussian(50, std=12, sym=True)
>>> SFT = ShortTimeFFT(win, hop=2, fs=1/T, mfft=800, scale_to='magnitude')
>>> ts = ("'quadratic', vertex_zero=True", "'quadratic', vertex_zero=False",
...       "'logarithmic'", "'hyperbolic'")
>>> fg1, ax1s = plt.subplots(2, 2, sharex='all', sharey='all',
...                          figsize=(6, 5),  layout="constrained")
>>> for x_, ax_, t_ in zip([x_qu0, x_qu1, x_log, x_hyp], ax1s.ravel(), ts):
...     aSx = abs(SFT.stft(x_))
...     im_ = ax_.imshow(aSx, origin='lower', aspect='auto', extent=SFT.extent(N),
...                      cmap='plasma')
...     ax_.set_title(t_)
...     if t_ == "'hyperbolic'":
...         fg1.colorbar(im_, ax=ax1s, label='Magnitude $|S_z(t,f)|$')
>>> _ = fg1.supxlabel("Time $t$ in Seconds")  # `_ =` is needed to pass doctests
>>> _ = fg1.supylabel("Frequency $f$ in Hertz")
>>> plt.show()

Finally, the short-time Fourier transform of a complex-valued linear chirp
ranging from -30 Hz to 30 Hz is depicted:

>>> z_lin = chirp(t, f0=-30, f1=30, t1=N*T, method="linear", complex=True)
>>> SFT.fft_mode = 'centered'  # needed to work with complex signals
>>> aSz = abs(SFT.stft(z_lin))
...
>>> fg2, ax2 = plt.subplots()
>>> ax2.set_title(r"Linear Chirp from $-30\,$Hz to $30\,$Hz")
>>> ax2.set(xlabel="Time $t$ in Seconds", ylabel="Frequency $f$ in Hertz")
>>> im2 = ax2.imshow(aSz, origin='lower', aspect='auto',
...                  extent=SFT.extent(N), cmap='viridis')
>>> fg2.colorbar(im2, label='Magnitude $|S_z(t,f)|$')
>>> plt.show()

Note that using negative frequencies makes only sense with complex-valued signals.
Furthermore, the magnitude of the complex exponential function is one whereas the
magnitude of the real-valued cosine function is only 1/2.
y              ?)_chirp_phasenpdeg2radr   r   )	r    f0t1f1methodphivertex_zerorB   phases	            r+   r   r     sB    L <rzz#NE&266"U(9BFF5M9r,   c                 0   [        U 5      n [        U5      n[        U5      n[        U5      nUS;   a#  X1-
  U-  nS[        -  X-  SU-  U -  U -  -   -  nU$ US;   aQ  X1-
  US-  -  nU(       a  S[        -  X-  X`S-  -  S-  -   -  nU$ S[        -  X0-  XbU -
  S-  US-  -
  -  S-  -   -  n U$ US;   a_  X-  S::  a  [        S5      eX:X  a  S[        -  U-  U -  nU$ U[	        X1-  5      -  nS[        -  U-  U-  [        X1-  X-  5      S	-
  -  n U$ US
;   ap  US:X  d  US:X  a  [        S5      eX:X  a  S[        -  U-  U -  nU$ U* U-  X-
  -  nS[        -  U* U-  -  [	        [        R                  " SX-  -
  5      5      -  n U$ [        SU< S35      e)zo
Calculate the phase used by `chirp` to generate its output.

See `chirp` for a description of the arguments.

)linearlinlir         ?)	quadraticquadq   )logarithmicr
   log        zJFor a logarithmic chirp, f0 and f1 must be nonzero and have the same sign.g      ?)
hyperbolichypr   z2For a hyperbolic chirp, f0 and f1 must be nonzero.r   zUmethod must be 'linear', 'quadratic', 'logarithmic', or 'hyperbolic', but a value of z was given.)r   floatr   r2   r
   r3   rE   abs)	r    rG   rH   rI   rJ   rL   betarM   sings	            r+   rD   rD     s    	
A	rB	rB	rB((2~B"&3:>A#556H LE 
-	-B!G$Fbft1f}q'889E> L; FbftQ1}rQw/F'G!'KKLE: L7 
/	/7c> ? @ @8FRK!OE, L) BG$DFTMB&#bgqv*>*DEE& L# 
(	(7bAg ( ) )8FRK!OE L 38rw'DFtebj)Cq16z0B,CCE L  <<B:[R S 	Sr,   c                 J    [        X5      nU[        S-  -  n[        X2-   5      $ )a	  
Frequency-swept cosine generator, with a time-dependent frequency.

This function generates a sinusoidal function whose instantaneous
frequency varies with time.  The frequency at time `t` is given by
the polynomial `poly`.

Parameters
----------
t : ndarray
    Times at which to evaluate the waveform.
poly : 1-D array_like or instance of numpy.poly1d
    The desired frequency expressed as a polynomial.  If `poly` is
    a list or ndarray of length n, then the elements of `poly` are
    the coefficients of the polynomial, and the instantaneous
    frequency is

      ``f(t) = poly[0]*t**(n-1) + poly[1]*t**(n-2) + ... + poly[n-1]``

    If `poly` is an instance of numpy.poly1d, then the
    instantaneous frequency is

      ``f(t) = poly(t)``

phi : float, optional
    Phase offset, in degrees, Default: 0.

Returns
-------
sweep_poly : ndarray
    A numpy array containing the signal evaluated at `t` with the
    requested time-varying frequency.  More precisely, the function
    returns ``cos(phase + (pi/180)*phi)``, where `phase` is the integral
    (from 0 to t) of ``2 * pi * f(t)``; ``f(t)`` is defined above.

See Also
--------
chirp

Notes
-----
.. versionadded:: 0.8.0

If `poly` is a list or ndarray of length `n`, then the elements of
`poly` are the coefficients of the polynomial, and the instantaneous
frequency is:

    ``f(t) = poly[0]*t**(n-1) + poly[1]*t**(n-2) + ... + poly[n-1]``

If `poly` is an instance of `numpy.poly1d`, then the instantaneous
frequency is:

      ``f(t) = poly(t)``

Finally, the output `s` is:

    ``cos(phase + (pi/180)*phi)``

where `phase` is the integral from 0 to `t` of ``2 * pi * f(t)``,
``f(t)`` as defined above.

Examples
--------
Compute the waveform with instantaneous frequency::

    f(t) = 0.025*t**3 - 0.36*t**2 + 1.25*t + 2

over the interval 0 <= t <= 10.

>>> import numpy as np
>>> from scipy.signal import sweep_poly
>>> p = np.poly1d([0.025, -0.36, 1.25, 2.0])
>>> t = np.linspace(0, 10, 5001)
>>> w = sweep_poly(t, p)

Plot it:

>>> import matplotlib.pyplot as plt
>>> plt.subplot(2, 1, 1)
>>> plt.plot(t, w)
>>> plt.title("Sweep Poly\nwith frequency " +
...           "$f(t) = 0.025t^3 - 0.36t^2 + 1.25t + 2$")
>>> plt.subplot(2, 1, 2)
>>> plt.plot(t, p(t), 'r', label='f(t)')
>>> plt.legend()
>>> plt.xlabel('t')
>>> plt.tight_layout()
>>> plt.show()

   )_sweep_poly_phaser   r   )r    polyrK   rM   s       r+   r   r     s)    x a&E28OCu{r,   c                 F    [        U5      nS[        -  [        X 5      -  nU$ )zw
Calculate the phase used by sweep_poly to generate its output.

See `sweep_poly` for a description of the arguments.

r   )r   r   r   )r    rb   intpolyrM   s       r+   ra   ra   D  s%     dmGFWW((ELr,   c                     [        X5      n[        R                  " U 5      n Uc  S[        U 5      -  nO5US:X  a  [	        U S-  5      nO [        US5      (       d  U4[        U 5      -  nSX1'   U$ )a	  
Unit impulse signal (discrete delta function) or unit basis vector.

Parameters
----------
shape : int or tuple of int
    Number of samples in the output (1-D), or a tuple that represents the
    shape of the output (N-D).
idx : None or int or tuple of int or 'mid', optional
    Index at which the value is 1.  If None, defaults to the 0th element.
    If ``idx='mid'``, the impulse will be centered at ``shape // 2`` in
    all dimensions.  If an int, the impulse will be at `idx` in all
    dimensions.
dtype : data-type, optional
    The desired data-type for the array, e.g., ``numpy.int8``.  Default is
    ``numpy.float64``.

Returns
-------
y : ndarray
    Output array containing an impulse signal.

Notes
-----
In digital signal processing literature the unit impulse signal is often
represented by the Kronecker delta. [1]_ I.e., a signal :math:`u_k[n]`,
which is zero everywhere except being one at the :math:`k`-th sample,
can be expressed as

.. math::

    u_k[n] = \delta[n-k] \equiv \delta_{n,k}\ .

Furthermore, the unit impulse is frequently interpreted as the discrete-time
version of the continuous-time Dirac distribution. [2]_

References
----------
.. [1] "Kronecker delta", *Wikipedia*,
       https://en.wikipedia.org/wiki/Kronecker_delta#Digital_signal_processing
.. [2] "Dirac delta function" *Wikipedia*,
       https://en.wikipedia.org/wiki/Dirac_delta_function#Relationship_to_the_Kronecker_delta

.. versionadded:: 0.19.0

Examples
--------
An impulse at the 0th element (:math:`\\delta[n]`):

>>> from scipy import signal
>>> signal.unit_impulse(8)
array([ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])

Impulse offset by 2 samples (:math:`\\delta[n-2]`):

>>> signal.unit_impulse(7, 2)
array([ 0.,  0.,  1.,  0.,  0.,  0.,  0.])

2-dimensional impulse, centered:

>>> signal.unit_impulse((3, 3), 'mid')
array([[ 0.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  0.]])

Impulse at (2, 2), using broadcasting:

>>> signal.unit_impulse((4, 4), 2)
array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.]])

Plot the impulse response of a 4th-order Butterworth lowpass filter:

>>> imp = signal.unit_impulse(100, 'mid')
>>> b, a = signal.butter(4, 0.2)
>>> response = signal.lfilter(b, a, imp)

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> plt.plot(np.arange(-50, 50), imp)
>>> plt.plot(np.arange(-50, 50), response)
>>> plt.margins(0.1, 0.1)
>>> plt.xlabel('Time [samples]')
>>> plt.ylabel('Amplitude')
>>> plt.grid(True)
>>> plt.show()

r   midr   __iter__r   )r   rE   
atleast_1dlentuplehasattr)r   idxr   outs       r+   r   r   Q  sn    v 
CMM% E
{SZ	EQJS*%%fs5z!CHJr,   )r   )rR   )i  rR   iiFF)rO   r   T)rO   Trf   )numpyrE   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r   __all__r   r   r   r   rD   r   ra   r[   r    r,   r+   <module>rr      sr    $ $ $ $EPHV =B^Bg:g:T1h_D
 ! gr,   