Local infeasibility in MATLAB - gekko

I need help with a dynamic optimization problem that consist in a consumed energy optimization of a UAV with this optimal control problem.
enter image description here
enter image description here
My code is this
Ecuations:
Parameters
tf
#Velocidad de rotores rad/s
#Las condiciones iniciales permiten igualar la acción de la gravedad
#Se tomo 4000rad/s como la velocidad maxima de los rotores
w1 = 912.32, >=0, <=3000
w2 = 912.32, >=0, <=3000
w3 = 912.32, >=0, <=3000
w4 = 912.32, >=0, <=3000
t1 = 0, >=0
t2 = 0, >=0
t3 = 0, >=0
t4 = 0, >=0
Constants
!----------------COEFICIENTES DEL MODELO-----------------!
#Gravedad
g = 9.81 !m/s^2
pi = 3.14159265359
#Motor Coefficients
J = 4.1904e-5 !kg*m^2
kt = 0.0104e-3 !N*m/A
kv = 96.342 !rad/s/volt
Dv = 0.2e-3 !N*m*s/rad
R = 0.2 !Ohms
#Battery parameters
Q = 1.55 !Ah
Rint = 0.02 !Ohms
E0 = 1.24 !volt
K = 2.92e-3 !volt
A = 0.156
B =2.35
#Quadrotor parameters
l = 0.175 !m
m = 1.3 !kg
Ix = 0.081 !kg*m^2
Iy = 0.081 !kg*m^2
Iz = 0.142 !kg*m^2
kb = 3.8305e-6 !N/rad/s
ktau = 2.2518e-8 !(N*m)/rad/s
#Parametrizacion del polinomio
a1 = -1.72e-5
a2 = 1.95e-5
a3 = -6.98e-6
a4 = 4.09e-7
b1 = 0.014
b2 = -0.0157
b3 = 5.656e-3
b4 = -3.908e-4
c1 = -0.8796
c2 = 0.3385
c3 = 0.2890
c4 = 0.1626
Variables
!------------------CONDICONES INICIALES------------------!
x = 0
xp = 0
y = 0
yp = 0
z = 0
zp = 0
pitch = 0, >=-pi/2, <=pi/2 !theta - restricciones
pitchp = 0
roll = 0, >=-pi/2, <=pi/2 !phi - restricciones
rollp = 0
yaw = 0 !psi
yawp = 0%, >=-200/180, <=200/180
#Función objetivo
of = 0 !condición inicial de la función objetivo
Intermediates
#Motor 1
aw1 = a1*w1^2 + b1*w1 + c1
bw1 = a2*w1^2 + b2*w1 + c2
cw1 = a3*w1^2 + b3*w1 + c3
dw1 = a4*w1^2 + b4*w1 + c4
#Motor 2
aw2 = a1*w2^2 + b1*w2 + c1
bw2 = a2*w2^2 + b2*w2 + c2
cw2 = a3*w2^2 + b3*w2 + c3
dw2 = a4*w2^2 + b4*w2 + c4
#Motor 3
aw3 = a1*w3^2 + b1*w3 + c1
bw3 = a2*w3^2 + b2*w3 + c2
cw3 = a3*w3^2 + b3*w3 + c3
dw3 = a4*w3^2 + b4*w3 + c4
#Motor 4
aw4 = a1*w4^2 + b1*w4 + c1
bw4 = a2*w4^2 + b2*w4 + c2
cw4 = a3*w4^2 + b3*w4 + c3
dw4 = a4*w4^2 + b4*w4 + c4
#frj(wj(t),Tj(t))
fr1=aw1*t1^3 + bw1*t1^2 + cw1*t1 + dw1
fr2=aw2*t2^3 + bw2*t2^2 + cw2*t2 + dw2
fr3=aw3*t3^3 + bw3*t3^2 + cw3*t3 + dw3
fr4=aw4*t4^3 + bw4*t4^2 + cw4*t4 + dw4
!---------------------CONTROL INPUTS---------------------!
T = kb * (w1^2 + w2^2 + w3^2 + w4^2)
u1 = kb * (w2^2 - w4^2)
u2 = kb * (w3^2 - w1^2)
u3 = ktau * (w1^2 - w2^2 + w3^2 - w4^2)
wline = w1 - w2 + w3 - w4
!-------------------ENERGIA POR ROTOR--------------------!
Ec1 = ((J*$w1 + ktau*w1^2 + Dv*w1)/fr1)*w1
Ec2 = ((J*$w2 + ktau*w2^2 + Dv*w2)/fr2)*w2
Ec3 = ((J*$w3 + ktau*w3^2 + Dv*w3)/fr3)*w3
Ec4 = ((J*$w4 + ktau*w4^2 + Dv*w4)/fr4)*w4
Ectotal = Ec1 + Ec2 + Ec3 + Ec4
Equations
!---------------MINIMIZAR FUNCIÓN OBJETIVO---------------!
minimize tf * of
!-----------------RELACION DE VARIABLES------------------!
xp = $x
yp = $y
zp = $z
pitchp = $pitch
rollp = $roll
yawp = $yaw
!-----------------CONDICONES DE FRONTERA-----------------!
#Condiciones finales del modelo
tf * x = 4
tf * y = 5
tf * z = 6
tf * xp = 0
tf * yp = 0
tf * zp = 0
tf * roll = 0
tf * pitch = 0
tf * yaw = 0
!-----------------TORQUE DE LOS MOTORES------------------!
t1 = J*$w1 + ktau*w1^2 + Dv*w1
t2 = J*$w2 + ktau*w2^2 + Dv*w2
t3 = J*$w3 + ktau*w3^2 + Dv*w3
t4 = J*$w4 + ktau*w4^2 + Dv*w4
!------------------------SUJETO A------------------------!
#Modelo aerodinámico del UAV
m*$xp = (cos(roll)*sin(pitch)*cos(yaw) + sin(roll)*sin(yaw))*T
m*$yp = (cos(roll)*sin(pitch)*sin(yaw) - sin(roll)*cos(yaw))*T
m*$zp = (cos(roll)*cos(pitch))*T-m*g
Ix*$rollp = ((Iy - Iz)*pitchp*yawp + J*pitchp*wline + l*u1)
Iy*$pitchp = ((Iz - Ix)*rollp*yawp - J*rollp*wline + l*u2)
Iz*$yawp = ((Ix - Iy)*rollp*pitchp + u3)
!--------------------FUNCIÓN OBJETIVO--------------------!
$of = Ectotal
MATLAB:
clear all; close all; clc
server = 'http://127.0.0.1';
app = 'traj_optima';
addpath('C:/Program Files/MATLAB/apm_matlab_v0.7.2/apm')
apm(server,app,'clear all');
apm_load(server,app,'ecuaciones_mod.apm');
csv_load(server,app,'tiempo2.csv');
apm_option(server,app,'apm.max_iter',200);
apm_option(server,app,'nlc.nodes',3);
apm_option(server,app,'apm.rtol',1);
apm_option(server,app,'apm.otol',1);
apm_option(server,app,'nlc.solver',3);
apm_option(server,app,'nlc.imode',6);
apm_option(server,app,'nlc.mv_type',1);
costo=1e-5;%1e-5
%VARIABLES CONTROLADAS
%Velocidades angulares
apm_info(server,app,'MV','w1');
apm_option(server,app,'w1.status',1);
apm_info(server,app,'MV','w2');
apm_option(server,app,'w2.status',1);
apm_info(server,app,'MV','w3');
apm_option(server,app,'w3.status',1);
apm_info(server,app,'MV','w4');
apm_option(server,app,'w4.status',1);
% Torques
apm_info(server,app,'MV','t1');
apm_option(server,app,'t1.status',1);
apm_info(server,app,'MV','t2');
apm_option(server,app,'t2.status',1);
apm_info(server,app,'MV','t3');
apm_option(server,app,'t3.status',1);
apm_info(server,app,'MV','t4');
apm_option(server,app,'t4.status',1);
%Salida
output = apm(server,app,'solve');
disp(output)
y = apm_sol(server,app);
z = y.x;
tiempo2.csv
time,tf
0,0
0.001,0
0.2,0
0.4,0
0.6,0
0.8,0
1,0
1.2,0
1.4,0
1.6,0
1.8,0
2,0
2.2,0
2.4,0
2.6,0
2.8,0
3,0
3.2,0
3.4,0
3.6,0
3.8,0
4,0
4.2,0
4.4,0
4.6,0
4.8,0
5,0
5.2,0
5.4,0
5.6,0
5.8,0
6,0
6.2,0
6.4,0
6.6,0
6.8,0
7,0
7.2,0
7.4,0
7.6,0
7.8,0
8,0
8.2,0
8.4,0
8.6,0
8.8,0
9,0
9.2,0
9.4,0
9.6,0
9.8,0
10,1
Finally the answer obtained is:
enter image description here
I need help with this local infeasibility problem, please.

