MATLAB에서 파일 당 하나 이상의 함수를 정의하고 해당 파일 외부에서 함수에 액세스 할 수 있습니까?


217

EE에서 학사 학위를 공부할 때 MATLAB은 각 기능이 하나의 라이너 인 경우에도 자체 파일에 정의되도록 요구했습니다.

지금 대학원을 공부하고 있는데 MATLAB에서 프로젝트를 작성해야합니다. 최신 버전의 MATLAB에 여전히 이것이 필요합니까?

파일에 둘 이상의 기능을 넣을 수 있다면 이에 대한 제한이 있습니까? 예를 들어 파일 외부의 모든 함수에 액세스 할 수 있습니까? 아니면 파일과 이름이 같은 함수에만 액세스 할 수 있습니까?

참고 : MATLAB 릴리스 R2007b를 사용하고 있습니다.

답변:


271

m 파일의 첫 번째 함수 (예 : main 함수 )는 해당 m 파일이 호출 될 때 호출됩니다. 되지 필요한 주요 기능은 m-파일과 같은 이름을 가지고 있지만, 명확성을 위해 그것을 해야한다 . 함수와 파일 이름이 다르면 파일 이름 을 사용하여 기본 함수를 호출해야합니다.

로컬 함수 (또는 이전 용어에서 "하위 함수") 라고하는 m 파일의 모든 후속 함수는 해당 m 파일 의 기본 함수 및 기타 로컬 함수 만 호출 할 수 있습니다. 다른 m 파일의 함수는이를 호출 할 수 없습니다. 범위 지정 동작은 여전히 ​​동일하지만 R2016b부터는 스크립트에 로컬 함수를 추가 할 수도 있습니다 (즉, 스크립트 내에서만 호출 할 수 있음).

또한 다른 함수 내에서 함수를 선언 할 수도 있습니다. 이를 중첩 함수 라고하며 중첩 된 함수 내에서만 호출 할 수 있습니다. 또한 중첩 된 함수의 변수에 액세스 할 수 있으므로 작업하기가 약간 까다 롭지 만 매우 유용합니다.

생각할 음식 더 ...

SCFrenchJonas 의 답변에서 언급 한 것처럼 함수 핸들 을 출력 인수로 전달하는 것과 같이 위에서 설명한 일반적인 함수 범위 지정 동작에는 몇 가지 방법이 있습니다 (R2013b부터 시작하여 함수에 의해 촉진됨 ). 그러나 함수와 파일을 구성하는 더 나은 옵션이있을 수 있으므로 그러한 트릭에 의지하는 습관을들이는 것은 권하지 않습니다.localfunctions

예를 들어, 당신이 주요 기능이 있다고 가정 해 보자 Am 행 파일을 A.m로컬 기능과 함께 D, E하고 F. 이제 두 개의 다른 관련 기능을 가지고 가정 해 봅시다 BCm-파일 B.mC.m당신은 또한 호출 할 수 할 것인지, 각각, D, E,와 F. 다음과 같은 옵션이 있습니다.

  • 넣고 D, E그리고 F그들을 호출하는 다른 기능을 허용, 자신의 별도의 m-파일의 각. 단점은 이러한 기능의 범위가 큰 단지에 한정되지 않는 것입니다 A, B그리고 C하지만, 거꾸로이 매우 간단하다는 것이다.

  • 크리에이트 defineMyFunctions와 (조나스 '예처럼) m-파일을 D, E그리고 F지역의 기능과 주요 기능으로 단순히 반환 그들에게 핸들을 작동합니다. 이것은 당신이 유지할 수 있습니다 D, E그리고 F같은 파일에 있지만 호출 할 수있는 기능 이후 이러한 기능의 범위에 대해 아무것도하지 않는 defineMyFunctions그들을 호출 할 수 있습니다. 그런 다음 함수 핸들을 인수로 전달하여 필요한 위치에 있는지 확인해야합니다.

  • 복사 D, EFB.mC.m지역의 기능을한다. 이것은 사용법의 범위를 단지 A, BC로 제한하지만 다른 위치에 동일한 코드의 사본이 3 개 있기 때문에 코드 업데이트 및 유지 관리가 악몽이됩니다.

  • 개인 기능을 사용하십시오 ! 당신이있는 경우 A, B그리고 C같은 디렉토리에, 당신이라는 하위 디렉토리 생성 할 수 있습니다 private및 장소 D, E그리고 F거기에 별도의 m-파일로 각. 이것은 범위를 제한하여 바로 위의 디렉토리에있는 함수 (예 A: B, 및 C) 만 호출 할 수 있으며 동일한 위치 (여전히 다른 m 파일)에 함께 유지합니다.

    myDirectory/
        A.m
        B.m
        C.m
        private/
            D.m
            E.m
            F.m

이 모든 것은 귀하의 질문의 범위를 벗어난 것이며, 아마도 당신이 필요로하는 것보다 더 자세 할 것입니다. ;)


