MATLAB使用fzero - 返回错误

时间:2014-08-01 05:58:08

标签: matlab

我正在尝试正确使用MATLAB函数fzero,但我的程序不断返回错误消息。这是我的代码(由两个m文件组成):

friction_zero.m

function fric_zero = friction_zero(reynolds)
    fric_zero = 0.25*power(log10(5.74/(power(reynolds,0.9))),-2);

flow.m

function f = flow(fric)
    f = 1/(sqrt(fric))-1.873*log10(reynolds*sqrt(fric))-233/((reynolds*sqrt(fric))^0.9)-0.2361;
    f_initial = friction_zero(power(10,4));
    z = fzero(@flow,f_initial)

目标是在z运行时返回f作为flow.m指定等式的根。

我相信我的语法正确,因为我花了几个小时在线查看示例。会发生什么是它返回以下错误消息:

  

"未定义的功能或变量' fric'。"

(当然它未定义,它是我试图解决的变量!)

有人能指出我做错了什么吗?感谢

修改

感谢所有帮助过的人!你帮助我最终解决了我的问题。 我不得不添加另一个文件。以下是已完成的输出代码的完整摘要。

friction_zero.m

function fric_zero = friction_zero(re)

fric_zero = 0.25*power(log10(5.74/(power(re,0.9))),-2); %starting value for fric

flow.m

function z = flow(fric)

re = power(10,4);

z = 1/(sqrt(fric))-1.873*log10(re*sqrt(fric))-233/((re*sqrt(fric))^0.9)-0.2361;

flow2.m

f_initial = friction_zero(re); %arbitrary starting value (Reynolds)

x = @flow;

fric_root = fzero(x,f_initial)

返回输出:

fric_root = 0.0235

这似乎是正确的答案(p!)

我意识到(1)我没有在正确的地方定义reynolds(现在只是re),并且(2)我试图做太多,因此跳过x = @flow;行,由于某种原因,当我添加额外的行时,MATLAB停止抱怨。不确定为什么它不会@flow直接进入fzero()

再一次,谢谢:)。

2 个答案:

答案 0 :(得分:1)

您需要确保f是代码中的函数。这只是一个表达式,reynolds在未定义时是常量。因此,将此包装为匿名函数,并将fric作为输入变量。此外,您需要确保函数的输出变量为z,而不是f。由于您要解决fric,因此无需将此指定为flow的输入变量。此外,您需要指定f作为fzero的输入,而不是flowflow是主要功能的名称。此外,reynolds中的flow未定义,因此我假设它与您为friction_zero指定的内容相同。通过这些编辑,请尝试这样做:

function z = flow()
    reynolds = power(10,4);
    f = @(fric) 1/(sqrt(fric))-1.873*log10(reynolds*sqrt(fric))-233/((reynolds*sqrt(fric))^0.9)-0.2361;
    f_initial = friction_zero(reynolds);
    z = fzero(@f, f_initial); %// You're solving for `f`, not flow.  flow is your function name

答案 1 :(得分:0)

你遇到问题的原因是我认为flow没有参数被调用。您应该阅读更多关于matlab functions的内容。顺便说一句,雷诺兹也没有定义。

我恐怕无法完全帮助你,因为我没有做流体力学。但是,我可以告诉你有关功能的事情。

matlab函数定义如下所示:

function x0 = f(xGuess)
    a = 2;
    fcn =@(t) a*t.^3+t; % t must not be an input to f.
    disp(fcn);
    a = 3;
    disp(fcn);
    x0 = fsolve(fcn1,xGuess); % x0 is calculated here

然后可以将该函数称为myX0 = f(myGuess)。当您使用参数和返回值定义matlab函数时,您必须告诉matlab如何处理它们。 Matlab无法猜测。在此函数中,您告诉matlab在解决匿名函数 xGuess时使用fsolve作为fcn的初始猜测。另请注意,matlab并未假定未定义的变量是一个独立变量。您需要告诉matlab现在我想创建一个具有独立变量fcn的匿名函数t

观察1:我使用.^。这是因为函数将使用参数对其进行求值,并且此参数也可以是向量。在这个特殊情况下,我想要逐点评估。使用fsolve时这不是必需的,但如果f不是矩阵方程,那么这是一种很好的做法,因为"矢量化"经常在matlab中使用。

观察2:注意即使a更改其值,该功能也不会改变。这是因为matlab在定义函数时传递变量的值而不是变量本身。一个程序员会说变量是通过它的值传递的,而不是通过指针传递的。这意味着fcn实际上定义为fcn = @(x) 2*t.^3+t;。使用变量a只是一个方便(常量也可能很复杂,但发现它们只是一个值)。

有了这些知识,你应该能够在你面前解决问题。此外,函数中对flow的递归调用将导致崩溃。当你编写一个像这样调用自己的函数时,你必须有一个停止标准,告诉程序什么时候停止。就像现在一样,flow会在最后一行调用if z = fzero(@flow,f_initial) 500次,然后崩溃。 Alos也可以用零输入定义函数:

function plancksConstant = h()
    plancksConstant  = 6.62606957e−34;

调用hh()将使Plancks保持不变。

祝你好运!