MATLAB 함수의 일부 반환 값을 우아하게 무시하는 방법은 무엇입니까?


120

모든 n-1반환 값에 대해 더미 변수를 만들 필요없이 함수에서 'n 번째'반환 값을 가져올 수 있습니까?

MATLAB에 다음과 같은 기능이 있다고 가정 해 보겠습니다.

function [a,b,c,d] = func()
a = 1;
b = 2;
c = 3;
d = 4;

이제 세 번째 반환 값 에만 관심이 있다고 가정 합니다. 이는 하나의 더미 변수를 생성하여 수행 할 수 있습니다.

[dummy, dummy, variableThatIWillUse, dummy] = func;
clear dummy;

그러나 나는 이것이 다소 추한 것이라고 생각한다 . 다음 중 하나와 같은 작업을 할 수 있다고 생각하지만 할 수는 없습니다.

[_, _, variableThatIWillUse, _] = func;

[, , variableThatIWillUse, ] = func;

variableThatIWillUse = func(3);

variableThatIWillUse = func()(3);

작동 하는 우아한 방법이 있습니까?


지금까지 가장 좋은 해결책은 단순히를 variableThatIWillUse더미 변수로 사용하는 것입니다. 이렇게하면 작업 공간을 오염시키는 실제 더미 변수를 만들지 않아도됩니다 (또는 정리해야 함). 요컨대, 해결책은 variableThatIWillUse흥미로운 값까지 모든 반환 값에 대해 사용하는 것입니다. 이후의 반환 값은 간단히 무시할 수 있습니다.

[variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func;

나는 여전히 이것이 매우 추악한 코드라고 생각하지만 더 좋은 방법이 없다면 대답을 받아 들일 것입니다.


내 대답에서 설명한 것처럼 셀형 배열을 사용하는 것 외에도 변수 이름을 반복하는 것이 유일한 다른 해결책 일 것입니다. 변수 이름이 "variableThatIWillUse"만큼 길지 않기를 바랍니다. =)
gnovice 2009

사실 그들은 그렇습니다. '더미'는 예일뿐입니다. 일반적으로 'variableThatIWillNotUse'를 사용합니다. 다른 변수의 이름은 'variableThatIMightUse', 'variableThatIWillUse2'및 'variableThatCanBarelyFitOnA80CharacterLine'입니다. 긴 이름과 살인 등급 사이의 상관 관계를 조사하고 있습니다. ;)
Jordi

26
실제로 R2009b 이후 함수 반환 무시는 '~'-Char를 사용하여 더 우아하게 해결됩니다. 예 : [~, b] = sort (rand (10,1))
ymihere

1
초보 독자 : ^가 정답이어야합니다. 아래 ManWithSleeve의 답변 참조
A.Wan

