<commit_before>from functools import partial, singledispatch
import warnings
import numbers
from typing import Union, Tuple, List

from tcontrol.transferfunction import TransferFunction, _tf_to_symbol
from tcontrol.statespace import StateSpace, tf2ss
from tcontrol.plot_utility import _plot_response_curve
import numpy as np
import sympy as sym

__all__ = ['impulse', 'step', 'ramp', 'any_input']


def __get_cs(sys_, input_signal):
    """

    :param sys_:
    :type sys_: TransferFunction
    :param input_signal:
    :type input_signal: str
    :return:
    :rtype: sym.Add
    """
    from sympy.parsing.sympy_parser import parse_expr

    s = sym.Symbol('s')
    t = sym.Symbol('t')

    input_expr = sym.simplify(parse_expr(input_signal))

    signal_table = {'step': 1/s, 'impulse': 1, '0': 0, 'ramp': 1/s**2,
                    'user': sym.laplace_transform(input_expr, t, s)[0]}
    gs, *_ = _tf_to_symbol(sys_.num, sys_.den)
    cs = gs*signal_table.get(input_signal, signal_table["user"])
    return cs


def __ilaplace(expr):
    """
    Use:
        conduct the ilaplace transform

    :param expr: the expression
    :type expr: sympy.Add
    :return:
    :rtype:
    """
    from sympy.integrals.transforms import inverse_laplace_transform
    s = sym.Symbol('s')
    t = sym.Symbol('t')
    cs = expr.apart(s)

    tmp = sum(cs.args)
    if expr.equals(tmp):
        polys = [sym.nsimplify(i, tolerance=0.001, rational=True) for i in tmp.args]
        ilaplace_p = partial(inverse_laplace_transform, s=s, t=t)
        ct = 0
        for i in polys:
            i = ilaplace_p(i)
            ct += i
    else:
        cs = sym.nsimplify(expr, tolerance=0.001, rational=True)
        ct = inverse_laplace_transform(cs, s, t)

    if ct.has(sym.Heaviside):
        ct = ct.replace(sym.Heaviside, sym.numbers.One)
    if ct.has(sym.InverseLaplaceTransform):
        ct = ct.replace(sym.InverseLaplaceTransform, sym.numbers.Zero)

    return ct


# convert system to state space then get result
def _any_input(sys_, t, input_signal=0, init_cond=None):
    """
    Accept any input signal, then calculate the response of the system.

    :param sys_: the system
    :type sys_: TransferFunction | StateSpace
    :param t: time
    :type t: np.ndarray
    :param input_signal: input signal accepted by the system
    :type input_signal: numbers.Real | np.ndarray
    :param init_cond: initial condition of the system
    :type init_cond: None | numbers.Real | np.ndarray

    :return: system output and time array
    :rtype: Tuple[np.ndarray, np.ndarray]

    :raises TypeError: when give wrong types of arguments
    :raises ValueError: raised when t, input_signal or init_cond has a wrong shape
    :raises NotImplementedError: when system is a MIMO system

    .. note:: This is internal api.
    """
    # convert transfer function or continuous system to discrete system
    dt = t[1] - t[0]
    if dt > 0.02 and sys_.is_ctime:
        warnings.warn("Large sample time will lead to low accuracy.",
                      stacklevel=3)

    if sys_.is_ctime:
        d_sys_ = StateSpace.discretize(sys_, dt)
    else:
        if _is_dt_validated(sys_, dt):
            d_sys_ = sys_<commit_msg>refactor: replace discretize with c2d<commit_after>from functools import partial, singledispatch
import warnings
import numbers
from typing import Union, Tuple, List

from .transferfunction import TransferFunction, _tf_to_symbol
from .statespace import StateSpace, tf2ss
from .plot_utility import _plot_response_curve
from .discretization import c2d
import numpy as np
import sympy as sym

__all__ = ['impulse', 'step', 'ramp', 'any_input']


def __get_cs(sys_, input_signal):
    """

    :param sys_:
    :type sys_: TransferFunction
    :param input_signal:
    :type input_signal: str
    :return:
    :rtype: sym.Add
    """
    from sympy.parsing.sympy_parser import parse_expr

    s = sym.Symbol('s')
    t = sym.Symbol('t')

    input_expr = sym.simplify(parse_expr(input_signal))

    signal_table = {'step': 1/s, 'impulse': 1, '0': 0, 'ramp': 1/s**2,
                    'user': sym.laplace_transform(input_expr, t, s)[0]}
    gs, *_ = _tf_to_symbol(sys_.num, sys_.den)
    cs = gs*signal_table.get(input_signal, signal_table["user"])
    return cs


def __ilaplace(expr):
    """
    Use:
        conduct the ilaplace transform

    :param expr: the expression
    :type expr: sympy.Add
    :return:
    :rtype:
    """
    from sympy.integrals.transforms import inverse_laplace_transform
    s = sym.Symbol('s')
    t = sym.Symbol('t')
    cs = expr.apart(s)

    tmp = sum(cs.args)
    if expr.equals(tmp):
        polys = [sym.nsimplify(i, tolerance=0.001, rational=True) for i in tmp.args]
        ilaplace_p = partial(inverse_laplace_transform, s=s, t=t)
        ct = 0
        for i in polys:
            i = ilaplace_p(i)
            ct += i
    else:
        cs = sym.nsimplify(expr, tolerance=0.001, rational=True)
        ct = inverse_laplace_transform(cs, s, t)

    if ct.has(sym.Heaviside):
        ct = ct.replace(sym.Heaviside, sym.numbers.One)
    if ct.has(sym.InverseLaplaceTransform):
        ct = ct.replace(sym.InverseLaplaceTransform, sym.numbers.Zero)

    return ct


# convert system to state space then get result
def _any_input(sys_, t, input_signal=0, init_cond=None):
    """
    Accept any input signal, then calculate the response of the system.

    :param sys_: the system
    :type sys_: TransferFunction | StateSpace
    :param t: time
    :type t: np.ndarray
    :param input_signal: input signal accepted by the system
    :type input_signal: numbers.Real | np.ndarray
    :param init_cond: initial condition of the system
    :type init_cond: None | numbers.Real | np.ndarray

    :return: system output and time array
    :rtype: Tuple[np.ndarray, np.ndarray]

    :raises TypeError: when give wrong types of arguments
    :raises ValueError: raised when t, input_signal or init_cond has a wrong shape
    :raises NotImplementedError: when system is a MIMO system

    .. note:: This is internal api.
    """
    # convert transfer function or continuous system to discrete system
    dt = t[1] - t[0]
    if dt > 0.02 and sys_.is_ctime:
        warnings.warn("Large sample time will lead to low accuracy.",
                      stacklevel=3)

    if sys_.is_ctime:
        d_sys_ = c2d(sys_, dt)
    else:
        if _is_dt_validated(sys_, dt):
            d_sys_ = sys_
{'fraction_non_alphanumeric': 0.10152363184079602, 'fraction_numerical': 0.00792910447761194, 'mean_word_length': 2.929749541844838, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '485219', 'n_tokens_mistral': 2181, 'n_tokens_neox': 2072, 'n_words': 613}