Na przykład, jeśli chcę odczytać środkową wartość magic(5)
, mogę to zrobić w następujący sposób:
M = magic(5);
value = M(3,3);
dostać value == 13
. Chciałbym móc zrobić coś takiego:
value = magic(5)(3,3);
value = (magic(5))(3,3);
zrezygnować ze zmiennej pośredniej. Jednak MATLAB narzeka Unbalanced or unexpected parenthesis or bracket
na pierwszy nawias przed 3
.
Czy możliwe jest odczytanie wartości z tablicy / macierzy bez uprzedniego przypisania jej do zmiennej?
matlab
indexing
matrix
return-value
variable-assignment
Joe Kearney
źródło
źródło
testmatrix('magi', 5)(3, 3)
na Scilabie, jak imagic(5)(3, 3)
na Oktawie działają jak urok!Odpowiedzi:
Możliwe jest robienie tego, co chcesz, ale musisz użyć funkcjonalnej formy operatora indeksowania. Podczas wykonywania operacji indeksowania za pomocą
()
faktycznie wywołujeszsubsref
funkcję. Więc nawet jeśli nie możesz tego zrobić:Możesz to zrobić:
Brzydkie, ale możliwe. ;)
Ogólnie rzecz biorąc, wystarczy zmienić krok indeksowania na wywołanie funkcji, aby nie było dwóch zestawów nawiasów następujących po sobie. Innym sposobem na to byłoby zdefiniowanie własnej anonimowej funkcji do indeksowania w indeksie dolnym. Na przykład:
Jednak kiedy wszystko zostanie powiedziane i zrobione, rozwiązanie tymczasowej zmiennej lokalnej jest znacznie bardziej czytelne i zdecydowanie to, co sugerowałbym.
źródło
clear
na tymczasowy (których nikt nigdy nie) - tymczasowy ma tendencję do trzymać się dłużejKilka dni temu był tylko dobry post na blogu o Lorenie na temat Art of Matlab z kilkoma klejnotami, które mogą pomóc. W szczególności za pomocą funkcji pomocniczych, takich jak:
gdzie
paren()
można użyć jakwróciłby
Przypuszczam również, że będzie to szybsze niż odpowiedź gnovice, ale nie sprawdziłem (użyj profilera !!!). To powiedziawszy, musisz gdzieś dołączyć te definicje funkcji. Osobiście uczyniłem je niezależnymi funkcjami na mojej ścieżce, ponieważ są one bardzo przydatne.
Te i inne funkcje są teraz dostępne w dodatku Functional Programming Constructs, który jest dostępny za pośrednictwem Eksploratora dodatków MATLAB lub wymiany plików .
źródło
myfunc().attr
?myfunc()
zwróci strukturę zawierającą atrybutattr
, to aby uzyskać dostępattr
obecnie, muszę to zrobićS = myfunc(); S.attr
. Pytanie brzmi, czy możemy mieć funkcję pomocnikagetattr(myfunc(), 'attr')
analogicznie do pomocnikówparen
icurly
. Nie rozumiem, co to ma wspólnego z przybornikiem bazy danych.Co sądzisz o korzystaniu z nieudokumentowanych funkcji:
lub w przypadku tablic komórkowych:
Tak jak magia :)
AKTUALIZACJA:
Złe wieści, powyższy hack już nie działa w R2015b ! W porządku, to była nieudokumentowana funkcjonalność i nie możemy polegać na niej jako obsługiwanej funkcji :)
Jeśli zastanawiasz się, gdzie znaleźć tego rodzaju rzeczy, zajrzyj do folderu
fullfile(matlabroot,'bin','registry')
. Jest tam kilka plików XML z listą różnego rodzaju gadżetów. Ostrzegamy, że bezpośrednie wywołanie niektórych z tych funkcji może łatwo zawiesić sesję MATLAB.źródło
':'
Aby uniknąć błędu, należy użyć operatora dwukropka (:) z apostrofamiUndefined function or variable "builtin"
.builtin('_paren', magic(5), ':', 2)
to znaczy : (w niektórych miejscach działa to bez cudzysłowów bezpośrednio,:
w przeciwieństwie do':'
, na przykład podczas uruchamiania w wierszu polecenia bezpośrednio, nie z wnętrza funkcji. to błąd w analizatorze!)end
z tym skorzystać?end
sztuczka nie działa w tej składni, musisz być jawny w indeksowaniu .. (To samo ograniczenie dotyczy większości innych wymienionych odpowiedzi)Przynajmniej w MATLAB 2013a możesz używać
getfield
takich jak:uzyskać element w (1,2)
źródło
niestety składnia like
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źródło
Zauważ, że jeśli porównasz czasy działania ze standardowym sposobem (przypisz wynik, a następnie uzyskaj dostęp do wpisów), będą one dokładnie takie same.
Moim zdaniem, podstawową kwestią jest: MATLAB nie ma wskaźników, musisz z tym żyć.
źródło
Może być prostsze, jeśli utworzysz nową funkcję:
a następnie użyj go:
źródło
subref
robi ... ale w bardziej ogólny sposób.Twoja początkowa notacja jest najbardziej zwięzłym sposobem:
Jeśli robisz to w pętli, możesz po prostu ponownie przypisać M za każdym razem i zignorować również jasne polecenie.
źródło
Aby uzupełnić odpowiedź Amro, możesz użyć
feval
zamiastbuiltin
. Tak naprawdę nie ma różnicy, chyba że spróbujesz przeciążyć funkcję operatora:Interesujące jest to, że
feval
wydaje się to nieco szybsze niżbuiltin
(o ~ 3,5%), przynajmniej w Matlabie 2013b, co jest dziwne, biorąc pod uwagę, żefeval
należy sprawdzić, czy funkcja jest przeciążona, w przeciwieństwie dobuiltin
:źródło
feval
robi „normalną” rzecz i dlatego może w pełni wykorzystać tę listę.builtin
musi szukać gdzie indziej, aby znaleźć tylko wbudowane funkcje. Prawdopodobnie ten przypadek nie jest zoptymalizowany prawie tak bardzo, jak przypadek „normalny”, ponieważ dlaczego miałbyś wkładać pieniądze w optymalizację czegoś, co nie jest często używane?