o
    Ö­j¹>  ã                   @   sÄ   d Z ddlZddlmZmZmZmZmZmZm	Z	m
Z
mZ ddlmZ ddlmZmZmZ g d¢Zdd	„ Zd
d„ Zdd„ Zdd„ Zdd„ Zdd„ Zddd„Zd dd„Zdd„ Zd dd„Zd!dd„ZdS )"zr
ltisys -- a collection of functions to convert linear time invariant systems
from one representation to another.
é    N)	Úr_ÚeyeÚ
atleast_2dÚpolyÚdotÚasarrayÚzerosÚarrayÚouter)Úlinalgé   )Útf2zpkÚzpk2tfÚ	normalize)Útf2ssÚabcd_normalizeÚss2tfÚzpk2ssÚss2zpkÚcont2discretec                 C   s¶  t | |ƒ\} }t| jƒ}|dkrt| g| jƒ} | jd }t|ƒ}||kr*d}t|ƒ‚|dks2|dkrDtg tƒtg tƒtg tƒtg tƒfS t 	tj
| jd || f| jd�| f¡} | jd dkrjt| dd…df ƒ}ntdggtƒ}|dkr‘| | j¡}t
dƒt
d|jd fƒt
|jd dfƒ|fS t|dd… gƒ }t|t|d |d ƒf }t|d dƒ}	| dd…dd…f t| dd…df |dd… ƒ }
| |
jd |	jd f¡}||	|
|fS )	a½  Transfer function to state-space representation.

    Parameters
    ----------
    num, den : array_like
        Sequences representing the coefficients of the numerator and
        denominator polynomials, in order of descending degree. The
        denominator needs to be at least as long as the numerator.

    Returns
    -------
    A, B, C, D : ndarray
        State space representation of the system, in controller canonical
        form.

    Examples
    --------
    Convert the transfer function:

    .. math:: H(s) = \frac{s^2 + 3s + 3}{s^2 + 2s + 1}

    >>> num = [1, 3, 3]
    >>> den = [1, 2, 1]

    to the state-space representation:

    .. math::

        \dot{\textbf{x}}(t) =
        \begin{bmatrix} -2 & -1 \\ 1 & 0 \end{bmatrix} \textbf{x}(t) +
        \begin{bmatrix} 1 \\ 0 \end{bmatrix} \textbf{u}(t) \\

        \textbf{y}(t) = \begin{bmatrix} 1 & 2 \end{bmatrix} \textbf{x}(t) +
        \begin{bmatrix} 1 \end{bmatrix} \textbf{u}(t)

    >>> from scipy.signal import tf2ss
    >>> A, B, C, D = tf2ss(num, den)
    >>> A
    array([[-2., -1.],
           [ 1.,  0.]])
    >>> B
    array([[ 1.],
           [ 0.]])
    >>> C
    array([[ 1.,  2.]])
    >>> D
    array([[ 1.]])
    r   z7Improper transfer function. `num` is longer than `den`.r   )ÚdtypeéÿÿÿÿN)r   r   é   )r   ÚlenÚshaper   r   Ú
ValueErrorr	   ÚfloatÚnpÚhstackr   r   Úreshaper   r   r
   )ÚnumÚdenÚnnÚMÚKÚmsgÚDÚfrowÚAÚBÚC© r+   úY/var/www/html/CropPilot/venv/lib/python3.10/site-packages/scipy/signal/_lti_conversion.pyr      s8   8

ÿ(ÿ2r   c                 C   s   | d u rt dƒS | S )N©r   r   )r   ©Úargr+   r+   r,   Ú_none_to_empty_2ds   s   r0   c                 C   s   | d urt | ƒS d S ©N)r   r.   r+   r+   r,   Ú_atleast_2d_or_nonez   s   ÿr2   c                 C   s   | d ur| j S dS )N)NN)r   )r#   r+   r+   r,   Ú_shape_or_none   s   r3   c                  G   s   | D ]
}|d ur|  S qd S r1   r+   )Úargsr/   r+   r+   r,   Ú_choice_not_none†   s
   ÿÿr5   c                 C   s(   | j dkr	t|ƒS | j |krtdƒ‚| S )Nr-   z*The input arrays have incompatible shapes.)r   r   r   )r#   r   r+   r+   r,   Ú_restoreŒ   s
   

