먼저 로컬 변수에 할당하지 않고 함수에서 반환 한 MATLAB 배열을 어떻게 인덱싱 할 수 있습니까?


363

예를 들어에서의 중간 값을 읽으려면 다음 magic(5)과 같이하십시오.

M = magic(5);
value = M(3,3);

얻을 value == 13. 다음 중 하나와 같은 작업을 수행하고 싶습니다.

value = magic(5)(3,3);
value = (magic(5))(3,3);

중간 변수를 제거합니다. 그러나 MATLAB은 Unbalanced or unexpected parenthesis or bracket앞에있는 첫 번째 괄호에 대해 불평 합니다 3.

변수 / 변수를 먼저 변수에 할당하지 않고 배열 / 매트릭스에서 값을 읽을 수 있습니까?


2
또한이 주제에 대해 다음 기사를 찾았습니다. mathworks.com/matlabcentral/newsreader/view_thread/280225 이 주제에 대한 새로운 정보가있는 사람이 있습니까?

2
이 구문은 실제로 Octave에서 제대로 작동합니다. MATLAB을 사용하는 동료가 내 코드를 실행하는 데 문제가있을 때만이 문제를 발견했습니다.
— sffc

2
간단히 말해서 MATLAB.
— user76284

1
재귀 추출은 버전 6 이후 Scilab ( scilab.org ) 에서도 작동합니다 .
— Stéphane Mottelet

testmatrix('magi', 5)(3, 3)Scilab에와 magic(5)(3, 3)마법처럼 모두 작업 옥타브에!
— Foad

답변:


384

실제로 원하는 것을 수행하는 것이 가능하지만 기능적인 형태의 인덱싱 연산자를 사용해야합니다. 를 사용하여 인덱싱 작업을 수행하면 ()실제로 subsref함수를 호출하게 됩니다. 따라서이 작업을 수행 할 수는 없지만 :

value = magic(5)(3, 3);

당신 은 이것을 할 수 있습니다 :

value = subsref(magic(5), struct('type', '()', 'subs', {{3, 3}}));

추악하지만 가능합니다. ;)

일반적으로 인덱싱 단계를 함수 호출로 변경하면 바로 다음에 두 세트의 괄호가 없어집니다. 이를 수행하는 또 다른 방법 은 첨자 인덱싱을 수행하기 위해 자신의 익명 함수 를 정의하는 것 입니다. 예를 들면 다음과 같습니다.

subindex = @(A, r, c) A(r, c);     % An anonymous function for 2-D indexing
value = subindex(magic(5), 3, 3);  % Use the function to index the matrix

그러나 모든 것이 말되고 완료되면 임시 로컬 변수 솔루션을 훨씬 더 읽기 쉽고 확실히 제안 할 것입니다.


26
잘 아세요! 비록 그것이 추악하고, 아마도 임시 Var 솔루션보다 읽기 쉽지 않다는 데 동의합니다. 눈에 잘 띄지 않는 MATLAB 지식 +1!
— 두 번째

57
그것은 역겨운 일이지만 매우 명확한 대답입니다. 잘 했어! 그것에 대한 뒷길이있을 것이라고 추측했을 것입니다. temp 변수를 계속 사용할 것입니다.
— Joe Kearney

29
그래도 중간 변수는 여전히 완전히 생성됩니다. 따라서 임시 로컬 변수를 만들지 않고 메모리를 절약하는 것이 목적이라면 운이 없습니다.
— 샘 로버츠

8
@ SamRoberts : Matlab과 같은 엄격한 평가 언어로 그 문제를 해결할 수는 없습니다. 사람들이 이것을 원하는 주된 이유는 메모리 절약이 아니라 간결함 / 가독성입니다.
— 기계 달팽이

5
@SamRoberts : 사실,하지만은 않습니다 호출의 부담에서 당신 저장 clear(아무도 이제까지하지 않습니다하는) 임시에이 - 임시 주위에 더 이상 집착하는 경향이있다
— RODY Oldenhuis

131

