예제 #1
0
def test_apart():
    assert apart(1) == 1
    assert apart(1, x) == 1

    f, g = (x**2 + 1)/(x + 1), 2/(x + 1) + x - 1

    assert apart(f, full=False) == g
    assert apart(f, full=True) == g

    f, g = 1/(x+2)/(x+1), 1/(1 + x) - 1/(2 + x)

    assert apart(f, full=False) == g
    assert apart(f, full=True) == g

    f, g = 1/(x+1)/(x+5), -1/(5 + x)/4 + 1/(1 + x)/4

    assert apart(f, full=False) == g
    assert apart(f, full=True) == g

    assert apart((E*x+2)/(x-pi)*(x-1), x) == \
        2 - E + E*pi + E*x - (2 + E*pi)*(-pi + 1)/(x - pi)

    assert apart(Eq((x**2 + 1)/(x + 1), x), x) == Eq(x - 1 + 2/(x + 1), x)

    raises(NotImplementedError, "apart(1/(x + 1)/(y + 2))")
예제 #2
0
def test_apart():
    assert apart(1) == 1
    assert apart(1, x) == 1

    f, g = (x**2 + 1)/(x + 1), 2/(x + 1) + x - 1

    assert apart(f, full=False) == g
    assert apart(f, full=True) == g

    f, g = 1/(x+2)/(x+1), 1/(1 + x) - 1/(2 + x)

    assert apart(f, full=False) == g
    assert apart(f, full=True) == g

    f, g = 1/(x+1)/(x+5), -1/(5 + x)/4 + 1/(1 + x)/4

    assert apart(f, full=False) == g
    assert apart(f, full=True) == g

    assert apart((E*x+2)/(x-pi)*(x-1), x) == \
        2 - E + E*pi + E*x + (E*pi + 2)*(pi - 1)/(x - pi)

    assert apart(Eq((x**2 + 1)/(x + 1), x), x) == Eq(x - 1 + 2/(x + 1), x)

    raises(NotImplementedError, "apart(1/(x + 1)/(y + 2))")
예제 #3
0
def test_noncommutative_pseudomultivariate():
    class foo(Expr):
        is_commutative=False
    e = x/(x + x*y)
    c = 1/(1 + y)
    assert apart(e + foo(e)) == c + foo(c)
    assert apart(e*foo(e)) == c*foo(c)
예제 #4
0
def test_apart_extension():
    f = 2 / (x**2 + 1)
    g = I / (x + I) - I / (x - I)

    assert apart(f, extension=I) == g
    assert apart(f, gaussian=True) == g

    f = x / ((x - 2) * (x + I))

    assert factor(together(apart(f)).expand()) == f

    # https://github.com/sympy/sympy/issues/18531
    from sympy.core import Mul

    def mul2(expr):
        # 2-arg mul hack...
        return Mul(2, expr, evaluate=False)

    f = ((x**2 + 1)**3 / ((x - 1)**2 * (x + 1)**2 * (-x**2 + 2 * x + 1) *
                          (x**2 + 2 * x - 1)))
    g = (1 / mul2(x - sqrt(2) + 1) - 1 / mul2(x - sqrt(2) - 1) +
         1 / mul2(x + 1 + sqrt(2)) - 1 / mul2(x - 1 + sqrt(2)) + 1 / mul2(
             (x + 1)**2) + 1 / mul2((x - 1)**2))

    assert apart(f, x, extension={sqrt(2)}) == g
예제 #5
0
def test_apart_symbolic():
    f = a*x**4 + (2*b + 2*a*c)*x**3 + (4*b*c - a**2 + a*c**2)*x**2 + (-2*a*b + 2*b*c**2)*x - b**2
    g = a**2*x**4 + (2*a*b + 2*c*a**2)*x**3 + (4*a*b*c + b**2 + a**2*c**2)*x**2 + (2*c*b**2 + 2*a*b*c**2)*x + b**2*c**2

    assert apart(f/g, x) == 1/a - 1/(x + c)**2 - b**2/(a*(a*x + b)**2)

    assert apart(1/((x + a)*(x + b)*(x + c)), x) == \
        1/((a - c)*(b - c)*(c + x)) - 1/((a - b)*(b - c)*(b + x)) + 1/((a - b)*(a - c)*(a + x))
