def calculateQTF(ABCDr):
    A, B, C, D = partitionABCD(ABCDr, 4)

    #Construct an ABCD description of the closed-loop system
    # sys is a tuple in A, B, C, D form
    Acl = A + np.dot(B[:, 2:4], C)
    Bcl = B
    Ccl = C
    Dcl = np.hstack((D[:, 0:2], np.eye(2)))
    #sys = (A + np.dot(B[:, 2:4], C), B, C,
    #       np.hstack((D[:, 0:2], np.eye(2))))

    #Calculate the 2x4 matrix of transfer functions
    tfs = np.empty((2, 4), dtype=object)
    # Each tf is a tuple in num, den form
    # tf[i, j] corresponds to the TF from input j to output i
    for i in range(2):
        for j in range(4):
            tfs[i, j] = ss2tf(Acl, Bcl, Ccl[i, :], Dcl[i, :], input=j)

    #Reduce these to NTF, STF, INTF and ISTF
    if any(tfs[0, 2][1] != tfs[1, 3][1]):
        raise RuntimeError('TF Denominator mismatch. Location 1')

    ntf_x = (0.5 * (tfs[0, 2][0] + tfs[1, 3][0]), tfs[0, 2][1])
    intf_x = (0.5 * (tfs[0, 2][0] - tfs[1, 3][0]), tfs[0, 2][1])

    if any(tfs[0, 3][1] != tfs[1, 2][1]):
        raise RuntimeError('TF Denominator mismatch. Location 2')

    ntf_y = (0.5 * (tfs[1, 2][0] - tfs[0, 3][0]), tfs[1, 2][1])
    intf_y = (0.5 * (tfs[1, 2][0] + tfs[0, 3][0]), tfs[1, 2][1])

    if any(ntf_x[1] != ntf_y[1]):
        raise RuntimeError('TF Denominator mismatch. Location 3')
    if any(tfs[0, 0][1] != tfs[1, 1][1]):
        raise RuntimeError('TF Denominator mismatch. Location 4')

    stf_x = (0.5 * (tfs[0, 0][0] + tfs[1, 1][0]), tfs[0, 0][1])
    istf_x = (0.5 * (tfs[0, 0][0] - tfs[1, 1][0]), tfs[0, 0][1])

    if any(tfs[0, 1][1] != tfs[1, 0][1]):
        raise RuntimeError('TF Denominator mismatch. Location 5')

    stf_y = (0.5 * (tfs[1, 0][0] - tfs[0, 1][0]), tfs[1, 0][1])
    istf_y = (0.5 * (tfs[1, 0][0] + tfs[0, 1][0]), tfs[1, 0][1])

    if any(stf_x[1] != stf_y[1]):
        raise RuntimeError('TF Denominator mismatch. Location 6')

    # suppress warnings about complex TFs
    #warning('off')
    ntf = cancelPZ(tf2zpk(ntf_x[0] + 1j*ntf_y[0], ntf_x[1]))
    intf = cancelPZ(tf2zpk(intf_x[0] + 1j*intf_y[0], intf_x[1]))
    stf = cancelPZ(tf2zpk(stf_x[0] + 1j*stf_y[0], ntf_x[1]))
    istf = cancelPZ(tf2zpk(istf_x[0] + 1j*istf_y[0], intf_x[1]))
    #warning('on')

    return ntf, stf, intf, istf
Calculate noise and signal transfer functions for a quadrature modulator
dataset/ETHPy150Open ggventurini/python-deltasigma/deltasigma/_calculateQTF.py/calculateQTF