Error when taking gradient of symbolic function - matlab

I get an error when taking the gradient of a symbolic function. Can anyone tell me why I get this error?
syms x1 x2 R
L0=0; %[m]
k1=8; %[N/m]
k2=4; %[N/m]
F1=5; %[N]
F2=10; %[N]
F = 0.5*k1*(sqrt(x1^2 + (L0-x2)^2) - L0)^2 + 0.5*k2*(sqrt(x1^2 + (L0+x2)^2)
- L0)^2 - F1*x1 - F2*x2;
f = matlabFunction(F);
R = 0.1;
GI = x1^2 + x2^2 - R^2;
gi = matlabFunction(GI);
epsilon=0.001;
xo=[0,0]';
k = 0;
r = (sqrt(5)-1) / 2;
rpe=0.01;
Merit_pe = #(x1,x2) f(x1,x2) + rpe*(max(0,gi(x1,x2)))^2;
g = gradient(Merit_pe, [x1 x2]);
Error:
Error using sym/max (line 97)
Input arguments must be convertible to
floating-point numbers.
Error in
Ex>#(x1,x2)f(x1,x2)+rpe*(max(0,gi(x1,x2)))^2
Error in sym>funchandle2ref (line 1249)
S = x(S{:});
Error in sym>tomupad (line 1154)
x = funchandle2ref(x);
Error in sym (line 163)
S.s = tomupad(x);
Error in sym/gradient (line 17)
args = privResolveArgs(sym(f));
Error in Ex (line 31)
g = gradient(Merit_pe, [x1 x2])
I think the max part is causing me trouble, but I still need to determine the gradient of this function. Any advise? (I could do it by hand I guess, but I'd rather not if I don't have to)

Directly taking the gradient of max(0,gi(x1,x2)) is not possible in matlab. Instead the function should be defined according to the following definition.
The function Merit_pe can then be defined as follows:
if gi(xo(1,1),xo(2,1)) > 0
Merit_pe = #(x1,x2) f(x1,x2) + rpe*(gi(x1,x2))^2;
else
Merit_pe = #(x1,x2) f(x1,x2);
end
The gradient can then be determined using:
g = gradient(Merit_pe, [x1 x2]);

Related

Matlab error while calculating double integral

