How do I make simulation/optimization work in Matlab? - simulation

I am trying to link SimEvent and the optimization module of MATLAB. For that, I first need to define a function that runs the simulation then call it in an optimization function. I got the idea of the simulation/optimization code from the link below:
http://au.mathworks.com/videos/optimizing-manufacturing-production-processes-68961.html
I tried to go through all the code I see in this video but, when I am applying it, it is not working. Here is my code:
function finalresults = SimOpt ()
intcon = [1];
A=[];
b=[];
Aeq=[];
beq = [];
lb = [1];
ub= [10];
finalresults= intlinprog(#f,intcon,A,b,Aeq,beq,lb,ub);
function obj = f(vecX)
NumServers = vecX(1);
NumTruck = vecX(2);
set_param('concreting10/Positioning and Unloading','NumberOfServers',num2str(NumServers));
set_param('concreting10/Washing','NumberOfServers',num2str(NumTruck));
simOut = sim('concreting10','SaveOutput','on','OutputSaveName','WaitingTimeInQueue');
z = simOut.get('WaitingTimeInQueue');
waiting = max(z);
cost = [100 200]*vecX';
obj = waiting*1000+cost;
end
end
When I run the whole code I get this warning:
Error using intlinprog (line 122) INTLINPROG requires the following inputs to be of data type double: 'f'.
Error in SimOpt (line 26) finalresults= intlinprog(#f,intcon,A,b,Aeq,beq,lb,ub);
Any help will be appreciated.

Change the last line in the function to
obj = waiting * 1000.0 + cost
MATLAB and many other HLLs convert data type to integer if multiplied by an integer type constant value. So it is necessary to multiply the constant as double type by adding a decimal point.

Related

Optimization with genetic algorithm in matlab

I have written a simple optimization code using genetic algorithm.I don't know why I get error during running the code.Here is my code:
f = #(x1,x2) 1-x1.^2+(x1-x2).^2;
A = [1 1;-1 2;2 1];
b =[2 2 3]' ;
Aeq = [];
beq = [];
Lb = [0 0]';
Ub = [];
[Xopt,Fval] = ga(f,2,A,b,Aeq,beq,Lb,Ub)
I don not know why matlab gives me error.I wrote this programm based on the "Genetic algorithm Documentation" bit still gives me error:
Error using #(x1,x2)1-x1.^2+(x1-x2).^2
Not enough input arguments.
Error in createAnonymousFcn>#(x)fcn(x,FcnArgs{:}) (line 11)
fcn_handle = #(x) fcn(x,FcnArgs{:});
Error in makeState (line 48)
firstMemberScore = FitnessFcn(state.Population(initScoreProvided+1,:));
Error in galincon (line 18)
state = makeState(GenomeLength,FitnessFcn,Iterate,output.problemtype,options);
Error in ga (line 351)
[x,fval,exitFlag,output,population,scores] = galincon(FitnessFcn,nvars, ...
Caused by:
Failure in initial user-supplied fitness function evaluation. GA cannot continue
Objective functions of all optimization methods in MATLAB only accept 1 argument. According to ga documents:
fun — Objective function
Objective
function, specified as a function handle or function name. Write the
objective function to accept a row vector of length nvars and return a
scalar value.
When the 'UseVectorized' option is true, write fun to accept a
pop-by-nvars matrix, where pop is the current population size. In this
case, fun returns a vector the same length as pop containing the
fitness function values. Ensure that fun does not assume any
particular size for pop, since ga can pass a single member of a
population even in a vectorized calculation.
Change you objective function and it should work:
f = #(x) 1-x(1).^2+(x(1)-x(2)).^2;

Solve equation {exponential *prod exponential(ln)}

I want to solve a equation in MATLAB with fsolve
I'm trying to do that:
function F = root2d(P);
lambda = 2*10^-4;
th = -40:-1:-106;
PL1 = 10471285.480509; % (mw)
p1 = 10;
p2 = 6 ;
p3 = 8 ;
al = 2.5;
T = 10.^(th./10);
r = (p1*PL1^(-1)./T).^(1/al);
R = (p2*PL1^(-1)./T).^(1/al);
syms P
c = (lambda.*pi.*(R.^2));
j = 1:3;
D = zeros(3,67);
for k = 1:numel(j)
F(1) = (prod(D(k,:)==exp(P(1).*c.*(log(P(1)).^k/factorial(k))))).*exp(-(lambda*P(1).*pi.*(r.^2)))-P;
end
fun = #root2d;
P0 = 0;
P = fsolve(fun,P0)
Do you have an idea?
There are a couple of problems in this code. I will help you with the most tricky.
It is identified using rubberduck debugging. Let me exemplify it by explaining your code to you.
Starting from the top you define a function called root2d, which returns some object F, then in this function you define alot of constants. With these cosntants defined, you can define your symbolic function F, which we earlier saw was the output of the function. Continuing in this function, root2d, you now create a function handle fun to root2d, and then in the last line you call fsolve to solve fun.
Did you see the error?
fsolve calls fun which is a function handle to root2d. Thus fsolve calls root2d. Running root2d MATLAB comes across a new fsolve which calls root2d. I.e. root2d will be pushed unto the stack over and over again.
This is solved by taking the last three lines out of the function, and then running them from another script or from the terminal.
Doing so results in a new error:
Unable to perform assignment because the indices on the left side are
not compatible with the size of the right side.
Error in sym/privsubsasgn (line 1085)
L_tilde2 = builtin('subsasgn',L_tilde,struct('type','()','subs',{varargin}),R_tilde);
Error in sym/subsasgn (line 922)
C = privsubsasgn(L,R,inds{:});
Error in SO (line 18)
F(1) = (prod(D(k,:)==exp(P(1).*c.*(log(P(1)).^k/factorial(k))))).*exp(-(lambda*P(1).*pi.*(r.^2)))-P;
Error in fsolve (line 242)
fuser = feval(funfcn{3},x,varargin{:});
Caused by:
Failure in initial objective function evaluation. FSOLVE cannot
continue.
I.e. you have to ensure that your objective function, F(1) =... is correctly written.

Receiving MATLAB Error Regarding Function Arguments

When running my MATLAB script below, I keep getting an error that states:
Error using spa (Line 147)
The value of the window
size must be an integer greater than 2.
Error in "projectName" G = spa(xFunction2, x)
I've tried putting in multiple types of arguments into "spa" (data, windowsize, frequency) but it still yields the same error(s). Help?
n = 1:1024;
%Signal Function
xFunction = sqrt(10)*exp(j*2*pi*0.10*n)+ sqrt(20)*exp(j*2*pi*0.20*n) + sqrt(625);
%Complex Noise Function
zFunction = 0.707*randn(size(n)) + j*0.707*randn(size(n));
%Computing the value of x(n) + sqrt(625)*z
xFunction2 = xFunction + sqrt(625)*zFunction;
G = spa(xFunction2,51);
figure(1);
plot(w, 10*log10(G));
Acording the documentation of spa the first argument is iddata type. In addition, the time serie has to be a column vector.
So, to make it works change G = spa(xFunction2,51); for G = spa(xFunction2(:),51);. To do it the correct way, convert your time serie to iddata:
Ts = 0.1; % what ever is your sampling time.
myiddata = iddata(xFunction2(:),[],Ts);
G = spa(myiddata,51);
In addition, you should use spectrum(G) or bode(G)to plot the result.

correct function handle for integral2 in matlab

I created a function in matlab that returns a vector like
function w = W_1D(x,pos,h)
w=zeros(1,length(x));
if (h~=0)
xmpos = x-pos;
inds1 = (-h <= xmpos) & (xmpos < 0);
w(inds1) = xmpos(inds1)./h + 1;
inds2 = (0 <= xmpos) & (xmpos <= h);
w(inds2) = -xmpos(inds2)./h + 1;
else
error('h shouldn't be 0')
end
end
Thus, in the end, there is a vector w of size length(x).
Now i created a second function like
function f = W_2D(x,y,pos_1,pos_2,h)
w_x = W_1D(x,pos_1,h);
w_y = W_1D(y,pos_2,h);
f = w_x'*w_y;
end
where length(x)=length(y). Thus, the function W_2D obviously returns a matrix.
But when I now try to evaluate the integral over a rectangular domain like e.g.
V = integral2(#(x,y) W_2D(x,y,2,3,h),0,10,0,10);
matlab returns some errors:
Error using integral2Calc>integral2t/tensor (line 242)
Integrand output size does not match the input size.
Error in integral2Calc>integral2t (line 56)
[Qsub,esub] = tensor(thetaL,thetaR,phiB,phiT);
Error in integral2Calc (line 10)
[q,errbnd] = integral2t(fun,xmin,xmax,ymin,ymax,optionstruct);
Error in integral2 (line 107)
Q = integral2Calc(fun,xmin,xmax,yminfun,ymaxfun,opstruct);
I also tried to vary something in the W_2D-function: instead of f = w_x'*w_y;
I tried f = w_x.'*w_y;
or w_y = transpose(w_y); f = kron(w_x,w_y);, but there is always this error with the Integrand output size-stuff.
Can anyone explain, where my fault is?
EDIT: After Werner's hint with the keyboard debugging method, I can tell you the following.
The first step returns w_x of type <1x154 double>, w_y is <1x192 double>, x and y are both <14x14 double>. In the next step, f appears with a value of <154x192 double>. Then everything disappears, except x and y and the matlab-function integral2Calc.m appears in the editor and it jumps to the Function Call Stack integral2t/tensor and after some more steps, the error occurs here
Z = FUN(X,Y); NFE = NFE + 1;
if FIRSTFUNEVAL
if ~isfloat(Z)
error(message('MATLAB:integral2:UnsupportedClass',class(Z)));
end
% Check that FUN is properly vectorized. This is important here
% because we (otherwise) always pass in square matrices, which
% reduces the probability of the user generating an error by
% using matrix functions instead of elementwise functions.
Z1 = FUN(X(VTSTIDX),Y(VTSTIDX)); NFE = NFE + 1;
if ~isequal(size(Z),size(X)) || ~isequal(size(Z1),size(VTSTIDX))
% Example:
% integral2(#(x,y)1,0,1,0,1)
error(message('MATLAB:integral2:funSizeMismatch'));
end
Hope that information is detailed enough...I have no idea what happenes, because my example is exact as it is given on the mathworks site about integral2, isn't it?
Maybe I should precise a bit more, what I wanna do: since W_2D gives me a surface w(x,y) of a compactly supported 2-dimensional hat-function, stored in a matrix w, I want to calculate the volume between the (x,y)-plane and the surface z=w(x,y)...
EDIT2: I still do not understand how to handle the problem, that integral2 creates matrices as inputs for my W_1D-functions, which are called in W_2D and intended to have a <1xn double>-valued input and return a <1xn double> output, but at least I can simply use the following to solve the integration over the tensor product by using two one-dimensional integral-calls, that is
V = integral(#(x)integral(#(y)W_1D(y,3,h),0,10).*W_1D(x,2,h),0,10);
This first function is quite wrong. You are not indexing the array positions while you are doing w = x inside for.
Besides, if that would work, you are returning a line vector, that is, size 1xlength(x) and when you do w_x'*w_y you are doing length(x)x1 times 1xlength(y), which would give you a matrix length(x)*length(y).
Consider correcting your function:
function w = W_1D(x,pos)
w = zeros(length(x),1); % Allocate w as column vector, so that the product gives a scalar (as I suppose that it is what you want.
for ii=1:length(x) % Here, so that is indexes w and x elements as you need
w(ii)=x(ii) - pos; % I changed your code to something that makes sense, but I don't know if that is what you want to do, you have to adapt it to work correctly.
end
end
You may also want to debug your functions, consider adding keyboard before your operations and check what they are returning using dbstep. I.e:
function f = W_2D(x,y,pos_1,pos_2)
w_x = W_1D(x,pos_1);
w_y = W_1D(y,pos_2);
keyboard
f = w_x'*w_y;
end
Execution will stop at keyboard, then you can check w_x size, w_y size, and do dbstep to go after f = w_x'*w_y and see what it returned. After you finish debug, you can do dbcont so that it will continue execution.
This answer is a draft as it is quite difficult to help you with the information you have provided. But I think you can start working the things out with this. If you have more doubts feel free to ask.

Non linear function parameter estimation - matlab, lsqnonlin, fzero

I'm having difficulty with a fitting problem. From the errors that I get I imagine that the boundaries are not defined correctly and I haven't managed to find a solution. Any help would be very much appreciated.
Alternative methods for the solution of the same problem are also accepted.
Description
I have to estimate the parameters of a non-linear function of the type:
A*y(x) + B*EXP(C*y(x)) + g(x,D) = 0
subjected to the parameters PAR = [A,B,C,D] being within the range
LB < PAR < UB
Code
To solve the problem I'm using the Matlab functions lsqnonlin and fzero. The simplified code used is reported below.
The problem is divided in four functions:
parameterEstimation - (a wrapper for the lsqnonlin function)
objectiveFunction_lsq - (the objective function for the param estimation)
yFun - (the function returing the value of the variable y)
objectiveFunction_zero - (the objective function of the non-linear equation used to calculate y)
Errors
Running the code on the data I get the this waring
Warning: Length of lower bounds is > length(x); ignoring extra bounds
and this error
Failure in initial user-supplied objective function evaluation.
LSQNONLIN cannot continue
This makes me to think that the boundaries are not correctly used or not correctly called, but maybe the problem is elsewhere.
function Done = parameterEstimation()
%read inputs
Xmeas = xlsread('filepath','worksheet','range');
Ymeas = xlsread('filepath','worksheet','range');
%inital values and boundary conditions
initialGuess = [1,1,1,1]; %model parameters initial guess
LB = [0,0,0,0]; %model parameters lower boundaries
UB = [2,2,2,2]; %model parameters upper boundaries
%parameter estimation
calcParam = lsqnonlin(#objectiveFunction_lsq_2,initialGuess,LB,UB,[],Xmeas,Ymeas);
Done = calcParam;
function diff = objectiveFunction_lsq_2(PAR,Xmeas,Ymeas)
y_calculated = yFun(PAR,Xmeas);
diff = y_calculated-Ymeas;
function result = yFun(PAR,X)
y_0 = 2;
val = fzero(#(y)objfun_y(y,PAR,X),y_0);
result = val;
function result = objfun_y(y,PAR,X)
A = PAR(1);
B = PAR(2);
A = PAR(3);
C = PAR(4);
D = PAR(5);
val = A*y+B*exp(y*C)+g(D,X);
result = val;
I don't have the optimization toolbox, but are you sure you can pass the constants like that?
I would do this instead:
calcParam = lsqnonlin(#(PAR) objectiveFunction_lsq_2(PAR,Xmeas,Ymeas),initialGuess,LB,UB);