MATLAB Yalmip: unable to run optimizer; error in eliminatevariables - matlab

Bottomline:
Matlab throws the errors below and it is not obvious to me what is the root cause. The problem seems to reside in the input arguments, but I cannot figure out exactly what it is. I would greatly appreciate any help in finding it.
Index exceeds matrix dimensions.
Error in eliminatevariables (line 42)
aux(model.precalc.index2) = value(model.precalc.jj2);
Error in optimizer/subsref (line 276)
[self.model,keptvariablesIndex] =
eliminatevariables(self.model,self.model.parameterIndex,thisData(:),self.model.parameterIndex);
Error in SCMv0_justrun (line 68)
[solutions,diagnostics] = controller{inputs};
Background:
I am trying to program a Model Predictive Control but I am not very familiar yet with either Yalmip or mathematical optimization algorithms. I have made sure that the defined inputs and the actual inputs have the same dimensions, hence why I am surprised that the error has to do with matrix dimensions.
The error originates in when my code calls the optimizer.
My code is based on: https://yalmip.github.io/example/standardmpc/
Here is my code (the first part of the code is only needed to define the optimization problem and is marked between "%%%%%"; the error occurs near the end):
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
yalmip('clear')
clear all
% Model data
A = eye(3);
B = [1 0 -1 0 0 0 0; 0 1 0 -1 0 0 0; 0 0 0 0 1 -1 -1];
nx = 3; % Number of states
nu = 7; % Number of inputs
% MPC data
Q = [10 10 20]';
R = [10 10 1 1 5 3 3]';
C = [50 0; 0 30];
N = 90;
ny = 2;
E = [0 0 0 0 0 1 0; 0 0 0 0 0 0 1];
u = sdpvar(repmat(nu,1,N),repmat(1,1,N));
x = sdpvar(repmat(nx,1,N+1),repmat(1,1,N+1));
r = sdpvar(repmat(ny,1,N+1),repmat(1,1,N+1));
d = sdpvar(ny,1);
pastu = sdpvar(nu,1);
dx = 0.05;
Gx=[-1*eye(3);eye(3)];
gx = [0 0 0 500 500 1000]';
COVd = [zeros(5,7);0 0 0 0 0 10 0; 0 0 0 0 0 0 10];
COVx = zeros(nx,nx);
auxa = eye(5);
auxb = zeros(5,2);
Gu = [-1*eye(7,7); auxa auxb;0 0 0 0 0 1 1];
gu = [zeros(7,1); 200; 200; 50; 50; 100; 500];
Ga = [0 0 0.5 0.5 -1 0 0];
constraints = [];
objective = 0;
for k = 1:N
r{k} = r{k} + d;
objective = objective + Q'*x{k} + R'*u{k} + (r{k}-E*u{k})'*C*(r{k}-E*u{k});
constraints = [constraints, x{k+1} == A*x{k}+B*u{k}];
COVx = A*COVx*A' + B*COVd*B';
COVGx = Gx*COVx*Gx';
StDevGx = sqrt(diag(COVGx));
chance = gx - norminv(1-dx/(length (gx)*N))*StDevGx;
constraints = [constraints, Ga*u{k}==0, Gu*u{k}<=gu, Gx*x{k}<=gx-chance];
end
objective = objective + Q'*x{N+1};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
parameters_in = {x{1},[r{:}],d,pastu};
solutions_out = {[u{:}], [x{:}]};
controller = optimizer(constraints, objective,[],parameters_in,solutions_out);
x = 100*ones(nx,1);
clf;
disturbance = randn(ny,1)*10;
oldu = zeros(nu,1);
hold on
for i = 1:150
future_r = [4*sin((i:i+N)/40);3*sin((i:i+N)/20)];% match dimensions of r
inputs = {x,future_r,disturbance,oldu};
[solutions,diagnostics] = controller{inputs};
U = solutions{1};oldu = U(1);
X = solutions{2};
if diagnostics == 1
error('The problem is infeasible');
end
x = A*x+B*u;
end

