Comment puis-je indexer un tableau MATLAB renvoyé par une fonction sans l’assigner d’abord à une variable locale?

Par exemple, si je veux lire la valeur intermédiaire de magic(5) , je peux le faire comme ceci:

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

pour obtenir la value == 13 . Je voudrais pouvoir faire quelque chose comme l’un de ces:

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

se passer de la variable intermédiaire. Cependant, MATLAB se plaint de Unbalanced or unexpected parenthesis or bracket sur la première parenthèse avant le 3 .

Est-il possible de lire les valeurs d’un tableau / masortingce sans lui atsortingbuer au préalable une variable?

Il est effectivement possible de faire ce que vous voulez, mais vous devez utiliser la forme fonctionnelle de l’opérateur d’indexation. Lorsque vous effectuez une opération d’indexation à l’aide de () , vous effectuez un appel à la fonction subsref . Donc, même si vous ne pouvez pas faire ça:

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

Vous pouvez le faire:

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

Moche, mais possible. 😉

En général, il suffit de changer l’étape d’indexation en appel de fonction pour ne pas avoir deux ensembles de parenthèses qui se suivent immédiatement. Une autre façon de faire serait de définir votre propre fonction anonyme pour effectuer l’indexation en indice. Par exemple:

 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 masortingx 

Cependant, au bout du compte, la solution de variables locales temporaires est beaucoup plus lisible, et certainement ce que je suggère.

Il y a quelques jours, il y avait juste un bon article sur Loren sur l’art de Matlab avec quelques joyaux qui pourraient aider. En particulier, l’utilisation de fonctions d’aide telles que:

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

paren() peut être utilisé comme

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

retournerais

 ans = 16 

Je suppose aussi que ce sera plus rapide que la réponse de gnovice, mais je n’ai pas vérifié (utilisez le profileur !!!). Cela étant dit, vous devez également inclure ces définitions de fonctions quelque part. Personnellement, je les ai rendus indépendants sur mon chemin, car ils sont super utiles.

Ces fonctions, ainsi que d’autres, sont désormais disponibles dans le module complémentaire Fonctions de functional programmings, disponible via l’Explorateur de modules MATLAB ou l’ échange de fichiers .

Que pensez-vous de l’utilisation des fonctionnalités non documentées:

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

ou pour les tableaux de cellules:

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

Juste comme par magie 🙂


METTRE À JOUR:

Mauvaise nouvelle, le hack ci-dessus ne fonctionne plus dans R2015b ! C’est bien, c’était une fonctionnalité non documentée et nous ne pouvons pas compter sur elle comme une fonctionnalité supscope 🙂

Pour ceux qui se demandent où trouver ce genre de chose, regardez dans le dossier fullfile(matlabroot,'bin','registry') . Il y a un tas de fichiers XML qui répertorient toutes sortes de goodies. Sachez qu’appeler directement certaines de ces fonctions peut facilement bloquer votre session MATLAB.

Au moins dans MATLAB 2013a, vous pouvez utiliser getfield comme:

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

pour obtenir l’élément à (1,2)

Malheureusement, la syntaxe comme magic(5)(3,3) n’est pas prise en charge par matlab. vous devez utiliser des variables intermédiaires temporaires. vous pouvez libérer la mémoire après utilisation, par exemple

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

Notez que si vous comparez les temps d’exécution avec la méthode standard (affectez le résultat puis accédez aux entrées), ils sont exactement les mêmes.

 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 

À mon avis, l’essentiel est le suivant: MATLAB n’a pas de pointeurs, vous devez vivre avec.

Cela pourrait être plus simple si vous créez une nouvelle fonction:

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

et ensuite l’utiliser:

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

Votre notation initiale est la manière la plus concise de le faire:

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

Si vous faites cela en boucle, vous pouvez simplement réaffecter M à chaque fois et ignorer également la déclaration claire.

Pour compléter la réponse d’Amro, vous pouvez utiliser feval au lieu de builtin . Il n’y a pas de différence, vraiment, à moins d’essayer de surcharger la fonction opérateur:

BUILTIN (…) est identique à FEVAL (…) sauf qu’il appellera la version intégrée originale de la fonction même si une version surchargée existe (pour que cela fonctionne, vous ne devez jamais surcharger BUILTIN).

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

Ce qui est intéressant, c’est que feval semble être juste un petit peu plus rapide que le builtin (de ~ 3,5%), du moins dans Matlab 2013b, ce qui est étrange étant donné que feval doit vérifier si la fonction est surchargée.

 >> 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.