How to find Multi variables using GA in matlab? - matlab

Here is my model:
Solving this problem, I used GA in matlab
function F = sim_fit(q,k,m)
%retailer
a(1,1)=3;a(2,1)=2;a(3,1)=3;a(1,2)=1;a(2,2)=1.1;a(3,2)=9;
d(1,1)=1850;d(2,1)=2000;d(3,1)=3000;d(1,2)=2100;d(2,2)=1300;d(3,2)=900;
hr(1,1)=2.4;hr(2,1)=1.3;hr(3,1)=38;hr(1,2)=4.5;hr(2,2)=3.6;hr(3,2)=45;
so(1,1)=3.5;so(2,1)=1.5;so(3,1)=2.5;so(1,2)=0.3;so(2,2)=0.6;so(3,2)=6.3;
t(1,1)=1;t(2,1)=1;t(3,1)=3;t(1,2)=1;t(2,2)=1;t(3,2)=3;
E(1,1)=2;E(2,1)=2;E(3,1)=10;E(1,2)=2;E(2,2)=2;E(3,2)=10;
Y(1,1)=3;Y(2,1)=3;Y(3,1)=11;Y(1,2)=3;Y(2,2)=3;Y(3,2)=11;
%vendor
S=100;
hv(1)=3.5;hv(2)=4;
C(1)=10; C(2)=50;
Cv(1)=2.4; Cv(2)=3;
Cf(1)=3; Cf(2)=1.2;
s(1)=0.3; s(2)=0.1;
the(1)=0.01; the(2)=0.03;
dv(1)=sum(d(1,1)+d(1,2));dv(2)=sum(d(2,1)+d(2,2));
Q(1)=sum(q(1,1)+q(1,2));Q(2)=sum(q(2,1)+q(2,2));
P(1)=10000; P(2)=8000;
%function
for j=1:2
for i=1:2
F= S*dv(i)/(Q(i)*m(i,j))+(hv(i)*Q(i)*((m(i)-1)*(1-dv(i)/P(i))+dv(i)/P(i)))/2+...
dv(i)*(m(i)*C(i)+m(i)*Q(i)*Cv(i)+Cf(i))+m(i)*s(i)*dv(i)*Q(i)*the(i)/2+...
a(i,j).*d(i,j)./q(i,j)+(hr(i,j).*((1-k(i,j)).^2).*q(i,j))./2+...
k(i,j).^2.*so(i,j).*q(i,j)./2+(m(i)*t(i,j).*d(i,j))./q(i,j)+(m(i)*E(i,j).*d(i,j))./q(i,j)+...
Y(i,j).*d(i,j);
end
end
end
function [C, ceq] = sim_constraint(q,k,m)
B(:,1)=200;B(:,2)=300;
W(:,1)=100;W(:,2)=100;
b(1)=10; b(2)=14;
w(1)=1; w(2)=1.5;
P(1)=10000; P(2)=8000;
C=[(m(1).*q(1,1).*b(1)+m(2).*q(2,1).*b(2))-B(:,1);
(m(1).*q(1,2).*b(1)+m(2).*q(2,2).*b(2))-B(:,2);
(m(1).*q(1,1).*w(1)+m(2).*q(2,1).*w(2))-W(:,1);
(m(1).*q(1,2).*w(1)+m(2).*q(2,2).*w(2))-W(:,2);
m(1)*Q(1)-P(1);m(2)*Q(2)-P(2)
k(1,1)-1;k(1,2)-1;k(2,1)-1;k(2,2)-1];
ceq=[d(1,1)+d(1,2)-dv(1);(d(2,1)+d(2,2))-dv(2);
(q(1,1)+q(1,2))-Q(1);(q(2,1)+q(2,2))-Q(2)];
end
First, I don't know how to input Xij which is binary variable in sim_fitness function.
Second, in order to solve this problem, I use Optimization Toolbox.
Error message said "need more input variable."
How can I fix it?