It's a bug in the latest version of YALMIP.

Related

Building newton iteration in MATLAB

I seem to get the error "Warning: Matrix is singular to working precision." when trying to get delta_x. It should be using 5x1 and 5x5 matrices.
clc; close all; clear all;
phi = 1;
delta_x = 1;
error = 10e-15;
x = [ 0; 0; 0; 0; 0];
n =1;
B =0.025;
while norm(phi)>= error && norm(delta_x) >= error
G = [ 40e3 -20e3 -20e3 0 1; -20e3 20e3 0 0 0; -20e3 0 20e3 0 0; 0 0 0 0 0; 0 0 0 0 0];
fx = [ 0;
B*((-x(4)-0.7)*(x(2)-x(4))-(((x(2)-x(4))^2)/2));
B*((-x(4)-0.7)*(x(3)-x(4))-(((x(3)-x(4))^2)/2));
-B*((-x(4)-0.7)*(x(2)-x(4))-(((x(2)-x(4))^2)/2))- B*((-x(4)-0.7)*(x(3)-x(4))-(((x(3)-x(4))^2)/2));
0];
b = [ 0; 0; 0; 200e-6; 2.5];
dfx = [ 0 0 0 0 0;
0 -B*(0.7+x(2)) 0 B*(0.7+x(4)) 0;
0 0 -B*(0.7+x(3)) B*(0.7+x(4)) 0;
0 B*(0.7+x(2)) B*(0.7+x(3)) -2*B*(0.7+x(2)) 0;
0 0 0 0 0];
phi = G*x + fx - b;
m = G + dfx;
delta_x = -m\phi;
x = x+delta_x;
norm_delta_x(n) = norm(delta_x);
norm_phi(n) = norm(phi);
n = n+1;
end
The dimensions of matrices 5x1 and 5x5 are fine, but what you are doing in the step delta_x = -m\phi is solving for an inverse of matrix m. Since m is a matrix that is singular (try running det(m) and you will get a zero), an inverse matrix does not exist. Matlab sees this and notifies you by telling you "Matrix is singular to working precision".

Undefined function or variable for 3dos mechanism

I tried to make a 3dof(3 degrees of freedom mechanism) in matlab but i get this error and i don't know why.
this is for a school project and i need to simulate a human finger.
the code is running normal but after i enter the values for the angles it says that A,B,C are
undefined and i don't know why
a1 = input('valuarea lui q1(grade):');
a2 = input('valuarea lui q2(grade):');
a3 = input('valuarea lui q3(grade):');
L1=35;
L2=45;
L3=30;
z = [-10 10];
plot(z,10);
grid ON;
O=[0;0;0;1];
m= linspace(pi/2,pi/2+a1*pi/180,100);
n = linspace(-pi/2,a2*pi/180,100);
k=linspace(-pi/2,a3*pi/180,100);
for a=1:100
[A1,B1,C1] = Transform(m(a),n(a),k(a),L1,L2,L3);
x = [O(1) A(1) B(1) C(1)];
y = [O(2) A(2) B(2) C(2)];
Cx(i)= C1(1);
Cy(i) = C1(2);
i=i+1;
Plot = plot(x,y,'r',...1
'LineWidth',1);
title('Sumularea unui deget');
plot(Cx,Cy,'--g',...
'LineWidth',1);
pause(0.075);
delete(Plot);
end
plot(x,y,'r',...
'LineWidth',3);
function [A,B,C ] = Transform( m,n,p,l1,l2,l3 )
P = [0;0;0;1];
T1 = [cos(m) -sin(m) 0 0;sin(m) cos(m) 0 0;0 0 1 0; 0 0 0 1];
T2 = [cos(n) -sin(n) 0 11;sin(n) cos(n) 0 0;0 0 1 0; 0 0 0 1];
T3 = [cos(p) -sin(p) 0 12;sin(p) cos(p) 0 0;0 0 1 0; 0 0 0 1];
T4 = [1 0 0 13;0 1 0 0; 0 0 1 0; 0 0 0 1];
A = T1*T2*P;
B = T1*T2*T3*P;
C = T1*T2*T3*T3*P;
end
In your main function, this is the first use of the variables:
x = [O(1) A(1) B(1) C(1)];
They are never written previously. Instead A1 is written, which is a different variable. I guess you mixed the two up.