I'm trying to calculate a double integral but get an error.
My code is:
clear
Gamma = rand([22,1]);
data_i = rand([1,10]);
Y_1 = 1;
fun = #(D_star, Y_0 ) fun1(D_star , Y_1 , Y_0 , Gamma , data_i);
p = integral2 ( fun , 0 , 1 , 0 , 1);
and the function fun1 is defined as
function [p] = fun1(D_star , Y_1 , Y_0 , Gamma , data_i)
gamma=Gamma(1:3);
beta_1=Gamma(4:5);
beta_0=Gamma(6:7);
alpha_D=Gamma(8);
alpha_1=Gamma(9);
alpha_0=Gamma(10);
sigma2_1=Gamma(11);
sigma2_0=Gamma(12);
Lambda=Gamma(13:17);
sigma2_M=Gamma(18:22);
Sigma2_temp = [1 ; sigma2_1 ; sigma2_0 ; sigma2_M];
Alpha = [alpha_D ; alpha_1 ; alpha_0 ; Lambda];
Sigma2 = Alpha * Alpha' + diag(Sigma2_temp);
Z = data_i(3:5);
X = data_i(3:4);
M = data_i(6:10);
Mu = [Z*gamma , X*beta_1 , X*beta_0 , zeros(1,5) ]';
YY = [D_star ; Y_1 ; Y_0 ; M' ];
p = mvnpdf(YY,Mu,Sigma2);
end
I don't think there is a problem in the definition of the functions because I can evaluate them (e.g. fun(1,1) give me an answer). The error message that I get is:
Error using vertcat
Dimensions of matrices being concatenated are not consistent.
Error in fun1 (line 23)
YY = [D_star ; Y_1 ; Y_0 ; M' ];
Error in #(D_star,Y_0)fun1(D_star,Y_1,Y_0,Gamma,data(n,:))
Error in integral2Calc>integral2t/tensor (line 228)
Z = FUN(X,Y); NFE = NFE + 1;
Error in integral2Calc>integral2t (line 55)
[Qsub,esub] = tensor(thetaL,thetaR,phiB,phiT);
Error in integral2Calc (line 9)
[q,errbnd] = integral2t(fun,xmin,xmax,ymin,ymax,optionstruct);
Error in integral2 (line 106)
Q = integral2Calc(fun,xmin,xmax,yminfun,ymaxfun,opstruct);
I tried also the command -quad2d- instead of -integral2- and got a similar error. Any ideas?
I found the problem. According to the documentation, when using -integral2-, the function inside the integral must get an array of both variables as an input and return an array as an output.

Matlab- 1D Numerical integration with function stored in multiple variables

as you can see in the last few lines below, I'm trying to store my function on multiple variables because it gets rather ugly. However, doing this yields the error shown below.
A fix for this would be to manually substitute k and kp, but this is precisely what I'm trying to avoid. Any help would be appreciated. thanks!
clc
clear
hbar = 1.055e-34;
mo = 9.1095e-31;
q = 1.602e-19;
kb=1.38065e-23;
T=298;
Ef = -0.1*q; % -100meV in units Joules
V0 = 1*q;
L = 1e-9;
k = #(E) (2*mo*E/hbar.^2)^.5;
kp = #(E) (2*mo*(V0-E)/hbar.^2)^.5;
fun = #(E) (exp(-2*kp*L) .* ((16*k.^2 .* kp.^2) ./ ((k.^2 + kp.^2).^2))) .* exp(-E./(kb*T));
Q = integral(fun,0,inf);
Error below
Undefined operator '*' for input arguments of type 'function_handle'.
Error in #(E)(exp(-2*kp*L).*((16*k.^2.*kp.^2)./((k.^2+kp.^2).^2))).*exp(-E./(kb*T))
Error in integralCalc/iterateScalarValued (line 314)
fx = FUN(t);
Error in integralCalc/vadapt (line 132)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 83)
[q,errbnd] = vadapt(#AToInfInvTransform,interval);
Error in integral (line 88)
Q = integralCalc(fun,a,b,opstruct);
Error in PS3_2 (line 17)
Q = integral(fun,0,inf);
Use this here
k = #(E) (2.*mo.*E./hbar.^2).^.5;
kp = #(E) (2.*mo.*(V0-E)./hbar.^2).^.5;
fun = #(E) (exp(-2*kp(E)*L).*((16*k(E).^2.*kp(E).^2)./((k(E).^2+kp(E).^2).^2))).*exp(-E./(kb*T));
Q = integral(fun,0,inf);
I think you need to pass the argument E, then are you sure kb*T is correct? Maybe kp(E)*T? Then, you forgot the . is the sqrt for k and kp, or if it isn't a sqrt then the dot is on the wrong side of the power symbol.

Strange error invoking ilaplace function in matlab

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);

Newton's method roots on Matlab

I am not so much experiences with Matlab. I just need it for the sake of solving some lengthy non-linear equations. Instead of using fzero, I wanna use Newton-Raphson's to solve the equation.
newton.m file contains the following code.
function [ x, ex ] = newton( f, df, x0, tol, nmax )
if nargin == 3
tol = 1e-4;
nmax = 1e1;
elseif nargin == 4
nmax = 1e1;
elseif nargin ~= 5
error('newton: invalid input parameters');
end
x(1) = x0 - (f(x0)/df(x0));
ex(1) = abs(x(1)-x0);
k = 2;
while (ex(k-1) >= tol) && (k <= nmax)
x(k) = x(k-1) - (f(x(k-1))/df(x(k-1)));
ex(k) = abs(x(k)-x(k-1));
k = k+1;
end
end
And in the main file, I have called this function as follows:
ext_H = newton( exp(x) + x^3, diff(exp(x) + x^3), 9, 0.5*10^-5, 10);
When I run this function, it gives me the following error.
Error using sym/subsref (line 9)
Error using maplemex
Error, (in MTM:-subsref) Array index out of range
Error in newton (line 37)
x(1) = x0 - (f(x0)/df(x0));
Error in main (line 104)
ext_H = newton( exp(x) + x^3, diff(exp(x) + x^3), 9, 0.5*10^-5, 10);
Could anyone please help me to get through this?
You can probably use Matlab's fsolve (http://uk.mathworks.com/help/optim/ug/fsolve.html) with a couple of options
x0 = 9;
options = optimoptions('fsolve','Algorithm','levenberg-marquardt','TolFun',5*10^-6,'MaxIter',100);
x = fsolve(#(x)(exp(x) + x^3), x0,options);
or just fzero (http://uk.mathworks.com/help/optim/ug/fzero.html) which implements BD algorithm
x = fzero(#(x)(exp(x) + x^3), x0);

MATLAB: How do I use a loop variable in the initial conditions in dsolve?

In MATLAB, I am trying to build a loop which calls dsolve with different initial conditions in each iteration. To accomplish this, I built this loop:
y0 = -2:0.5:2;
y1 = -2:2:2;
syms y(t)
for i = y1
for k = y0
y(t) = dsolve(diff(y,2) + diff(y) - 2*y == t^2 - 4*t + 3,...
['y(0) == ',num2str(k)],['Dy(0) == ',num2str(i)])
end
end
It works through the first iteration, but it fails for the second one with this error:
Error using mupadengine/feval (line 157)
MuPAD error: Error: Invalid equation or initial condition. [ode::splitSys]
Error in dsolve>mupadDsolve (line 325)
T = feval(symengine,'symobj::dsolve',sys,x,options);
Error in dsolve (line 186)
sol = mupadDsolve(args, options);
Error in MWE (line 9)
y(t) = dsolve(diff(y,2) + diff(y) - 2*y == t^2 - 4*t + 3,...
The command works outside the loop for all the initial conditions I have tried. Inside the loop, the first iteration works, the next one always fails. It does not seem to matter which ones I choose.
What's going on?
You can use different name for the solution
y0 = -2:0.5:2;
y1 = -2:2:2;
syms y(t);
for q = y1
for k = y0
ysol(t) = dsolve(diff(y,2) + diff(y) - 2*y == t^2 - 4*t + 3,...
['y(0) == ',num2str(k)],['Dy(0) == ',num2str(q)])
end
end
I would also change i to q
http://www.mathworks.com/help/matlab/ref/i.html