Ejemplo n.º 1
0
def rga_plot(G, axlim=None, w_start=-2, w_end=2, points=100):
    '''
    Plots the relative gain interaction between each output and input pairing
    
    Parameters
    ----------
    G : numpy array
        plant model
              
    Returns
    -------
    fig(RGA) : figure
        A figure of subplots for each interaction between an output and
        an input.
    
    Example
    -------
    # Adapted from example 3.11 pg 86 S. Skogestad
    >>> def G(s):
    ...     G = 0.01*numpy.exp(-5*s)/((s + 1.72e-4)*(4.32*s + 1))*numpy.array([[-34.54*(s + 0.0572), 1.913], [-30.22*s, -9.188*(s + 6.95e-4)]])
    ...     return G
    >>> rga_plot(G, axlim=[None, None, 0., 1.], w_start=-5, w_end=2)
    
    
    Note
    ----
    This entry draws on and improves RGA.py.
    If accepted, then RGA.py could be removed from the repository
    '''

    if axlim is None:
        axlim = [None, None, None, None]

    w = numpy.logspace(w_start, w_end, points)
    s = w * 1j

    dim = numpy.shape(
        G(0))  # Number of rows and columns in SS transfer function
    freqresp = map(G, s)

    count = 0  # Arrange the individual RGA responses to be compatible with the plotting order of plt.subplot
    rga = numpy.zeros([dim[0] * dim[1], points])
    for i in range(dim[0]):
        for k in range(dim[1]):
            rga[count, :] = numpy.array(
                numpy.abs(([utils.RGA(Gfr)[i, k] for Gfr in freqresp])))
            count += 1

    plt.figure('RGA')
    plt.clf()
    plt.gcf().set_facecolor('white')

    plot_No = 1

    for i in range(dim[0]):
        for k in range(dim[1]):
            plt.subplot(dim[0], dim[1], plot_No)
            plt.semilogx(w, rga[plot_No - 1])

            plot_No += 1

            plt.ylabel('|$\lambda$$_{ %s, %s}$|' % (i + 1, k + 1))
            plt.axis(axlim)
            if i == dim[
                    0] - 1:  # To avoid clutter only plot xlabel on the very bottom subplots
                plt.xlabel('Frequency [rad/unit time]')
            plt.title('Output %s vs. input %s' % (i + 1, k + 1))

    plt.show()
    return
Ejemplo n.º 2
0
def rga_nm_plot(G, pairing=None, axlim=None, w_start=-2, w_end=2, points=100):
    '''
    Plots the RGA number for a specified pairing
    
    Parameters
    ----------
    G : numpy array
        plant model
    
    pairing : sparse numpy array of the same shape as G
        An array of zeros with a 1. at each required output-input pairing
        The default is a diagonal pairing with 1.'s on the diagonal
              
    Returns
    -------
    fig(RGA Number) : figure
        A figure of the RGA number for a specified pairing over
        a given frequency range
    
    Example
    -------
    # Adapted from example 3.11 pg 86 S. Skogestad
    >>> def G(s):
    ...     G = 0.01*numpy.exp(-5*s)/((s + 1.72e-4)*(4.32*s + 1))*numpy.array([[-34.54*(s + 0.0572), 1.913], [-30.22*s, -9.188*(s + 6.95e-4)]])
    ...     return G
    >>> pairing = numpy.array([[1., 0.], [0., 1.]])
    >>> rga_nm_plot(G, pairing, axlim=[None, None, 0., 1.], w_start=-5, w_end=2)

    Note
    ----
    This plotting function can only be used on square systems
    '''

    if axlim is None:
        axlim = [None, None, None, None]
    w = numpy.logspace(w_start, w_end, points)
    s = w * 1j

    dim = numpy.shape(
        G(0))  # Number of rows and columns in SS transfer function
    freqresp = map(G, s)

    if pairing is None:  # Setting a blank entry to the default of a diagonal comparison
        diag = numpy.identity(dim[0])
        print('RGA number being calculated for a diagonal pairing')
    elif not all(pairing.shape == dim):
        print(
            'RGA_Number_Plot on plots square n by n matrices, make sure input matrix is square'
        )
        pass
    else:
        diag = pairing

    plt.figure('RGA Number')
    plt.clf()
    plt.gcf().set_facecolor('white')

    plt.semilogx(
        w, [numpy.sum(numpy.abs(utils.RGA(Gfr) - diag)) for Gfr in freqresp])

    plt.axis(axlim)
    plt.ylabel('||$\Lambda$(G) - I||$_{sum}$', fontsize=15)
    plt.xlabel('Frequency (rad/unit time)')

    plt.show()
    return