How to list all results of probability experiment in Matlab [duplicate]

I am writing a function in Matlab to model the length of stay in hospital of stroke patients. I am having difficulty in storing my output values.
Here is my function:
function [] = losdf(age, strokeType, dest)
% function to mdetermine length of stay in hospitaal of stroke patients
% t = time since admission (days);
% age = age of patient;
% strokeType = 1. Haemorhagic, 2. Cerebral Infarction, 3. TIA;
% dest = 5.Death 6.Nursing Home 7. Usual Residence;
alpha1 = 6.63570;
beta1 = -0.03652;
alpha2 = -3.06931;
beta2 = 0.07153;
theta0 = -8.66118;
theta1 = 0.08801;
mu1 = 22.10156;
mu2 = 2.48820;
mu3 = 1.56162;
mu4 = 0;
nu1 = 0;
nu2 = 0;
nu3 = 1.27849;
nu4 = 0;
rho1 = 0;
rho2 = 11.76860;
rho3 = 3.41989;
rho4 = 63.92514;
for t = 1:1:365
p = (exp(-exp(theta0 + (theta1.*age))));
if strokeType == 1
initialstatevec = [1 0 0 0 0 0 0];
elseif strokeType == 2
initialstatevec = [0 1 0 0 0 0 0];
else
initialstatevec = [0 0 (1-p) p 0 0 0];
end
lambda1 = exp(alpha1 + (beta1.*age));
lambda2 = exp(alpha2 + (beta2.*age));
Q = [ -(lambda1+mu1+nu1+rho1) lambda1 0 0 mu1 nu1 rho1;
0 -(lambda2+mu2+nu2+rho2) lambda2 0 mu2 nu2 rho2;
0 0 -(mu3+nu3+rho3) 0 mu3 nu3 rho3;
0 0 0 -(mu4+nu4+rho4) mu4 nu4 rho4;
0 0 0 0 0 0 0;
0 0 0 0 0 0 0;
0 0 0 0 0 0 0];
Pt = expm(t./365.*Q);
Pt = Pt(strokeType, dest);
Ft = sum(initialstatevec.*Pt);
Ft
end
end
Then to run my function I use:
losdf(75,3,7)
I want to plot my values of Ft in a graph from from 0 to 365 days. What is the best way to do this?
Do I need to store the values in an array first and if so what is the best way to do this?
Many ways to do this, one straightforward way is to save each data point to a vector while in the loop and plot that vector after you exit your loop.
...
Ft = zeros(365,1); % Preallocate Ft as a vector of 365 zeros
for t = 1:365
...
Ft(t) = sum(initialstatevec.*Pt); % At index "t", store your output
...
end
plot(1:365,Ft);

"Contour not rendered for non-finite ZData"