3
가장 좋아하는 답변 옵션은 다음과 같습니다 ^: @idigas
embert

1
@embert 나는 그가 좋아하는 질문과 관련하여 선의를 표명했다고 가정한다.
OJFord

79

일반적으로 귀하의 질문에 대한 답변은 아니오입니다. 파일 당 두 개 이상의 외부에서 보이는 기능을 정의 할 수 없습니다. 함수 핸들을 로컬 함수로 반환 할 수 있으며 편리한 방법은 구조체의 필드를 만드는 것입니다. 예를 들면 다음과 같습니다.

function funs = makefuns
  funs.fun1=@fun1;
  funs.fun2=@fun2;
end

function y=fun1(x)
  y=x;
end

function z=fun2
  z=1;
end

사용 방법은 다음과 같습니다.

>> myfuns = makefuns;
>> myfuns.fun1(5)    
ans =
     5
>> myfuns.fun2()     
ans =
     1

36

단일 파일에 개별적으로 액세스 가능한 여러 기능을 갖는 유일한 방법객체 지향 프로그래밍을 사용하여 정적 방법 을 정의하는 것 입니다. 당신은 기능에 액세스 것 myClass.static1(), myClass.static2()

OOP 기능은 R2008a 이후 공식적으로 만 지원되므로, 문서화되지 않은 오래된 OOP 구문을 사용하지 않는 한 @gnovice에서 설명한대로 대답은 '아니오 ' 입니다.

편집하다

외부에서 액세스 할 수있는 파일 내에 여러 함수를 정의하는 또 다른 방법은 여러 함수 핸들 을 반환하는 함수를 만드는 것 입니다. 다시 말해, 정의 함수를로 호출 [fun1,fun2,fun3]=defineMyFunctions한 후 out1=fun1(inputs)등을 사용할 수 있습니다 .


나는이 목적으로 oop을 사용하지 않을 것이며, 특히 정적 메소드에 대해 상당한 오버 헤드를 추가합니다. ( stackoverflow.com/questions/1693429/… )
Daniel

1
@Daniel : 엄청난 양의 함수 호출을 수행하고 메소드의 계산이 준 순간적 인 경우에만 오버 헤드가 눈에.니다. 두 가지 조건 모두 벡터화가없고 의미없는 기능인 설계가 잘못되었음을 나타냅니다. 따라서, 나는 너무 걱정하지 않을 것입니다.
Jonas

23

나는 SCFrench의 답변을 정말로 좋아 합니다. assignin 함수를 사용하여 함수를 작업 공간으로 직접 가져 오기 위해 쉽게 수정할 수 있음을 지적하고 싶습니다 . (이렇게하면 파이썬의 "import x에서 y 가져 오기"방식을 많이 생각 나게합니다)

function message = makefuns
  assignin('base','fun1',@fun1);
  assignin('base','fun2',@fun2);
  message='Done importing functions to workspace';
end

function y=fun1(x)
  y=x;
end

function z=fun2
  z=1;
end

그런 다음 다음과 같이 사용하십시오.

>> makefuns
ans =
Done importing functions to workspace

>> fun1(123)
ans =
   123

>> fun2()
ans =
     1

assignin('caller',...)더 정확할 것입니다. 다른 기능 내에서 이러한 기능을 사용할 수 있습니다.
Cris Luengo

10

SCFrench의 답변과 동일한 줄을 따라 C # 스타일이 더 많이 회전합니다.

여러 정적 메소드를 포함하는 클래스를 만들고 싶습니다. 예를 들면 다음과 같습니다.

