def impulse_response(sys, T=None, X0=0., input=0, output=None,
                     transpose=False):
    # pylint: disable=W0622
    """Impulse response of a linear system

    If the system has multiple inputs or outputs (MIMO), one input has
    to be selected for the simulation. Optionally, one output may be
    selected. The parameters `input` and `output` do this. All other
    inputs are set to 0, all other outputs are ignored.

    For information on the **shape** of parameters `T`, `X0` and
    return values `T`, `yout`, see :ref:`time-series-convention`.

    Parameters
    ----------
    sys: StateSpace, TransferFunction
        LTI system to simulate

    T: array-like object, optional
        Time vector (argument is autocomputed if not given)

    X0: array-like object or number, optional
        Initial condition (default = 0)

        Numbers are converted to constant arrays with the correct shape.

    input: int
        Index of the input that will be used in this simulation.

    output: int
        Index of the output that will be used in this simulation. Set to None
        to not trim outputs

    transpose: bool
        If True, transpose all input and output arrays (for backward
        compatibility with MATLAB and scipy.signal.lsim)

    Returns
    -------
    T: array
        Time values of the output
    yout: array
        Response of the system

    See Also
    --------
    ForcedReponse, initial_response, step_response

    Examples
    --------
    >>> T, yout = impulse_response(sys, T, X0)
    """
    sys = _get_ss_simo(sys, input, output)

    # System has direct feedthrough, can't simulate impulse response numerically
    if np.any(sys.D != 0) and isctime(sys):
        warnings.warn('System has direct feedthrough: ``D != 0``. The infinite '
                      'impulse at ``t=0`` does not appear in the output. \n'
                      'Results may be meaningless!')

    # create X0 if not given, test if X0 has correct shape.
    # Must be done here because it is used for computations here.
    n_states = sys.A.shape[0]
    X0 = _check_convert_array(X0, [(n_states,), (n_states, 1)],
                              'Parameter ``X0``: \n', squeeze=True)

    # Compute new X0 that contains the impulse
    # We can't put the impulse into U because there is no numerical
    # representation for it (infinitesimally short, infinitely high).
    # See also: http://www.mathworks.com/support/tech-notes/1900/1901.html
    B = np.asarray(sys.B).squeeze()
    new_X0 = B + X0

    # Compute T and U, no checks necessary, they will be checked in lsim
    if T is None:
        T = _default_response_times(sys.A, 100)
    U = np.zeros_like(T)

    T, yout, _xout = forced_response(
        sys, T, U, new_X0,
        transpose=transpose)
    return T, yout
def step_response(sys, T=None, X0=0., input=None, output=None,
                  transpose=False):
    # pylint: disable=W0622
    """Step response of a linear system

    If the system has multiple inputs or outputs (MIMO), one input has
    to be selected for the simulation. Optionally, one output may be
    selected. The parameters `input` and `output` do this. All other
    inputs are set to 0, all other outputs are ignored.

    For information on the **shape** of parameters `T`, `X0` and
    return values `T`, `yout`, see :ref:`time-series-convention`.

    Parameters
    ----------
    sys: StateSpace, or TransferFunction
        LTI system to simulate

    T: array-like object, optional
        Time vector (argument is autocomputed if not given)

    X0: array-like or number, optional
        Initial condition (default = 0)

        Numbers are converted to constant arrays with the correct shape.

    input: int
        Index of the input that will be used in this simulation.

    output: int
        Index of the output that will be used in this simulation. Set to None
        to not trim outputs

    transpose: bool
        If True, transpose all input and output arrays (for backward
        compatibility with MATLAB and scipy.signal.lsim)

    Returns
    -------
    T: array
        Time values of the output

    yout: array
        Response of the system

    See Also
    --------
    forced_response, initial_response, impulse_response

    Examples
    --------
    >>> T, yout = step_response(sys, T, X0)
    """
    sys = _get_ss_simo(sys, input, output)
    if T is None:
        if isctime(sys):
            T = _default_response_times(sys.A, 100)
        else:
            # For discrete time, use integers
            tvec = _default_response_times(sys.A, 100)
            T = range(int(np.ceil(max(tvec))))

    U = np.ones_like(T)

    T, yout, _xout = forced_response(sys, T, U, X0,
                                     transpose=transpose)

    return T, yout