r6   c                 C   sè   t t| |||fƒ\} }}}t| ƒ\}}t|ƒ\}}t|ƒ\}}	t|ƒ\}
}t|||	ƒ}t||ƒ}t||
ƒ}|du sA|du sA|du rEtdƒ‚t t| |||fƒ\} }}}t| ||fƒ} t|||fƒ}t|||fƒ}t|||fƒ}| |||fS )a³  Check state-space matrices and ensure they are 2-D.

    If enough information on the system is provided, that is, enough
    properly-shaped arrays are passed to the function, the missing ones
    are built from this information, ensuring the correct number of
    rows and columns. Otherwise a ValueError is raised.

    Parameters
    ----------
    A, B, C, D : array_like, optional
        State-space matrices. All of them are None (missing) by default.
        See `ss2tf` for format.

    Returns
    -------
    A, B, C, D : array
        Properly shaped state-space matrices.

    Raises
    ------
    ValueError
        If not enough information on the system was provided.

    Nz%Not enough information on the system.)Úmapr2   r3   r5   r   r0   r6   )r(   r)   r*   r&   ÚMAÚNAÚMBÚNBÚMCÚNCÚMDÚNDÚpÚqÚrr+   r+   r,   r   •   s    

r   c                 C   sj  t | |||ƒ\} }}}|j\}}||krtdƒ‚|dd…||d …f }|dd…||d …f }zt| ƒ}W n tyA   d}Y nw |jdkra|jdkrat |¡}|jdkr]| jdkr]g }||fS | jd }	| dd…df |dd…df  |ddd…f  | d }
t ||	d f|
j¡}t	|ƒD ]}t
||dd…f ƒ}t| t||ƒ ƒ|| d |  ||< q‘||fS )a  State-space to transfer function.

    A, B, C, D defines a linear state-space system with `p` inputs,
    `q` outputs, and `n` state variables.

    Parameters
    ----------
    A : array_like
        State (or system) matrix of shape ``(n, n)``
    B : array_like
        Input matrix of shape ``(n, p)``
    C : array_like
        Output matrix of shape ``(q, n)``
    D : array_like
        Feedthrough (or feedforward) matrix of shape ``(q, p)``
    input : int, optional
        For multiple-input systems, the index of the input to use.

    Returns
    -------
    num : 2-D ndarray
        Numerator(s) of the resulting transfer function(s). `num` has one row
        for each of the system's outputs. Each row is a sequence representation
        of the numerator polynomial.
    den : 1-D ndarray
        Denominator of the resulting transfer function(s). `den` is a sequence
        representation of the denominator polynomial.

    Examples
    --------
    Convert the state-space representation:

    .. math::

        \dot{\textbf{x}}(t) =
        \begin{bmatrix} -2 & -1 \\ 1 & 0 \end{bmatrix} \textbf{x}(t) +
        \begin{bmatrix} 1 \\ 0 \end{bmatrix} \textbf{u}(t) \\

        \textbf{y}(t) = \begin{bmatrix} 1 & 2 \end{bmatrix} \textbf{x}(t) +
        \begin{bmatrix} 1 \end{bmatrix} \textbf{u}(t)

    >>> A = [[-2, -1], [1, 0]]
    >>> B = [[1], [0]]  # 2-D column vector
    >>> C = [[1, 2]]    # 2-D row vector
    >>> D = 1

    to the transfer function:

    .. math:: H(s) = \frac{s^2 + 3s + 3}{s^2 + 2s + 1}

    >>> from scipy.signal import ss2tf
    >>> ss2tf(A, B, C, D)
    (array([[1., 3., 3.]]), array([ 1.,  2.,  1.]))
    z)System does not have the input specified.Nr   r   ç        )r   r   r   r   Úsizer   ÚravelÚemptyr   Úranger   r   )r(   r)   r*   r&   ÚinputÚnoutÚninr!   r    Ú
