def RGA_w(w_start, w_end, x, y): """ w_start is the start of logspace w_end is the ending of the logspace x and y is refer to the indices of the RGA matrix that needs to be plotted this is to calculate the RGA at different frequencies this give more conclusive values of which pairing would give fast responses under dynamic situations""" w = np.logspace(w_start, w_end, 1000) store = np.zeros([len(x), len(w)]) count = 0 for w_i in w: RGA_w = RGA(G(w_i)) store[:, count] = RGA_w[x, y] count = count + 1 for i in range(len(x)): plt.loglog(w, store[i, :]) plt.title('RGA over Freq') plt.xlabel('w') plt.ylabel('|RGA values| given x , y ') plt.show()
def RGAnumber(A): RGAnum = np.sum(np.abs(RGA(A) - np.identity(len(A)))) return RGAnum
def IterRGA(A, n): for _ in range(1, n): A = RGA(A) return A
# The minimized coondition number is not implemented. # Examples 3.13-15 are all similar def condnum(A): gamma = A[0] / A[-1] return gamma def IterRGA(A, n): for _ in range(1, n): A = RGA(A) return A def RGAnumber(A): RGAnum = np.sum(np.abs(RGA(A) - np.identity(len(A)))) return RGAnum G = np.matrix([[100, 0], [0, 1]]) [U, S, V] = np.linalg.svd(G) R = RGA(G) ItR = IterRGA(G, 4) numR = RGAnumber(G) numC = condnum(S) print('RGA:\n', R, '\nIterative RGA:\n', ItR, '\nCondition Number:\n', numC)
import numpy as np from utils import RGA G = np.matrix([[16.8, 30.5, 4.30], [-16.7, 31.0, -1.41], [1.27, 54.1, 5.4]]) # Iterative evaluation of the RGA k = 1 while (k <= 5): G = RGA(G) print('Iteration**', k, '\n', G.round(3)) k = k + 1 # result confirms diagonal dominance pairing since G converges # to identity matrix
from __future__ import print_function import numpy as np from utils import RGA # 3x3 plant at steady-state G = np.matrix([[16.8, 30.5, 4.30], [-16.7, 31.0, -1.41], [1.27, 54.1, 5.40]]) print(np.round(RGA(G), 2)) # pairing rule 2: avoid pairing negative RGA elements # RGA = [[1.50, 0.99, -1.48], [-0.41, 0.97, 0.45], [-0.08, -0.95, 2.03]] # Therefore pair the diagonal elements because they are positive, this means # use u1 to control y1, u2 to control y2 and u3 to control y3
import numpy as np from utils import RGA # 3x3 plant at steady-state G = np.matrix([[16.8, 30.5, 4.30], [-16.7, 31.0, -1.41], [1.27, 54.1, 5.40]]) print RGA(G) # pairing rule 2: avoid pairing negative RGA elements # RGA = [[1.50, 0.99, -1.48], [-0.41, 0.97, 0.45], [-0.08, -0.95, 2.03]] # Therefore pair the diagonal elements because they are positive, this means # use u1 to control y1, u2 to control y2 and u3 to control y3
import numpy as np from utils import RGA # 3x3 plant at steady-state G = np.matrix([[16.8, 30.5, 4.30], [-16.7, 31.0, -1.41], [1.27, 54.1, 5.40]]) print np.round(RGA(G),2) # pairing rule 2: avoid pairing negative RGA elements # RGA = [[1.50, 0.99, -1.48], [-0.41, 0.97, 0.45], [-0.08, -0.95, 2.03]] # Therefore pair the diagonal elements because they are positive, this means # use u1 to control y1, u2 to control y2 and u3 to control y3
def RGAnumberoffDiag(A): RGAnumOD = np.sum(np.abs(RGA(A) - np.array([[0, 1], [1, 0]]))) return RGAnumOD
from __future__ import print_function import numpy as np from utils import RGA # Blending process: mix sugar (u1) and water (u2) to control amount # (y1 = F) and sugar fraction(y2 = x) in a soft drink # y = G*u # After linearization the equations become: # y1 = u1+u2 # y2 = (1-x*)/(F*)u1 - (x*/F*)u2 # given that at steady-state # x* = 0.2 # F* = 2 kg/s # therefore; # G(s) = np.matrix([[1, 1], [(1-x*)/F* -x*/F*]]) # after substitution G = np.matrix([[1, 1], [0.4, -0.1]]) print(RGA(G)) # pairing rule 1: prefer pairing on RGA elements close to 1 # RGA = [[0.2, 0.8], [0.8, 0.2]] # RGA11 = 0.2; effect of u1 on y1 # RGA12 = 0.8 close to 1; effect of u2 (water) on the amount y1 # RGA21 = 0.8 close to 1; effect of u1(sugar) on the sugar fraction y2 # RGA22 = 0.2; effect of u2 (water) on the sugar fraction y2 # It is reasonable to use input u2 (water) to control amount y1 hence RGA = 0.8 # and use input u1 (sugar) to control the sugar fraction y2
import numpy as np from utils import RGA G = np.matrix([[16.8, 30.5, 4.30], [-16.7, 31.0, -1.41], [1.27, 54.1, 5.4]]) # Define 6 alternate pairings I1 = np.asmatrix(np.eye(3)) I2 = np.matrix([[0, 1, 0], [0, 0, 1], [1, 0, 0]]) I3 = np.matrix([[0, 0, 1], [1, 0, 0], [0, 1, 0]]) I4 = np.matrix([[0, 0, 1], [0, 1, 0], [1, 0, 0]]) I5 = np.matrix([[1, 0, 0], [0, 0, 1], [0, 1, 0]]) I6 = np.matrix([[0, 1, 0], [1, 0, 0], [0, 0, 1]]) for I in I1, I2, I3, I4, I5, I6: print('Pairing', '\n', I, 'RGA Number =', np.sum(np.abs(RGA(G) - I))) # Pairing of diagonal matrix I1 provides the smallest RGA number and is # is therefor preferred
import numpy as np import matplotlib.pyplot as plt from utils import RGA # example 3.9 Skogestad pg 85 A = np.matrix([[1, 1], [0.4, -0.1]]) print RGA(A) # the next two function is to calculate the frequency dependent RGA def G(w): """ function to create the matrix of transfer functions""" s = w * 1j # the matrix transfer function # this specific one is Example 3.11 G = 1 / (5 * s + 1) * np.matrix([[s + 1, s + 4], [1, 2]]) return G def RGA_alt(G): """instead of using util's""" return np.array(G) * np.array(G.I).T def RGA_w(w_start, w_end, x, y): """ w_start is the start of logspace w_end is the ending of the logspace