def initial_response(sys, T=None, X0=0., input=0, output=None,
                     transpose=False):
    # pylint: disable=W0622
    """Initial condition response of a linear system

    If the system has multiple outputs (MIMO), optionally, one output
    may be selected. If no selection is made for the output, all
    outputs are given.

    For information on the **shape** of parameters `T`, `X0` and
    return values `T`, `yout`, see :ref:`time-series-convention`.

    Parameters
    ----------
    sys: StateSpace, or TransferFunction
        LTI system to simulate

    T: array-like object, optional
        Time vector (argument is autocomputed if not given)

    X0: array-like object or number, optional
        Initial condition (default = 0)

        Numbers are converted to constant arrays with the correct shape.

    input: int
        Ignored, has no meaning in initial condition calculation. Parameter
        ensures compatibility with step_response and impulse_response

    output: int
        Index of the output that will be used in this simulation. Set to None
        to not trim outputs

    transpose: bool
        If True, transpose all input and output arrays (for backward
        compatibility with MATLAB and scipy.signal.lsim)

    Returns
    -------
    T: array
        Time values of the output
    yout: array
        Response of the system

    See Also
    --------
    forced_response, impulse_response, step_response

    Examples
    --------
    >>> T, yout = initial_response(sys, T, X0)
    """
    sys = _get_ss_simo(sys, input, output)

    # Create time and input vectors; checking is done in forced_response(...)
    # The initial vector X0 is created in forced_response(...) if necessary
    if T is None:
        T = _default_response_times(sys.A, 100)
    U = np.zeros_like(T)

    T, yout, _xout = forced_response(sys, T, U, X0, transpose=transpose)
    return T, yout
def step_info(sys, T=None, SettlingTimeThreshold=0.02,
              RiseTimeLimits=(0.1, 0.9)):
    '''
    Step response characteristics (Rise time, Settling Time, Peak and others).

    Parameters
    ----------
    sys: StateSpace, or TransferFunction
        LTI system to simulate

    T: array-like object, optional
        Time vector (argument is autocomputed if not given)

    SettlingTimeThreshold: float value, optional
        Defines the error to compute settling time (default = 0.02)

    RiseTimeLimits: tuple (lower_threshold, upper_theshold)
        Defines the lower and upper threshold for RiseTime computation

    Returns
    -------
    S: a dictionary containing:
        RiseTime: Time from 10% to 90% of the steady-state value.
        SettlingTime: Time to enter inside a default error of 2%
        SettlingMin: Minimum value after RiseTime
        SettlingMax: Maximum value after RiseTime
        Overshoot: Percentage of the Peak relative to steady value
        Undershoot: Percentage of undershoot
        Peak: Absolute peak value
        PeakTime: time of the Peak
        SteadyStateValue: Steady-state value


    See Also
    --------
    step, lsim, initial, impulse

    Examples
    --------
    >>> info = step_info(sys, T)
    '''
    sys = _get_ss_simo(sys)
    if T is None:
        if isctime(sys):
            T = _default_response_times(sys.A, 1000)
        else:
            # For discrete time, use integers
            tvec = _default_response_times(sys.A, 1000)
            T = range(int(np.ceil(max(tvec))))

    T, yout = step_response(sys, T)

    # Steady state value
    InfValue = yout[-1]

    # RiseTime
    tr_lower_index = (np.where(yout >= RiseTimeLimits[0] * InfValue)[0])[0]
    tr_upper_index = (np.where(yout >= RiseTimeLimits[1] * InfValue)[0])[0]
    RiseTime = T[tr_upper_index] - T[tr_lower_index]

    # SettlingTime
    sup_margin = (1. + SettlingTimeThreshold) * InfValue
    inf_margin = (1. - SettlingTimeThreshold) * InfValue
    # find Steady State looking for the first point out of specified limits
    for i in reversed(range(T.size)):
        if((yout[i] <= inf_margin) | (yout[i] >= sup_margin)):
            SettlingTime = T[i + 1]
            break

    # Peak
    PeakIndex = np.abs(yout).argmax()
    PeakValue = yout[PeakIndex]
    PeakTime = T[PeakIndex]
    SettlingMax = (yout).max()
    SettlingMin = (yout[tr_upper_index:]).min()
    # I'm really not very confident about UnderShoot:
    UnderShoot = yout.min()
    OverShoot = 100. * (yout.max() - InfValue) / (InfValue - yout[0])

    # Return as a dictionary
    S = {
        'RiseTime': RiseTime,
        'SettlingTime': SettlingTime,
        'SettlingMin': SettlingMin,
        'SettlingMax': SettlingMax,
        'Overshoot': OverShoot,
        'Undershoot': UnderShoot,
        'Peak': PeakValue,
        'PeakTime': PeakTime,
        'SteadyStateValue': InfValue
    }

    return S
