¿Cómo puedo indexar una matriz MATLAB devuelta por una función sin asignarla primero a una variable local?
Por ejemplo, si quiero leer el valor medio de magic(5)
, puedo hacerlo como esto:
M = magic(5);
value = M(3,3);
Para obtener value == 13
. Me gustaría poder hacer algo como uno de estos:
value = magic(5)(3,3);
value = (magic(5))(3,3);
Para prescindir de la variable intermedia. Sin embargo, MATLAB se queja de Unbalanced or unexpected parenthesis or bracket
en el primer paréntesis antes de 3
.
¿Es posible leer valores de un array/matriz sin asignarlo primero a una variable?
9 answers
En realidad es posible hacer lo que quieras, pero tienes que usar la forma funcional del operador de indexación. Cuando realiza una operación de indexación utilizando ()
, en realidad está haciendo una llamada a la subsref
función. Entonces, aunque no puedes hacer esto:
value = magic(5)(3, 3);
Usted puede hacer esto:
value = subsref(magic(5), struct('type', '()', 'subs', {{3, 3}}));
Feo, pero posible. ;)
En general, solo tiene que cambiar el paso de indexación a una llamada a función para que no tenga dos conjuntos de paréntesis inmediatamente después uno del otro. Otra forma de hacer esto sería definir su propia función anónima para hacer la indexación subíndice. Por ejemplo:
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
Sin embargo, cuando todo está dicho y hecho, la solución temporal de la variable local es mucho más legible, y definitivamente lo que sugeriría.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-04 18:46:47
Solo hubo una buena entrada en el blog en Loren sobre el arte de Matlab hace un par de días con un par de gemas que podrían ayudar. En particular, usando funciones auxiliares como:
paren = @(x, varargin) x(varargin{:});
curly = @(x, varargin) x{varargin{:}};
Donde paren()
se puede usar como
paren(magic(5), 3, 3);
Volvería
ans = 16
También conjeturo que esto será más rápido que la respuesta de gnovice, pero no lo he comprobado (¡Usa el perfilador!!!). Dicho esto, también tienes que incluir estas definiciones de función en alguna parte. Yo personalmente he hecho las funciones independientes en mi camino, porque son súper útiles.
Estas funciones y otras están ahora disponibles en el complemento Functional Programming Constructs que está disponible a través del Explorador de complementos de MATLAB o en el Intercambio de archivos .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-22 11:44:41
¿Cómo te sientes sobre el uso de características no documentadas:
>> builtin('_paren', magic(5), 3, 3) %# M(3,3)
ans =
13
O para matrices de celdas:
>> builtin('_brace', num2cell(magic(5)), 3, 3) %# C{3,3}
ans =
13
Al igual que la magia :)
ACTUALIZACIÓN:
Malas noticias, el hack anterior ya no funciona en R2015b! Eso está bien, era una funcionalidad indocumentada y no podemos confiar en ella como una característica compatible:)
Para aquellos que se preguntan dónde encontrar este tipo de cosas, busque en la carpeta fullfile(matlabroot,'bin','registry')
. Hay un montón de archivos XML que enumeran todo tipo de golosinas. Ser advirtió que llamar a algunas de estas funciones directamente puede bloquear fácilmente su sesión de MATLAB.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-31 07:54:47
Al menos en MATLAB 2013a se puede utilizar getfield
me gusta:
a=rand(5);
getfield(a,{1,2}) % etc
Para obtener el elemento en (1,2)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-30 20:25:46
Desafortunadamente una sintaxis como magic(5)(3,3)
no es compatible con matlab. es necesario utilizar variables intermedias temporales. puede liberar la memoria después de su uso, por ejemplo,
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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-02 12:46:10
Tenga en cuenta que si compara los tiempos de ejecución con la forma estándar (asigna el resultado y luego accede a las entradas), son exactamente los mismos.
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
En mi opinión, la conclusión es : MATLAB no tiene punteros, tienes que vivir con ello.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-04 18:31:09
Podría ser más simple si haces una nueva función:
function [ element ] = getElem( matrix, index1, index2 )
element = matrix(index1, index2);
end
Y luego usarlo:
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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-01 16:58:07
Su notación inicial es la forma más concisa de hacer esto:
M = magic(5); %create
value = M(3,3); % extract useful data
clear M; %free memory
Si está haciendo esto en un bucle, puede reasignar M cada vez e ignorar la declaración clara también.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-20 18:16:36
Para complementar la respuesta de Amro, puedes usar feval
en lugar de builtin
. No hay diferencia, realmente, a menos que intente sobrecargar la función del operador:
BUILTIN(...) es lo mismo que FEVAL(...) excepto que llamará a la versión original incorporada de la función incluso si está sobrecargada existe (para que esto funcione, nunca debes sobrecargar BUILTIN).
>> feval('_paren', magic(5), 3, 3) % M(3,3)
ans =
13
>> feval('_brace', num2cell(magic(5)), 3, 3) % C{3,3}
ans =
13
Lo interesante es que feval
parece ser un poco más rápido que builtin
(en ~3.5%), en menos en Matlab 2013b, que es raro dado que feval
necesita verificar si la función está sobrecargada, a diferencia de 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-12 20:54:00