3

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?

John Hedengren
14.5k1 gold badge24 silver badges32 bronze badges
asked Feb 26, 2025 at 13:03

1 Answer 1

1

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()
answered Mar 8, 2025 at 22:53
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.