Beispiel #5
0
def initial_response(sys, T=None, X0=0., input=0, output=0, transpose=False,
                    **keywords):
    #pylint: disable=W0622
    """Initial condition response of a linear system
    
    If the system has multiple inputs or outputs (MIMO), one input and one 
    output have to be selected for the simulation. The parameters `input` 
    and `output` do this. All other inputs are set to 0, all other outputs 
    are ignored.
    
    For information on the **shape** of parameters `T`, `X0` and 
    return values `T`, `yout` see: :ref:`time-series-convention`

    Parameters
    ----------
    sys: StateSpace, or TransferFunction
        LTI system to simulate

    T: array-like object, optional
        Time vector (argument is autocomputed if not given)

    X0: array-like object or number, optional
        Initial condition (default = 0)

        Numbers are converted to constant arrays with the correct shape.

    input: int
        Index of the input that will be used in this simulation.

    output: int
        Index of the output that will be used in this simulation.

    transpose: bool
        If True, transpose all input and output arrays (for backward
        compatibility with MATLAB and scipy.signal.lsim)

    **keywords:
        Additional keyword arguments control the solution algorithm for the 
        differential equations. These arguments are passed on to the function
        :func:`lsim`, which in turn passes them on to
        :func:`scipy.integrate.odeint`. See the documentation for
        :func:`scipy.integrate.odeint` for information about these
        arguments.


    Returns
    -------
    T: array
        Time values of the output
    yout: array
        Response of the system
    
    See Also
    --------
    forced_response, impulse_response, step_response

    Examples
    --------
    >>> T, yout = initial_response(sys, T, X0)
    """
    sys = _convertToStateSpace(sys) 
    sys = _mimo2siso(sys, input, output, warn_conversion=True)

    # Create time and input vectors; checking is done in forced_response(...)
    # The initial vector X0 is created in forced_response(...) if necessary
    if T is None:
        T = _default_response_times(sys.A, 100)
    U = np.zeros_like(T)

    T, yout, _xout = forced_response(sys, T, U, X0, transpose=transpose,
                                    **keywords)
    return T, yout
