<commit_before>from .transferfunction import TransferFunction
from .statespace import StateSpace

import numpy as np

__all__ = ['tf2ss', 'ss2tf']


def tf2ss(sys_):
    """
    Convert transfer function model to state space model.

    :param sys_: the system
    :type sys_: TransferFunction

    :return: corresponded transfer function model
    :rtype: StateSpace
    """
    try:
        nump = np.poly1d(sys_.num)
        denp = np.poly1d(sys_.den)
    except AttributeError as e:
        raise TypeError("TransferFunction expected got {0}".format(type(sys_))) from e
    dt = sys_.dt

    if denp[denp.order] != 1:
        nump /= denp[denp.order]
        denp /= denp[denp.order]
    q, r = nump/denp
    num = r.coeffs
    bn = q.coeffs
    den = denp.coeffs
    D = np.matrix(bn)

    if sys_.is_gain:
        A = np.mat([[0]])
        B = np.mat([[0]])
        C = np.mat([[0]])
        return StateSpace(A, B, C, D, dt=dt)
    else:
        # generate matrix A
        A = np.zeros((1, den.shape[0] - 2))
        A = np.concatenate((A, np.eye(den.shape[0] - 2)), axis=0)
        den = den[1:]
        den = np.mat(den[::-1])
        A = np.concatenate((A, -den.T), axis=1)

        B = np.zeros(A.shape[0])
        B[A.shape[0] - num.shape[0]:] = num
        B = np.mat(B[::-1]).T
        c = np.zeros(A.shape[0])
        c[-1] = 1
        C = np.mat(c)
        return StateSpace(A.T, C.T, B.T, D, dt=dt)


def ss2tf(sys_):
    """
    Covert state space model to transfer function model.
    Only for SISO now

    a(s) = det(sI - A)
    R_{n-1} = I
    R_{n-2} = R_{n-1} * A + a_{n-1} * I
    E_{n-1} = C * R_{n-1} * B

    G(s) = (E_{n-1}s^{n-1} + E_{n-2}s^{n-2} + ... + E_0) / a(s) + D

    :param sys_: system
    :type sys_: StateSpace
    :return: corresponded transfer function model
    :rtype: TransferFunction
    """

    n = sys_.A.shape[0]
    p = sys_.B.shape[1]
    q = sys_.C.shape[0]

    cp = np.poly(sys_.A) # characteristic polynomial
    I = np.eye(n)
    R = I
    E = np.empty((n, q * p))

    for i in range(n):
        E[i] = (sys_.C @ R @ sys_.B).ravel('C')<commit_msg>refactor: simplify tf2ss codes<commit_after>from .transferfunction import TransferFunction
from .statespace import StateSpace

import numpy as np

__all__ = ['tf2ss', 'ss2tf']


def tf2ss(sys_):
    """
    Convert transfer function model to state space model.

    :param sys_: the system
    :type sys_: TransferFunction

    :return: corresponded transfer function model
    :rtype: StateSpace
    """
    try:
        nump = np.poly1d(sys_.num)
        denp = np.poly1d(sys_.den)
    except AttributeError as e:
        raise TypeError(f'TransferFunction expected got {type(sys_)}') from e

    if not sys_.is_siso:
        raise ValueError('tf2ss only for siso system right now.')

    dt = sys_.dt
    if denp[denp.order] != 1:
        nump /= denp[denp.order]
        denp /= denp[denp.order]
    q, r = nump / denp
    num = r.coeffs
    bn = q.coeffs
    den = denp.coeffs
    D = np.atleast_2d(bn)

    if sys_.is_gain:
        A = np.array([[0]])
        B = np.array([[0]])
        C = np.array([[0]])
    else:
        # generate matrix A
        n = den.shape[0] - 1
        A = np.zeros((n, n))
        A[0: n - 1, 1:] = np.eye(n - 1)
        den = den[1:]
        A[-1] = -den[::-1]

        B = np.zeros((n, 1))
        B[-1] = 1

        C = np.zeros((1, n))
        C[0, 0: num.shape[0]] = num[::-1]

    return StateSpace(A, B, C, D, dt=dt)


def ss2tf(sys_):
    """
    Covert state space model to transfer function model.
    Only for SISO now

    a(s) = det(sI - A)
    R_{n-1} = I
    R_{n-2} = R_{n-1} * A + a_{n-1} * I
    E_{n-1} = C * R_{n-1} * B

    G(s) = (E_{n-1}s^{n-1} + E_{n-2}s^{n-2} + ... + E_0) / a(s) + D

    :param sys_: system
    :type sys_: StateSpace
    :return: corresponded transfer function model
    :rtype: TransferFunction
    """

    n = sys_.A.shape[0]
    p = sys_.B.shape[1]
    q = sys_.C.shape[0]

    cp = np.poly(sys_.A)  # characteristic polynomial
    I = np.eye(n)
    R = I
    E = np.empty((n, q * p))

    for i in range(n):
        E[i] = (sys_.C @ R @ sys_.B).ravel('C')
{'fraction_non_alphanumeric': 0.1631718486382261, 'fraction_numerical': 0.020486864304651724, 'mean_word_length': 2.000723065798988, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '216258', 'n_tokens_mistral': 1691, 'n_tokens_neox': 1631, 'n_words': 410}