classdef Statistics

    methods(Static)
        function val = MyMean(data)
            val = mean(data);
        end

        function val = MyStd(data)
            val = std(data);
        end
    end

end

메소드가 정적이므로 클래스를 설치하지 않아도됩니다. 다음과 같이 함수를 호출합니다.

data = 1:10;

mean = Statistics.MyMean(data);
std = Statistics.MyStd(data);     

4

Octave를 사용하여 하나의 .m 파일에 여러 함수를 정의한 다음 해당 파일의 함수를 사용해야하는 .m 파일 내에서 명령을 사용합니다.

source("mycode.m");

이것이 Matlab과 함께 사용할 수 있는지 확실하지 않습니다.

octave:8> help source
'source' is a built-in function

 -- Built-in Function:  source (FILE)
     Parse and execute the contents of FILE.  This is equivalent to
     executing commands from a script file, but without requiring the
     file to be named `FILE.m'.

3

다음과 같은 기본 기능과 함께 하나의 기본 파일로 기능을 그룹화 할 수도 있습니다.

function [varargout] = main( subfun, varargin )
[varargout{1:nargout}] = feval( subfun, varargin{:} ); 

% paste your subfunctions below ....
function str=subfun1
str='hello'

그런 다음 subfun1 을 호출 하면 다음과 같습니다. str = main ( 'subfun1')


0

R2017b 현재 공식적으로는 불가능합니다. 관련 문서의 상태가 :

프로그램 파일은 여러 기능을 포함 할 수 있습니다. 파일에 함수 정의 만 포함 된 경우 첫 번째 함수가 주 함수이며 MATLAB이 파일 이름과 연결하는 함수입니다. 기본 기능 또는 스크립트 코드를 따르는 기능을 로컬 기능이라고합니다. 로컬 기능은 파일 내에서만 사용할 수 있습니다.

그러나 다른 답변에서 제안 된 해결 방법은 비슷한 것을 얻을 수 있습니다.


이것이 바로 답변 시작 부분에 Gnovice가 말한 내용이 아닌가?
Adiel

@Adiel 아마도 그 대답 이후 몇 년이 지났으며 누군가가 무엇이 바뀌 었는지 궁금 할 것입니다.
Dev-iL

아무것도 바뀌 었어도 여전히 얻지 못했습니다 ...? :)
Adiel

아니. 이 특정 주제를 다루기 위해 추가 된 일부 문서 외에.
Dev-iL

이 답변을 작성한 이유는 여러 릴리스 전에 스크립트 끝에 추가 할 수있는 기능을 도입했기 때문에 이와 관련하여 변경된 내용이 있는지 궁금 할 수 있습니다 (답 : 아니오).
Dev-iL

-1

나는 SCFRenchRu Hasha 를 옥타브로 시도했습니다 .

그리고 마침내 작동합니다 : 그러나 나는 약간의 수정을했습니다.

function message = makefuns
    assignin('base','fun1', @fun1);   % Ru Hasha
    assignin('base', 'fun2', @fun2);  % Ru Hasha
    message.fun1=@fun1;               % SCFrench
    message.fun2=@fun2;               % SCFrench
end

function y=fun1(x)
    y=x;
end

function z=fun2
    z=1;
end

다른 'm'파일에서 호출 가능

printf("%d\n", makefuns.fun1(123));
printf("%d\n", makefuns.fun2());

최신 정보:

때문에 나는 대답을 추가 하지도 72이나 20이 일하지 나를 위해 옥타브에. 내가 쓴 것은 완벽하게 작동합니다 (그리고 지난 금요일에 게시물을 쓸 때 지난 금요일에 테스트했습니다).


2
이것이 당신이 복사하고있는 기존의 두 답변과 어떻게 다른지 설명 할 수 있다면, 나는 downvote를 제거 할 것입니다. 이전에 댓글을 달지 못해 죄송합니다. 두 방법을 하나의 함수로 결합하여 중복되는 일을 제외하고는 이것이 어떻게 다른지 알 수 없습니다. 또한 참조하는 답변에 대한 적절한 링크를 삽입하십시오. "+72"및 "+20"은 매우 암호입니다. 시간이 지남에 따라 변경되는 투표 수를 참조한다는 것을 인식하는 데 시간이 걸렸습니다. 이해할 수 없는.
Cris Luengo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.