This is not an answer to your question. But please, please start using matlab as it was intended:) If it was this cumbersome, then people would not be using it.
The net happiness of the human race will increase if you change your existing code to something like this:
function F = sim_fit(q,k,m)
%retailer
a=[3 2 3; 1 1.1 9].'; %or a=[3 1; 2 1.1; 3 9];
d=[1850 2000 3000; 2100 1300 900].';
hr=[2.4 1.3 38; 4.5 3.6 45].';
so=[3.5 1.5 2.5; 0.3 0.6 6.3].';
t=[1 1 3; 1 1 3].';
E=[2 2 10; 2 2 10].';
Y=[3 3 11; 3 3 11].';
%vendor
S=100;
hv=[3.5 4];
C=[10 50];
Cv=[2.4 3];
Cf=[3 1.2];
s=[0.3 0.1];
the=[0.01 0.03];
dv=sum(d(1:2,:),2).'; %row vector like the earlier ones
Q=sum(q(1:2,:),2).';
P=[10000 8000];
%function
for j=1:2
for i=1:2
F= S*dv(i)/(Q(i)*m(i,j))+(hv(i)*Q(i)*((m(i)-1)*(1-dv(i)/P(i))+dv(i)/P(i)))/2+...
dv(i)*(m(i)*C(i)+m(i)*Q(i)*Cv(i)+Cf(i))+m(i)*s(i)*dv(i)*Q(i)*the(i)/2+...
a(i,j).*d(i,j)./q(i,j)+(hr(i,j).*((1-k(i,j)).^2).*q(i,j))./2+...
k(i,j).^2.*so(i,j).*q(i,j)./2+(m(i)*t(i,j).*d(i,j))./q(i,j)+(m(i)*E(i,j).*d(i,j))./q(i,j)+...
Y(i,j).*d(i,j);
end
end
end
function [C, ceq] = sim_constraint(q,k,m)
B=[200 300];
W=[100 100];
b=[10 14];
w=[1 1.5];
P=[10000 8000];
mtmp=reshape(m(1:2),1,[]); %since I don't know its size, be on the safe side
qtmp=q(1:2,1:2); %same thing here
%WHAT IS Q?
%WHAT IS d?
%WHAT IS dv?
C=[((mtmp.*b)*qtmp - B).';
((mtmp.*w)*qtmp - W).';
(mtmp.*Q-P).'; %assuming Q is of size [1, 2]
reshape(k(1:2,1:2).',4,1)-1];
ceq=[sum(d(1:2,1:2),2)-dv.';
sum(q(1:2,1:2),2)-Q.']; %assuming Q is of size [1, 2]
end
Sorry, I didn't have it in me to decrypt your expression for F. I strongly suggest getting familiar with the basic array syntax of matlab, and checking for yourself whether I made any mistakes during the conversion of your code. If you learn how to work with matrices and vectors, expressions like what you have for F can be radically simplified.
Also, the definition of the variables Q, d and dv seem to be missing from your second function. Those aren't globals, are they?

Related

Creating a number of matrices/vectors based on a number

I have a simple for loop that is used to simulated data,
for t=2:T;
Y_star(t,1,b)=[Y_star(t-1,1,b) X_1_star(t-1,1,b) X_2_star(t-1,1,b) 1]*beta(:,i)+w(t-1)*e(t-1,i);
X_1_star(t,1,b)=Theta(1,1)+Phi(1,:,1)*[X_1_star(t-1,1,b) ; X_2_star(t-1,1,b)]+w(t-1)*v(t-1,1,i);
X_2_star(t,1,b)=Theta(2,1)+Phi(2,:,1)*[X_1_star(t-1,1,b) ; X_2_star(t-1,1,b)]+w(t-1)*v(t-1,2,i);
end;
The issue I am having is this is fine when I have two X variables, however, I would like to write the code so that I can increase the number of variables to change each time, 4 say.
In this case, I would need X_1_star, X_2_star, X_3_star and X_4_star.
I can handle the Phi and Theta coefficients, as well as the w and v and e however I am struggling with creating the matrices for X's.
Any ideas would be greatly, I have tried storing the matrices within cells but I struggled to get this working.
Following the commnets, here is a simple example
%% Simple example
%-------------------------------------------------------------------------%
Phi = [0.9954 0.0195;
0.0012 0.9567];
Theta= [0.007;0.051];
beta = [0.06;-0.10;1.66;-0.88];
N = 1;
e = rand(370,1);
v = randn(370,2);
t = 371;
T = 371;
yy = rand(370,1);
X_1 = rand(370,1);
X_2 = rand(370,1);
B=50;
Y_star=zeros(T,N,B);
X_1_star=zeros(T,N,B);
X_2_star=zeros(T,N,B);
for b=1:B;
Y_star(1,:,b)=yy(1,:);
X_1_star(1,:,b)=X_1(1,:);
X_2_star(1,:,b)=X_2(1,:);
w=randn(T-1,1);
for t=2:T;
for i=1:N;
Y_star(t,i,b)=[Y_star(t-1,i,b) X_1_star(t-1,i,b) ...
X_2_star(t-1,i,b) 1]*beta(:,i)+w(t-1)*e(t-1,i);
X_1_star(t,i,b)=Theta(1,i)+Phi(1,:,i)*[X_1_star(t-1,i,b) ; ...
X_2_star(t-1,i,b)]+w(t-1)*v(t-1,1,i);
X_2_star(t,i,b)=Theta(2,i)+Phi(2,:,i)*[X_1_star(t-1,i,b) ; ...
X_2_star(t-1,i,b)]+w(t-1)*v(t-1,2,i);
end;
end;
disp(b);
end;
I ideally this to do the same thing but not be dependent upon writing X_1 and X_2, as I would like to increase this sometimes to a larger number.
I have tried reshaping as the commnets suggested but not sure how this would or could work in this example.
I think this problem is simply one of matrix algebra.
With the X variables it appears like you are simulating a small VAR model.
Instead of dynamic matrices as the answer above, I think it would make more sense to simulating the x data as a larger matrix instead of vectors.
Here is a simple example,
First, I show you a two variable case, both in the method you use, and by jointly simulating the data...
Then I show with a 3 variable case how to extend this...
All you have to do is take the size of the beta matrix (or alpha) as I guessing these are determined before the matrix...
%Simulating a small VAR model
%% 2 - variable case
rng('default')
b = [0.4 0.5;0.6 0.07];
a = [0.1 0.2];
v=randn(100,2);
x1 = zeros(100,1);
x2 = zeros(100,1);
xm=zeros(100,2);
T=100;
for t=2:T;
x1(t)=a(1)+b(1,:)*[x1(t-1) ; x2(t-1)]+v(t-1,1);
x2(t)=a(2)+b(2,:)*[x1(t-1) ; x2(t-1)]+v(t-1,2);
end;
for t=2:T;
xm(t,:)=a+xm(t-1,:)*b'+v(t-1,:)
end;
[xm x1 x2]
%% 3 - variable case
rng('default')
b = [0.4 0.5 0.1;0.6 0.07 0.1; 0.3 0.4 0.7];
a = [0.1 0.2 0.3];
v=randn(100,size(b,2));
xm=zeros(100,size(b,2));
for t=2:T;
xm(t,:)=a+xm(t-1,:)*b'+v(t-1,:)
end;
I generally find structure arrays more useful for this kind of dynamic indexing (where you don't know how many you'll have of X_1_star, X_2_star...)
I didn't try to reproduce the whole example, but it might go something like this if you're trying to get up to X_4_star:
...
nX=4;
for i=1:N
Y_star(t,i,b)=[Y_star(t-1,i,b) X_1_star(t-1,i,b) ...
X_2_star(t-1,i,b) 1]*beta(:,i)+w(t-1)*e(t-1,i);
for n=1:nX
X(n).star(t,i,b)=...
end
end

how to fix Matrix dimensions must agree

I am trying to plot Z0 in term of t
I get this error Matrix dimensions must agree.
I know that ‘T’ is a scalar, and ‘X’ and ‘Y’ are (51x26) matrices, and ‘t’ is a (1x501) vector.It is not possible to multiply them, because they are not conformable to matrix multiplication
I need a solution please I am new to MATLAB
sigma0=0;
el= 0.5;
L= 1 ;
h= 0.5 ;
a= 1;
N= 3;
g=10;
rho=1000;
Z0=0;
t=0:0.01:5;
x=0:0.02:el;
y=0:0.02:L;
[X,Y]=mesh grid (x,y);
sigma=0;
T=3*pi/4;
for n=0:N
for m=0:N
A=pi*((m/el)^(2)+(n/L)^(2))^(0.5);
B=(g*A+(sigma/rho)*A^3)*atan(A*h);
C=B^(0.5);
Z=a*cos(C.*T).*cos((m*pi/el).*X).*cos((n*pi/L).*Y);
Zs=Z0+Z;
Z0=Zs;
end
end
m=3;
n=4;
A=pi*((m/el)^(2)+(n/L)^(2))^(0.5);
B0=(g*A+(sigma0./rho)*A^3)*atan(A*h);
C0=(B0.^(0.5));
Z0=(a.*cos(C0.*T)).*cos((m*pi/el).*X).*(cos((n*pi/L).*Y));
figure
subplot(221)
plot(t,length(Z0));
xlabel(' temps s');
ylabel(' élévation z(x,y)y');
title(' sans tension superficielle');
legend('sigma0')
The result I expect to see a sinusoidal figure
I think all you need is replacing plot(t,length(Z0)); with plot(1:length(Z0), Z0);
I am not getting an error message, and I can't see where you try to multiple by t.
Execute clear all just in case...
Except that, you posted a syntax error [X,Y]=mesh grid (x,y); should be [X,Y]=meshgrid (x,y);.
Replace plot(t,length(Z0));
With: plot(1:length(Z0), Z0);
Here is the result:

State space system gives different bode plot then transfer function matrix

I have a state space system with matrices A,B,C and D.
I can either create a state space system, sys1 = ss(A,B,C,D), of it or compute the transfer function matrix, sys2 = C*inv(z*I - A)*B + D
However when I draw the bode plot of both systems, they are different while they should be the same.
What is going wrong here? Does anyone have a clue? I know btw that the bodeplot generated by sys1 is correct.
The system can be downloaded here: https://dl.dropboxusercontent.com/u/20782274/system.mat
clear all;
close all;
clc;
Ts = 0.01;
z = tf('z',Ts);
% Discrete system
A = [0 1 0; 0 0 1; 0.41 -1.21 1.8];
B = [0; 0; 0.01];
C = [7 -73 170];
D = 1;
% Set as state space
sys1 = ss(A,B,C,D,Ts);
% Compute transfer function
sys2 = C*inv(z*eye(3) - A)*B + D;
% Compute the actual transfer function
[num,den] = ss2tf(A,B,C,D);
sys3 = tf(num,den,Ts);
% Show bode
bode(sys1,'b',sys2,'r--',sys3,'g--');
Edit: I made a small mistake, the transfer function matrix is sys2 = C*inv(z*I - A)*B + D, instead of sys2 = C*inv(z*I - A)*B - D which I did wrote done before. The problem still holds.
Edit 2: I have noticted that when I compute the denominator, it is correct.
syms z;
collect(det(z*eye(3) - A),z)
Your assumption that sys2 = C*inv(z*I- A)*B + D is incorrect. The correct equivalent to your state-space system (A,B,C,D) is sys2 = C*inv(s*I- A)*B + D. If you want to express it in terms of z, you'll need to invert the relationship z = exp(s*T). sys1 is the correct representation of your state-space system. What I would suggest for sys2 is to do as follows:
sys1 = ss(mjlsCE.A,mjlsCE.B,mjlsCE.C,mjlsCE.D,Ts);
sys1_c = d2c(sys1);
s = tf('s');
sys2_c = sys1_c.C*inv(s*eye(length(sys1_c.A)) - sys1_c.A)*sys1_c.B + sys1_c.D;
sys2_d = c2d(sys2_c,Ts);
That should give you the correct result.
Due to inacurracy of the inverse function extra unobservable poles and zeros are added to the system. For this reason you need to compute the minimal realization of your transfer function matrix.
Meaning
% Compute transfer function
sys2 = minreal(C*inv(z*eye(3) - A)*B + D);
What you are noticing is actually a numerical instability regarding pole-zero pair cancellations.
If you run the following code:
A = [0, 1, 0; 0, 0, 1; 0.41, -1.21, 1.8] ;
B = [0; 0; 0.01] ;
C = [7, -73, 170] ;
D = 1 ;
sys_ss = ss(A, B, C, D) ;
sys_tf_simp = tf(sys_ss) ;
s = tf('s') ;
sys_tf_full = tf(C*inv(s*eye(3) - A)*B + D) ;
zero(sys_tf_simp)
zero(sys_tf_full)
pole(sys_tf_simp)
pole(sys_tf_full)
you will see that the transfer function formulated by matrices directly has a lot more poles and zeros than the one formulated by MatLab's tf function. You will also notice that every single pair of these "extra" poles and zeros are equal- meaning that they cancel with each other if you were to simply the rational expression. MatLab's tf presents the simplified form, with equal pole-zero pairs cancelled out. This is algebraically equivalent to the unsimplified form, but not numerically.
When you call bode on the unsimplified transfer function, MatLab begins its numerical plotting routine with the pole-zero pairs not cancelled algebraically. If the computer was perfect, the result would be the same as in the simplified case. However, numerical error when evaluating the numerator and denominators effectively leaves some of the pole-zero pairs "uncancelled" and as many of these poles are in the far right side of the s plane, they drastically influence the output behavior.
Check out this link for info on this same problem but from the perspective of design: http://ctms.engin.umich.edu/CTMS/index.php?aux=Extras_PZ
In your original code, you can think of the output drawn in green as what the naive designer wanted to see when he cancelled all his unstable poles with zeros, but the output drawn in red is what he actually got because in practice, finite-precision and real-world tolerances prevent the poles and zeros from cancelling perfectly.
Why is an unobservable / uncontrollable pole? I think this issue comes only because the inverse of a transfer function matrix is inaccurate in Matlab.
Note:
A is 3x3 and the minimal realization has also order 3.
What you did is the inverse of a transfer function matrix, not a symbolic or numeric matrix.
# Discrete system
Ts = 0.01;
A = [0 1 0; 0 0 1; 0.41 -1.21 1.8];
B = [0; 0; 0.01];
C = [7 -73 170];
D = 1;
z = tf('z', Ts)) # z is a discrete tf
A1 = z*eye(3) - A # a tf matrix with a direct feedthrough matrix A
# inverse it, multiply with C and B from left and right, and plus D
G = D + C*inv(A1)*B
G is now a scalar (SISO) transfer function.
Without "minreal", G has order 9 (funny, I don't know how Matlab computes it, perhaps the "Adj(.)/det(.)" method). Matlab cannot cancel the common factors in the numerator and the denominator, because z is of class 'tf' rather than a symbolic variable.
Do you agree or do I have misunderstanding?

Plotting time graph in MATLAB

I have a function of this form in MATLAB,
C=S*e^(L*t)*inv(S)*C_0
where my
S=[-2 -3;3 -2]
L=[0.5 0; 0 1.5]
C_0=[1; 1]
I need to plot this function with respect to time. My output C is a 2-by-1 matrix.
What I have done is computed e^L separately using b=expm(L) and then I inserted mpower(b,t) into the function. So my resulting function in the script looks like
b=expm(L);
C=S*mpower(b,t)*inv(S)*C_0;
Now, how should I go about plotting this w.r.t time. I tried defining the time vector and then using it, but quite obviously I get the error message which says matrix dimensions do not agree. Can someone give me a suggestion?
You can probably do this in a vectorised manner but if you're not worried about speed or succinct code, why not just write a for loop?
ts = 1 : 100;
Cs = zeros(2, length(ts) );
S = [-2 -3;3 -2];
L = [0.5 0; 0 1.5];
C_0 = [1; 1];
for ii = 1 : length(ts)
b = expm(L);
Cs(:,ii) = S*mpower(b,ts(ii))*inv(S)*C_0;
end
ts contains the time values, Cs contains the values of C at each time.

Muller method in Matlab doesn't find complex roots

My problem is that my Mullers method algorithm in Matlab doesn’t find the complex roots only real. It doesn’t matter which point I choose. My algorithm only finds -1.9713 in range [-2, 0] and 1.4660 in range [1 2] after using the roots function I know that roots are:
roots([2 0.5 -5 2 -3])
ans =
-1.9713
1.4660
0.1276 + 0.7090i
0.1276 - 0.7090i
Here is my code:
function [sol,sol2,i] = Muller2()
min=-2;
max=0;
f=[2 0.5 -5 2 -3]
x=min
for i=1:Inf
%calculating coefficients of the quadratic equation
a=polyval(polyder(polyder(f)), x)/2;
b=polyval(polyder(f), x);
c=polyval(f, x);
%solving delta
d=b^2-4*a*c;
%calculating roots
z1=-2*c/(b+sqrt(d));
z2=-2*c/(b-sqrt(d));
%choosing the closer root
if(abs(polyval(f, z1))<=abs(polyval(f, z2)))
x=x+z1;
else
x=x+z2;
end
sol2(i)=x
if(abs(polyval(f,x))<=20*eps)
break;
end
end
sol=x
I figured it out. In this fragment of code:
%choosing the closer root
if(abs(polyval(f, z1))<=abs(polyval(f, z2)))
x=x+z1;
else
x=x+z2;
end
I changed this:
if(abs(polyval(f, z1))<=abs(polyval(f, z2)))
to this:
if(abs(z1))<=abs(z2))
and the algorithm is now working correctly