Beispiel #6
0
def step_response(sys,
                  T=None,
                  X0=0.,
                  input=None,
                  output=None,
                  transpose=False,
                  return_x=False,
                  squeeze=True):
    # pylint: disable=W0622
    """Step response of a linear system

    If the system has multiple inputs or outputs (MIMO), one input has
    to be selected for the simulation. Optionally, one output may be
    selected. The parameters `input` and `output` do this. All other
    inputs are set to 0, all other outputs are ignored.

    For information on the **shape** of parameters `T`, `X0` and
    return values `T`, `yout`, see :ref:`time-series-convention`.

    Parameters
    ----------
    sys: StateSpace, or TransferFunction
        LTI system to simulate

    T: array-like object, optional
        Time vector (argument is autocomputed if not given)

    X0: array-like or number, optional
        Initial condition (default = 0)

        Numbers are converted to constant arrays with the correct shape.

    input: int
        Index of the input that will be used in this simulation.

    output: int
        Index of the output that will be used in this simulation. Set to None
        to not trim outputs

    transpose: bool
        If True, transpose all input and output arrays (for backward
        compatibility with MATLAB and scipy.signal.lsim)

    return_x: bool
        If True, return the state vector (default = False).

    squeeze: bool, optional (default=True)
        If True, remove single-dimensional entries from the shape of
        the output.  For single output systems, this converts the
        output response to a 1D array.

    Returns
    -------
    T: array
        Time values of the output

    yout: array
        Response of the system

    xout: array
        Individual response of each x variable

    See Also
    --------
    forced_response, initial_response, impulse_response

    Examples
    --------
    >>> T, yout = step_response(sys, T, X0)
    """
    sys = _get_ss_simo(sys, input, output)
    if T is None:
        if isctime(sys):
            T = _default_response_times(sys.A, 100)
        else:
            # For discrete time, use integers
            tvec = _default_response_times(sys.A, 100)
            T = range(int(np.ceil(max(tvec))))

    U = np.ones_like(T)

    T, yout, xout = forced_response(sys,
                                    T,
                                    U,
                                    X0,
                                    transpose=transpose,
                                    squeeze=squeeze)

    if return_x:
        return T, yout, xout

    return T, yout
def impulse_response(sys,
                     T=None,
                     X0=0.,
                     input=0,
                     output=None,
                     transpose=False,
                     return_x=False):
    # pylint: disable=W0622
    """Impulse response of a linear system

    If the system has multiple inputs or outputs (MIMO), one input has
    to be selected for the simulation. Optionally, one output may be
    selected. The parameters `input` and `output` do this. All other
    inputs are set to 0, all other outputs are ignored.

    For information on the **shape** of parameters `T`, `X0` and
    return values `T`, `yout`, see :ref:`time-series-convention`.

    Parameters
    ----------
    sys: StateSpace, TransferFunction
        LTI system to simulate

    T: array-like object, optional
        Time vector (argument is autocomputed if not given)

    X0: array-like object or number, optional
        Initial condition (default = 0)

        Numbers are converted to constant arrays with the correct shape.

    input: int
        Index of the input that will be used in this simulation.

    output: int
        Index of the output that will be used in this simulation. Set to None
        to not trim outputs

    transpose: bool
        If True, transpose all input and output arrays (for backward
        compatibility with MATLAB and scipy.signal.lsim)

    return_x: bool
        If True, return the state vector (default = False).

    Returns
    -------
    T: array
        Time values of the output
    yout: array
        Response of the system
    xout: array
        Individual response of each x variable

    See Also
    --------
    forced_response, initial_response, step_response

    Examples
    --------
    >>> T, yout = impulse_response(sys, T, X0)
    """
    sys = _get_ss_simo(sys, input, output)

    # System has direct feedthrough, can't simulate impulse response numerically
    if np.any(sys.D != 0) and isctime(sys):
        warnings.warn(
            'System has direct feedthrough: ``D != 0``. The infinite '
            'impulse at ``t=0`` does not appear in the output. \n'
            'Results may be meaningless!')

    # create X0 if not given, test if X0 has correct shape.
    # Must be done here because it is used for computations here.
    n_states = sys.A.shape[0]
    X0 = _check_convert_array(X0, [(n_states, ), (n_states, 1)],
                              'Parameter ``X0``: \n',
                              squeeze=True)

    # Compute T and U, no checks necessary, they will be checked in lsim
    if T is None:
        T = _default_response_times(sys.A, 100)
    U = np.zeros_like(T)

    # Compute new X0 that contains the impulse
    # We can't put the impulse into U because there is no numerical
    # representation for it (infinitesimally short, infinitely high).
    # See also: http://www.mathworks.com/support/tech-notes/1900/1901.html
    if isctime(sys):
        B = np.asarray(sys.B).squeeze()
        new_X0 = B + X0
    else:
        new_X0 = X0
        U[0] = 1.

    T, yout, _xout = forced_response(sys, T, U, new_X0, transpose=transpose)

    if return_x:
        return T, yout, _xout

    return T, yout