The infeasible solution is caused by the terminal constraints:
tf * z = 4
tf * z = 5
tf * z = 6
When tf=0, the constraints are evaluated to 0=4, 0=5, 0=6 and the solver reports that these can not be satisfied by the solver. Instead, you can pose the constraints as:
tf * (x-4) = 0
tf * (y-5) = 0
tf * (z-6) = 0
That way, the constraint is valid when tf=0 and when tf=1 at the final time. A potential better way yet is to convert the terminal constraints to objective terms with f=1000 such as:
minimize f*tf*((x-4)^2 + (y-5)^2 + (z-6)^2)
minimize f*tf*(xp^2 + yp^2 + zp^2)
minimize f*tf*(roll^2 + pitch^2 + yaw^2)
That way, the optimizer won't report an infeasible solution if it can't reach the terminal constraints as discussed in the pendulum problem. I made a few other modifications to your model and script to achieve a successful solution. Here is a summary:
Converted terminal constraints to objective function (soft constraints)
Parameters t1-t4 should be variables
Fixed degree of freedom issue by making w1-w4 variables and w1p-w4p variables. w1-w4 are differential states.
Added constraints to w1p-w4p between -10 and 10 to help the solver converge
Added initialization step to simulate the model before optimizing. There are more details on initialization strategies in this paper: Safdarnejad, S.M., Hedengren, J.D., Lewis, N.R., Haseltine, E., Initialization Strategies for Optimization of Dynamic Systems, Computers and Chemical Engineering, 2015, Vol. 78, pp. 39-50, DOI: 10.1016/j.compchemeng.2015.04.016
Model
Parameters
tf
w1p = 0 > -10 < 10
w2p = 0 > -10 < 10
w3p = 0 > -10 < 10
w4p = 0 > -10 < 10
Constants
!----------------COEFICIENTES DEL MODELO-----------------!
#Gravedad
g = 9.81 !m/s^2
pi = 3.14159265359
#Motor Coefficients
J = 4.1904e-5 !kg*m^2
kt = 0.0104e-3 !N*m/A
kv = 96.342 !rad/s/volt
Dv = 0.2e-3 !N*m*s/rad
R = 0.2 !Ohms
#Battery parameters
Q = 1.55 !Ah
Rint = 0.02 !Ohms
E0 = 1.24 !volt
K = 2.92e-3 !volt
A = 0.156
B =2.35
#Quadrotor parameters
l = 0.175 !m
m = 1.3 !kg
Ix = 0.081 !kg*m^2
Iy = 0.081 !kg*m^2
Iz = 0.142 !kg*m^2
kb = 3.8305e-6 !N/rad/s
ktau = 2.2518e-8 !(N*m)/rad/s
#Parametrizacion del polinomio
a1 = -1.72e-5
a2 = 1.95e-5
a3 = -6.98e-6
a4 = 4.09e-7
b1 = 0.014
b2 = -0.0157
b3 = 5.656e-3
b4 = -3.908e-4
c1 = -0.8796
c2 = 0.3385
c3 = 0.2890
c4 = 0.1626
Variables
!------------------CONDICONES INICIALES------------------!
x = 0
xp = 0
y = 0
yp = 0
z = 0
zp = 0
pitch = 0, >=-pi/2, <=pi/2 !theta - restricciones
pitchp = 0
roll = 0, >=-pi/2, <=pi/2 !phi - restricciones
rollp = 0
yaw = 0 !psi
yawp = 0 %, >=-200/180, <=200/180
#Velocidad de rotores rad/s
#Las condiciones iniciales permiten igualar la acción de la gravedad
#Se tomo 4000rad/s como la velocidad maxima de los rotores
w1 = 912.32, >=0, <=3000
w2 = 912.32, >=0, <=3000
w3 = 912.32, >=0, <=3000
w4 = 912.32, >=0, <=3000
t1 = 0, >=0
t2 = 0, >=0
t3 = 0, >=0
t4 = 0, >=0
#Función objetivo
of = 0 !condición inicial de la función objetivo
Intermediates
#Motor 1
aw1 = a1*w1^2 + b1*w1 + c1
bw1 = a2*w1^2 + b2*w1 + c2
cw1 = a3*w1^2 + b3*w1 + c3
dw1 = a4*w1^2 + b4*w1 + c4
#Motor 2
aw2 = a1*w2^2 + b1*w2 + c1
bw2 = a2*w2^2 + b2*w2 + c2
cw2 = a3*w2^2 + b3*w2 + c3
dw2 = a4*w2^2 + b4*w2 + c4
#Motor 3
aw3 = a1*w3^2 + b1*w3 + c1
bw3 = a2*w3^2 + b2*w3 + c2
cw3 = a3*w3^2 + b3*w3 + c3
dw3 = a4*w3^2 + b4*w3 + c4
#Motor 4
aw4 = a1*w4^2 + b1*w4 + c1
bw4 = a2*w4^2 + b2*w4 + c2
cw4 = a3*w4^2 + b3*w4 + c3
dw4 = a4*w4^2 + b4*w4 + c4
#frj(wj(t),Tj(t))
fr1=aw1*t1^3 + bw1*t1^2 + cw1*t1 + dw1
fr2=aw2*t2^3 + bw2*t2^2 + cw2*t2 + dw2
fr3=aw3*t3^3 + bw3*t3^2 + cw3*t3 + dw3
fr4=aw4*t4^3 + bw4*t4^2 + cw4*t4 + dw4
!---------------------CONTROL INPUTS---------------------!
T = kb * (w1^2 + w2^2 + w3^2 + w4^2)
u1 = kb * (w2^2 - w4^2)
u2 = kb * (w3^2 - w1^2)
u3 = ktau * (w1^2 - w2^2 + w3^2 - w4^2)
wline = w1 - w2 + w3 - w4
!-------------------ENERGIA POR ROTOR--------------------!
Ec1 = ((J*$w1 + ktau*w1^2 + Dv*w1)/fr1)*w1
Ec2 = ((J*$w2 + ktau*w2^2 + Dv*w2)/fr2)*w2
Ec3 = ((J*$w3 + ktau*w3^2 + Dv*w3)/fr3)*w3
Ec4 = ((J*$w4 + ktau*w4^2 + Dv*w4)/fr4)*w4
Ectotal = Ec1 + Ec2 + Ec3 + Ec4
! scaling factor for terminal constraint
f = 1000
Equations
!---------------MINIMIZAR FUNCIÓN OBJETIVO---------------!
minimize tf * of
!-----------------RELACION DE VARIABLES------------------!
xp = $x
yp = $y
zp = $z
pitchp = $pitch
rollp = $roll
yawp = $yaw
w1p = $w1
w2p = $w2
w3p = $w3
w4p = $w4
!-----------------CONDICONES DE FRONTERA-----------------!
#Condiciones finales del modelo
#tf * (x-4) = 0
#tf * (y-5) = 0
#tf * (z-6) = 0
#tf * xp = 0
#tf * yp = 0
#tf * zp = 0
#tf * roll = 0
#tf * pitch = 0
#tf * yaw = 0
minimize f*tf*((x-4)^2 + (y-5)^2 + (z-6)^2)
minimize f*tf*(xp^2 + yp^2 + zp^2)
minimize f*tf*(roll^2 + pitch^2 + yaw^2)
!-----------------TORQUE DE LOS MOTORES------------------!
t1 = J*w1p + ktau*w1^2 + Dv*w1
t2 = J*w2p + ktau*w2^2 + Dv*w2
t3 = J*w3p + ktau*w3^2 + Dv*w3
t4 = J*w4p + ktau*w4^2 + Dv*w4
!------------------------SUJETO A------------------------!
#Modelo aerodinámico del UAV
m*$xp = (cos(roll)*sin(pitch)*cos(yaw) + sin(roll)*sin(yaw))*T
m*$yp = (cos(roll)*sin(pitch)*sin(yaw) - sin(roll)*cos(yaw))*T
m*$zp = (cos(roll)*cos(pitch))*T-m*g
Ix*$rollp = ((Iy - Iz)*pitchp*yawp + J*pitchp*wline + l*u1)
Iy*$pitchp = ((Iz - Ix)*rollp*yawp - J*rollp*wline + l*u2)
Iz*$yawp = ((Ix - Iy)*rollp*pitchp + u3)
!--------------------FUNCIÓN OBJETIVO--------------------!
$of = Ectotal
MATLAB Script
clear all; close all; clc
server = 'http://byu.apmonitor.com';
app = 'traj_optima';
addpath('apm')
apm(server,app,'clear all');
apm_load(server,app,'ecuaciones_mod.apm');
csv_load(server,app,'tiempo2.csv');
apm_option(server,app,'apm.max_iter',1000);
apm_option(server,app,'apm.nodes',3);
apm_option(server,app,'apm.rtol',1e-6);
apm_option(server,app,'apm.otol',1e-6);
apm_option(server,app,'apm.solver',3);
apm_option(server,app,'apm.imode',6);
apm_option(server,app,'apm.mv_type',1);
costo=1e-5;%1e-5
%VARIABLES CONTROLADAS
%Velocidades angulares
apm_info(server,app,'MV','w1p');
apm_option(server,app,'w1p.status',1);
apm_info(server,app,'MV','w2p');
apm_option(server,app,'w2p.status',1);
apm_info(server,app,'MV','w3p');
apm_option(server,app,'w3p.status',1);
apm_info(server,app,'MV','w4p');
apm_option(server,app,'w4p.status',1);
%Salida
disp('')
disp('------------- Initialize ----------------')
apm_option(server,app,'apm.coldstart',1);
output = apm(server,app,'solve');
disp(output)
disp('')
disp('-------------- Optimize -----------------')
apm_option(server,app,'apm.time_shift',0);
apm_option(server,app,'apm.coldstart',0);
output = apm(server,app,'solve');
disp(output)
y = apm_sol(server,app);
z = y.x;
This gives a successful solution but the terminal constraints are not met. The solver optimizes the use of w1p-w4p to minimize the objective but there is no solution that makes it to the terminal constraints.
The solution was found.
The final value of the objective function is 50477.4537378181
---------------------------------------------------
Solver : IPOPT (v3.12)
Solution time : 3.06940000000759 sec
Objective : 50477.4537378181
Successful solution
---------------------------------------------------
As a next step, I recommend that you increase the number of time points or allow the final time to change to meet the terminal constraints. You may also want to consider switching to Python Gekko that uses the same underlying engine as APM MATLAB. In this case, the modeling language is fully integrated with Python.