예제 #6
0
def test_noncommutative_pseudomultivariate():
    # apart doesn't go inside noncommutative expressions
    class foo(Expr):
        is_commutative=False
    e = x/(x + x*y)
    c = 1/(1 + y)
    assert apart(e + foo(e)) == c + foo(c)
    assert apart(e*foo(e)) == c*foo(c)
예제 #7
0
def test_apart_symbolic():
    f = a*x**4 + (2*b + 2*a*c)*x**3 + (4*b*c - a**2 + a*c**2)*x**2 + (-2*a*b + 2*b*c**2)*x - b**2
    g = a**2*x**4 + (2*a*b + 2*c*a**2)*x**3 + (4*a*b*c + b**2 + a**2*c**2)*x**2 + (2*c*b**2 + 2*a*b*c**2)*x + b**2*c**2

    assert apart(f/g, x) == 1/a - 1/(x + c)**2 - b**2/(a*(a*x + b)**2)

    assert apart(1/((x + a)*(x + b)*(x + c)), x) == \
        1/((a - c)*(b - c)*(c + x)) - 1/((a - b)*(b - c)*(b + x)) + 1/((a - b)*(a - c)*(a + x))
예제 #8
0
def test_noncommutative_pseudomultivariate():
    class foo(Expr):
        is_commutative = False

    e = x / (x + x * y)
    c = 1 / (1 + y)
    assert apart(e + foo(e)) == c + foo(c)
    assert apart(e * foo(e)) == c * foo(c)
예제 #9
0
def test_noncommutative_pseudomultivariate():
    # apart doesn't go inside noncommutative expressions
    class foo(Expr):
        is_commutative=False
    e = x/(x + x*y)
    c = 1/(1 + y)
    assert apart(e + foo(e)) == c + foo(c)
    assert apart(e*foo(e)) == c*foo(c)
def test_apart_extension():
    f = 2 / (x**2 + 1)
    g = I / (x + I) - I / (x - I)

    assert apart(f, extension=I) == g
    assert apart(f, gaussian=True) == g

    f = x / ((x - 2) * (x + I))

    assert factor(together(apart(f)).expand()) == f
예제 #11
0
def test_apart_extension():
    f = 2/(x**2 + 1)
    g = I/(x + I) - I/(x - I)

    assert apart(f, extension=I) == g
    assert apart(f, gaussian=True) == g

    f = x/((x - 2)*(x + I))

    assert factor(together(apart(f))) == f
예제 #12
0
def test_issue_20163():
    assert apart(1/(x**6+1), extension=[sqrt(3), I]) == \
        (sqrt(3) + I)/(2*x + sqrt(3) + I)/6 + \
        (sqrt(3) - I)/(2*x + sqrt(3) - I)/6 - \
        (sqrt(3) - I)/(2*x - sqrt(3) + I)/6 - \
        (sqrt(3) + I)/(2*x - sqrt(3) - I)/6 + \
        I/(x + I)/6 - I/(x - I)/6
예제 #13
0
def test_noncommutative():
    class foo(Expr):
        is_commutative = False

    e = x / (x + x * y)
    c = 1 / (1 + y)
    assert apart(e + foo()) == c + foo()
예제 #14
0
def test_noncommutative():
    class foo(Expr):
        is_commutative = False

    e = x / (x + x * y)
    c = 1 / (1 + y)
    assert apart(e + foo()) == c + foo()
예제 #15
0
def test_apart_matrix():
    M = Matrix(2, 2, lambda i, j: 1 / (x + i + 1) / (x + j))

    assert apart(M) == Matrix([
        [1 / x - 1 / (x + 1), (x + 1)**(-2)],
        [1 / (2 * x) - (S.Half) / (x + 2), 1 / (x + 1) - 1 / (x + 2)],
    ])