def initial_response(sys,
                     T=None,
                     X0=0.,
                     input=0,
                     output=None,
                     transpose=False,
                     return_x=False):
    # pylint: disable=W0622
    """Initial condition response of a linear system

    If the system has multiple outputs (MIMO), optionally, one output
    may be selected. If no selection is made for the output, all
    outputs are given.

    For information on the **shape** of parameters `T`, `X0` and
    return values `T`, `yout`, see :ref:`time-series-convention`.

    Parameters
    ----------
    sys: StateSpace, or TransferFunction
        LTI system to simulate

    T: array-like object, optional
        Time vector (argument is autocomputed if not given)

    X0: array-like object or number, optional
        Initial condition (default = 0)

        Numbers are converted to constant arrays with the correct shape.

    input: int
        Ignored, has no meaning in initial condition calculation. Parameter
        ensures compatibility with step_response and impulse_response

    output: int
        Index of the output that will be used in this simulation. Set to None
        to not trim outputs

    transpose: bool
        If True, transpose all input and output arrays (for backward
        compatibility with MATLAB and scipy.signal.lsim)

    return_x: bool
        If True, return the state vector (default = False).

    Returns
    -------
    T: array
        Time values of the output
    yout: array
        Response of the system
    xout: array
        Individual response of each x variable

    See Also
    --------
    forced_response, impulse_response, step_response

    Examples
    --------
    >>> T, yout = initial_response(sys, T, X0)
    """
    sys = _get_ss_simo(sys, input, output)

    # Create time and input vectors; checking is done in forced_response(...)
    # The initial vector X0 is created in forced_response(...) if necessary
    if T is None:
        T = _default_response_times(sys.A, 100)
    U = np.zeros_like(T)

    T, yout, _xout = forced_response(sys, T, U, X0, transpose=transpose)

    if return_x:
        return T, yout, _xout

    return T, yout
