我的教授让我写一个程序来执行二分程序来找到一个方程的根。在继续之前,以下是目前的程序文件:
function [l,r,nf] = bisect(fname,a,b,tol)
nf=0;
if (fname(a)*fname(b))>0
errflag='Choose an interval (a,b) where f(a)*f(b) is negative'
root='N/A'
else
while abs(fname(a)-fname(b))>tol
p=a+(b-a)/2;
if (fname(a)*fname(p))<0
b=p;
else
a=p;
end
nf=nf+1;
end
end
nf
l=a
r=b
end
除了bisect.m
文件之外,他还让我们编写了一个简单的程序fofx.m
,以便在任何时候评估等式。它看起来像:
function [y]=fofx(x)
y=cos(x)-sin(x);
end
他希望我们输入fofx.m
作为输入参数,以便可以使用任何通用方程.m文件。他给我们分配了一个测试例程来操作该程序。测试程序(我不允许更改)是
try
delete('prog4run');
end
diary prog4run
format long e
[l,r,nfb] = bisect('fofx',0.7,0.9,1e-6);
p = l+(r-l)/2;
disp(' ')
disp(' ')
disp(' Bisect output:')
disp('root approx:'),p
disp(' ')
disp('error:'),abs(p-pi/4)
disp(' ')
disp('number of fcn evals:'),nfb
disp(' ')
disp(' ')
当我通过输入以下命令在命令窗口中调用程序时:
bisect(@fofx,0.7,0.9,1e-6)
Bisect完美无缺。但是,当他的测试程序使用该行时:
[l,r,nfb] = bisect('fofx',0.7,0.9,1e-6)
即使我在命令窗口中键入它,我也会收到错误:
Attempted to access fname(0.7); index must be a positive integer or logical.
Error in bisect (line 5)
if (fname(a)*fname(b))>0
Error in SCProg4Test (line 13)
[l,r,nfb] = bisect('fofx',0.7,0.9,1e-6);
任何人都可以帮助我吗?
答案 0 :(得分:2)
问题是bisect
函数期望fname
是函数句柄。
如果fname
是一个字符串,则用于表示传递参数的括号实际上是字符串数组的索引,如果索引不是整数或逻辑,则MALTAB会抛出该错误。
最好的办法是在进入例程之前进行一些前期输入检查。 例如:
if ~isa(fname,'function_handle')
if ischar(fname)
fname = str2func(fname);
else
error('Input ''fname'' must be either a function handle or the name of a valid function.')
end
end
如果fname
是一个字符串,它也是当前工作目录或MATLAB路径中文件的名称,str2func
会将其转换为句柄,一切都会好。
如果您想确保MATLAB能够找到该文件,您可以使用exist(fname,'file')==2
检查字符串是否是有效的文件名。
您还可以使用feval
函数除了函数句柄或函数名称(字符串)作为第一个参数,函数的输入作为后续参数:
vala = feval(fname,a);
我认为这有点笨拙,但这是MATLAB中ode
套件使用的过程,这就是ode45
的第一个参数可以是句柄或字符串的原因。