Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simulate ARX model with initial values

Tags:

gekko

I'm trying to simulate an ARX model based on this example

import numpy as np
from gekko import GEKKO
import matplotlib.pyplot as plt

na = 2 # Number of A coefficients
nb = 1 # Number of B coefficients
ny = 2 # Number of outputs
nu = 2 # Number of inputs

# A (na x ny)
A = np.array([[0.36788,0.36788],\
              [0.223,-0.136]]) 
# B (ny x (nb x nu))
B1 = np.array([0.63212,0.18964]).T
B2 = np.array([0.31606,1.26420]).T
B = np.array([[B1],[B2]])

C = np.array([0,0])

# create parameter dictionary
# parameter dictionary p['a'], p['b'], p['c']
# a (coefficients for a polynomial, na x ny)
# b (coefficients for b polynomial, ny x (nb x nu))
# c (coefficients for output bias, ny)
p = {'a':A,'b':B,'c':C}

# Create GEKKO model
m = GEKKO(remote=False)

# Build GEKKO ARX model
y,u = m.arx(p)

# load inputs
tf = 20 # final time
u1 = np.zeros(tf+1)
u2 = u1.copy()
u1[5:] = 3.0
u2[10:] = 5.0
u[0].value = u1
u[1].value = u2

# customize names
mv1 = u[0]
mv2 = u[1]
cv1 = y[0]
cv2 = y[1]

# options
m.time = np.linspace(0,tf,tf+1)
m.options.imode = 4
m.options.nodes = 2

# simulate
m.solve()

plt.figure(1)
plt.subplot(2,1,1)
plt.plot(m.time,mv1.value,'r-',label=r'$MV_1$')
plt.plot(m.time,mv2.value,'b--',label=r'$MV_2$')
plt.ylabel('MV')
plt.legend(loc='best')
plt.subplot(2,1,2)
plt.plot(m.time,cv1.value,'r:',label=r'$CV_1$')
plt.plot(m.time,cv2.value,'b.-',label=r'$CV_2$')
plt.ylabel('CV')
plt.xlabel('Time (sec)')
plt.legend(loc='best')
plt.show()

but providing initial output values.

I tried y,u = m.arx(p,y_init) but got an error message

numpy.ndarray object has no attribute 'name'

Is it possible to adapt the example adding initial values for the outputs?

like image 362
ht2507 Avatar asked Dec 17 '25 21:12

ht2507


1 Answers

Use the .value property of the MV or CV objects to update the initial values. Here is an example:

# update mv values
step_up = np.zeros(tf+1); step_up[5:]=0.5
mv1.value = step_up
pulse = np.ones(tf+1)*0.1; pulse[5:10]=0.7
mv2.value = pulse

# update initial condition and solution guess values
cv1.value = 0.5
cv2.value = np.ones(tf+1)

Simulation Results for ARX Model

The cv1.value = 0.5 updates both the initial condition and all guess values in the simulation horizon. It is equivalent to cv1.value=0.5*np.ones(tf+1). If the initial guess values can also be an array of different values. With an ARX model, a good initial guess is often not required because the nonlinear programming solver can easily solve the system of linear equations. For MPC applications, Gekko automatically solves the next cycle of the controller with time shifted values from the prior solution. This can be adjusted with the default value of m.options.TIME_SHIFT=1. Here is the complete code:

import numpy as np
from gekko import GEKKO
import matplotlib.pyplot as plt

na = 2 # Number of A coefficients
nb = 1 # Number of B coefficients
ny = 2 # Number of outputs
nu = 2 # Number of inputs

# A (na x ny)
A = np.array([[0.36788,0.36788],\
              [0.223,-0.136]]) 
# B (ny x (nb x nu))
B1 = np.array([0.63212,0.18964]).T
B2 = np.array([0.31606,1.26420]).T
B = np.array([[B1],[B2]])

C = np.array([0,0])

# create parameter dictionary
# parameter dictionary p['a'], p['b'], p['c']
# a (coefficients for a polynomial, na x ny)
# b (coefficients for b polynomial, ny x (nb x nu))
# c (coefficients for output bias, ny)
p = {'a':A,'b':B,'c':C}

# Create GEKKO model
m = GEKKO(remote=False)

# Build GEKKO ARX model
y,u = m.arx(p)

# load inputs
tf = 20 # final time
u1 = np.zeros(tf+1)
u2 = u1.copy()
u1[5:] = 3.0
u2[10:] = 5.0
u[0].value = u1
u[1].value = u2

# customize names
mv1 = u[0]
mv2 = u[1]
cv1 = y[0]
cv2 = y[1]

# update mv values
step_up = np.zeros(tf+1); step_up[5:]=0.5
mv1.value = step_up
pulse = np.ones(tf+1)*0.1; pulse[5:10]=0.7
mv2.value = pulse

# update initial condition and solution guess values
cv1.value = 0.5
cv2.value = np.ones(tf+1)

# options
m.time = np.linspace(0,tf,tf+1)
m.options.imode = 4
m.options.nodes = 2

# simulate
m.solve()

plt.figure(figsize=(6,3.5))
plt.subplot(2,1,1)
plt.plot(m.time,mv1.value,'r-',label=r'$MV_1$')
plt.plot(m.time,mv2.value,'b--',label=r'$MV_2$')
plt.ylabel('MV')
plt.legend(loc='best')
plt.subplot(2,1,2)
plt.plot(m.time,cv1.value,'r:',label=r'$CV_1$')
plt.plot(m.time,cv2.value,'b.-',label=r'$CV_2$')
plt.ylabel('CV')
plt.xlabel('Time (sec)')
plt.legend(loc='best')
plt.tight_layout()
plt.savefig('results.png',dpi=300)
plt.show()
like image 147
John Hedengren Avatar answered Dec 20 '25 15:12

John Hedengren



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!