Using fzero function to solve a nonlinear equation with one input
조회 수: 5 (최근 30일)
이전 댓글 표시
Hi,
I am trying to solve this non-linear equation for alpha using a range of values of X (0-100) [so that I can plot alpha vs X].
function y=equations(alpha)
[D, A, R] = geom();
[n, m] = setglbl();
[X] = setX();
Ag = (R.^2)*(pi-alpha+0.5*sin(2*alpha)) ;
Sgw = 2*R*(pi-alpha) ;
Si = 2*R*sin(alpha) ;
Dg = 4*Ag/(Sgw+Si) ;
Al = (R.^2)*(alpha-0.5*sin(2*alpha)) ;
Slw = 2*R*alpha ;
Dl = 4*Al/Slw ;
ag = Ag/A ;
y=((X.^2).*(1-ag).^(n-2)*(D/Dl).^(n+1))-(ag.^(m-2)*(D/Dg).^(m+1)*(1+(Dg*Si/Al)));
end
WHERE
function [X] = setX
global X ;
X=linspace(0,100,101) ;
end
AND
function [Cg, Cl, n, m] = setglbl
global Cg Cl n m
n=1;
m=1;
end
AND
function [D, A, R] = geom()
D = 0.3; %Pipe Diameter (m)
R = D/2; %Pipe Radius (m)
A = pi*(R^2); %Cross-sectional Area (m^2)
end
I KEEP GETTING ERRORS:
Error using fzero (line 301)
FZERO cannot continue because user-supplied function_handle ==> equations failed with the error below.
*Matrix dimensions must agree.*
>> equations
*Not enough input arguments.*
Error in equations (line 7)
Ag = (R.^2)*(pi-alpha+0.5*sin(2*alpha)) ; % [m^2] Cross-sectional area of gas phase in pipe
Does anyone have some advice on what the problem could be?
Should the X interval be defined differently? Or should X be used as a second input to the function?
Any help appreciated!
댓글 수: 0
채택된 답변
Walter Roberson
2017년 2월 14일
You need to change
function [n, m] = setglbl
global n m
n=1;
m=1;
end
However, you have
X=linspace(0,100,101) ;
so X is a vector of length 101, and you have
y=((X.^2).*(1-ag).^(n-2)*(D/Dl).^(n+1))-(ag.^(m-2)*(D/Dg).^(m+1)*(1+(Dg*Si/Al)));
so y is going to be a vector the same length as X. You cannot fzero an entire vector.
Your formula has some numeric problems that need to be worked around. Revised source is:
function alphaVsX
[D, A, R] = geom();
[n, m] = setglbl();
X = setX();
alpha = arrayfun( @(x) fzero( @(alpha) equations(alpha, x, D, A, R, m, n), [1E-4, pi-1E-4]), X );
plot(X, alpha);
xlabel('X')
ylabel('alpha')
end
function [D, A, R] = geom()
D = 0.3; %Pipe Diameter (m)
R = D/2; %Pipe Radius (m)
A = pi*(R^2); %Cross-sectional Area (m^2)
end
function [n, m] = setglbl
n=1;
m=1;
end
function [X] = setX
X=linspace(0,100,101) ;
end
function y = equations(alpha, X, D, A, R, m, n)
Ag = (R.^2)*(pi-alpha+0.5*sin(2*alpha)) ;
Sgw = 2*R*(pi-alpha) ;
Si = 2*R*sin(alpha) ;
Dg = 4*Ag/(Sgw+Si) ;
Al = (R.^2)*(alpha-0.5*sin(2*alpha)) ;
Slw = 2*R*alpha ;
Dl = 4*Al/Slw ;
ag = Ag/A ;
if X == 0
y = 0;
else
y=((X.^2).*(1-ag).^(n-2)*(D/Dl).^(n+1)) - (ag.^(m-2)*(D/Dg).^(m+1)*(1+(Dg*Si/Al)));
end
end
댓글 수: 7
Walter Roberson
2017년 3월 17일
You have
alpha = arrayfun( @(x) fzero( @(alpha) equationsch(alpha, X, A, m, n, Z, al), [1E-4, pi-1E-4]), X, al );
which has three arguments for arrayfun: the function handle, X, and al . arrayfun() takes a function handle and passes each of the remaining arguments to it, so because you are providing two arguments after the function handle, the function handle has to take two arguments. But it does not: the function handle takes only one argument, lower-case x. If each X entry is to be paired with each al entry, then you need to have your function handle
@(x) fzero( @(alpha) equationsch(alpha, X, A, m, n, Z, al), [1E-4, pi-1E-4])
take two arguments instead.
After that, notice that your function handle has a formal parameter lower-case x as an argument, but it does nothing with that argument. Instead, it passes upper-case X to the function, which is the entire vector of X values.
Perhaps you want
alpha = arrayfun( @(one_X, one_al) fzero( @(alpha) equationsch(alpha, one_X, A, m, n, Z, one_al), [1E-4, pi-1E-4]), X, al );
추가 답변 (2개)
Torsten
2017년 3월 17일
Does this work ?
function [alpha] = getalphach
[A] = geom();
[n, m, Z] = setglblch();
X = setX();
al = setal();
for i=1:numel(X)
Xloc = X(i);
for j = 1:numel(al)
alloc = al(j);
alpha(i,j) = fzero(@(x)equationsch(x,Xloc,A,m,n,Z,alloc),[1e-4, pi-1e-4]);
end
end
Best wishes
Torsten.
댓글 수: 3
Torsten
2017년 3월 17일
편집: Torsten
2017년 3월 17일
Try to call fzero with a single starting value, e.g.
alpha(i,j) = fzero(@(x)equationsch(x,Xloc,A,m,n,Z,alloc),pi-1e-4);
If fzero cannot find a solution, you should first plot your function to see whether a zero really exists.
By the way: Your call to fzero must be with a small x:
Not:
alpha(i,j) = fzero(@(x)equationsch(X,Xloc,m,n,Z,alloc),[1e-4, pi-1e-4]);
But:
alpha(i,j) = fzero(@(x)equationsch(x,Xloc,m,n,Z,alloc),[1e-4, pi-1e-4]);
Best wishes
Torsten.
Torsten
2017년 3월 22일
Sure.
function [alpha] = getalphach
[A] = geom();
[n, m, Z] = setglblch();
[X,al] = setmartvar();
for i=1:numel(X)
Xloc = X(i);
alloc = al(i);
alpha(i) = fzero(@(x)equationsch(x,Xloc,A,m,n,Z,alloc),[1e-4, pi-1e-4]);
end
Best wishes
Torsten.
참고 항목
카테고리
Help Center 및 File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기
제품
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!