며칠 전에 Loren의 Matlab에 관한 좋은 블로그 게시물 이 있었는데 도움이 될만한 몇 가지 보석이 있습니다. 특히 다음과 같은 도우미 기능 사용

paren = @(x, varargin) x(varargin{:});
curly = @(x, varargin) x{varargin{:}};

어디에서 paren()사용할 수 있습니까

paren(magic(5), 3, 3);

돌아올 것이다

ans = 16

나는 이것이 gnovice의 대답보다 빠를 것이라고 생각하지만 확인하지 않았습니다 (프로필러 사용 !!!). 즉,이 함수 정의를 어딘가에 포함시켜야합니다. 나는 개인적으로 내 경로에서 독립적 인 기능을 만들었습니다. 매우 유용하기 때문입니다.

이러한 함수 및 기타 함수는 이제 MATLAB 애드온 탐색기 또는 파일 교환을 통해 제공되는 Functional Programming Constructs 애드온에서 사용할 수 있습니다 .


2
이것은 gnovice의 답변 후반부의 약간 더 일반적인 버전입니다. 또한 좋습니다.
— Joe Kearney

무엇에 대해 myfunc().attr?
— gerrit

@gerrit, 어떻게 도와 줍니까? 데이터베이스 도구 상자가 없으면 x.attr () 필드를 사용할 수 없습니다.
— T. Furfaro

@ T.Furfaro Huh? myfunc()속성이 포함 된 구조를 반환하는 경우 현재 attr액세스 attr하려면해야 S = myfunc(); S.attr합니다. 문제는 헬퍼 와 헬퍼 getattr(myfunc(), 'attr')와 같은 헬퍼 기능을 가질 수 있는지 입니다. 데이터베이스 도구 상자와 관련이 무엇인지 이해하지 못합니다. parencurly
— gerrit

2
@gerrit 죄송합니다, 총 혼란입니다 (귀하의 "attr"이 임의적이라는 것을 알지 못했습니다-db tb에는 명시 적으로 정의 된 필드가 있습니다). 나는 당신이 찾고있는 것이 getfield ()
— T. Furfaro

75

문서화되지 않은 기능 사용에 대해 어떻게 생각하십니까?

>> builtin('_paren', magic(5), 3, 3)               %# M(3,3)
ans =
    13

또는 셀형 배열의 경우 :

>> builtin('_brace', num2cell(magic(5)), 3, 3)     %# C{3,3}
ans =
    13

마술처럼 :)


최신 정보:

나쁜 소식, 위의 핵은 더 이상 R2015b 에서 작동하지 않습니다 ! 괜찮습니다. 문서화되지 않은 기능이므로 지원되는 기능으로 사용할 수 없습니다. :)

이 유형의 것을 어디에서 찾을 수 있는지 궁금한 분은 폴더를 찾으십시오 fullfile(matlabroot,'bin','registry'). 모든 종류의 장점을 나열하는 XML 파일이 많이 있습니다. 이러한 함수 중 일부를 직접 호출하면 MATLAB 세션이 쉽게 중단 될 수 있습니다.


@RodyOldenhuis : 지금 기억 나지 않습니다. 매장 된 코드로 읽었어야한다고 생각합니다.)
— Amro

2
':'오류를 피 하려면 콜론 (:) 연산자를 아포스트로피와 함께 사용해야합니다 Undefined function or variable "builtin".
— 도미니크

@Dominik : 맞습니다. 두 번째 열을 슬라이스하고 싶다고 말하십시오. builtin('_paren', magic(5), ':', 2)(특정 위치 에서는 명령 프롬프트에서 함수 내부가 아닌 직접 명령 프롬프트에서 실행할 때 와 :는 달리 따옴표없이 직접 ':'작동합니다. 그것은 파서의 버그입니다!)
— Amro

2
나는 end이것과 함께 사용할 수 있는 방법이 있다고 생각하지 않습니까?
— knedlsepp 2019

2
@knedlsepp : 아니, 불행하게도 전체 end-trickery는 이 구문에하지 작업, 당신은 당신의 색인에 명시해야합니다 않습니다 .. (동일 제한은 대부분의 다른 목록에 대한 답변 적용)
— 암로

54