num_statesÚ	type_testÚkÚCkr+   r+   r,   r   Ä   s.   :
ÿ

8(r   c                 C   s   t t| ||ƒŽ S )a:  Zero-pole-gain representation to state-space representation

    Parameters
    ----------
    z, p : sequence
        Zeros and poles.
    k : float
        System gain.

    Returns
    -------
    A, B, C, D : ndarray
        State space representation of the system, in controller canonical
        form.

    )r   r   )Úzr@   rM   r+   r+   r,   r     s   r   c                 C   s   t t| ||||d�Ž S )aª  State-space representation to zero-pole-gain representation.

    A, B, C, D defines a linear state-space system with `p` inputs,
    `q` outputs, and `n` state variables.

    Parameters
    ----------
    A : array_like
        State (or system) matrix of shape ``(n, n)``
    B : array_like
        Input matrix of shape ``(n, p)``
    C : array_like
        Output matrix of shape ``(q, n)``
    D : array_like
        Feedthrough (or feedforward) matrix of shape ``(q, p)``
    input : int, optional
        For multiple-input systems, the index of the input to use.

    Returns
    -------
    z, p : sequence
        Zeros and poles.
    k : float
        System gain.

    )rH   )r   r   )r(   r)   r*   r&   rH   r+   r+   r,   r   1  s   r   Úzohc                 C   sø  t | ƒdkr
