2015-01-07 2 views
0

두 개의 Matlab 함수 f=fun1(x)f=fun2(x,y)은 매우 비슷하므로 단일 함수 f=fun(x,y)에 통합하고 싶습니다. 제 함수의 Matlab에서 하나의 함수로 여러 유사한 함수를 통합

제가
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 

대. 그래서 실제로 fun1fun2의 하위 함수입니다. 나는이 내가 해결하고 싶은 문제의 짧은 단순화 된 예입니다

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=fun(x,y,method_number)를 구성하고 싶습니다. 내 진짜 문제는 내가 닮은 세 가지를 가진 f=fun1(x,y,z), f=fun2(x,y)f=fun3(x)이고 그 중 fun3fun2의 하위 함수이고 fun2은 위의 것과 같은 의미의 하위 함수 인 fun1입니다. 나는 이 비효율적 일 수 있기 때문에 어디서나 switch-case 또는 if-else을 사용하는 것이 옵션이라고 생각하지 않습니다. 또한 코드 레이아웃을 완전히 파괴합니다.

+0

[로컬 함수] (http://es.mathworks.com/help/matlab/matlab_prog/local-functions.html) 및 [중첩 함수] (http://es.mathworks.com/ help/matlab/matlab_prog/nested-functions.html) –

답변

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 개의 인수 (첫 번째 인수에서 파트를 계산하기 위해 호출 할 수 있음)를 사용하여 파트를 계산할 수 있습니다.


사례 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 ... thenswitch없이 해결책을 요구했다. 계산에 따라 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

좋은 답변 ... [misquote]의 힌트 (http://en.wiktionary.org/wiki/Houston,_we_have_a_problem) :-P –

+0

좋은데, 나 (실제 문제에서) for-loop로 시작하는 재귀 함수 호출이 확실하지 않습니다. 내가 틀렸을 수도 있지만 처음부터 살펴보면 루프를 추가하는 것은 중첩 된 for-loops로 끝날 수 있으며 재귀 함수 호출을 피함으로써 피할 수 있습니다. – Nras

+0

@Hoki 마지막 단락에서 설명하려고했듯이 실제 문제에는 몇 가지 유사점이 있습니다. 그리고 때로는 많은 횟수로 실행되는 'for'루프에도 있습니다. 따라서'switch-case '와'if-else'의 사용은 부적절합니다. – Adriaan

0

코드를 복제하여 입력 인수 수가 narginN 번인지 확인하지 않아도됩니다. 한 번 확인하고 어떤 계산을 수행해야하며 그것을 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 

이것은 호키의 대답의 변형입니다. 실제로, for 루프를 추가하고 중복 된 코드를 추가하여 재귀 함수 호출을 제거하기 시작했습니다.

관련 문제