1
예제에서 세 번째 출력 인수 만 원하는 경우 다음을 사용해야합니다. [variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func; 더미 변수를 지울 필요가 없습니다. 최신 MATLAB 버전> = R2009b의 경우 [~, ~, variableThatIWillUse] = func;
티에리 Dalon

답변:


38

이것은 다소 해킹이지만 작동합니다.

먼저 간단한 예제 함수 :

Func3 = @() deal(1,2,3);
[a,b,c]=Func3();
% yields a=1, b=2, c=3

이제 여기서 핵심은 다중 표현식 할당의 왼쪽에서 변수를 두 번 사용 하면 이전 할당이 이후 할당으로 인해 방해를 받는다는 것입니다.

[b,b,c]=Func3();
% yields b=2, c=3

[c,c,c]=Func3();
% yields c=3

(편집 : 확인하기 위해, 나는 [mu,mu,mu]=polyfit(x,y,n)당신이 관심있는 모든 polyfit것이 세 번째 인수 인 경우이 기술이 작동하는지 확인했습니다 )


편집 : 더 나은 접근 방식이 있습니다. 대신 ManWithSleeve의 답변을 참조하십시오 .


7
이렇게 해결하려고 생각하지 않았습니다. 그러나이 솔루션은 영리함을 위해 의도의 명확성을 희생한다고 생각합니다.
Jukka Dahlbom 2009

5
저는 개인적으로 [정크, 정크, c] = function_call ()을 사용하고 "정크"가 중요한 변수가 아니며 필요한 경우 지울 메모리가 많다고 가정합니다.
Jason S

5
투표자에게 : 왜 -1인가? 이 답변은 R2009b가 출시되기 전에 작성되었으므로 @ManWithSleeve의 답변은 당시에는 작동하지 않았을 것입니다. 물론 이것이 올바른 접근 방식입니다.
Jason S

2
답변의 첫 번째 줄에있는 의견이 도움이 될까요? 방금 Google을 통해 여기에 왔으므로 업데이트 할 가치가있는 것 같습니다.
FvD 2013

왼쪽에서 오른쪽으로의 할당은 The MathWorks에 의해 공식적으로 보장되지 않으므로 [c, c, c] = myFunc () 뒤에 c를 사용해서는 안됩니다. (여기 참조 주석 # 26 : blogs.mathworks.com/loren/2009/09/11/... )
매트 크라우스

226

MATLAB 버전 7.9 (R2009b)에서는 ~를 사용할 수 있습니다.

[~, ~, variableThatIWillUse] = myFunction();

(가) 있습니다 ,선택 사항이 아니다. 입력 [~ ~ var]만으로는 작동하지 않으며 오류가 발생합니다.

자세한 내용은 릴리스 정보 를 참조하십시오.


3
"_"가 아니라는 것이 좀 짜증이납니다. (이미 촬영 한 것

4
@SamB 다음 사용하더라도 not운영자 것은 같이 don't care아니라고 나쁘지
토비아스 Kienzler

28
(가) 있습니다를 수행 ,선택하지 않습니다. 그냥 타이핑는 [~ ~ var]것입니다 하지 작업 및 오류가 발생합니다.
eykanal

나는 이것이 "정답"이라고 말할 것입니다. 다른 하나는 존재하지 않는 문제를 해결하기위한 해킹입니다. 의도 된 말장난 없음 ...
patrik

6
질문은 ~가 작동하지 않는 R2009b 이전에 2009 년에 제기되었습니다.
Tom Anderson

37

변수가 비트 버킷에 들어가도록 남겨 두는 스타일을 사용하려는 경우 합리적인 대안은 다음과 같습니다.

[ans,ans,variableThatIWillUse] = myfun(inputs);

ans는 물론 matlab의 기본 정크 변수이며 세션 과정에서 자주 덮어 쓰입니다.

이제 MATLAB이 허용하는 새로운 트릭을 좋아하지만 ~를 사용하여 무시 된 반환 변수를 지정하지만 이전 버전의 사용자가 코드를 사용할 수 없다는 점에서 이전 버전과의 호환성 문제입니다. 나는 일반적으로 최소한 몇 개의 MATLAB 릴리스가 발행 될 때까지 이와 같은 새로운 것을 사용하지 않기 때문에 사용자가 매우 적을 것입니다. 예를 들어, 지금도 사람들은 익명 함수를 사용할 수 없을만큼 충분히 오래된 MATLAB 릴리스를 사용하고 있습니다.


7
예, 영리하지만 기본 Matlab 편집기는 ans 변수에 아무것도 할당하면 경고를 표시합니다. 경고를받는 것이 매우 우아하다고 생각하지 않습니다 ...
Jordi

11
경고를 끌 수 있습니다. 이 주석 문자열 % # ok로 줄을 끝내면 Mlint는 이것을 무시합니다. 경고가 없습니다.

13

사용할 수있는 또 다른 옵션이 있습니다. 먼저 모든 출력을 캡처하는 셀형 배열을 만듭니다 ( NARGOUT 함수를 사용하여 주어진 함수가 반환하는 출력 수를 결정할 수 있음).

a = cell(1,3);  % For capturing 3 outputs
% OR...
a = cell(1,nargout(@func));  % For capturing all outputs from "func"

그런 다음 다음과 같이 함수를 호출합니다.

[a{:}] = func();

그리고 단순히에서 요소를 제거 당신이 원하는 것을하고 덮어 :

a = a{3};  % Get the third output

9

kth out 함수를 작성했습니다.


function kth = kthout(k,ffnc,varargin)
%% kthout: take the kth varargout from a func call %FOLDUP
% 
% kth = kthout(k,ffnc,varargin)
%
% input:
%  k                      which varargout to get
%  ffnc                   function to call;
%  varargin               passed to ffnc;
% output:
%  kth                    the kth argout;
% global:
% nb: 
% See also:
% todo:
% changelog: 
%
%% %UNFOLD

[outargs{1:k}]  = feval(ffnc,varargin{:});
kth                         = outargs{k};

end %function

그런 다음 전화 할 수 있습니다

val_i_want  = kthout(3,@myfunc,func_input_1,func_input_2); %etc

다음과 같이 함수를 마무리 할 수도 있습니다.

func_i_want = @(varargin)(kthout(3,@myfunc,varargin{:}));  %assuming you want the 3rd output.

그 후에 사용

val_i_want = func_i_want(func_input_1,func_input_2);

이와 같은 익명 함수를 사용하는 것과 관련된 오버 헤드가 있으며 이것은 수천 번 호출되는 코드에서 수행 할 작업이 아닙니다.


4

Matlab 2010a에서 저는 당신이 요구하는 것을 깔끔하게하는 방법을 찾았습니다. 단순히 따옴표없이 문자 "~"를 더미 변수 (여러 매개 변수를 반환 할 때 원하는만큼)로 사용하는 것입니다. 이는 함수가 누락 된 데이터를 처리하도록 설계된 경우 함수에 대한 입력 매개 변수에도 적용됩니다. 이것이 이전 버전에 존재했는지는 모르겠지만 최근에 발견했습니다.


11
이전 답변을 보지 못 하셨나요?
yuk

1

선택한 출력 만 반환하는 함수 (또는 익명 함수)를 만들 수 있습니다.

select = @(a,b) a(b);

그런 다음 다음과 같이 함수를 호출 할 수 있습니다.

select(func,2);
select(func,1:3);

또는 출력을 변수에 할당 할 수 있습니다.

output(1,2:4) = select(func,1:3);

나를 위해 작동하지 않습니다. 시도decimatedfftx = select(fft(x,12),1:4:12);
NotGaeL

1
select(func,2)전화 func(2). 이것이 출력 인수를 선택하는 위치를 알지 못합니다.
Cris Luengo

0

다음과 같이 ans (n)을 사용하지 않는 이유가 있습니까?

a=rand([5 10 20 40]);

size(a);

b=ans(2);

b = 10을 제공하고 이렇게하면 모든 Matlab 버전과 호환되지 않습니까?

또한 이것은 얼마나 많은 인수가 있을지 모를 때 두 번째 출력 인수를 얻기 위해 작동합니다! 반면에 이렇게하면 :

[~, b] = size(a);

그러면 b = 8000! (더 많은 인수를 잡으려면 ~로 끝나야합니다!)


이 대답은 반환되는 변수가 벡터라고 가정하며 아마도 OP가 의미하는 바가 아닐 것입니다.
닐 Traft

이것은 말이되지 않습니다. size(a)그리고 [b,c]=size(a)다른 일을 반환합니다. MATLAB의 함수는 출력 인수의 수에 따라 동작을 변경합니다.
Cris Luengo

이 답변을 이해하는 데 어려움을 겪고 있습니다. 이것이 원래의 질문에 직접적으로 대답하지 않는다는 것은 말할 것도없고, 이것이 여기서 답변의 질에 어떻게 기여하는지 모르겠습니다.
rayryeng

6 년이 지난 지금 더 이상 Matlab을 사용하지 않습니다. 내가 기억하는 한 "size ()"함수는 관련이 없었습니다. 여러 인수를 반환하는 함수로 사용했습니다. 요점은 단순히 func ()를 호출 한 다음 ans (n)을 호출하여 반환 된 변수 번호 n의 값을 가져올 수 있다는 것입니다. 이것은 특정 상황에서 잘 작동하고 이전 버전과 호환되는 것으로 보입니다. 물론 특정 기능이나 변수 유형에서만 작동 할 수 있습니다. 6 년 후에 제가 도울 수있는만큼입니다.
user1596274
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.