|  ¡ S t | ƒdkr1tt| d | d ƒ|||d�}t|d |d |d |d ƒ|f S t | ƒdkr[tt| d | d | d ƒ|||d�}t|d |d |d |d ƒ|f S t | ƒdkrh| \}}}}ntdƒ‚|dkr„|d	u rxtd
ƒ‚|dk s€|dkr„tdƒ‚|dkrÌt 	|j
d ¡|| |  }	t |	t 	|j
d ¡d| | |  ¡}
t |	|| ¡}t |	 ¡ | ¡ ¡}| ¡ }||t ||¡  }�n)|dksÔ|dkrÜt| |ddd�S |dksä|dkrìt| |ddd�S |dkrøt| |ddd�S |dk�r[t ||f¡}t t |j
d |j
d f¡t |j
d |j
d f¡f¡}t ||f¡}t || ¡}|d	|j
d …d	d	…f }|d	d	…d|j
d …f }
|d	d	…|j
d d	…f }|}|}nš|dk�rÇ|j
d }|j
d }t t ||g¡| t 	|¡¡}t||d|  fƒ}t |g|gg¡}t |¡}|d	|…d|…f }|d	|…||| …f }|d	|…|| d	…f }|}
|| ||  }|}|||  }n.|dk�rít |d¡�s×tdƒ‚t || ¡}
|
| | }|}|| | }ntd|› d�ƒ‚|
||||fS )a\  
    Transform a continuous to a discrete state-space system.

    Parameters
    ----------
    system : a tuple describing the system or an instance of `lti`
        The following gives the number of elements in the tuple and
        the interpretation:

            * 1: (instance of `lti`)
            * 2: (num, den)
            * 3: (zeros, poles, gain)
            * 4: (A, B, C, D)

    dt : float
        The discretization time step.
    method : str, optional
        Which method to use:

            * gbt: generalized bilinear transformation
            * bilinear: Tustin's approximation ("gbt" with alpha=0.5)
            * euler: Euler (or forward differencing) method ("gbt" with alpha=0)
            * backward_diff: Backwards differencing ("gbt" with alpha=1.0)
            * zoh: zero-order hold (default)
            * foh: first-order hold (*versionadded: 1.3.0*)
            * impulse: equivalent impulse response (*versionadded: 1.3.0*)

    alpha : float within [0, 1], optional
        The generalized bilinear transformation weighting parameter, which
        should only be specified with method="gbt", and is ignored otherwise

    Returns
    -------
    sysd : tuple containing the discrete system
        Based on the input type, the output will be of the form

        * (num, den, dt)   for transfer function input
        * (zeros, poles, gain, dt)   for zeros-poles-gain input
        * (A, B, C, D, dt) for state-space system input

    Notes
    -----
    By default, the routine uses a Zero-Order Hold (zoh) method to perform
    the transformation. Alternatively, a generalized bilinear transformation
    may be used, which includes the common Tustin's bilinear approximation,
    an Euler's method technique, or a backwards differencing technique.

    The Zero-Order Hold (zoh) method is based on [1]_, the generalized bilinear
    approximation is based on [2]_ and [3]_, the First-Order Hold (foh) method
    is based on [4]_.

    References
    ----------
    .. [1] https://en.wikipedia.org/wiki/Discretization#Discretization_of_linear_state_space_models

    .. [2] http://techteach.no/publications/discretetime_signals_systems/discrete.pdf

    .. [3] G. Zhang, X. Chen, and T. Chen, Digital redesign via the generalized
        bilinear transformation, Int. J. Control, vol. 82, no. 4, pp. 741-754,
        2009.
        (https://www.mypolyuweb.hk/~magzhang/Research/ZCC09_IJC.pdf)

    .. [4] G. F. Franklin, J. D. Powell, and M. L. Workman, Digital control
        of dynamic systems, 3rd ed. Menlo Park, Calif: Addison-Wesley,
        pp. 204-206, 1998.

    Examples
    --------
    We can transform a continuous state-space system to a discrete one:

    >>> import numpy as np
    >>> import matplotlib.pyplot as plt
    >>> from scipy.signal import cont2discrete, lti, dlti, dstep

    Define a continuous state-space system.

    >>> A = np.array([[0, 1],[-10., -3]])
    >>> B = np.array([[0],[10.]])
    >>> C = np.array([[1., 0]])
    >>> D = np.array([[0.]])
    >>> l_system = lti(A, B, C, D)
    >>> t, x = l_system.step(T=np.linspace(0, 5, 100))
    >>> fig, ax = plt.subplots()
    >>> ax.plot(t, x, label='Continuous', linewidth=3)

    Transform it to a discrete state-space system using several methods.

    >>> dt = 0.1
    >>> for method in ['zoh', 'bilinear', 'euler', 'backward_diff', 'foh', 'impulse']:
    ...    d_system = cont2discrete((A, B, C, D), dt, method=method)
    ...    s, x_d = dstep(d_system)
    ...    ax.step(s, np.squeeze(x_d), label=method, where='post')
    >>> ax.axis([t[0], t[-1], x[0], 1.4])
    >>> ax.legend(loc='best')
    >>> fig.tight_layout()
    >>> plt.show()

    r   r   r   )ÚmethodÚalphaé   é   zKFirst argument must either be a tuple of 2 (tf), 3 (zpk), or 4 (ss) arrays.ÚgbtNzUAlpha parameter must be specified for the generalized bilinear transform (gbt) methodzDAlpha parameter must be within the interval [0,1] for the gbt methodg      ð?ÚbilinearÚtusting      à?ÚeulerÚforward_diffrC   Úbackward_diffrP   ÚfohÚimpulsez<Impulse method is only applicable to strictly proper systemszUnknown transformation method 'ú')r   Úto_discreter   r   r   r   r   r   r   r   r   r   ÚsolveÚ	transposer   r   r   ÚvstackÚexpmÚ
block_diagÚblockÚallclose)ÚsystemÚdtrQ   rR   ÚsysdÚaÚbÚcÚdÚimaÚadÚbdÚcdÚddÚem_upperÚem_lowerÚemÚmsÚnÚmÚms11Úms12Úms13r+   r+   r,   r   O  sˆ   cÿ$ÿ$(
ÿ


 

r   )NNNN)r   )rP   N)Ú__doc__Únumpyr   r   r   r   r   r   r   r   r	   r
   Úscipyr   Ú_filter_designr   r   r   Ú__all__r   r0   r2   r3   r5   r6   r   r   r   r   r   r+   r+   r+   r,   Ú<module>   s"    ,a
	
/Y