Related

Why MHE after 12 seconds runs skeptically over my model?

I am new to control systems and have tried to use GEKKO. For my model simulation geos correct and run however at MHE and also at MPC It runs correctly when t = 15 seconds after that if t = 16 seconds at the 12th it goes skeptical as shown on the attached figure. Is there a reason for that?
m = GEKKO(remote = False)
g = m.Const(value = 9.81)
Cc = m.Const(value = 2*10**-5)
D1 = m.Const(value = 0.1016)
D2 = m.Const(value = 0.1016)
h1 = m.Const(value = 100)
hv = m.Const(value = 1000)
L1 = m.Const(value = 500)
L2 = m.Const(value = 1100)
V1 = m.Const(value = 4.054)
V2 = m.Const(value = 9.729)
A1 = m.Const(0.008107)
A2 = m.Const(0.008107)
beta1 = m.Const(value = 1.5 * 10**9)
beta2 = m.Const(value = 1.5* 10**9)
Pres = m.Const(value = 1.261 * 10**7)
M = m.Const(value = 1.992 * 10**8)
rho = m.Const(value = 932)
PI = m.Const(value = 2.32 * 10**(-9))
visc = m.Const(value = 0.024)
fo = m.Const(value = 60)
Inp = m.Const(value = 65)
Pnp = m.Const(value = 1.625 * 10**5)
z = m.MV(1, lb = 0.1, ub = 1)
f = m.MV(35, lb = 35, ub = 65)
f.STATUS = 1
f.DMAX = 30
f.DCOST = 0.0002 # slow down change of frequency
f.UPPER = 65
Ppin = m.CV()
Ppin.STATUS = 1 # add the SP to the objective
Ppin.SP = 6e6 # set point
Ppin.TR_INIT = 1 # set point trajectory
Ppin.TAU = 5 # time constant of trajectory
Pwf = m.Var(ub = Pres)
Ppout = m.Var()
Pwh = m.Var()
Pm = m.Var()
P_fric_drop = m.Var()
F1 = m.Var()
F2 = m.Var()
q = m.Var(lb = 0)
qc = m.Var(lb = 0)
qr = m.Var(lb = 0)
I = m.Var()
H = m.Var()
BHP = m.Var(lb = 0)
BHPo = m.Var()
qo = m.Var()
Ho = m.Var()
m.Equation([Pwh.dt() == beta2*(q-qc)/V2,
Pwf.dt() == beta1*(qr-q)/V1,
q.dt() == (1/M)*(Pwf - Pwh - rho*g*hv - P_fric_drop + (Ppout-Ppin))])
m.Equation([qr == PI*(Pres - Pwf),
qc == Cc*z*(m.sqrt((Pwh - Pm))),
Pm == Pwh/2,
P_fric_drop == F1 + F2,
F1 == 0.158 * rho * L1* q**2 * visc**0.5 /(D1 * A1**2 * (rho*D1*q)**0.5),
F2 == 0.158 * rho * L2* q**2 * visc**0.5 /(D2 * A2**2 * (rho*D2*q)**0.5)])
m.Equation([
qo == q * fo/f,
H == Ho * (f/fo)**2,
BHPo == -2.3599e9*qo**3 - 1.8082e7*qo**2 + 4.3346e6*qo + 9.4355e4,
BHP == BHPo * (f/fo)**3,
Ppin == Pwf - rho*g*h1 - F1,
Ho == 9.5970e2+7.4959e3*qo+-1.2454e6*qo**2,
I == Inp * BHP / Pnp,
Ppout == H*rho*g + Ppin
])
m.options.solver = 1
m.options.MAX_ITER = 250
m.options.IMODE = 1
m.solve(debug=True)
tf = 30 # final time (sec)
st = 2.0 # simulation time intervals
nt = int(tf/st)+1 # simulation time points
m.time = np.linspace(0,tf,nt)
m.options.CV_TYPE = 2 # squared error
m.options.solver = 3
m.options.NODES=2
m.options.IMODE = 5
m.solve(debug = False)
I wasn't able to reproduce the problem you encountered so I'll give a few specific suggestions for troubleshooting your application and improving the ability of the solver to find a solution.
Help the Solver Find a Solution
Avoid sqrt(-negative)
#qc == Cc*z*(m.sqrt((Pwh - Pm)))
qc**2 == Cc**2 * z**2 * (Pwh - Pm) # avoid negative in sqrt
Avoid potential for divide by zero. The value of q is constrained away from zero but look for other equations that could be improved by re-arrangement.
#qo == q * fo/f
qo * f == q * fo
#H == Ho * (f/fo)**2
H * fo**2 == Ho * f**2
#I == Inp * BHP / Pnp
I * Pnp == Inp * BHP
Constrain the FVs and MVs
It can often help to put small DMAX or limit the upper and lower bound for FVs and MVs. Constraints on the Var types can lead to infeasible solutions.
Reduce the degrees of freedom
For MHE applications, I recommend that you use FVs instead of MVs for your unknown parameters. The FVs calculate a single value over all of the measurements. The MVs calculate a new parameter value for every time point. Using an FV instead of an MV can help the solver because there are fewer decisions for the optimizer and the parameter values won't be adjusted to track signal noise.
Check the Solutions
Configure the objective function.
For MHE applications, you need to have some CV values that you are trying to match that have FSTATUS=1. In the example you posted there are no CVs with FSTATUS=1 or any inserted measurements. MHE is to align a model with measured CVs values by adjusting the unknown parameters as FVs or MVs.
Check the solver status to make sure that it found a successful solution with APPSTAUTS==1
if m.options.APPSTATUS==1:
print('Successful Solution)
else:
print('Solver Failed to Find a Solution')
Create plots of the variables, especially if there is a problematic period. You can often see where there is an integrating variable such as qr or qc that are approaching a variable constraint. Here is an example where I converted your MHE application into an MPC application. I'm adjusting the friction factor f (not realistic) and the valve opening z to show how the MPC drives Ppin to the target set point.
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
m = GEKKO(remote = False)
g = m.Const(value = 9.81)
Cc = m.Const(value = 2*10**-5)
D1 = m.Const(value = 0.1016)
D2 = m.Const(value = 0.1016)
h1 = m.Const(value = 100)
hv = m.Const(value = 1000)
L1 = m.Const(value = 500)
L2 = m.Const(value = 1100)
V1 = m.Const(value = 4.054)
V2 = m.Const(value = 9.729)
A1 = m.Const(0.008107)
A2 = m.Const(0.008107)
beta1 = m.Const(value = 1.5 * 10**9)
beta2 = m.Const(value = 1.5* 10**9)
Pres = m.Const(value = 1.261 * 10**7)
M = m.Const(value = 1.992 * 10**8)
rho = m.Const(value = 932)
PI = m.Const(value = 2.32 * 10**(-9))
visc = m.Const(value = 0.024)
fo = m.Const(value = 60)
Inp = m.Const(value = 65)
Pnp = m.Const(value = 1.625 * 10**5)
z = m.MV(1, lb = 0.1, ub = 1)
z.STATUS = 1
z.DMAX = 0.01
f = m.MV(35, lb = 35, ub = 65)
f.STATUS = 1
f.DMAX = 30
f.DCOST = 0.0002 # slow down change of frequency
f.UPPER = 65
Ppin = m.CV()
Ppin.STATUS = 1 # add the SP to the objective
Ppin.SP = 6e6 # set point
Ppin.TR_INIT = 1 # set point trajectory
Ppin.TAU = 5 # time constant of trajectory
Pwf = m.Var(ub = Pres)
Ppout = m.Var()
Pwh = m.Var()
Pm = m.Var()
P_fric_drop = m.Var()
F1 = m.Var()
F2 = m.Var()
q = m.Var(lb = 0)
qc = m.Var(lb = 0)
qr = m.Var(lb = 0)
I = m.Var()
H = m.Var()
BHP = m.Var(lb = 0)
BHPo = m.Var()
qo = m.Var()
Ho = m.Var()
m.Equation([Pwh.dt() == beta2*(q-qc)/V2,
Pwf.dt() == beta1*(qr-q)/V1,
M * q.dt() == Pwf - Pwh - rho*g*hv - P_fric_drop + (Ppout-Ppin)])
m.Equation([qr == PI*(Pres - Pwf),
qc == Cc*z*(m.sqrt((Pwh - Pm))),
Pm == Pwh/2,
P_fric_drop == F1 + F2,
F1 == 0.158 * rho * L1* q**2 * visc**0.5 /(D1 * A1**2 * (rho*D1*q)**0.5),
F2 == 0.158 * rho * L2* q**2 * visc**0.5 /(D2 * A2**2 * (rho*D2*q)**0.5)])
m.Equation([
qo * f == q * fo,
H * fo**2 == Ho * f**2,
BHPo == -2.3599e9*qo**3 - 1.8082e7*qo**2 + 4.3346e6*qo + 9.4355e4,
BHP == BHPo * (f/fo)**3,
Ppin == Pwf - rho*g*h1 - F1,
Ho == 9.5970e2+7.4959e3*qo+-1.2454e6*qo**2,
I * Pnp == Inp * BHP,
Ppout == H*rho*g + Ppin
])
m.options.solver = 1
m.options.MAX_ITER = 250
m.options.IMODE = 1
m.solve()
tf = 30 # final time (sec)
st = 2.0 # simulation time intervals
nt = int(tf/st)+1 # simulation time points
m.time = np.linspace(0,tf,nt)
m.options.CV_TYPE = 2 # squared error
m.options.solver = 3
m.options.NODES=2
m.options.IMODE = 6
plt.figure(figsize=(10,5))
for i in range(10):
m.solve(disp=False)
print(i,m.options.APPSTATUS)
plt.subplot(10,1,i+1)
plt.plot(m.time+i*st,Ppin.value)
plt.xlim([0,50])
plt.ylim([6e6,7e6])
plt.show()
Your application looks like it is for hydraulic pressure control in drilling. There are additional models available on GitHub. I hope you'll consider contributing your model or case studies to the open-source repository.

NORMSINV and Square root in Ruby

How do I calculate NORMSINV of a number (between 0 and 1) and Square root of a number in Ruby ?
I am using the functions in Excel as below and I need to implement it in Ruby.
=NORMSINV(A1)
=SQRT(A1)
As c650 pointed out in his comment, the square root of x is just
x**0.5
Martin Vidner gave you a link to a decent algorithm for approximation of the normal distribution. For your convenience, I ported it to Ruby:
# algorithm ported from http://www.source-code.biz/snippets/vbasic/9.htm
A1 = -39.6968302866538
A2 = 220.946098424521
A3 = -275.928510446969
A4 = 138.357751867269
A5 = -30.6647980661472
A6 = 2.50662827745924
B1 = -54.4760987982241
B2 = 161.585836858041
B3 = -155.698979859887
B4 = 66.8013118877197
B5 = -13.2806815528857
C1 = -7.78489400243029E-03
C2 = -0.322396458041136
C3 = -2.40075827716184
C4 = -2.54973253934373
C5 = 4.37466414146497
C6 = 2.93816398269878
D1 = 7.78469570904146E-03
D2 = 0.32246712907004
D3 = 2.445134137143
D4 = 3.75440866190742
P_low = 0.02425
P_high = 1 - P_low
def phi(p)
raise ArgumentError if p < 0 || p > 1
if p < P_low
q = (-2 * Math::log(p))**0.5
(((((C1 * q + C2) * q + C3) * q + C4) * q + C5) * q + C6) /
((((D1 * q + D2) * q + D3) * q + D4) * q + 1)
elsif p <= P_high
q = p - 0.5
r = q * q
(((((A1 * r + A2) * r + A3) * r + A4) * r + A5) * r + A6) * q /
(((((B1 * r + B2) * r + B3) * r + B4) * r + B5) * r + 1)
else
q = (-2 * Math::log(1 - p))**0.5
(((((C1 * q + C2) * q + C3) * q + C4) * q + C5) * q + C6) /
((((D1 * q + D2) * q + D3) * q + D4) * q + 1)
end
end

Find ratio/algorithm to translate different coordinate systems?

So I have two different coordinate systems, one is the incoming data and the other is how i plot points in the app. Is there a formula that, given some aligned up points, will give me an algorithm to calculate future points? Eg:
X = 6.5 & Y = 2 on one system is == X = 3101 & Y = 3441 in the other system.
Another set is 6.45/2.37 = 3211/3414. From these two matchups, how can I calculate a formula to "translate" one system into the other?
You need to solve two equations with two unknowns for X, and then the same for Y.
Let's go through this. First we do X:
3101 = 6.5 * a + b
3211 = 6.45 * a + b
First we isolate b:
3101 - 6.5 * a = b
3211 - 6.45 * a = b
Which gives:
3101 - 6.5 * a = 3211 - 6.45 * a
Now we can solve for a:
3101 - 6.5 * a - 3211 + 6.45 * a = 0
-110 -0.05 * a = 0
-110 = 0.05 * a
-2200 = a
Given this a we can solve for b using either of the original two equations:
3101 - 6.5 * a = b
3101 - 6.5 * -2200 = b
3101 + 14300 = b
17401 = b
b = 17401
So for X we have this formula:
X2 = -2200 * X1 + 17401
Let's try X1 = 6.5 and X1 = 6.45:
X2 = -2200 * 6.5 + 17401
X2 = -14300 + 17401
X2 = 3101
X2 = -2200 * 6.45 + 17401
X2 = -14190 + 17401
X2 = 3211
Doing the exact same math for Y gives me that the relationship follows this formula:
Y2 = Y1 * A + B
3441 = 2 * A + B 3414 = 2.37 * A + B
3441 - 2 * A = B 3414 - 2.37 * A = B
3441 - 2 * A = 3414 - 2.37 * A
3441 - 2 * A - 3414 + 2.37 * A = 0
27 + 0.37 * A = 0
0.37 * A = -27
0.37 * A = -27
A = -72.973
3441 = 2 * A + B
3441 = 2 * -72.973 + B
3441 - 2 * -72.973 = B
3441 + 145.946 = B
3586.946 = B
B = 3586.946
Which gives:
Y2 = Y1 * -72.973 + 3586.946
Let's test:
Y2 = 2 * -72.973 + 3586.946
Y2 = -145.946 + 3586.946
Y2 = 3441
Y2 = 2.37 * -72.973 + 3586.946
Y2 = -172.946 + 3586.946
Y2 = 3414
Your translation formulas are this:
X2 = X1 * -2200 + 17401
Y2 = Y1 * 72.973 + 3586.946
what you want is called linear interpolation, rule of three, etc

Solve mixed equation in one variable

I have this equation and want to solve it for v. I tried Mathematica but it is not able to do it. Is there any software, language capable of solving it?
Equation:
Solve[1 + 0.0914642/v^5 - 1.87873/v^4 + 96.1878/v^2 - (
17.3914 E^(-(0.0296/v^2)) (1.398 + 0.0296/v^2))/v^2 - 0.947895/v -
1.37421 v == 0, v]
The text file/m-file is here.
Using Mathematica 9 :-
Clear[v]
expr = 1 + 0.0914642/v^5 - 1.87873/v^4 + 96.1878/v^2 - (
17.3914 E^(-(0.0296/v^2)) (1.398 + 0.0296/v^2))/v^2 - 0.947895/v -
1.37421 v;
sol = Solve[expr == 0, v, Reals]
{{v -> -0.172455}, {v -> 0.0594091}, {v -> 0.105179}, {v -> 3.93132}}
Checking solutions :-
roots = v /. sol;
(v = #; expr) & /# roots
{2.27374*10^-13, 2.32703*10^-12, -9.66338*10^-13, -1.77636*10^-15}
(v = #; Chop[expr]) & /# roots
{0, 0, 0, 0}
Try this in Matlab. You need to have the Symbolic Math Toolbox installed:
>> syms v %// declare symbolic variable, used in defining y
>> y = 1 + 0.0914642/v^5 - 1.87873/v^4 + 96.1878/v^2 - (17.3914*exp(-(0.0296/v^2)) * (1.398 + 0.0296/v^2))/v^2 - 0.947895/v - 1.37421*v;
>> solve(y,v) %// seeks zeros of y as a function of v
ans =
3.931322452560060553464772086259
>> subs(y,3.931322452560060553464772086259) %// check
ans =
-4.4409e-016 %// almost 0 (precision of floating point numbers): it is correct
Without the symbolic math toolbox, you can still do it numerically with fzero:
a1 = 8.99288497*10^(-2);
a2 = -4.94783127*10^(-1);
a3 = 4.77922245*10^(-2);
a4 = 1.03808883*10^(-2);
a5 = -2.82516861*10^(-2);
a6 = 9.49887563*10^(-2);
a7 = 5.20600880*10^(-4);
a8 = -2.93540971*10^(-4);
a9 = -1.77265112*10^(-3);
a10 = -2.51101973*10^(-5);
a11 = 8.93353441*10^(-5);
a12 = 7.88998563*10^(-5);
a13 = -1.66727022*10^(-2);
a14 = 1.39800000 * exp(0);
a15 = 2.96000000*10^(-2);
t = 30;
p = 10;
tr = t/(273.15 + 31.1);
pr = p/(73.8);
s1 = #(v) (a1 + (a2/tr^2) + (a3/tr^3))./v;
s2 = #(v) (a4 + (a5/tr^2) + (a6/tr^3))./v.^2;
s3 = #(v) (a7 + (a8/tr^2) + (a9/tr^3))./v.^4;
s4 = #(v) (a10 + (a11/tr^2) + (a12/tr^3))./v.^5;
s5 = #(v) (a13./(tr^3.*v.^2)).*(a14 + (a15./v.^2)).*exp(-a15./v.^2);
y = #(v) -(pr*v./tr) + 1 + s1(v) + s2(v) + s3(v) + s4(v) + s5(v);
root = fzero(y, [1 5]);
% Visualization
fplot(y, [1 5]); hold all; refline(0,0); line([root,root], [-10,30])

How to accelerate matlab code?

I'm using matlab to implement a multilayer neural network. In the code I represent
the value of each node AS netValue{k}
the weight between layer k and k + 1 AS weight{k}
etc.
Since these data is three-dimensional, I have to use cell to hold a 2-D matrix to enable matrix multiply.
So it becomes really really slow to train the model, which I expect to have resulted from the usage of cell.
Can anyone tell me how to accelerate this code? Thanks
clc;
close all;
clear all;
input = [-2 : 0.4 : 2;-2:0.4:2];
ican = 4;
depth = 4; % total layer - 1, by convension
[featureNum , sampleNum] = size(input);
levelNum(1) = featureNum;
levelNum(2) = 5;
levelNum(3) = 5;
levelNum(4) = 5;
levelNum(5) = 2;
weight = cell(0);
for k = 1 : depth
weight{k} = rand(levelNum(k+1), levelNum(k)) - 2 * rand(levelNum(k+1) , levelNum(k));
threshold{k} = rand(levelNum(k+1) , 1) - 2 * rand(levelNum(k+1) , 1);
end
runCount = 0;
sumMSE = 1; % init MSE
minError = 1e-5;
afa = 0.1; % step of "gradient ascendence"
% training loop
while(runCount < 100000 & sumMSE > minError)
sumMSE = 0; % sum of MSE
for i = 1 : sampleNum % sample loop
netValue{1} = input(:,i);
for k = 2 : depth
netValue{k} = weight{k-1} * netValue{k-1} + threshold{k-1}; %calculate each layer
netValue{k} = 1 ./ (1 + exp(-netValue{k})); %apply logistic function
end
netValue{depth+1} = weight{depth} * netValue{depth} + threshold{depth}; %output layer
e = 1 + sin((pi / 4) * ican * netValue{1}) - netValue{depth + 1}; %calc error
assistS{depth} = diag(ones(size(netValue{depth+1})));
s{depth} = -2 * assistS{depth} * e;
for k = depth - 1 : -1 : 1
assistS{k} = diag((1-netValue{k+1}).*netValue{k+1});
s{k} = assistS{k} * weight{k+1}' * s{k+1};
end
for k = 1 : depth
weight{k} = weight{k} - afa * s{k} * netValue{k}';
threshold{k} = threshold{k} - afa * s{k};
end
sumMSE = sumMSE + e' * e;
end
sumMSE = sqrt(sumMSE) / sampleNum;
runCount = runCount + 1;
end
x = [-2 : 0.1 : 2;-2:0.1:2];
y = zeros(size(x));
z = 1 + sin((pi / 4) * ican .* x);
% test
for i = 1 : length(x)
netValue{1} = x(:,i);
for k = 2 : depth
netValue{k} = weight{k-1} * netValue{k-1} + threshold{k-1};
netValue{k} = 1 ./ ( 1 + exp(-netValue{k}));
end
y(:, i) = weight{depth} * netValue{depth} + threshold{depth};
end
plot(x(1,:) , y(1,:) , 'r');
hold on;
plot(x(1,:) , z(1,:) , 'g');
hold off;
Have you used the profiler to find out what functions are actually slowing down your code? It shows what lines take the most time to execute.

Resources