예제 #16
0
def test_apart_matrix():
    M = Matrix(2, 2, lambda i, j: 1/(x + i + 1)/(x + j))

    assert apart(M) == Matrix([
        [1/x - 1/(x + 1),            (x + 1)**(-2)        ],
        [1/(2*x) - (S(1)/2)/(x + 2), 1/(x + 1) - 1/(x + 2)],
    ])
예제 #17
0
def test_apart_extension():
    f = 2 / (x**2 + 1)
    g = I / (x + I) - I / (x - I)

    assert apart(f, extension=I) == g
    assert apart(f, gaussian=True) == g

    f = x / ((x - 2) * (x + I))

    assert factor(together(apart(f)).expand()) == f

    f, g = _make_extension_example()

    # XXX: Only works with dotprodsimp. See test_apart_extension_xfail below
    from sympy.matrices import dotprodsimp
    with dotprodsimp(True):
        assert apart(f, x, extension={sqrt(2)}) == g
예제 #18
0
def test_apart_full():
    f = 1 / (x**2 + 1)

    assert apart(f, full=False) == f
    assert (apart(
        f, full=True) == -RootSum(x**2 + 1, Lambda(a, a /
                                                   (x - a)), auto=False) / 2)

    f = 1 / (x**3 + x + 1)

    assert apart(f, full=False) == f
    assert apart(f, full=True) == RootSum(
        x**3 + x + 1,
        Lambda(
            a,
            (a**2 * Rational(6, 31) - a * Rational(9, 31) + Rational(4, 31)) /
            (x - a),
        ),
        auto=False,
    )

    f = 1 / (x**5 + 1)

    assert apart(f, full=False) == (Rational(-1, 5)) * (
        (x**3 - 2 * x**2 + 3 * x - 4) /
        (x**4 - x**3 + x**2 - x + 1)) + (Rational(1, 5)) / (x + 1)
    assert apart(f, full=True) == -RootSum(
        x**4 - x**3 + x**2 - x + 1, Lambda(a, a / (x - a)), auto=False) / 5 + (
            Rational(1, 5)) / (x + 1)
예제 #19
0
def test_apart_full():
    f = 1/(x**2 + 1)

    assert apart(f, full=False) == f
    assert apart(f, full=True) == -RootSum(x**2 + 1, Lambda(a, a/(x - a)), auto=False)/2

    f = 1/(x**3 + x + 1)

    assert apart(f, full=False) == f
    assert apart(f, full=True) == RootSum(x**3 + x + 1, Lambda(a, (6*a**2/31 - 9*a/31 + S(4)/31)/(x - a)), auto=False)

    f = 1/(x**5 + 1)

    assert apart(f, full=False) == \
        (-S(1)/5)*((x**3 - 2*x**2 + 3*x - 4)/(x**4 - x**3 + x**2 - x + 1)) + (S(1)/5)/(x + 1)
    assert apart(f, full=True) == \
        -RootSum(x**4 - x**3 + x**2 - x + 1, Lambda(a, a/(x - a)), auto=False)/5 + (S(1)/5)/(x + 1)
def test_apart_full():
    f = 1 / (x**2 + 1)

    assert apart(f, full=False) == f
    assert apart(f, full=True) == \
        -RootSum(x**2 + 1, Lambda(a, a/(x - a)), auto=False)/2

    f = 1 / (x**3 + x + 1)

    assert apart(f, full=False) == f
    assert apart(f, full=True) == \
        RootSum(x**3 + x + 1,
        Lambda(a, (6*a**2/31 - 9*a/31 + S(4)/31)/(x - a)), auto=False)

    f = 1 / (x**5 + 1)

    assert apart(f, full=False) == \
        (-S(1)/5)*((x**3 - 2*x**2 + 3*x - 4)/(x**4 - x**3 + x**2 -
         x + 1)) + (S(1)/5)/(x + 1)
    assert apart(f, full=True) == \
        -RootSum(x**4 - x**3 + x**2 - x + 1,
        Lambda(a, a/(x - a)), auto=False)/5 + (S(1)/5)/(x + 1)
