MATLAB Optimization toolbox example - matlab

https://www.mathworks.com/help/optim/examples/banana-function-minimization.html
fun = #(x)(100*(x(2) - x(1)^2)^2 + (1 - x(1))^2);
options = optimset('OutputFcn',#bananaout,'Display','off');
x0 = [-1.9,2];
[x,fval,eflag,output] = fminsearch(fun,x0,options);
title 'Rosenbrock solution via fminsearch'
Fcount = output.funcCount;
disp(['Number of function evaluations for fminsearch was ',num2str(Fcount)])
disp(['Number of solver iterations for fminsearch was ',num2str(output.iterations)])
What is #bananaout here?
This is giving me the following error,
??? Error using ==> feval
Attempt to execute SCRIPT bananaout as a function:
C:\Users\admin\Desktop\bananaout.m
Error in ==> callAllOptimOutputFcns at 12
stop(i) = feval(OutputFcn{i},xOutputfcn,optimValues,state,varargin{:});
Error in ==> fminsearch>callOutputAndPlotFcns at 464
stop = callAllOptimOutputFcns(outputfcn,xOutputfcn,optimValues,state,varargin{:})
|| stop;
Error in ==> fminsearch at 199
[xOutputfcn, optimValues, stop] =
callOutputAndPlotFcns(outputfcn,plotfcns,v(:,1),xOutputfcn,'init',itercount, ...
Error in ==> test_optim at 9
[x,fval,eflag,output] = fminsearch(fun,x0,options)

As per the doc, Output Functions are called by the optimizer at every time step, enabling you to do things like plot the progress of the optimization.
In your case you get an error because bananaout seems to be a script when it needs to be a function (with specific inputs - see the doc for their details). Did you happen to save the example code in a script called bananaout? If so, rename the script.
You can see a list of all m-code that you have that are called bananaout by executing the following:
>> which bananaout -all
One of them will be the function that the example should be calling, while another will be the one that you have created and need to rename/remove.

Related

fzero: Too many output arguments

To learn how to work with fzero() I tried this code:
function equation(x)
k=(96-x)/6;
end
and then:
x0=4;
x=fzero('equation',x0)
The error is:
??? Error using ==> fzero at 307
FZERO cannot continue because user supplied function_handle ==> equation
failed with the error below.
Too many output arguments.
fzerois expecting a return value from your equation so (internally) it is trying to assign something to the output of that function. If I try
result = equation(42);
I get the same error message
Error using equation
Too many output arguments.
Just change your function signature to
function [k] = equation(x)
to indicate that k is the output of this function.
Try to supply the function argument as handle:
x = fzero(#equation,x0)

Error running matlab code after compiling

It looks like this has been asked many times, but none of the past posts seem to solve my question. All those had to do with matrix/vector while my code does not have any of these, just simple variables. It takes three variables as arguments. It works perfectly fine within the Matlab environment. I only got the error when I compiled it with mcc -m Normal.m and tried to run with the executable like this "./Normal 1 5 0.5". The complete error message is:
Error using /
Matrix dimensions must agree.
Error in Normal (line 4)
MATLAB:dimagree
It is complaining about line 4: N=2/dt, what is wrong with this?
Here is the code:
function val=Normal(l1,l2,dt)
const=(l2/l1-1);
N=2/dt;
S=1.0/sqrt(l2/l1);
Z(1)=S;
for i=2:N
t= -1+(i-1)*dt;
Z(i)=1.0/sqrt(const*t*t+1);
S=S+2*Z(i);
end
Z(21)=1.0/(l2/l1);
S=S+1.0/sqrt(l2/l1);
val=dt*S/2;
end
But dt is not a scalar when passed into the standalone through the command ./Normal 1 5 0.5. It is a character array with 3 elements ('0', '.','5')!
When passing numerical arguments to a standalone, they are passed as strings. Thus, inside the function, you need to convert '0.5' into a double, and similarly for l1 and l2:
dt = str2num(dt);
l1 = str2num(l1);
l2 = str2num(l2);
Note that you can use isdeployed to determine at runtime if the function is a standalone:
if isdeployed, dt = str2num(dt); end
And you might need to display the result:
if isdeployed, disp(val); end
Result:
>> system('Normal 1 5 0.5');
1.4307
>> Normal(1,5,0.5) % .m function for comparison
ans =
1.4307

Program runs normally in Matlab but won't work in Parallel Toolbox

I recently asked about a related problem here:
https://stackoverflow.com/questions/21171836/storing-matrix-output-in-higher-dimensional-matrix
I now simply want to run the code in a parallel configuration, but when I do I get the following error:
??? Error using ==> parallel_function at 598
Error in ==> OIRE at 136
Undefined function or variable "best_index".
Error in ==> OIRE_MSE_test at 73
parfor t=1:nsims
Error in ==> OIRE_MSE_test at 95
[b_OIRE OIRE_opt_b(:,:,t)]=OIRE(y,x,iter);
The code works fine so long as I drop the matlab pool open/close and the parfor command.
How come this won't run in parallel toolbox?
clc;
n=100;
p=7;
alpha1=0.999999;
error_vol=0.1;
iter=1000;
nsims=200;
OIRE_opt_b=zeros(7,3,nsims);
OIRE_opt_MSE=zeros(1,3,nsims);
OIRE_opt_index=zeros(1,3,nsims);
GIREI_opt_b=zeros(7,3,nsims);
GIREI_opt_MSE=zeros(1,3,nsims);
GIREI_opt_index=zeros(1,3,nsims);
GIREII_opt_b=zeros(7,3,nsims);
GIREII_opt_MSE=zeros(1,3,nsims);
GIREII_opt_index=zeros(1,3,nsims);
LRRE_opt_b=zeros(7,3,nsims);
LRRE_opt_MSE=zeros(1,3,nsims);
LRRE_opt_index=zeros(1,3,nsims);
matlabpool open
x=zeros(n,p);
for i=1:n
z_i4=normrnd(0,1);
x(i,p)=z_i4;
for j=1:p-1
x(i,j)=x(i,j)+alpha1*z_i4;
x(i,j)= x(i,j)+(1-alpha1^2)^(0.5)*normrnd(0,1);
end
end
b_act=[5;1;10;-20;200;30;-2];
parfor t=1:nsims
residuals=normrnd(0,error_vol,n,1);
y=x*b_act + residuals;
y_store(:,t)=y;
y=y_store(:,t);
[b_OIRE OIRE_opt_b(:,:,t) OIRE_opt_MSE(:,:,t) OIRE_opt_index(:,:,t)]=OIRE(y,x,iter);
end
called function
function [b_OIRE OIRE_opt_b OIRE_opt_MSE OIRE_opt_index]=OIRE(y,x,iter)
dim=1;
pool=[10,100,1000,10000,1000000,10000000];
count=0;
[n, p]=size(x);
b=x\y;
b_OIRE = b; % [#1] initialize b_LRRE as b
sigma_sq=((y-x*b)'*(y-x*b))/(n-p); %'
b_act=[1;0;1;1;0;1;1];
econFlag=0;
[U,sigma,V] = svd(x,econFlag);
U1=U(:,1:p);
d=zeros(p,1);
d=diag(d);
alpha=V'*b_OIRE; %'
Delta=sigma.^1;
Delta=diag(Delta);
f=Delta.*alpha;
F=diag(f);
Theta=sum(f);
c=p^2*sigma_sq+p*Theta^2;
g=Theta*sum(alpha);
I=ones(p,1);
a=sigma_sq*I+Theta*f;
b=F*alpha;
k=zeros(p,1);
A=sigma_sq*eye(p)+F.^2;
varRho=(g-a'*pinv(A)*b)*pinv(c-a'*pinv(A)*a);
k=pinv(A)*b-varRho*pinv(A)*a;
K=diag(k);
D=varRho*I*I';
b_OIRE= V*(K+D)*U1'*y;
MSE=(k'*A*k)+(2*varRho*a'*k)-(2*b'*k)+(c*varRho^2)-(2*g*varRho)+(alpha'*alpha);
best_OIRE_MSE=MSE;
best_b_OIRE=b_OIRE;
for jj=1:iter % [## "iter" denotes the iteration number]
alpha=V'*b_OIRE; %'
Delta=sigma.^1; % [Error! not sigma.^2 but sigma.^1]
Delta=diag(Delta);
f=Delta.*alpha;
F=diag(f);
Theta=sum(f);
c=p^2*sigma_sq+p*Theta^2;
g=Theta*sum(alpha);
I=ones(p,1);
a=sigma_sq*I+Theta*f;
b=F*alpha;
k=zeros(p,1);
A=sigma_sq*eye(p)+F.^2;
varRho=(g-a'*pinv(A)*b)*pinv(c-a'*pinv(A)*a);
k=pinv(A)*b-varRho*pinv(A)*a;
K=diag(k);
D=varRho*I*I';
b_OIRE= V*(K+D)*U1'*y;
MSE=(k'*A*k)+(2*varRho*a'*k)-(2*b'*k)+(c*varRho^2)-(2*g*varRho)+(alpha'*alpha);
if(MSE<best_OIRE_MSE)
best_b_OIRE=b_OIRE;
best_OIRE_MSE=MSE;
best_index=jj+1;
end
if( any(jj == pool))
count=count+1;
OIRE_opt_b(:,count)=best_b_OIRE;
OIRE_opt_MSE(count)=best_OIRE_MSE;
OIRE_opt_index(count)=best_index;
end
end
end
matlabpool close
Your problem is that best_index is never defined anywhere other than in the MSE<best_OIRE_MSE if-statement.
This is what I suspect is happening. When you run your code without the parfor, it iterates through sequentially (i.e. jj==1 will always occur before jj==2 etc). Without looking through the intricacies of your code, I suspect this means that MSE<best_OIRE_MSE will always be true before (or on the same iteration as) any(jj==pool) is true. This means that by the time your code reaches the any(jj == pool) if-statement, best_index will always have been set.
The problem comes with the fact that parfor offers no guarantees as to the execution order of your loop. jj==10 might well run before jj==2. This means that there is no guarantee that best_index will be defined by the time it reaches the any(jj == pool) if-statement - hence your error.
My suggestion would be to define best_index outside your main parfor loop to something like -1, and then ignore any cases where OIRE_opt_index is negative.

Anonymous function inside a script error

I created an anonymous function inside a script and I can't get MATLAB to run the fminsearch? Here's an what I have so far:
V=x(1);
f=x(2);
q=#(x) (pi.*D.*L)./(1000.*V.*f);
fminsearch(#q,x);
The variables D and L are defined, but MATLAB gives me the following error:
Error: File: Testing.m Line: 51 Column: 17
"q" was previously used as a variable, conflicting with its use here as the name of a function or command.
See "How MATLAB Recognizes Command Syntax" in the MATLAB documentation for details.
q is not mentioned before this command. What am I doing wrong?
Another thing that could solve my problem is to get my script to write a function file, but how to do that?
Remove the second #:
V=x(1);
f=x(2);
q=#(x) (pi.*D.*L)./(1000.*V.*f);
fminsearch(q,x);
q is a function handle. fminsearch expects a function handle. You can create a function handle out of a function using an # (e.g. #min), but you don't need to do that here.
You can also write the anonymous function inline with the search command:
V=x(1);
f=x(2);
fminsearch(#(x) (pi.*D.*L)./(1000.*V.*f),x);
UPDATE (credits to #wakjah)
For your code to do anything sensible, you should use the argument x of the anonymous function:
x0 = [initialV, initialF];
fminsearch(#(x) (pi.*D.*L)./(1000.*x(1).*x(2)), x0);
#function creates a function handle for an existing function.
q = #(x) whatever... creates a function handle called q.
But, you can't create a function handle for a function handle, only for a function.
See this:
>> fones = #ones
fones =
#ones
>> ffones = #fones
Error: "fones" was previously used as a
variable,
conflicting with its use here as the name
of a function or command.
See MATLAB Programming, "How MATLAB
Recognizes Function Calls That Use
Command Syntax" for details.
In Matlab, a function handle is a kind of a pointer to a function and is distinct from a function (unlike in some other languages where the a function identifier can be passed and stored as any other variable).
It's important to note that calling a function and a function handle results in the same behaviour. Except for the case where the identifier is used without any parentheses following it:
>> ones
ans =
1
>> fones
fones =
#ones
>> ones(2)
ans =
1 1
1 1
>> fones(2)
ans =
1 1
1 1

'Undefined function or variable' in Matlab

Here is my code:
function [im,sindx,end1]=alln(im,i,j,secret,sindx,end1)
slen=length(secret);
p=im(i,j);
neigh= [im(i-1,j) im(i+1,j) im(i,j-1) im(i,j+1) im(i-1,j-1) im(i+1,j-1) im(i-1,j+1) im(i+1,j+1)];
minpix = min (neigh)
maxpix = max (neigh)
if minpix < p < maxpix
lowlim = minpix+1;
highlim = maxpix-1;
range = highlim-lowlim+1;
nbits=floor(log2(abs(range)));
if sindx+nbits-1>slen
end1=1;
return
end
for k=1:nbits
bin(k)=secret(sindx+k-1);
end
b = bin2dec(bin);
newvalue1 = abs (minpix + b);
newvalue2 = abs (maxpix - b);
if abs(p-newvalue1)<= abs(p-newvalue2)
im(i,j) = newvalue1;
else
im(i,j) = newvalue2;
end
sindx=sindx+nbits;
end
end
My main program calls this function. When I run the program, I get the following error message:
??? Undefined function or variable "bin".
Error in ==> alln at 34
b = bin2dec(bin);
I know there are many experts for whom this is not a problem at all. I am new to MATLAB. Please guys, show me the way, which type of modification in the code can overcome this problem?
First of all, are there some lines missing from the file? Perhaps you've stripped some comments from the top? Because the error message says that
b = bin2dec(bin);
is line 34, but it's line 22 in the code you present.
OK, that aside...
The error message says that 'bin' isn't defined, but I see that it's being set on the line...
bin(k)=secret(sindx+k-1);
That suggests to me that THAT line isn't being run.
I see that that bin = ... line is inside of a 'for' loop, so I suspect that the for loop is run zero times, meaning that 'bin' never gets defined. What is nbits? Is it 1, or perhaps less than 1? THAT would prevent the loop from running at all.
Try removing the semicolon from the end of the
nbits=floor(log2(abs(range)));
line and run your code again.
Leaving off the semicolon will force the value of nbits to be printed in the Command Window. I bet you'll find that it's 1 or less. If that's the case, then start looking at HOW nbits is calculated, and I bet you'll find the problem.
At what input arguments to the function alln, are you getting the error?
Lets suppose that nbits is 0, then the following loop will not run:
for k=1:nbits
bin(k)=secret(sindx+k-1);
end
So, bin will be undefined. So, the error happens. This is one of the cases where the error can happen. There are many such possible cases.