I want to build a series of different function with matlab and integrate and differentiate the results. but the mathwork says the output of the str2func can't access the variable or could bot be used by other function.
Is any one help me with this problem?
I want to create these function:
f1= #(x,l) x.*(l-x);
f2= #(x,l) x.^2.*(l-x).^2.*(l/2-x).^2;
f3= #(x,l) x.^3.*(l-x).^3;
f4= #(x,l) x.^4.*(l-x).^6.*(l/2-x).^4;
f5= #(x,l) x.^5.*(l-x).^5;
f6= #(x,l) x.^6.*(l-x).^6.*(l/2-x).^6;
f7= #(x,l) x.^7.*(l-x).^7;
f8= #(x,l) x.^8.*(l-x).^8.*(l/2-x).^8;
f9= #(x,l) x.^9.*(l-x).^9;
f10= #(x,l) x.^10.*(l-x).^10.*(l/2-x).^10;
I write this function:
syms x l
f=cell(10,1);
fun=cell(10,1);
for i=1:10
if mod(i,2) ~= 0
f{i}=['x','.^',num2str(i),'.*','(l-x)','.^',num2str(i)];
else
f{i}=['x','.^',num2str(i),'.*','(l-x)','.^',num2str(i),'.*','(l/2-x)','.^',num2str(i)];
end
end
for i=1:10
for j=1:10
if mod(i,2) ~= 0 & mod(j,2) ~= 0
Fs = ['(x)','x','.^',num2str(i),'.*','(l-x)','.^',num2str(i),'*','x','.^',num2str(j),'.*','(l-x)','.^',num2str(j)];
FS = str2func (Fs)
fjnew = str2func(['(x)','x','.^',num2str(j),'.*','(l-x)','.^',num2str(j)])
fj_diff = diff(fjnew,x)
when I run that the error is :
Undefined function '(x)x.^1.*(l-x).^1' for input arguments of type 'sym'.
Error in sym>funchandle2ref (line 1172)
S = x(S{:});
Error in sym>tomupad (line 989)
x = funchandle2ref(x);
Error in sym (line 142)
S.s = tomupad(x,'');
Error in sym/privResolveArgs (line 810)
argout{k} = sym(arg);
Error in sym/diff (line 21)
args = privResolveArgs(S,varargin{:});
Your Sincerely
Saeed Nasiri
I found all your problems.
The character "l" is not the character "1". One of them is L and the other is a number. You just wrote "l" \ell\ instead of "1" \one\ in (l-x). EDIT I just realised you actually want l not 1.
Function handles are not (x)x.^2 (random example), they are #(x)x.^2! You forgot to add the "#" in all the calls, thus =['(x)' should be =['#(x)'
3.Your functions are actually (as yourself described in the post), variable respect x and l. Thus, you need the function handle to say that. Change =['#(x)' for =['#(x,l)'.
Iam not sure if you are aware of this, but you dont use practically any of the parts of your code. Your code can be reduced to 4 lines and it will do exactly the same. Fs,FS adn f are never use.:
The result of your code is the same as:
for i=1:10
for j=1:10
if mod(i,2) ~= 0 & mod(j,2) ~= 0
fjnew = str2func(['#(x,l)','x','.^',num2str(j),'.*','(l-x)','.^',num2str(j)])
fj_diff = diff(fjnew,x)
end
end
end
So unless you are doing more stuff with it later, there is no need to compute stuff unnecessarily.
Related
I am using MATLAB and I want to find the root of an equation F(x)-u=0. Here u=0.2861 and
F=normcdf(sqrt(lambda/t)*(t/mu-1))+exp(2*lambda/mu)*normcdf(-sqrt(lambda/t)*(t/mu+1)).
The value of lambda and mu are both 1.
I typed the following code
[x,fval] = fzero(#(t) normcdf(sqrt(lambda/t)*(t/mu-1))+exp(2*lambda/mu)*normcdf(-sqrt(lambda/t)*(t/mu+1))-u, 10);
and hope this can help me find the root. I can show mathematically that this equation has unique root. However, I keep on getting the following error
Error using erfc Input must be real and full.
Error in normcdf>localnormcdf (line 128) p(todo) = 0.5 * erfc(-z ./
sqrt(2));
Error in normcdf (line 50) [varargout{1:max(1,nargout)}] =
localnormcdf(uflag,x,varargin{:});
Error in
Test>#(t)normcdf(sqrt(lambda/t)*(t/mu-1))+exp(2*lambda/mu)*normcdf(-sqrt(lambda/t)*(t/mu+1))-u
Error in fzero (line 363)
a = x - dx; fa = FunFcn(a,varargin{:});
Then I did a "brutal force" method.
t = [0:0.001:20];
F = normcdf(sqrt(lambda./t).*(t/mu-1))+exp(2*lambda/mu).*normcdf(-sqrt(lambda./t).*(t/mu+1))-u;
plot(t,F)
I can clearly eyeball that F(t)-u is increasing in t and the root is around 0.4. My question is why fzero does not work in this case and is there a way to make fzero work?
The problem is that the function does not change sign, which is required as the docs say:
x = fzero(fun,x0) tries to find a point x where fun(x) = 0. This
solution is where fun(x) changes sign — fzero cannot find a root of a
function such as x^2.
I broke up your code to make it a bit clearer (at least for me).
lambda = 1;
mu = 1;
u = 1;
% break up function code
arg1 = #(t) +sqrt(lambda./t).*(t./mu-1);
arg2 = #(t) -sqrt(lambda./t).*(t./mu+1);
fnc = #(t) normcdf(arg1(t))+exp(2*lambda/mu).*normcdf(arg2(t))-u;
% call fzero to find the root
% [x,fval] = fzero(fnc, 10);
% plot
x = 0:0.01:10;
plot(x,fnc(x))
The function is not defined for any input t < 0 due to the sqrt in my function handle arg. So if you plot it for values t > 0, you see that it never passes zero.
EDITED: sign mix-up in the arguments. Thx flxx for pointing this out. Plot & code updated. The argument still holds.
I am solving the following fmincon problem in Matlab
clear
rng default
XZW_temp=[0.5450 0.8175 -0.5451 0.2724];
X1_temp=[0 0.0852 0 -0.0852];
X2_temp=[2.0132 1.0066 -2.0132 -1.0066];
options = optimset('linprog');
options.Display = 'off';
fun=#(x)inner_max(x,XZW_temp, X1_temp, X2_temp, options);
ub=Inf*ones(4,1);
lb=zeros(4,1);
x0=ones(4,1);
[~, f]=fmincon(fun,x0,[],[],[],[],lb,ub);
where inner_max is the following
function i_m=inner_max(x,XZW_temp, X1_temp, X2_temp, options)
f=-[x'*XZW_temp.'; x'*X1_temp.'; x'*X2_temp.'];
Aeq=[1 0 0];
beq=1;
lb=-Inf*ones(3,1);
ub=Inf*ones(3,1);
[~,fval] = linprog(f,[],[],Aeq,beq,lb,ub,options);
i_m=-fval;
end
I get the following error
In an assignment A(:) = B, the number of elements in A and B must be the same.
Error in finitedifferences
Error in computeFinDiffGradAndJac
Error in barrier
Error in fmincon (line 798)
[X,FVAL,EXITFLAG,OUTPUT,LAMBDA,GRAD,HESSIAN] = barrier(funfcn,X,A,B,Aeq,Beq,l,u,confcn,options.HessFcn, ...
I do not understand what I'm doing wrong. Could you help?
I think you can write your anonymous function in fmincon like below, such that arguments XZW_temp, X1_temp,and X2_temp can be pass to fmincon from global environment, i.e.,
[~, f]=fmincon(#(x) inner_max(x,XZW_temp, X1_temp, X2_temp),x0,[],[],[],[],lb,ub);
such that
>> f
f = 1.0898
N.B.: I removed option from inner_max, so the function looks like
function i_m=inner_max(x,XZW_temp, X1_temp, X2_temp)
f=-[x'*XZW_temp.'; x'*X1_temp.'; x'*X2_temp.'];
Aeq=[1 0 0];
beq=1;
lb=-Inf*ones(3,1);
ub=Inf*ones(3,1);
[~,fval] = linprog(f,[],[],Aeq,beq,lb,ub);
i_m=-fval;
end
I want to solve a simple problem with fmincon but It returns an error message.
I have 2 functions f_2 and f_1 and I want to minimize each of them individually. I want to write f_1 and f_2 in a one matlab function i.e., my fun.m. Then I want to call each of them using an index from the main code. Here is the code you can see:
main code:
AA=[1 2 -1 -0.5 1];bb=-2;
xo=[1 1 1 1 1];
VLB=[-1 -1 -1 -1 -1];
VUB=[100 100 100 100 100];
for F_index = 1:2
[x,fval]=fmincon(#myfun,xo,AA,bb,[],[],VLB,VUB)
end
%% here is the function
function f = myfun(x, F_index)
if F_index == 1
f = norm(x)^2 - 4*x(4)*(x(2) + 3.4*x(5))^2 ;
end
if F_index == 2
f = 100*(x(3) - x(5)) + (3*x(1)+2*x(2) - x(3)/3)^2 + 0.01*(x(4) - x(5))
end
Undefined function or variable 'F_index'.
Error in myfun (line 2) if F_index == 1
Error in fmincon (line 564)
initVals.f =
feval(funfcn{3},X,varargin{:});
Error in main (line 6)
[x,fval]=fmincon(#myfun,xo,AA,bb,[],[],VLB,VUB)
Caused by:
Failure in initial user-supplied objective
function evaluation. FMINCON cannot continue.
The error message clearly states the problem: The variable F_index is undefined within the function myfun. Variables in Matlab have a scope restricted to the function (or rather "workspace") within which they are defined. They can be made "global", but that's not something you normally want to do.
A workaround is to use nested functions, where variables of the enclosing function become available in the nested function:
function main_function
AA=[1 2 -1 -0.5 1];bb=-2;
xo=[1 1 1 1 1];
VLB=[-1 -1 -1 -1 -1];
VUB=[100 100 100 100 100];
F_index = 1;
for F_index = 1:2
[x,fval]=fmincon(#myfun,xo,AA,bb,[],[],VLB,VUB)
end
function f = myfun(x)
if F_index == 1
f = norm(x)^2 - 4*x(4)*(x(2) + 3.4*x(5))^2 ;
end
if F_index == 2
f = 100*(x(3) - x(5)) + (3*x(1)+2*x(2) - x(3)/3)^2 + 0.01*(x(4) - x(5))
end
end
end
Now myfun is nested in main_function and has access to its variables.
You can bind extra arguments using anonymous functions:
fmincon(#(x) myfun(x, F_index), ...)
Here, the value of F_index is evaluated and becomes part of the anonymous function.
However, these look like completely independent functions. Why not separate them all the way, and use a cell array of handles for the iteration?
fcns = {#fun1, #fun2};
for F_index = 1:2
[x,fval]=fmincon(fcns{F_index},xo,AA,bb,[],[],VLB,VUB)
end
You need to learn about variables in/out functions.
Practically in any programming language, when you enter a function, that function can only access the variables that are created inside, or that are passed as an argument as x, y, z and potato in the next example: myfun(x,y,z, potato).
This means that in:
function f = myfun(x)
if F_index == 1
f = norm(x)^2 - 4*x(4)*(x(2) + 3.4*x(5))^2 ;
end
end
myfun does not have any idea what F_index is.
One of the ways of solving it is declaring F_index as global, but I would recommend you rather change the function somehow, so it doesn't access out of function variables.
`
function [LLF, LL, H ] = garchlike(data)
p=1;
q=1;
if isempty(q)
m=p;
else
m = max(p,q);
end
%this are the parameters
psi=[0.01;0.01];
gamma=[0;0.02;0.02;0];
lambda=[0;0.03;0.03;0];
A=[1;-0.04;-0.03;1];
stdestimate = std(data,1);
data = [stdestimate ; data];
T = size(data,1);
B=(reshape(A,2,2))^-1;
%I am squaring each element of the inverse of A
B2=((reshape(A,2,2))^-1).^2;
%getting the Bl matrix(squared interactions)
Bl=[B2(1,:);B(1,:).*B(2,:);B2(2,:)];
garchc=Bl*psi;
garcha=Bl*(reshape(gamma,2,2))*reshape(A.^2,2,2);
garchb= Bl*(reshape(lambda,2,2))*reshape(A.^2,2,2);
H(1,1).day=[0.001; 0; 0; 0.002; ];
%convert to matrix
H(1,1).day=ivech(H(1,1).day);
for t = (m + 1):T
H(1,t).day= ivech(garchc + garcha*(diag(H(1,t-1).day))+ garchb*(data((t-1),:).^2)');
end
% Getting the loglikelihood
LLF=zeros(1,T);
%the loklikelihood
for t = (m + 2):T
LLF(t)= log(det(H(1,t).day))+ data(t,:)/(H(1,t).day)*data(t,:)';
end
t=(m+2):T;
LLF=-LLF(t);
LL=sum(LLF);
`
I have this function from up and trying to minimize using fmincon:
` [parameters,LLF,EXITFLAG, OUTPUT,HESSIAN] = fmincon('garchlike', [psi;gamma;lambda;A],sumA ,sumB ,[] , [] , LB , UB,[],options, data, p , q);`
I don't know why is not working and gives me an error :
"Error using garchlike
Error using garchlike
Too many input arguments.
Error in fmincon (line 631)
initVals.f = feval(funfcn{3},X,varargin{:});
Caused by:
Failure in initial user-supplied objective function evaluation. FMINCON cannot continue."
"Error using garchlike Too many input arguments." is your problem.
fmincon is calling garchlike([psi;gamma;lambda;A],data, p , q), but your garchlike only takes 1 argument.
Pro tip: learn how to use the debugger. Start by setting dbstop if error.
EDIT: okay, here are some more details. Please read carefully.
Your garchlike takes 1 argument as input, while your fmincon is calling it with 4 arguments.
Either (1) you need to remove those 3 extra arguments (namely, data, p, q) from fmincon, or (2) make garchlike take 3 more arguments!!
I have an equation in Matlab according to X parameter . I want to find the amount of X for the random amounts of F(x) .
and I tried the code below . but It gives me two different results while my equation should have just one result .
even I tried the roots(f) instead of solve(f) but it gave me an error :
??? Undefined function or method 'isfinite' for input arguments of
type 'sym'.
anybody can help me in this ?
what should I do ?
even if I have a wrong idea about solving this problem please tell me .
Thank you
function betaDistribution_2(a,b)
syms x ;
y=inline((x^(a-1))*((1-x)^(b-1)));
beta=quad(y,0,1);
g=(1/beta)*(x^(a-1))*((1-x)^(b-1));
% I have this equation and I want to find the amount of x for the random
%amounts of p
p=int(g,x,0,x);
for i=0:50
fxi=rand(1);
f=p-fxi;
xi=solve(f);
result=eval(xi);
disp(result)
end
end
Try to filter your solutions.
a=1;
b=2;
% a threshold for imagery part
SMALL=1e-9;
syms x real;
y=inline((x^(a-1))*((1-x)^(b-1)));
beta=quad(y,0,1);
g=(1/beta)*(x^(a-1))*((1-x)^(b-1));
p=int(g,x,0,x);
% return true for physically meaningfull results
filter = #(xc) abs(imag(xc))<SMALL && real(xc)>0 && subs(g, x, xc) > 0 && subs(p, x, xc)>0;
for m=0:50
fxi=rand(1);
f=p-fxi;
xi=solve(f, x);
result=eval(xi);
idx = arrayfun (filter, result);
result = result(idx);
% make sure it is OK
assert(length(result)==1);
disp(result)
end