예제 #21
0
def test_apart_extension_xfail():
    f, g = _make_extension_example()
    assert apart(f, x, extension={sqrt(2)}) == g
예제 #22
0
def partFrac(expr, Ndigits):
    expr = expr.cancel()
    expr = apart(adjustCoeff(expr), s, full=True).doit()
    
    return sp.N(expr, Ndigits)
예제 #23
0
def test_issue_5798():
    assert apart(
        2*x/(x**2 + 1) - (x - 1)/(2*(x**2 + 1)) + 1/(2*(x + 1)) - 2/x) == \
        (3*x + 1)/(x**2 + 1)/2 + 1/(x + 1)/2 - 2/x
예제 #24
0
    def _run(self, num_str, denum_str, in_type):
        in_allowed = ['real', 'pwl']
        assert in_type in in_allowed, 'Allowed input stimulus should be among %s' % in_allowed

        # create symbols
        rsvd_var = ['t', 's', 'si', 'si_a', 'si_b']
        expr = S('(' + num_str + ')/(' + denum_str + ')')
        for x in expr.atoms():
            if str(x) not in rsvd_var:
                try:
                    float(x)
                except:
                    vars()[str(x)] = Symbol(str(x), real=True)

        t, s, si, si_a, si_b = symbols(' '.join(rsvd_var), real=True)

        # transfer function
        num = eval(num_str)
        denum = eval(denum_str)
        TF = num / denum

        # input
        if in_type == 'pwl':
            xin = si_a / s + si_b / s**2
            in_str = 'ramp'
        else:
            xin = si / s
            in_str = 'step'

        # forced response
        Ysf = (TF * xin)  # forced respose

        # natural response
        ais_d, order_denum = self.__get_order(denum)
        ais_n, order_num = self.__get_order(num)

        yos = ['yo%d' % x for x in range(order_denum)]
        for v in yos:
            vars()[v] = Symbol(v, real=True)
        xis = ['xi%d' % x for x in range(order_denum)]
        for v in xis:
            vars()[v] = Symbol(v, real=True)

        s = Symbol('s', real=True)  # Why does 's' symbol disappear
        init_yo = self.__get_init_expr(ais_d, order_denum, 'yo')
        init_xi = self.__get_init_expr(ais_n, order_num, 'xi')
        init_expr = init_yo
        if init_xi != '':
            init_expr = init_expr + '-' + init_xi
        Ysn = eval(
            init_expr
        ) / denum  # I hate eval(), but S() and parse_expr() screw me

        Ys = Ysf + Ysn  # Complete Transfer function
        Ys_pfd = apart(Ys, s)
        yt, yt_basis = self.__inv_laplace(
            Ys_pfd.as_ordered_terms())  # complete time-domain response

        # sort out basis
        yt_basis.sort(key=lambda tup: tup[0])

        self.__print_fn('Transfer Function', TF)
        self.__print_fn('Forced response in s-domain to %s input' % in_str,
                        Ysf)
        self.__print_fn('natural response in s-domain', Ysn)
        self.__print_fn(
            'Complete response in s-domain after partial fraction decomposition',
            Ys_pfd)
        self.__print_fn(
            'Complete response in time domain to %s input' % in_str, yt)

        print '=' * 40
        print 'Nonpretty expression for y(t)'
        print '=' * 40
        print 'y(t)= ', yt

        return yt_basis
