ó
Ë½÷Xc           @` sC  d  Z  d d l m Z m Z m Z d d l 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 m Z d d l m Z d d l m Z m Z m Z d d	 d
 d d d g Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d d d d d „ Z d d „ Z  d „  Z! d d „ Z" d d d „ Z# d S(   sr   
ltisys -- a collection of functions to convert linear time invariant systems
from one representation to another.
i    (   t   divisiont   print_functiont   absolute_importN(
   t   r_t   eyet
   atleast_2dt   polyt   dott   asarrayt   productt   zerost   arrayt   outer(   t   linalgi   (   t   tf2zpkt   zpk2tft	   normalizet   tf2sst   abcd_normalizet   ss2tft   zpk2sst   ss2zpkt   cont2discretec         C` sW  t  |  | ƒ \ }  } t |  j ƒ } | d k rH t |  g |  j ƒ }  n  |  j d } t | ƒ } | | k r‚ d } t | ƒ ‚ n  | d k sš | d k rÎ t g  t ƒ t g  t ƒ t g  t ƒ t g  t ƒ f St d t	 |  j d | | f |  j ƒ |  f }  |  j d d k r0t
 |  d d … d f ƒ } n t d g g t ƒ } | d k rŸ| j |  j ƒ } t	 d ƒ t	 d | j d f ƒ t	 | j d d f ƒ | f St | d g ƒ } t | t | d | d ƒ f } t | d d ƒ }	 |  d d … d d … f t |  d d … d f | d ƒ }
 | j |
 j d |	 j d f ƒ } | |	 |
 | f S(	   s½  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.]])
    i   s7   Improper transfer function. `num` is longer than `den`.i    s   -1iÿÿÿÿNi   (   i   i   (   R   t   lent   shapeR   t   dtypet
   ValueErrorR   t   floatR   R
   R   t   reshapeR   R   (   t   numt   dent   nnt   Mt   Kt   msgt   Dt   frowt   At   Bt   C(    (    s:   /tmp/pip-build-7oUkmx/scipy/scipy/signal/lti_conversion.pyR      s4    8$0!=#c         C` s   |  d  k r t d ƒ S|  Sd  S(   Ni    (   i    i    (   t   NoneR
   (   t   arg(    (    s:   /tmp/pip-build-7oUkmx/scipy/scipy/signal/lti_conversion.pyt   _none_to_empty_2du   s    
c         C` s   |  d  k	 r t |  ƒ Sd  S(   N(   R(   R   (   R)   (    (    s:   /tmp/pip-build-7oUkmx/scipy/scipy/signal/lti_conversion.pyt   _atleast_2d_or_none|   s    c         C` s   |  d  k	 r |  j Sd Sd  S(   Ni   (   N(   NN(   R(   R   (   R    (    (    s:   /tmp/pip-build-7oUkmx/scipy/scipy/signal/lti_conversion.pyt   _shape_or_none   s    c          G` s%   x |  D] } | d  k	 r | Sq Wd  S(   N(   R(   (   t   argsR)   (    (    s:   /tmp/pip-build-7oUkmx/scipy/scipy/signal/lti_conversion.pyt   _choice_not_noneˆ   s    c         C` s?   |  j  d k r t | ƒ S|  j  | k r7 t d ƒ ‚ n  |  Sd  S(   Ni    s*   The input arrays have incompatible shapes.(   i    i    (   R   R
   R   (   R    R   (    (    s:   /tmp/pip-build-7oUkmx/scipy/scipy/signal/lti_conversion.pyt   _restoreŽ   s
    
c         C` s]  t  t |  | | | f ƒ \ }  } } } t |  ƒ \ } } t | ƒ \ } } t | ƒ \ } }	 t | ƒ \ }
 } t | | |	 ƒ } t | | ƒ } t | |
 ƒ } | d k sÃ | d k sÃ | d k rÒ t d ƒ ‚ n  t  t |  | | | f ƒ \ }  } } } t |  | | f ƒ }  t | | | f ƒ } t | | | f ƒ } t | | | f ƒ } |  | | | f S(   s¿  Check state-space matrices and ensure they are two-dimensional.

    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.

    s%   Not enough information on the system.N(   t   mapR+   R,   R.   R(   R   R*   R/   (   R%   R&   R'   R#   t   MAt   NAt   MBt   NBt   MCt   NCt   MDt   NDt   pt   qt   r(    (    s:   /tmp/pip-build-7oUkmx/scipy/scipy/signal/lti_conversion.pyR   —   s     '$'c         C` s  t  |  | | | ƒ \ }  } } } | j \ } } | | k rK t d ƒ ‚ n  | d d … | | d … f } | d d … | | d … f } y t |  ƒ } Wn t k
 r´ d } n Xt | j d d ƒd k rCt | j d d ƒd k rCt j | ƒ } t | j d d ƒd k r9t |  j d d ƒd k r9g  } n  | | f S|  j d }	 |  d d … d f | d d … d f | d d d … f | }
 t j | |	 d f |
 j ƒ } x] t	 | ƒ D]O } t
 | | d d … f ƒ } t |  t | | ƒ ƒ | | d | | | <q¾W| | f S(   s’  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-dimensional column vector
    >>> C = [[1, 2]]    # 2-dimensional 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.]))
    s)   System does not have the input specified.Ni   t   axisi    (   R   R   R   R   R	   t   numpyt   ravelR
   R   t   rangeR   R   (   R%   R&   R'   R#   t   inputt   noutt   ninR   R   t
   num_statest	   type_testt   kt   Ck(    (    s:   /tmp/pip-build-7oUkmx/scipy/scipy/signal/lti_conversion.pyR   Æ   s,    :!  
66	
B1c         C` s   t  t |  | | ƒ Œ  S(   s:  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   (   t   zR9   RE   (    (    s:   /tmp/pip-build-7oUkmx/scipy/scipy/signal/lti_conversion.pyR     s    c         C` s   t  t |  | | | d | ƒŒ  S(   sª  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.

    R@   (   R   R   (   R%   R&   R'   R#   R@   (    (    s:   /tmp/pip-build-7oUkmx/scipy/scipy/signal/lti_conversion.pyR   3  s    t   zohc      
   C` sî  t  |  ƒ d k r |  j ƒ  St  |  ƒ d k r„ t t |  d |  d ƒ | d | d | ƒ} t | d | d | d | d ƒ | f St  |  ƒ d k ró t t |  d |  d |  d ƒ | d | d | ƒ} t | d | d | d | d ƒ | f St  |  ƒ d k r|  \ } } } } n t d ƒ ‚ | d	 k rw| d k rMt d
 ƒ ‚ qw| d k  se| d k rwt d ƒ ‚ qwn  | d	 k r4t	 j
 | j d ƒ | | | }	 t j |	 t	 j
 | j d ƒ d | | | ƒ }
 t j |	 | | ƒ } t j |	 j ƒ  | j ƒ  ƒ } | j ƒ  } | | t	 j | | ƒ } n§| d k sL| d k ret |  | d d	 d d ƒS| d k s}| d k r–t |  | d d	 d d ƒS| d k r»t |  | d d	 d d ƒS| d k rËt	 j | | f ƒ } t	 j t	 j | j d | j d f ƒ t	 j | j d | j d f ƒ f ƒ } t	 j | | f ƒ } t j | | ƒ } | d | j d … d d … f } | d d … d | j d … f }
 | d d … | j d d … f } | } | } n t d | ƒ ‚ |
 | | | | f S(   sþ  
    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 : {"gbt", "bilinear", "euler", "backward_diff", "zoh"}, 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)

    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]_.

    References
    ----------
    .. [1] http://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.
        (http://www.ece.ualberta.ca/~gfzhang/research/ZCC07_preprint.pdf)

    i   i   i    t   methodt   alphai   i   sK   First argument must either be a tuple of 2 (tf), 3 (zpk), or 4 (ss) arrays.t   gbtsU   Alpha parameter must be specified for the generalized bilinear transform (gbt) methodsD   Alpha parameter must be within the interval [0,1] for the gbt methodg      ð?t   bilineart   tusting      à?t   eulert   forward_diffg        t   backward_diffRH   Ns"   Unknown transformation method '%s'(   R   t   to_discreteR   R   R   R   R   R   R(   t   npR   R   R   t   solvet	   transposeR   t   hstackR
   t   vstackt   expm(   t   systemt   dtRI   RJ   t   sysdt   at   bt   ct   dt   imat   adt   bdt   cdt   ddt   em_uppert   em_lowert   emt   ms(    (    s:   /tmp/pip-build-7oUkmx/scipy/scipy/signal/lti_conversion.pyR   Q  sX    =
#	*$*"2&)###	($   t   __doc__t
   __future__R    R   R   R=   RR   R   R   R   R   R   R   R	   R
   R   R   t   scipyR   t   filter_designR   R   R   t   __all__R   R*   R+   R,   R.   R/   R(   R   R   R   R   R   (    (    (    s:   /tmp/pip-build-7oUkmx/scipy/scipy/signal/lti_conversion.pyt   <module>   s&   F		a						/Y	