I'm trying to plot a frequency characteristic equation using ezplot, but Matlab gives the following warning, "Contour not rendered for non-finite ZData". I have used this command to plot frequency equations previously but now I get a warning and the plot display is empty and it does not change the axis range as well. Can someone please help. Would be much appreciated.
Here's the code i'm using.
% Transfer Matrix for Case-I, thin rotor
clear all;
clc;
EI = 1626;
l = 0.15;
m = 0.44108;
It = 2.178*10^-4;
I_p = 2.205*10^-5;
Itr = 0.24;
I_pr = 0.479;
syms p n;
F = [1 l*1i l^2/(2*EI)*1i l^3/(6*EI);
0 1 l/EI -l^2/(2*EI)*1i;
0 0 1 -l*1i;
0 0 0 l];
P = [ 1 0 0 0;
0 1 0 0;
0 -It*p^2+I_p*n*p 1 0;
-m*p^2 0 0 1];
P_r = [1 0 0 0;
0 1 0 0;
0 -Itr*p^2+I_pr*n*p 1 0;
-m*p^2 0 0 1];
A = F*P*F*P*F*P*F;
B = P_r*F*P*F*P*F;
r = A(1,2)/A(1,4);
a12_p = 0;
a22_p = A(2,2)-r*A(2,4);
a32_p = A(3,2)-r*A(3,4);
a42_p = A(4,2)-r*A(4,4);
Ap(2,2) = a22_p;
Ap(3,2) = a32_p;
Ap(4,2) = a42_p;
Ap(4,4) = 1;
C = B*Ap;
M = [C(3,2) C(3,4);
C(4,2) C(4,4)];
sol = det(M);
ezplot(sol,[-2*10^10 2*10^10]);
The sol is displayed if u ask for it but the plot doesn't display.
Thanks in advance for ur help !! Much appreciated.

matrix dimensions matlab

I Have my function below, the idea being that X is a 3x3 extract from T to be used in the loop, it correctly extracts the 3 rows but for some reason produces far too many columns, see example below.
function T = tempsim(rows, cols, topNsideTemp, bottomTemp, tol)
T = zeros(rows,cols);
T(1,:) = topNsideTemp;
T(:,1) = topNsideTemp;
T(:,rows) = topNsideTemp;
T(rows,:) = bottomTemp;
S = [0 1 0; 1 1 1; 0 1 0];
X = zeros(3,3);
A = zeros(3,3);
for ii = 2:(cols-1);
jj = 2:(rows-1);
X = T([(ii-1) ii (ii+1)], [(jj-1) jj (jj+1)])
A = X.*S;
T = (sum(sum(A)))/5
end
test sample
EDU>> T = tempsim(5,4,100,50,0)
X =
100 100 100 100 100 100 100 100 100
100 0 0 0 0 0 0 0 100
100 0 0 0 0 0 0 0 100
ans =
100 100 100 100 100 100 100 100 100
100 0 0 0 0 0 0 0 100
100 0 0 0 0 0 0 0 100
??? Error using ==> times
Matrix dimensions must agree.
Error in ==> tempsim at 14
A = X.*S;
any thoughts on how to fix this?
There's no need to preallocate X and A if you do a complete assignment anyway. Then, you replace T with a scalar inside the loop, which makes you run into problems in the next iteration. What I'm guessing you want could look something like this:
function T = tempsim(rows, cols, topNsideTemp, bottomTemp, tol)
T = zeros(rows,cols);
T(1,:) = topNsideTemp;
T(:,1) = topNsideTemp;
T(:,rows) = topNsideTemp;
T(rows,:) = bottomTemp;
S = [0 1 0; 1 1 1; 0 1 0];
for ii = 1:(cols-2);
for jj = 1:(rows-2);
X = T(ii:ii+2, jj:jj+2);
A = X.*S;
T(ii,jj) = (sum(sum(A)))/5;
end
end
Although I'm not sure if you really mean to do that – you're working on T while modifying it. As a wild guess, I suspect you might be looking for something like
conv2(T, S/5, 'same')
instead, perhaps after making your fixed-temp borders twice as thick and re-setting them after the call (since conv2 does zero-padding at the outer borders).
Here:
jj = 2:(rows-1);
X = T([(ii-1) ii (ii+1)], [(jj-1) jj (jj+1)])
jj becomes [2 3 4]
so X is
T([1 2 3], [ [2 3 4]-1 [2 3 4] [2 3 4]+1 ])
You probably missed a for loop.