예제 #25
0
def test_apart():
    assert apart(1) == 1
    assert apart(1, x) == 1

    f, g = (x**2 + 1) / (x + 1), 2 / (x + 1) + x - 1

    assert apart(f, full=False) == g
    assert apart(f, full=True) == g

    f, g = 1 / (x + 2) / (x + 1), 1 / (1 + x) - 1 / (2 + x)

    assert apart(f, full=False) == g
    assert apart(f, full=True) == g

    f, g = 1 / (x + 1) / (x + 5), -1 / (5 + x) / 4 + 1 / (1 + x) / 4

    assert apart(f, full=False) == g
    assert apart(f, full=True) == g

    assert apart((E*x + 2)/(x - pi)*(x - 1), x) == \
        2 - E + E*pi + E*x + (E*pi + 2)*(pi - 1)/(x - pi)

    assert apart(Eq((x**2 + 1) / (x + 1), x), x) == Eq(x - 1 + 2 / (x + 1), x)

    assert apart(x / 2, y) == x / 2

    f, g = (x + y) / (2 * x - y), Rational(3, 2) * y / (2 * x - y) + S.Half

    assert apart(f, x, full=False) == g
    assert apart(f, x, full=True) == g

    f, g = (x + y) / (2 * x - y), 3 * x / (2 * x - y) - 1

    assert apart(f, y, full=False) == g
    assert apart(f, y, full=True) == g

    raises(NotImplementedError, lambda: apart(1 / (x + 1) / (y + 2)))
예제 #26
0
def test_apart_extension_xfail():
    if ON_TRAVIS:
        skip('Too slow for Travis')
    f, g = _make_extension_example()
    assert apart(f, x, extension={sqrt(2)}) == g
예제 #27
0
def test_apart_extension():
    f = 2 / (x**2 + 1)
    g = I / (x + I) - I / (x - I)

    assert apart(f, extension=I) == g
    assert apart(f, gaussian=True) == g
예제 #28
0
def test_apart_extension():
    f = 2/(x**2 + 1)
    g = I/(x + I) - I/(x - I)

    assert apart(f, extension=I) == g
    assert apart(f, gaussian=True) == g
예제 #29
0
def step_response_numerical_data(system,
                                 prec=8,
                                 lower_limit=0,
                                 upper_limit=10,
                                 **kwargs):
    """
    Returns the numerical values of the points in the step response plot
    of a SISO continuous-time system. By default, adaptive sampling
    is used. If the user wants to instead get an uniformly
    sampled response, then ``adaptive`` kwarg should be passed ``False``
    and ``nb_of_points`` must be passed as additional kwargs.
    Refer to the parameters of class :class:`sympy.plotting.plot.LineOver1DRangeSeries`
    for more details.

    Parameters
    ==========

    system : SISOLinearTimeInvariant
        The system for which the unit step response data is to be computed.
    prec : int, optional
        The decimal point precision for the point coordinate values.
        Defaults to 8.
    lower_limit : Number, optional
        The lower limit of the plot range. Defaults to 0.
    upper_limit : Number, optional
        The upper limit of the plot range. Defaults to 10.
    kwargs :
        Additional keyword arguments are passed to the underlying
        :class:`sympy.plotting.plot.LineOver1DRangeSeries` class.

    Returns
    =======

    tuple : (x, y)
        x = Time-axis values of the points in the step response. NumPy array.
        y = Amplitude-axis values of the points in the step response. NumPy array.

    Raises
    ======

    NotImplementedError
        When a SISO LTI system is not passed.

        When time delay terms are present in the system.

    ValueError
        When more than one free symbol is present in the system.
        The only variable in the transfer function should be
        the variable of the Laplace transform.

        When ``lower_limit`` parameter is less than 0.

    Examples
    ========

    >>> from sympy.abc import s
    >>> from sympy.physics.control.lti import TransferFunction
    >>> from sympy.physics.control.control_plots import step_response_numerical_data
    >>> tf1 = TransferFunction(s, s**2 + 5*s + 8, s)
    >>> step_response_numerical_data(tf1)   # doctest: +SKIP
    ([0.0, 0.025413462339411542, 0.0484508722725343, ... , 9.670250533855183, 9.844291913708725, 10.0],
    [0.0, 0.023844582399907256, 0.042894276802320226, ..., 6.828770759094287e-12, 6.456457160755703e-12])

    See Also
    ========

    step_response_plot

    """
    if lower_limit < 0:
        raise ValueError("Lower limit of time must be greater "
                         "than or equal to zero.")
    _check_system(system)
    _x = Dummy("x")
    expr = system.to_expr() / (system.var)
    expr = apart(expr, system.var, full=True)
    _y = _fast_inverse_laplace(expr, system.var, _x).evalf(prec)
    return LineOver1DRangeSeries(_y, (_x, lower_limit, upper_limit),
                                 **kwargs).get_points()