적어도 MATLAB 2013a에서는 다음 getfield과 같이 사용할 수 있습니다 .

a=rand(5);
getfield(a,{1,2}) % etc

(1,2)에서 요소를 얻으려면


5
이것은 실제로 좋은 방법입니다. 어떤 단점이 있습니까?
— mmumboss

6
@mmumboss : 그것은 문서화되지 않은 행동이며,이 기능은 차후 버전에서 예고없이 사라질 수 있습니다. 이 외에도 단점이 없습니다.
— Daniel

6
MATLAB2017b부터이 기능이 문서화되었습니다.
— njspeer

15

불행히도 같은 구문 magic(5)(3,3)은 matlab에서 지원되지 않습니다. 임시 중간 변수를 사용해야합니다. 사용 후 메모리를 비울 수 있습니다. 예 :

tmp = magic(3);
myVar = tmp(3,3);
clear tmp

12

실행 시간을 표준 방식과 비교하면 (결과에 할당 한 다음 항목에 액세스) 정확히 동일합니다.

subs=@(M,i,j) M(i,j);
>> for nit=1:10;tic;subs(magic(100),1:10,1:10);tlap(nit)=toc;end;mean(tlap)

ans =

0.0103

>> for nit=1:10,tic;M=magic(100); M(1:10,1:10);tlap(nit)=toc;end;mean(tlap)

ans =

0.0101

내 의견으로는, 결론은 : MATLAB에는 포인터가 없으므로 함께 사용해야합니다.


6

새로운 기능을 만들면 더 간단 할 수 있습니다.

function [ element ] = getElem( matrix, index1, index2 )
    element = matrix(index1, index2);
end

그리고 그것을 사용하십시오 :

value = getElem(magic(5), 3, 3);

1
그러나 이것은 정확히 무엇 subref을하는 것이지만보다 일반적인 방식입니다.
— Shai

2
예, 좀 더 일반적인 방법이지만 친절하지는 않습니다.
— Vugar

4

초기 표기법은 가장 간결한 방법입니다.

M = magic(5);  %create
value = M(3,3);  % extract useful data
clear M;  %free memory

루프 에서이 작업을 수행하는 경우 매번 M을 다시 할당하고 명확한 명령문도 무시할 수 있습니다.


6
나는 이것이 더 간결하다는 데 동의하고, 말한 것처럼 지우기는 루프에서 좋은 생각이지만, 중간 과제를 피할 수 있는지에 대한 질문이 있습니다.
— Joe Kearney

1

Amro의 답변을 보완하기 위해 feval대신 사용할 수 있습니다 builtin. 연산자 함수를 오버로드하지 않으면 실제로 차이가 없습니다.

BUILTIN (...)은 FEVAL (...)과 동일하지만 오버로드 된 기능이 존재하더라도 함수의 원래 내장 버전을 호출한다는 점을 제외하면 (BUILTIN에 과부하가 걸리지 않아야 함)

>> feval('_paren', magic(5), 3, 3)               % M(3,3)
ans =
    13

>> feval('_brace', num2cell(magic(5)), 3, 3)     % C{3,3}
ans =
    13

흥미로운 것은 즉 feval단지 작은 조금 더 빨리 이상의 것 같다 builtin(~ 3.5 %로), 주어진 이상한 matlab에 2013b, 적어도 feval함수가 오버로드 된 경우 요구 사항이 달리 확인 builtin:

>> tic; for i=1:1e6, feval('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 49.904117 seconds.
>> tic; for i=1:1e6, builtin('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 51.485339 seconds.

실제로는 이상하지 않습니다. MATLAB은 정의 된 함수 목록을 유지하므로 검색 할 것이 많지 않습니다. feval"정상적인"작업을 수행하므로이 목록을 최대한 활용할 수 있습니다. builtin내장 함수 만 찾을 수 있도록 다른 곳을 검색해야합니다. 아마도이 사례는“정상적인”사례만큼 최적화되지 않았을 것입니다. 왜 자주 사용하지 않는 것을 최적화하기 위해 돈을 투자하겠습니까?
— Cris Luengo 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.