Ejemplo n.º 3
0
def rga_plot(G,
             w_start=-2,
             w_end=2,
             axlim=None,
             points=1000,
             fig=0,
             plot_type='elements',
             input_label=None,
             output_label=None):
    """
    Plots the relative gain interaction between each output and input pairing

    Parameters
    ----------
    G : numpy matrix
        Plant model.
    plot_type : string
        Type of plot.

        =========      ============================
        plot_type      Type of plot
        =========      ============================
        all            All the RGAs on one plot
        output         Plots grouped by output
        input          Plots grouped by input
        element        Each element has its own plot
        =========      ============================

    Returns
    -------
    Plot : matplotlib figure

    Example
    -------
    Adapted from example 3.11 pg 86 S. Skogestad

    >>> def G(s):
    ...     G = 0.01**(-5*s)/((s + 1.72e-4)*(4.32*s + 1))*numpy.matrix([[-34.54*(s + 0.0572), 1.913], [-30.22*s, -9.188*(s + 6.95e-4)]])
    ...     return G
    >>> rga_plot(G, w_start=-5, w_end=2, axlim=[None, None, 0., 1.])
    """

    s, w, axlim = df.frequency_plot_setup(axlim, w_start, w_end, points)

    dim = G(0).shape  # Number of rows and columns in SS transfer function
    freqresp = [G(si) for si in s]

    plot_No = 1

    if (input_label is None) and (output_label is None):
        labels = False
    elif numpy.shape(input_label)[0] == numpy.shape(output_label)[0]:
        labels = True
    else:
        raise ValueError('Input and output label count is not equal')

    if plot_type == 'elements':
        fig = adjust_spine('Frequency [rad/unit time]', 'RGA magnitude', -0.05,
                           -0.03, 0.8, 0.9)
        for i in range(dim[0]):
            for j in range(dim[1]):
                ax = fig.add_subplot(dim[0], dim[1], plot_No)
                if labels:
                    ax.set_title('Output (%s) vs. Input (%s)' %
                                 (output_label[i], input_label[j]))
                else:
                    ax.set_title('Output %s vs. Input %s' % (i + 1, j + 1))
                ax.semilogx(
                    w,
                    numpy.array(
                        numpy.abs(
                            ([utils.RGA(Gfr)[i, j] for Gfr in freqresp]))))
                plot_No += 1

                ax.axis(axlim)
                ax.set_ylabel('$|\lambda$$_{%s, %s}|$' % (i + 1, j + 1))
                box = ax.get_position()
                ax.set_position(
                    [box.x0, box.y0, box.width * 0.8, box.height * 0.9])

    elif plot_type == 'outputs':  # i
        fig = adjust_spine('Frequency [rad/unit time]', 'RGA magnitude', -0.05,
                           -0.03, 1, 0.9)
        for i in range(dim[0]):
            ax = fig.add_subplot(dim[1], 1, plot_No)
            ax.set_title('Output %s vs. input j' % (i + 1))
            rgamax = []
            for j in range(dim[1]):
                rgas = numpy.array(
                    numpy.abs(([utils.RGA(Gfr)[i, j] for Gfr in freqresp])))
                ax.semilogx(w,
                            rgas,
                            label='$\lambda$$_{%s, %s}$' % (i + 1, j + 1))
                rgamax.append(max(rgas))

                if j == dim[1] - 1:  # self-scaling algorithm
                    if axlim is not None:
                        ax.axis(axlim)
                    else:
                        ax.axis([None, None, None, max(rgamax)])

            ax.set_ylabel('$|\lambda$$_{%s, j}|$' % (i + 1))
            box = ax.get_position()
            ax.set_position([box.x0, box.y0, box.width, box.height * 0.9])
            ax.legend()
            plot_No += 1

    elif plot_type == 'inputs':  # j
        fig = adjust_spine('Frequency [rad/unit time]', 'RGA magnitude', -0.05,
                           -0.03, 1, 0.9)
        for j in range(dim[1]):
            ax = fig.add_subplot(dim[0], 1, plot_No)
            ax.set_title('Output i vs. input %s' % (j + 1))
            rgamax = []
            for i in range(dim[0]):
                rgas = numpy.array(
                    numpy.abs(([utils.RGA(Gfr)[i, j] for Gfr in freqresp])))
                ax.semilogx(w,
                            rgas,
                            label='$\lambda$$_{%s, %s}$' % (i + 1, j + 1))
                rgamax.append(max(rgas))

                if i == dim[1] - 1:  # self-scaling algorithm
                    if axlim is not None:
                        ax.axis(axlim)
                    else:
                        ax.axis([None, None, None, max(rgamax)])

            ax.set_ylabel('$|\lambda$$_{i, %s}|$' % (j + 1))
            box = ax.get_position()
            ax.set_position([box.x0, box.y0, box.width, box.height * 0.9])
            ax.legend()
            plot_No += 1

    elif plot_type == 'all':
        for i in range(dim[0]):
            for j in range(dim[1]):
                plt.semilogx(
                    w,
                    numpy.array(
                        numpy.abs([utils.RGA(Gfr)[i, j] for Gfr in freqresp])))
                plt.axis(axlim)
                plt.ylabel('|$\lambda$$_{i,j}$|')
                plt.xlabel('Frequency [rad/unit time]')

    else:
        raise ValueError("Invalid plot_type parameter.")