Not able to use `fzero()` function in Matlab - matlab

I am new to Matlab. I am trying to solve a non-linear equation using this inbuilt Matlab function called fzero() but it's not giving me the results.
The main file goes like
A = 5;
B = 6;
C = 10;
eq = equation (A, B, C);
fzero(#(x)eq);
The other function file is:
function eq = equation (A, B, C)
syms x;
eq = A*x.^2 + B*x + C*(asinh(x)) ;
When I run this code, I get the following error:
Error using fzero (line 118)
The input should be either a structure with valid fields or at least two arguments to
FZERO.
Error in main (line 7)
fzero(#(x)eq);
Could someone help me with this?
EDIT:
WHen I specify the check point as 0, it returns me the following error.
Undefined function 'isfinite' for input arguments of type 'sym'.
Error in fzero (line 308)
elseif ~isfinite(fx) || ~isreal(fx)
Error in main (line 7)
fzero(#(x)eq, 0);

There are several mistakes in your code. For a start, fzero is for finding numerical roots of a non-linear equation, it is not for symbolic computations (check the documentation), so get rid of syms x. The correct way to call fzero in your case is a as follows:
A = 5;
B = 6;
C = 10;
eq = #(x) A*x^2 + B*x + C*(asinh(x));
x0 = 0; % or whatever starting point you want to specify
x = fzero(eq,x0)

You need to specify a guess, x0 point
fun = #sin; % function
x0 = 3; % initial point
x = fzero(fun,x0)

Related

Using Adams-Bashforth method in Matlab to solve Lorenz-System Equation

I am trying to use my second order Adams-Bashforth function here:
function [t,x] = Adams(f,t_max,x0,N)
h = t_max/N;
t = linspace(0,t_max,N+1);
x = zeros(2,N+1);
x(:,1) = x0;
x(:,2) = x0 + h.*(f(t(1),x(:,1)));
for i=2:N
x(:,i+1) = x(:,i) + h.*((3/2.*f(t(i),x(:,i))-(1/2).*f(t(i-1),x(:,i-1))));
end
end
In order to solve the Lorenz System Equation. However, whenever I try to call the function, I get an error.
sigma = 10;
beta = 8/3;
rho = 28;
f = #(t,a) [-sigma*a(1) + sigma*a(2); rho*a(1) - a(2) - a(1)*a(3); -beta*a(3) + a(1)*a(2)];
[t,a] = Adams(f,10,[1 1 1],100);
plot3(a(:,1),a(:,2),a(:,3))
Output:
"Unable to perform assignment because
the size of the left side is 2-by-1 and
the size of the right side is 1-by-3.
Error in Project>Adams (line 55)
x(:,1) = x0;"
Is the issue with my function, or with how I am calling my function? Any help would be appreciated.
in line 5 of your Adams function: x(:,1) = x0;
the input x0 is the initial conditions [1 1 1] a row vector of size [3x1], but x is an array of size zeros(2,N+1), or [2x101].
There are several mistakes here, the first you assign a row vector to a colon vector, not only that, but the size of the container in that first column of array x which is [2x1] , that is a different size than the size of x0. that is what the error tells you.
The function is buggy there , and it wont work unless you debug it according to the original intent of that method you are trying to implement.
note that also in the script f=#(t,... is expected to have an input t, but there is not t in the expression [-sigma*a(1) + sigma*a(2); rho*a(1) - a(2) - a(1)*a(3); -beta*a(3) + a(1)*a(2)];

Use Matlab/Maple to find roots of a nonlinear equation

I am having difficulty in finding roots of a nonlinear equation. I have tried Matlab and Maple both, and both give me the same error which is
Error, (in RootFinding:-NextZero) can only handle isolated zeros
The equation goes like
-100 + 0.1335600000e-5*H + (1/20)*H*arcsinh(2003.40/H)
The variable is H in the equation.
How do I find the roots (or the approximate roots) of this equation?
Matlab Code:
The function file:
function hor_force = horizontal(XY, XZ, Lo, EAo, qc, VA)
syms H
equation = (-1*ZZ) + (H/qc)*(cosh((qc/H)*(XZ- XB))) - H/qc + ZB;
hor_force = `solve(equation);`
The main file:
EAo = 7.5*10^7;
Lo = 100.17;
VA = 2002;
XY = 0;
ZY = 0;
XB = 50;
ZB = -2;
XZ = 100;
ZZ = 0;
ql = 40;
Error which Matlab shows:
Error using sym/solve (line 22)
Error using maplemex
Error, (in RootFinding:-NextZero) can only handle isolated zeros
Error in horizontal (line 8)
hor_force = solve(equation);
Error in main (line 34)
h = horizontal(XY, XZ, Lo, EAo, ql, VA)
http://postimg.org/image/gm93z3b7z/
You don't need the symbolic toolbox for this:
First, create an anonymous function that can take vectors at input (use .* and ./:
equation = #(H) ((-1*ZZ) + (H./qc).*(cosh((qc./H).*(XZ- XB))) - H./qc + ZB);
Second, create a vector that you afterwards insert into the equation to find approximately when the sign of the function changes. In the end, use fzero with x0 as the second input parameter.
H = linspace(1,1e6,1e4);
x0 = H(find(diff(sign(equation(H))))); %// Approximation of when the line crosses zero
x = fzero(equation, x0) %// Use fzero to find the crossing point, using the initial guess x0
x =
2.5013e+04
equation(x)
ans =
0
To verify:
You might want to check out this question for more information about how to find roots of non-polynomials.
In Maple, using the expression from your question,
restart:
ee := -100 + 0.1335600000e-5*H + (1/20)*H*arcsinh(2003.40/H):
Student:-Calculus1:-Roots(ee, -1e6..1e6);
[ 5 ]
[-1.240222868 10 , -21763.54830, 18502.23816]
#plot(ee, H=-1e6..1e6, view=-1..1);

Create flexible function handle

I am using numerical integration in MATLAB, with one varibale to integrate over but the function also contains a variable number of terms depending on the dimension of my data. Right now this looks like the following for the 2-dimensional case:
for t = 1:T
fxt = #(u) exp(-0.5*(x(t,1)-theta*norminv(u,0,1)).^2) .* ...
exp(-0.5*(x(t,2) -theta*norminv(u,0,1)).^2);
f(t) = integral(fxt,1e-4,1-1e-4,'AbsTol',1e-3);
end
I would like to have this function flexible in the sense that there could be any number of data points in, each in the following term:
exp(-0.5*(x(t,i) -theta*norminv(u,0,1)).^2);
I hope this is understandable.
If x and u have a valid dimension match (vector-vector or array-scalar) for the subtraction, you can put the whole matrix x into the handle and pass it to the integral function using the name-parameter pair ('ArrayValued',true):
fxt = #(u) exp(-0.5*(x - theta*norminv(u,0,1)).^2) .* ...
exp(-0.5*(x - theta*norminv(u,0,1)).^2);
f = integral(fxt,1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);
[Documentation]
You may need a loop if integral ever passes a vector u into the handle.
But in looking at how the integral function is written, the integration nodes are entered as scalars for array-valued functions, so the loop shouldn't be necessary unless some weird dimension-mismatch error is thrown.
Array-Valued Output
In response to the comments below, you could try this function handle:
fx = #(u,t,k) prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1)).^2),2);
Then your current loop would look like
fx = #(u,t,k) prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1)).^2),2);
k = 2;
for t = 1:T
f(t) = integral(#(u)fx(u,t,k),1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);
end
The ArrayValued flag is needed since x and u will have a dimension mismatch.
In this form, another loop would be needed to sweep through the k indexes.
However, we can improve this function by skipping the loop altogether since each iterate of the loop is independent by using the ArrayValued mode:
fx = #(u,k) prod(exp(-0.5*(x(:,1:k)-theta*norminv(u,0,1)).^2),2);
k = 2;
f = integral(#(u)fx(u,k),1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);
Vector-Valued Output
If ArrayValued is not desired, which may be the case if the integration requires a lot of subdivisions and a vector-valued u is preferable, you can also try a recursive version of the handle using cell arrays:
% x has size [T,K]
fx = cell(K,1);
fx{1} = #(u,t) exp(-0.5*(x(t,1) - theta*norminv(u,0,1)).^2);
for k = 2:K
fx{k} = #(u,t) fx{k-1}(u,t).*exp(-0.5*(x(t,k) - theta*norminv(u,0,1)).^2);
end
f(T) = 0;
k = 2;
for t = 1:T
f(t) = integral(#(u)fx{k}(u,t),1e-4,1-1e-4,'AbsTol',1e-3);
end
ThanksTroy but now I run into the follwing:
x = [0.3,0.8;1.5,-0.7];
T = size(x,1);
k = size(x,2);
theta= 1;
fx = #(u,t,k) prod(exp(-0.5*(x(t,1:k) - theta*norminv(u,0,1))^2));
for t = 1,T
f(t) = integral(#(u)fx(u,t,k),1e-4,1-1e-4,'AbsTol',1e-3);
end
Error using -
Matrix dimensions must agree.
Error in #(u,t,k)prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1))^2))
Error in #(u)fx(u,t,k)
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);

fsolve error in MATLAB

I am dealing with the following code:
function opemployment=eqns(unknown);
global kappa varphi lgamma beta r delta s x b e theta v;
h=unknown(1);
gamma=unknown(2);
opemployment(1)=(h^(gamma-1))*((1-kappa)*((lgamma*(varphi^beta))/(gamma*kappa*beta+1-kappa))*h^(gamma*beta-gamma)-(r+delta+s)*(s^(gamma-1))*x^(-gamma));
opemployment(2)=(1-kappa)*(b-e+(kappa/(1-kappa))*theta*v^(gamma-1));
and then call:
close all; clear all;
global kappa varphi lgamma beta r delta s x b e theta v;
kappa = 0.1;
varphi = 2;
lgamma = 3;
beta = 0.9;
r = 2;
delta = 2 ;
s = 3;
x = 5;
b = 4;
e =3;
theta = 3 ;
v = 2;
guess = [0.7,0.3];
sol=fsolve('eqns',guess)
Yet, I receive the following error:
'Error using feval
Undefined function 'eqns' for input arguments of type 'double'.
Error in fsolve (line 217)
fuser = feval(funfcn{3},x,varargin{:});
Caused by:
Failure in initial user-supplied objective function evaluation.
FSOLVE cannot continue.
I am a total MATLAB beginner and have no clue where the error lays.
You are not specifying the first parameter of fsolve correct. Taking a look at the documentation is always very useful when you're in doubt about how to call a function. For fsolve, it's here: http://www.mathworks.com/help/optim/ug/fsolve.html
In your case, for your fsolve statement, you must do this:
sol=fsolve(#eqns,guess)
fsolve expects a function handle to your function that you want to solve, not the actual name of the function itself.

numerical double integral function handle

power = 2;
sigma=0.1;
a = 1 /(sigma*sqrt(2*pi));
c= (sigma^2)*2;
syms x y
f = exp(-(x.^power)./c);
dfdx = diff(f,x);
c1 = diff(dfdx,x);
f = exp(-(y.^power)./c);
dfdy = diff(f,y);
c2 = diff(dfdy,y);
meancurvature = (c1 + c2)./ 2;
gaussiancuravture =(c1 .* c2);
mean_curv = integral2(meancurvature, -Inf,+Inf, -Inf, +Inf)
gauss_curv = integral2(gaussiancurvature, -Inf,+Inf, -Inf, +Inf)
I've tried everything in my limited matlab knowledge and google searching to find an answer to the error that comes up:
Error using integral2
First input argument must be a function handle.
You need pass in anonymous functions for the first argument. Create them using the # sign. For more details, check out these links
http://www.mathworks.com/help/matlab/matlab_prog/anonymous-functions.html
Using integral2 in Matlab with vectors