예제 #30
0
def test_issue_5798():
    assert apart(
        2*x/(x**2 + 1) - (x - 1)/(2*(x**2 + 1)) + 1/(2*(x + 1)) - 2/x) == \
        (3*x + 1)/(x**2 + 1)/2 + 1/(x + 1)/2 - 2/x
예제 #31
0
def impulse_response_numerical_data(system,
                                    prec=8,
                                    lower_limit=0,
                                    upper_limit=10,
                                    **kwargs):
    """
    Returns the numerical values of the points in the impulse response plot
    of a SISO continuous-time system. By default, adaptive sampling
    is used. If the user wants to instead get an uniformly
    sampled response, then ``adaptive`` kwarg should be passed ``False``
    and ``nb_of_points`` must be passed as additional kwargs.
    Refer to the parameters of class :class:`sympy.plotting.plot.LineOver1DRangeSeries`
    for more details.

    Parameters
    ==========

    system : SISOLinearTimeInvariant
        The system for which the impulse response data is to be computed.
    prec : int, optional
        The decimal point precision for the point coordinate values.
        Defaults to 8.
    lower_limit : Number, optional
        The lower limit of the plot range. Defaults to 0.
    upper_limit : Number, optional
        The upper limit of the plot range. Defaults to 10.
    kwargs :
        Additional keyword arguments are passed to the underlying
        :class:`sympy.plotting.plot.LineOver1DRangeSeries` class.

    Returns
    =======

    tuple : (x, y)
        x = Time-axis values of the points in the impulse response. NumPy array.
        y = Amplitude-axis values of the points in the impulse response. NumPy array.

    Raises
    ======

    NotImplementedError
        When a SISO LTI system is not passed.

        When time delay terms are present in the system.

    ValueError
        When more than one free symbol is present in the system.
        The only variable in the transfer function should be
        the variable of the Laplace transform.

        When ``lower_limit`` parameter is less than 0.

    Examples
    ========

    >>> from sympy.abc import s
    >>> from sympy.physics.control.lti import TransferFunction
    >>> from sympy.physics.control.control_plots import impulse_response_numerical_data
    >>> tf1 = TransferFunction(s, s**2 + 5*s + 8, s)
    >>> impulse_response_numerical_data(tf1)   # doctest: +SKIP
    ([0.0, 0.06616480200395854,... , 9.854500743565858, 10.0],
    [0.9999999799999999, 0.7042848373025861,...,7.170748906965121e-13, -5.1901263495547205e-12])

    See Also
    ========

    impulse_response_plot

    """
    if lower_limit < 0:
        raise ValueError("Lower limit of time must be greater "
                         "than or equal to zero.")
    _check_system(system)
    _x = Dummy("x")
    expr = system.to_expr()
    expr = apart(expr, system.var, full=True)
    _y = _fast_inverse_laplace(expr, system.var, _x).evalf(prec)
    return LineOver1DRangeSeries(_y, (_x, lower_limit, upper_limit),
                                 **kwargs).get_points()
