Jak mogę indeksować tablicę MATLAB zwracaną przez funkcję bez uprzedniego przypisania jej do zmiennej lokalnej?
Na przykład, jeśli chcę odczytać wartość środkową z magic(5)
, mogę to zrobić tak:
M = magic(5);
value = M(3,3);
Aby uzyskać value == 13
. Chciałbym móc zrobić coś takiego:
value = magic(5)(3,3);
value = (magic(5))(3,3);
Aby zrezygnować ze zmiennej pośredniej. Jednak MATLAB narzeka na Unbalanced or unexpected parenthesis or bracket
w pierwszym nawiasie przed 3
.
Czy jest możliwe odczytanie wartości z tablicy / macierzy bez uprzedniego przypisania jej do zmiennej?
9 answers
W rzeczywistości jest możliwe, aby robić to, co chcesz, ale musisz użyć formy funkcjonalnej operatora indeksującego. Kiedy wykonujesz operację indeksowania za pomocą ()
, w rzeczywistości dzwonisz do subsref
funkcja. Więc, nawet jeśli nie możesz zrobić tego:
value = magic(5)(3, 3);
You can do this:
value = subsref(magic(5), struct('type', '()', 'subs', {{3, 3}}));
Brzydkie, ale możliwe. ;)
Ogólnie rzecz biorąc, wystarczy zmienić krok indeksowania na wywołanie funkcji, aby nie mieć dwóch zestawów nawiasy bezpośrednio po sobie. Innym sposobem na to byłoby zdefiniowanie własnej funkcji anonimowej do indeksowania subskrybowanego. Na przykład:
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
Jednak, gdy wszystko zostanie powiedziane i zrobione, tymczasowe rozwiązanie zmiennej lokalnej jest dużo bardziej czytelne i zdecydowanie to, co sugerowałbym.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-04 18:46:47
Był właśniedobry post na blogu naLoren o sztuce Matlab kilka dni temu z kilkoma klejnotami, które mogą pomóc. W szczególności za pomocą funkcji pomocniczych, takich jak:
paren = @(x, varargin) x(varargin{:});
curly = @(x, varargin) x{varargin{:}};
Gdzie paren()
może być używany jak
paren(magic(5), 3, 3);
Zwróci
ans = 16
Domyślam się również, że będzie to szybsze niż odpowiedź gnovica, ale nie sprawdzałem (użyj profilera!!!). Mając to na uwadze, musisz również gdzieś zawrzeć te definicje funkcji. Ja osobiście zrobiłem są niezależne na mojej drodze, ponieważ są bardzo przydatne.
Te i inne funkcje są teraz dostępne w konstrukcjach programowania funkcyjnego dodatku, który jest dostępny za pośrednictwem Eksploratora dodatków MATLAB lub na wymianie plików .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-22 11:44:41
Co sądzisz o używaniu nieudokumentowanych funkcji:
>> builtin('_paren', magic(5), 3, 3) %# M(3,3)
ans =
13
Lub dla tablic komórkowych:
>> builtin('_brace', num2cell(magic(5)), 3, 3) %# C{3,3}
ans =
13
Just like magic:)
Aktualizacja:
Zła wiadomość, powyższy hack nie działa już w R2015b ! W porządku, była to nieudokumentowana funkcjonalność i nie możemy polegać na niej jako obsługiwanej funkcji:)
Dla tych, którzy zastanawiają się, gdzie znaleźć tego typu rzeczy, zajrzyj do folderu fullfile(matlabroot,'bin','registry')
. Jest tam kilka plików XML, które zawierają wszystkie rodzaje gadżetów. Be ostrzegł, że wywołanie niektórych z tych funkcji bezpośrednio może łatwo spowodować awarię sesji MATLAB.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-31 07:54:47
Przynajmniej w MATLAB 2013a można użyć getfield
like:
a=rand(5);
getfield(a,{1,2}) % etc
Aby uzyskać element at (1,2)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-30 20:25:46
Niestety składnia podobna do magic(5)(3,3)
nie jest obsługiwana przez matlab. musisz użyć tymczasowych zmiennych pośrednich. możesz zwolnić pamięć po użyciu, np.
tmp = magic(3);
myVar = tmp(3,3);
clear tmp
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-02 12:46:10
Zauważ, że jeśli porównasz czasy uruchomienia ze standardowym sposobem (jako znak wyniku i następnie dostęp do wpisów), są one dokładnie takie same.
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
Moim zdaniem najważniejsze jest to, że MATLAB nie ma wskaźników, trzeba z tym żyć.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-04 18:31:09
Może być prostsze, jeśli stworzysz nową funkcję:
function [ element ] = getElem( matrix, index1, index2 )
element = matrix(index1, index2);
end
A następnie użyj go:
value = getElem(magic(5), 3, 3);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-01 16:58:07
Twoja początkowa notacja jest najbardziej zwięzłym sposobem, aby to zrobić:
M = magic(5); %create
value = M(3,3); % extract useful data
clear M; %free memory
Jeśli robisz to w pętli, możesz po prostu zmienić przypisanie M za każdym razem i zignorować jasne oświadczenie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-20 18:16:36
Aby uzupełnić odpowiedź Amro, możesz użyć feval
zamiast builtin
. Nie ma różnicy, naprawdę, chyba że spróbujesz przeciążyć funkcję operatora:
BUILTIN(...) jest tym samym co FEVAL(...) z tym, że będzie to wywoływać oryginalna wbudowana wersja funkcji nawet w przypadku przeciążenia istnieje (aby to działało, nie wolno przeciążać BUILTIN).
>> feval('_paren', magic(5), 3, 3) % M(3,3)
ans =
13
>> feval('_brace', num2cell(magic(5)), 3, 3) % C{3,3}
ans =
13
Ciekawe jest to, że feval
wydaje się być trochę szybszy niż builtin
(o ~3,5%), w najmniej w Matlab 2013b, co jest dziwne, biorąc pod uwagę, że feval
musi sprawdzić, czy funkcja jest przeciążona, w przeciwieństwie do 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.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-12 20:54:00