Trying to find root of equation with fzero command in Matlab.

4 views (last 30 days)
I want to solve a problem in which I am given a function (seen below) where W is 4.9 and I must find v. I have to use the fzero method but I am having trouble with how to find the roots. How can I do this? (Function file and script file ARE separate and below)
function W = dforce(v)
global ro d mu A
Re = (ro*v*d)/mu;
Cd = (24/Re)+(6/(1+sqrt(Re)))+0.4;
W = Cd*0.5*ro*v^2*A;
end
_________________________________________________________________________________________________________
clear all, close all
global ro d mu A
m = 0.5;
g = 9.8;
N = m*g;
R = 287;
P = 101300;
d = 15;
A = (pi*d^2)/4;
T = linspace(-60,60,121); NT = length(T); mu = zeros(size(T)); ro = mu;
for i = 1:NT
b1 = 2.156954157e-14;
b2 = -5.332634033e-11;
b3 = 7.477905983e-8;
b4 = 2.527878788e-7;
mu(i) = b1*T(i)^3+b2*T(i)^2+b3*T(i)+b4;
ro(i) = P/(R*T(i));
dF = @(v)dforce(v)- N;
V = fzero(dF,0);
end

Accepted Answer

John D'Errico
John D'Errico on 7 Nov 2014
First of all, there is ABSOLUTELY no need to use global variables here. They are a crutch that will make your code poor, impossible to debug, hard to read and follow, etc. Avoid them, instead learning a better programming style at the same time.
Here, I've written dforce to take those variables as inputs. I've postpended the names of several variables with a _i to suggest that they are the i'th element of the external vectors ro and mu.
function W = dforce(v,ro_i,d,mu_i,A)
Re = (ro_i*v*d)/mu_i;
Cd = (24/Re)+(6/(1+sqrt(Re)))+0.4;
W = Cd*0.5*ro_i*v^2*A;
end
See that when the function handle dF is created, it is passed the values of those parameters. I've also preallocated V.
m = 0.5;
g = 9.8;
N = m*g;
R = 287;
P = 101300;
d = 15;
A = (pi*d^2)/4;
T = linspace(-60,60,121);
NT = length(T);
mu = zeros(size(T));
ro = mu;
V = zeros(size(T));
% move the declaration of b1,b2,b3,b4 outside the loop, as they are constants.
b1 = 2.156954157e-14;
b2 = -5.332634033e-11;
b3 = 7.477905983e-8;
b4 = 2.527878788e-7;
Now, the VERY first thing I would do is to test your function. Dopes it make sense? Is there a root to be found? Don't throw a loop at something and expect it to work. Don't write a mess of code and then expect it all to work without any testing.
ALWAYS check things. Check EVERY line if necessary to make sure it makes sense.
i = 1;
mu(i) = b1*T(i)^3+b2*T(i)^2+b3*T(i)+b4;
ro(i) = P/(R*T(i));
dF = @(v)dforce(v,ro(i),d,mu(i),A)- N;
A very good way to check things is with a plot. Does it make sense? If not, then why not? This is how you should use MATLAB. Make sure that you understand everything, that you have made no mistakes. Then when you put it all together at the end, you can be confident that it will indeed work.
ezplot(dF,[-1,1])
Warning: Function failed to evaluate on array inputs; vectorizing the function may speed up its evaluation and avoid the need to loop over array elements.
> In ezplot>ezplot1 at 484
In ezplot at 144
grid on
So, in fact, there is no root at all, at least not for the first value of T.
The point is, careful coding means that you work SLOWLY, one step at a time. Once you get more proficient at coding, you can do bigger chunks without needing to check quite as much.
  2 Comments
Yianni
Yianni on 7 Nov 2014
Thank you for the explanation, it helps clarify what I was confused about. Just one thing. I am trying to use V as the implicit varibale found using the fzero command. I am using the function file along with this but this script file is showing nothing but error. Do you know how to approach this using fzero at the end of the loop structure? I want to be able to plot v vs T eventually.
for i = 1:NT
mu(i) = b1*T(i)^3+b2*T(i)^2+b3*T(i)+b4;
ro(i) = P/(R*T(i));
dF = @(v)dforce(v,ro(i),d,mu(i),A)- N;
V(i) = fzero(dF,1);
end
John D'Errico
John D'Errico on 7 Nov 2014
You don't say what is the error.
My guess is it has something to do with the fact that there are no solutions to that problem, for at least SOME values of T. What do you expect to happen when no solution exists?
I tried your code, and this is the error I get as a typical response:
Exiting fzero: aborting search for an interval containing a sign change
because complex function value encountered during search.
(Function value at -0.28 is -21.2001+0.103539i.)
Check function or try again with a different starting value.
THERE IS NO SOLUTION. Of course, I told you that in my response. Wanting a solution to exist when none does is admirable, but you cannot have the impossible.
You need to reformulate your problem. Learn what it is you have done wrong.

Sign in to comment.

More Answers (0)

Categories

Find more on MATLAB in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!