예제 #32
0
def test_apart():
    assert apart(1) == 1
    assert apart(1, x) == 1

    f, g = (x**2 + 1)/(x + 1), 2/(x + 1) + x - 1

    assert apart(f, full=False) == g
    assert apart(f, full=True) == g

    f, g = 1/(x + 2)/(x + 1), 1/(1 + x) - 1/(2 + x)

    assert apart(f, full=False) == g
    assert apart(f, full=True) == g

    f, g = 1/(x + 1)/(x + 5), -1/(5 + x)/4 + 1/(1 + x)/4

    assert apart(f, full=False) == g
    assert apart(f, full=True) == g

    assert apart((E*x + 2)/(x - pi)*(x - 1), x) == \
        2 - E + E*pi + E*x + (E*pi + 2)*(pi - 1)/(x - pi)

    assert apart(Eq((x**2 + 1)/(x + 1), x), x) == Eq(x - 1 + 2/(x + 1), x)

    assert apart(x/2, y) == x/2

    f, g = (x+y)/(2*x - y), Rational(3/2)*y/((2*x - y)) + Rational(1/2)

    assert apart(f, x, full=False) == g
    assert apart(f, x, full=True) == g

    f, g = (x+y)/(2*x - y), 3*x/(2*x - y) - 1

    assert apart(f, y, full=False) == g
    assert apart(f, y, full=True) == g

    raises(NotImplementedError, lambda: apart(1/(x + 1)/(y + 2)))
예제 #33
0
def ramp_response_numerical_data(system,
                                 slope=1,
                                 prec=8,
                                 lower_limit=0,
                                 upper_limit=10,
                                 **kwargs):
    """
    Returns the numerical values of the points in the ramp response plot
    of a SISO continuous-time system. By default, adaptive sampling
    is used. If the user wants to instead get an uniformly
    sampled response, then ``adaptive`` kwarg should be passed ``False``
    and ``nb_of_points`` must be passed as additional kwargs.
    Refer to the parameters of class :class:`sympy.plotting.plot.LineOver1DRangeSeries`
    for more details.

    Parameters
    ==========

    system : SISOLinearTimeInvariant
        The system for which the ramp response data is to be computed.
    slope : Number, optional
        The slope of the input ramp function. Defaults to 1.
    prec : int, optional
        The decimal point precision for the point coordinate values.
        Defaults to 8.
    lower_limit : Number, optional
        The lower limit of the plot range. Defaults to 0.
    upper_limit : Number, optional
        The upper limit of the plot range. Defaults to 10.
    kwargs :
        Additional keyword arguments are passed to the underlying
        :class:`sympy.plotting.plot.LineOver1DRangeSeries` class.

    Returns
    =======

    tuple : (x, y)
        x = Time-axis values of the points in the ramp response plot. NumPy array.
        y = Amplitude-axis values of the points in the ramp response plot. NumPy array.

    Raises
    ======

    NotImplementedError
        When a SISO LTI system is not passed.

        When time delay terms are present in the system.

    ValueError
        When more than one free symbol is present in the system.
        The only variable in the transfer function should be
        the variable of the Laplace transform.

        When ``lower_limit`` parameter is less than 0.

        When ``slope`` is negative.

    Examples
    ========

    >>> from sympy.abc import s
    >>> from sympy.physics.control.lti import TransferFunction
    >>> from sympy.physics.control.control_plots import ramp_response_numerical_data
    >>> tf1 = TransferFunction(s, s**2 + 5*s + 8, s)
    >>> ramp_response_numerical_data(tf1)   # doctest: +SKIP
    (([0.0, 0.12166980856813935,..., 9.861246379582118, 10.0],
    [1.4504508011325967e-09, 0.006046440489058766,..., 0.12499999999568202, 0.12499999999661349]))

    See Also
    ========

    ramp_response_plot

    """
    if slope < 0:
        raise ValueError("Slope must be greater than or equal" " to zero.")
    if lower_limit < 0:
        raise ValueError("Lower limit of time must be greater "
                         "than or equal to zero.")
    _check_system(system)
    _x = Dummy("x")
    expr = (slope * system.to_expr()) / ((system.var)**2)
    expr = apart(expr, system.var, full=True)
    _y = _fast_inverse_laplace(expr, system.var, _x).evalf(prec)
    return LineOver1DRangeSeries(_y, (_x, lower_limit, upper_limit),
                                 **kwargs).get_points()