我有两个Matlab函数f=fun1(x)
和f=fun2(x,y)
非常相似,我想将它们集成到一个函数f=fun(x,y)
中。
对于我的第一个功能
function f=fun1(x)
N=1000; % Some large number.
for j=1:N
f=x^2;
end
和第二个功能
function f=fun2(x,y)
N=1000; % Some large number.
for j=1:N
f=x^2;
f=f+y;
end
。实际上fun1
实际上是fun2
的子函数。我想构建一个函数f=fun(x,y,method_number)
,如
function f=fun(x,y,method_number)
N=1000; % Some large number.
for j=1:N
f=x^2; % If method_number==1 run only this command....
f=f+y; % If method_number==2 run also this command.
end
这只是我想要解决的问题的简短示例。我真正的问题是我有三个长函数f=fun1(x,y,z)
,f=fun2(x,y)
和f=fun3(x)
有几个相似之处,其中fun3
是fun2
和{{的子函数1}}是fun2
的子函数,其含义与上面相同。我不认为使用fun1
或switch-case
是一个选项,因为if-else
可能非常大,这将是低效的。此外,它会完全破坏代码的布局。
答案 0 :(得分:3)
在你的情况下,你的每个函数都有不同数量的输入参数。如果是这种情况,matlab函数nargin
可以检测到这一点,您不必指定其他method
参数。
例如:
function f = fun(x,y,z)
switch nargin
case 1
f = x.^2; %// run only if ONE argument was specified
case 2
f = fun(x) + y; %// run only if TWO arguments were specified
case 3
f = fun(x,y) ./ z ; %// run only if THREE arguments were specified
otherwise
disp('Houston, we have a problem !!') ; %// run if NO or more than 3 arguments were specified
end
你可以用一个参数,两个或三个来调用f
而没有麻烦,Matlab只会执行与正确数量的参数相对应的函数。
当使用3个参数传递时,该函数可以调用自身来计算具有2个参数的部分(可以调用自身来计算第一个参数中的部分)。
案例二:如果递归确实无法从循环中取出,那么经典if ... then
将起作用:
function f = fun(x,y,z)
if nargin == 3
threeArgs = true ;
twoArgs = true ;
elseif nargin == 2
threeArgs = false ;
twoArgs = true ;
elseif nargin == 1
threeArgs = false ;
twoArgs = false ;
end
for it=1:1e6
f = x.^2; %// If method_number==1 run only this command....
%// ... other computations
if twoArgs
f = f + y ; %// If method_number==2 run also this command.
%// ... other computations
if threeArgs
f = f ./z ; %// If method_number==3 run also this command.
%// ... other computations
end
%// ... other computations only relevant to f(x,y)
end
%// ... other computations only relevant to f(x)
end
这将完全排除递归,并确保最小的计算次数。
现在我意识到这看起来有点笨拙的代码,你要求一个没有if ... then
和switch
的解决方案。根据您的计算,有一种方法可以避免任何if
或switch
,但可能并不适用于所有情况。
我们的想法是将invariant
运算符指定给y
或z
,以防它们被调用。
示例:
function f = fun(x,y,z)
if nargin < 3 ; z = 1 ; end
if nargin < 2 ; y = 0 ; end
for it=1:1e6
f = x.^2;
%// ... other computations just based on X
f = f + y ; %// This always run, but if "y" wasn't specified, it does not modify the result (f+0=f)
%// ... other computations
f = f ./z ; %// This always run, but if "z" wasn't specified, it does not modify the result (f./1=f)
%// ... other computations
end
这样可以避免代码中的任何流分支,但我只会针对简单的情况保留此方法,因为无论情况如何,计算总是会完成(尽管可能是某些JIT编译器足够聪明,不会打扰'无效'操作)。
答案 1 :(得分:0)
您可以通过复制代码来避免检查输入参数的数量nargin
N
- 次。您将检查一次,应该进行哪些计算并重复N
次。在此示例中,for循环是重复的代码。在某种程度上,这可能没问题。
function f = fun(x, y, z)
N = 1000;
switch nargin
%// Do something if only x is given
case 1
for j = 1:N
f = x.^2;
end
%// Do something else if only x and y are given
case 2
for j = 1:N
f = x.^2 + y;
end
%// Do something else if x, y and z are given
case 3
for j = 1:N
f = x.^2 + y - z;
end
otherwise
error('Use fun.m with 1, 2 or 3 arguments only!');
end
end
这是Hoki答案的变体。实际上,我从添加for循环开始,并通过添加重复代码来删除递归函数调用。