I've some problems in plotting a symbolic function in MatLab: for example when I try to plot the function f with ezplot, where:
f = 9/2 - ((2*x)/5 - 2/5)*(x/3 - 17/6) - x
I get the following error:
Error using findstr
Inputs must be character arrays.
Error in ezplot>ezplot1 (line 442)
if (isa(f, 'inline') && ~isempty(findstr(char(f), '=')))
Error in ezplot (line 145)
[hp, cax] = ezplot1(cax, f{1}, vars, labels, args{:});
Error in sym/ezplot (line 61)
h = ezplot(fhandle(f));
I've tried to convert the symbolic function f in the char form but it returns an analogous error:
Error using findstr
Inputs must be character arrays.
Error in ezplot>ezplot1 (line 442)
if (isa(f, 'inline') && ~isempty(findstr(char(f), '=')))
Error in ezplot (line 145)
[hp, cax] = ezplot1(cax, f{1}, vars, labels, args{:});
Thanks for any help!
You must have some problem with you function definition. Perhaps x has been defined incorrectly?
The following works, at least in Matlab 2010b. It defines f as a symbolic function of the symbolic variable x:
>> clear all
>> syms x
>> f = 9/2 - ((2*x)/5 - 2/5)*(x/3 - 17/6) - x;
>> ezplot(f)
The following is also valid. It defines f as a string:
>> clear all
>> f = '9/2 - ((2*x)/5 - 2/5)*(x/3 - 17/6) - x';
>> ezplot(f)
What if you define your function as an anonymous function:
myfun = #(x) 4.5 - (((2*x)/5 - 2/5)*(x/3 - 17/6) - x);
figure
ezplot(myfun)
I really don't know why the ezplot command doesn't work with my Matlab 2012b, so I had to go with a brutal solution like this :(
syms x
f = 9/2 - ((2*x)/5 - 2/5)*(x/3 - 17/6) - x;
k = 0.1;
x_p = 0:k:10;
y_p = subs(f,x,x_p);
plot(x_p,y_p)
Related
I am not good at Matlab at all. I am trying to find minimum of function witjh constrains.
I am trying to use eample line by line as it is in documentation (https://www.mathworks.com/help/optim/ug/optimization-toolbox-tutorial.html - part Constrained Optimization Example: User-Supplied Gradients)
I have tried following code:
f = #(x,y) x.*exp(-x.^2-y.^2)+(x.^2+y.^2)/20;
g = #(x,y) x.*y/2+(x-2).^2+(y-2).^2/2-4;
x0 = [2 ,0];
options = optimoptions('fmincon','Algorithm','interior-point','Display','iter');
gfun = #(x,y) deal(g(x,y),[]);
[x,fval,exitflag,output] = fmincon(f,x0,[],[],[],[],[],[],gfun,options);
And this is the console output:
>> Untitled4
Not enough input arguments.
Error in Untitled4>#(x,y)x.*exp(-x.^2-y.^2)+(x.^2+y.^2)/20 (line 1)
f = #(x,y) x.*exp(-x.^2-y.^2)+(x.^2+y.^2)/20;
Error in fmincon (line 552)
initVals.f = feval(funfcn{3},X,varargin{:});
Error in Untitled4 (line 7)
[x,fval,exitflag,output] = fmincon(f,x0,[],[],[],[],[],[],gfun,options);
Caused by:
Failure in initial objective function evaluation. FMINCON cannot continue.
I don't understand - what is wrong with my function?
you missed the part in the documentation defining fun,
and you miss-defined gfun.
(it is important that both are functions of a single variable, x)
Here is working code:
f = #(x,y) x.*exp(-x.^2-y.^2)+(x.^2+y.^2)/20;
g = #(x,y) x.*y/2+(x-2).^2+(y-2).^2/2-4;
x0 = [2 0];
options = optimoptions('fmincon','Algorithm','interior-point','Display','iter');
fun = #(x) f(x(1),x(2));
gfun = #(x) deal(g(x(1),x(2)),[]);
[x,fval,exitflag,output] = fmincon(fun,x0,[],[],[],[],[],[],gfun,options);
I am working through an example using fmincon().
I define my objective function in objFun.m
function f=objFun(x)
f = 100*(x(2) - (x(1))^2)^2 + (1 - x(1))^2;
end
and I define an initial point x0
x0=[1; -1]
And if I run the objective function with that point as a test I get
>> objFun(x0)
ans =
400
But when I try to use it in fmincon() I get
>> [x, fval] = fmincon(objFun, x0, [1;2],1,[],[],[0; -inf],[inf, 0]);
Not enough input arguments.
Error in objFun (line 2)
f = 100*(x(2) - (x(1))^2)^2 + (1 - x(1))^2;
I suspect I'm missing something very simple here, but what?
you need to pass a handle to the function #objFun not the function itself, and your A and x0 matrix need to be transposed, ie: a row with 2 columns, each row in A is another linear constraint.
x0=[1, -1];
A = [1,2];
b = 1;
[x, fval] = fmincon(#objFun, x0, A,b,[],[],[0; -inf],[inf; 0]);
function f=objFun(x)
f = 100*(x(2) - (x(1))^2)^2 + (1 - x(1))^2;
end
I've defined a function in Matlab like this:
clg = 2*pi*(alpha-alphai+0.5*A(1));
where A is an array which depends on alpha.
I want to evaluate clg for aplha=0.53.
I've tried subs(clg, alpha, 0.53), but It gives me a bunch of weird errors:
Error using sym/subs>normalize (line 210)
Entries in second argument must be scalar.
Error in sym/subs>mupadsubs (line 136)
[X2,Y2,symX,symY] = normalize(X,Y); %#ok
Error in sym/subs (line 124)
G = mupadsubs(F,X,Y);
Error in integral (line 45)
subs(clg, alpha, 0.53)
Any idea on how to achieve that?
Thanks!
I have no problem about your question.
>> syms x x1 x2
>> clg = 2*pi*(x-x1+0.5*x2);
>> subs(clg,x,0.53)
ans =
2*pi*(x2/2 - x1 + 53/100)
I am trying to reproduce the problem, but this works:
syms x
%A is a symbolic matrix that depends on x
A = inv([10*x, 2*x, 3*x;
4*x, 10, 6*x;
7*x, 8*x, 10*x])
%y is a symbolic expression defined such that
%it depends on A, but collapses to an expression of x
y = x + 0.5*A(2,2)
%subs returns a symbolic (in this case fraction) evaluation:
subs(y, x, 3)
%eval returns a numeric evaluation:
x = 3
eval(y)
(I have encountered the same error message as you in my own code, but have not yet hunted down its source.)
I am using ilaplace transform in matlab to compute the inverse Laplace transform of a function, however, I meet a strange error I cannot handle. Here is the output from matlab command line, where >> is the prompt. (s and t are syms symbolic variables)
>> N
N =
-(2.7071747341794232778783099808678e-34*(3.5938879023008902403763863659998e33*s - 68267793397927900578281423804583.0))/s^2
>> ilaplace(N)
Error using mupadmex
Error in MuPAD command: The argument is invalid. [_concat]
Evaluating: partfrac
Error in transform (line 74)
F = mupadmex('symobj::vectorizeSpecfunc', f.s, x.s, w.s, trans_func,
'infinity');
Error in sym/ilaplace (line 31)
F = transform('ilaplace', 's', 't', 'x', L, varargin{:});
>> ilaplace(-(2.7071747341794232778783099808678e-34*(3.5938879023008902403763863659998e33*s - 68267793397927900578281423804583.0))/s^2)
ans =
(23990078920530555628928726307903*t)/1298074214633706907132624082305024 - 4933332333844707562298796153537/5070602400912917605986812821504
The prblem is, if I directly invoke ilaplace(N), I have an error. However, if I pass the expression to ilaplace, I have the right answer. I don't know why.
EDIT: The complete code file is as follows.
syms s t;
syms s positive;
syms t positive;
tau = 4.2562313045743237429846099474892;
V_fitted = 1 - 1.015*exp(-0.0825*t); % CDF function
V_fitted_right_shift = subs(V_fitted, t, t - tau); % right shift CDF by tau
lambda_out = 1 / ( tau + int((1 - V_fitted_right_shift), [tau, Inf]) ); %arrival rate of the process
K = 4; %number of processes
V_CDF_superposed = 1 - (1 - V_fitted_right_shift)*(lambda_out * int((1-V_fitted_right_shift), [t-tau, Inf]))^(K - 1); %new CDF
FV_CDF_superposed = vpa(V_CDF_superposed);
Laplace_V_CDF_superposed = laplace(FV_CDF_superposed); %laplace transform
N = Laplace_V_CDF_superposed/(1 - s * Laplace_V_CDF_superposed);
N = vpa(N);
N = simplify(N);
N_t = ilaplace(N);
i try to run the following in order to integrate numerically:
nu = 8;
psi=-0.2;
lambda = 1;
git = #(u) tpdf((0 - lambda * skewtdis_inverse(u, nu, psi)), nu);
g(t,i) = integral(git,1e-10,1-1e-10,'AbsTol',1e-16);
where tpdf is a matlab function and skewtdis:inverse looks like this:
function inv = skewtdis_inverse(u, nu, lambda)
% PURPOSE: returns the inverse cdf at u of Hansen's (1994) 'skewed t' distribution
c = gamma((nu+1)/2)/(sqrt(pi*(nu-2))*gamma(nu/2));
a = 4*lambda*c*((nu-2)/(nu-1));
b = sqrt(1 + 3*lambda^2 - a^2);
if (u<(1-lambda)/2);
inv = (1-lambda)/b*sqrt((nu-2)./nu)*tinv(u/(1-lambda),nu)-a/b;
elseif (u>=(1-lambda)/2);
inv = (1+lambda)/b*sqrt((nu-2)./nu).*tinv(0.5+1/(1+lambda)*(u-(1-lambda)/2),nu)-a/b;
end
What i get out is:
Error in skewtdis_inverse (line 6)
c = gamma((nu+1)/2)/(sqrt(pi*(nu-2))*gamma(nu/2));
Output argument "inv" (and maybe others) not assigned during call to "F:\Xyz\skewtdis_inverse.m>skewtdis_inverse".
Error in #(u)tpdf((0-lambda*skewtdis_inverse(u,nu,psi)),nu)
Error in integralCalc/iterateScalarValued (line 314)
fx = FUN(t);
Error in integralCalc/vadapt (line 133)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 76)
[q,errbnd] = vadapt(#AtoBInvTransform,interval);
Error in integral (line 89)
Q = integralCalc(fun,a,b,opstruct);
If i , however call the function in thr handle directly there are no Problems:
tpdf((0 - lambda * skewtdis_inverse(1e-10, nu, psi)), nu)
ans =
1.4092e-11
tpdf((0 - lambda * skewtdis_inverse(1-1e-10, nu, psi)), nu)
ans =
7.0108e-10
Your effort is highly appreciated!
By default, integral expects the function handle to take a vector input.
In your code, the if-statement creates a complication since the condition will evaluate to true only if all elements of u satisfy it.
So, if u is a vector that has elements both greater than and less than (1-lambda)/2, inv will never be assigned.
There are two options:
Put the if-statement in a for-loop and iterate over all of the elements of u.
Use logical indexes for the assignment.
The second option is faster for large element count and, in my opinion, cleaner:
inv = u; % Allocation
IsBelow = u < (1-lambda)/2; % Below the threshold
IsAbove = ~IsBelow ; % Above the threshold
inv(IsBelow) = (1-lambda)/b*sqrt((nu-2)./nu)*tinv(u(IsBelow)/(1-lambda),nu)-a/b;
inv(IsAbove) = (1+lambda)/b*sqrt((nu-2)./nu)*tinv(0.5+1/(1+lambda)*(u(IsAbove)-(1-lambda)/2),nu)-a/b;