Beispiel #9
0
def step_info(sys,
              T=None,
              SettlingTimeThreshold=0.02,
              RiseTimeLimits=(0.1, 0.9)):
    '''
    Step response characteristics (Rise time, Settling Time, Peak and others).

    Parameters
    ----------
    sys: StateSpace, or TransferFunction
        LTI system to simulate

    T: array-like object, optional
        Time vector (argument is autocomputed if not given)

    SettlingTimeThreshold: float value, optional
        Defines the error to compute settling time (default = 0.02)

    RiseTimeLimits: tuple (lower_threshold, upper_theshold)
        Defines the lower and upper threshold for RiseTime computation

    Returns
    -------
    S: a dictionary containing:
        RiseTime: Time from 10% to 90% of the steady-state value.
        SettlingTime: Time to enter inside a default error of 2%
        SettlingMin: Minimum value after RiseTime
        SettlingMax: Maximum value after RiseTime
        Overshoot: Percentage of the Peak relative to steady value
        Undershoot: Percentage of undershoot
        Peak: Absolute peak value
        PeakTime: time of the Peak
        SteadyStateValue: Steady-state value


    See Also
    --------
    step, lsim, initial, impulse

    Examples
    --------
    >>> info = step_info(sys, T)
    '''
    sys = _get_ss_simo(sys)
    if T is None:
        if isctime(sys):
            T = _default_response_times(sys.A, 1000)
        else:
            # For discrete time, use integers
            tvec = _default_response_times(sys.A, 1000)
            T = range(int(np.ceil(max(tvec))))

    T, yout = step_response(sys, T)

    # Steady state value
    InfValue = yout[-1]

    # RiseTime
    tr_lower_index = (np.where(yout >= RiseTimeLimits[0] * InfValue)[0])[0]
    tr_upper_index = (np.where(yout >= RiseTimeLimits[1] * InfValue)[0])[0]
    RiseTime = T[tr_upper_index] - T[tr_lower_index]

    # SettlingTime
    sup_margin = (1. + SettlingTimeThreshold) * InfValue
    inf_margin = (1. - SettlingTimeThreshold) * InfValue
    # find Steady State looking for the first point out of specified limits
    for i in reversed(range(T.size)):
        if ((yout[i] <= inf_margin) | (yout[i] >= sup_margin)):
            SettlingTime = T[i + 1]
            break

    # Peak
    PeakIndex = np.abs(yout).argmax()
    PeakValue = yout[PeakIndex]
    PeakTime = T[PeakIndex]
    SettlingMax = (yout).max()
    SettlingMin = (yout[tr_upper_index:]).min()
    # I'm really not very confident about UnderShoot:
    UnderShoot = yout.min()
    OverShoot = 100. * (yout.max() - InfValue) / (InfValue - yout[0])

    # Return as a dictionary
    S = {
        'RiseTime': RiseTime,
        'SettlingTime': SettlingTime,
        'SettlingMin': SettlingMin,
        'SettlingMax': SettlingMax,
        'Overshoot': OverShoot,
        'Undershoot': UnderShoot,
        'Peak': PeakValue,
        'PeakTime': PeakTime,
        'SteadyStateValue': InfValue
    }

    return S
Beispiel #10
0
def initial_response(sys,
                     T=None,
                     X0=0.,
                     input=0,
                     output=None,
                     transpose=False,
                     **keywords):
    #pylint: disable=W0622
    """Initial condition response of a linear system
    
    If the system has multiple inputs or outputs (MIMO), one input and one 
    output have to be selected for the simulation. The parameters `input` 
    and `output` do this. All other inputs are set to 0, all other outputs 
    are ignored.
    
    For information on the **shape** of parameters `T`, `X0` and 
    return values `T`, `yout` see: :ref:`time-series-convention`

    Parameters
    ----------
    sys: StateSpace, or TransferFunction
        LTI system to simulate

    T: array-like object, optional
        Time vector (argument is autocomputed if not given)

    X0: array-like object or number, optional
        Initial condition (default = 0)

        Numbers are converted to constant arrays with the correct shape.

    input: int
        Index of the input that will be used in this simulation.

    output: int
        Index of the output that will be used in this simulation. Set to None
        to not trim outputs

    transpose: bool
        If True, transpose all input and output arrays (for backward
        compatibility with MATLAB and scipy.signal.lsim)

    **keywords:
        Additional keyword arguments control the solution algorithm for the 
        differential equations. These arguments are passed on to the function
        :func:`lsim`, which in turn passes them on to
        :func:`scipy.integrate.odeint`. See the documentation for
        :func:`scipy.integrate.odeint` for information about these
        arguments.


    Returns
    -------
    T: array
        Time values of the output
    yout: array
        Response of the system
    
    See Also
    --------
    forced_response, impulse_response, step_response

    Examples
    --------
    >>> T, yout = initial_response(sys, T, X0)
    """
    sys = _convertToStateSpace(sys)
    if output == None:
        sys = _mimo2simo(sys, input, warn_conversion=False)
    else:
        sys = _mimo2siso(sys, input, output, warn_conversion=False)

    # Create time and input vectors; checking is done in forced_response(...)
    # The initial vector X0 is created in forced_response(...) if necessary
    if T is None:
        T = _default_response_times(sys.A, 100)
    U = np.zeros_like(T)

    T, yout, _xout = forced_response(sys,
                                     T,
                                     U,
                                     X0,
                                     transpose=transpose,
                                     **keywords)
    return T, yout