399 Stimmen

Wie kann ich ein von einer Funktion zurückgegebenes MATLAB-Array indizieren, ohne es vorher einer lokalen Variablen zuzuweisen?

Wenn ich zum Beispiel den mittleren Wert von magic(5) Ich kann das so machen:

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

zu bekommen value == 13 . Ich würde gerne so etwas wie das hier machen können:

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

um auf die Zwischenvariable zu verzichten. MATLAB beschwert sich jedoch über Unbalanced or unexpected parenthesis or bracket auf die erste Klammer vor der 3 .

Ist es möglich, Werte aus einem Array/einer Matrix zu lesen, ohne sie vorher einer Variablen zuzuweisen?

419voto

gnovice Punkte 124264

Es ist tatsächlich es Es ist möglich, das zu tun, was Sie wollen, aber Sie müssen die funktionale Form des Indizierungsoperators verwenden. Wenn Sie eine Indizierungsoperation durchführen, indem Sie () machen Sie eigentlich einen Aufruf an die subsref Funktion. Auch wenn Sie also kann nicht dies tun:

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

Sie kann dies tun:

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

Hässlich, aber möglich. ;)

Im Allgemeinen müssen Sie nur den Indizierungsschritt in einen Funktionsaufruf umwandeln, damit Sie nicht zwei Sätze von Klammern unmittelbar hintereinander haben. Eine andere Möglichkeit, dies zu tun, wäre die Definition einer eigenen anonyme Funktion um die tiefgestellte Indizierung durchzuführen. Zum Beispiel:

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

Letzten Endes ist die Lösung mit den temporären lokalen Variablen jedoch viel besser lesbar, und das würde ich auf jeden Fall vorschlagen.

146voto

T. Furfaro Punkte 2107

Es gab nur guter Blogbeitrag auf Loren über die Kunst von Matlab vor ein paar Tagen mit ein paar Tipps, die helfen könnten. Insbesondere die Verwendung von Hilfsfunktionen wie:

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

donde paren() kann verwendet werden wie

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

würde zurückkehren

ans = 16

Ich würde auch vermuten, dass dies schneller sein wird als die Antwort von gnovice, aber ich habe es nicht überprüft (Benutzen Sie den Profiler!!!). Abgesehen davon müssen Sie diese Funktionsdefinitionen auch irgendwo einbinden. Ich persönlich habe sie zu unabhängigen Funktionen in meinem Pfad gemacht, weil sie sehr nützlich sind.

Diese und andere Funktionen sind jetzt in der Funktionale Programmierkonstrukte Add-On, das über den MATLAB Add-On Explorer oder auf der Dateiaustausch .

75voto

Amro Punkte 122495

Was halten Sie von der Verwendung undokumentierter Funktionen?

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

oder für Zellanordnungen:

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

Genau wie Magie :)


UPDATE

Die schlechte Nachricht: Der obige Hack funktioniert nicht mehr in R2015b ! Das ist in Ordnung, es war eine undokumentierte Funktion und wir können uns nicht darauf verlassen, dass diese Funktion unterstützt wird :)

Diejenigen, die sich fragen, wo sie diese Dinge finden können, finden sie im Ordner fullfile(matlabroot,'bin','registry') . Dort gibt es eine Reihe von XML-Dateien, in denen alle möglichen Dinge aufgelistet sind. Seien Sie gewarnt, dass der direkte Aufruf einiger dieser Funktionen leicht zum Absturz Ihrer MATLAB-Sitzung führen kann.

61voto

Ian M. García Punkte 711

Zumindest in MATLAB 2013a können Sie mit getfield mögen:

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

um das Element bei (1,2) zu erhalten

17voto

second Punkte 26650

Leider Syntax wie magic(5)(3,3) wird von matlab nicht unterstützt. sie müssen temporäre zwischenvariablen verwenden. sie können den speicher nach der verwendung wieder freigeben, z.b.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X