Par exemple, si je veux lire la valeur médiane de magic(5)
, je peux le faire comme ceci:
M = magic(5);
value = M(3,3);
pour obtenir value == 13
. J'aimerais pouvoir faire quelque chose comme l'un de ceux-ci:
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
dans la première parenthèse avant le 3
.
Est-il possible de lire les valeurs d'un tableau/matrice sans d'abord l'assigner à une variable?
En fait il est 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 appelez en fait la fonction subsref
. Donc, même si vous ne pouvez pas faire ceci:
value = magic(5)(3, 3);
Vous pouvez faire ceci:
value = subsref(magic(5), struct('type', '()', 'subs', {{3, 3}}));
Moche, mais possible. ;)
En général, il vous suffit de changer l'étape d'indexation en appel de fonction pour éviter que deux jeux de parenthèses ne se suivent immédiatement. Une autre façon de faire serait de définir votre propre fonction anonyme pour faire 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 matrix
Cependant, quand tout est dit et fait, la solution de variable locale temporaire est beaucoup plus lisible, et certainement ce que je suggérerais.
Il y avait juste bon article de blog sur Loren sur l'art de Matlab il y a quelques jours avec quelques gemmes qui pourraient aider. En particulier, en utilisant des fonctions d'assistance telles que:
paren = @(x, varargin) x(varargin{:});
curly = @(x, varargin) x{varargin{:}};
où paren()
peut être utilisé comme
paren(magic(5), 3, 3);
retournerais
ans = 16
Je suppose également que cela 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 fonction quelque part. Personnellement, j’en ai fait des fonctions indépendantes sur mon parcours, car elles sont super utiles.
Ces fonctions et d’autres sont maintenant disponibles dans l’add-on , construction fonctionnelle disponible dans l’Explorateur de compléments MATLAB ou dans la console Échange de fichiers .
Que pensez-vous de l'utilisation de fonctionnalités non documentées:
>> builtin('_paren', magic(5), 3, 3) %# M(3,3)
ans =
13
ou pour les matrices de cellules:
>> builtin('_brace', num2cell(magic(5)), 3, 3) %# C{3,3}
ans =
13
Comme par magie :)
Mauvaise nouvelle, le hack ci-dessus ne fonctionne plus dans R2015b! C'est bien, il s'agissait de fonctionnalités non documentées et nous ne pouvons pas nous en prévaloir en tant que fonctionnalité prise en charge :)
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épertorie toutes sortes de goodies. Soyez averti que l'appel direct de 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 en (1,2)
malheureusement, la syntaxe comme magic(5)(3,3)
n'est pas supportée 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 à la méthode standard (attribuez 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: MATLAB n'a pas de pointeur, vous devez vivre avec.
Cela pourrait être plus simple si vous créez une nouvelle fonction:
function [ element ] = getElem( matrix, index1, index2 )
element = matrix(index1, index2);
end
et ensuite l'utiliser:
value = getElem(magic(5), 3, 3);
Votre notation initiale est la manière la plus concise de procéder:
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 l’instruction clear.
Pour compléter la réponse d'Amro, vous pouvez utiliser feval
au lieu de builtin
. En réalité, il n'y a pas de différence, sauf si vous essayez de surcharger la fonction opérateur:
BUILTIN (...) est identique à FEVAL (...) sauf qu'il appellera la version intégrée d'origine de la fonction même s'il en existe une surchargée (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 un peu plus rapide que builtin
(environ 3,5%), du moins dans Matlab 2013b, ce qui est étrange étant donné que feval
doit vérifier si la fonction est surchargée, contrairement à 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.