6

Si tengo una matriz (de longitud desconocida hasta el tiempo de ejecución), ¿hay alguna manera de llamar a una función con cada elemento de la matriz como un parámetro separado?¿Hay un operador de splat (o equivalente) en Matlab?

así:

foo = @(varargin) sum(cell2mat(varargin)); 
bar = [3,4,5]; 
foo(*bar) == foo(3,4,5) 

Contexto: Tengo una lista de índices a una serie n -d, Q. Lo que quiero es algo como Q(a,b,:), pero solo tengo [a,b]. Dado que no sé n, no puedo simplemente codificar la indexación.

Respuesta

7

No hay operador en MATLAB que haga eso. Sin embargo, si sus índices (es decir, bar en su ejemplo) se almacenaron en un cell array, entonces se podría hacer esto:

bar = {3,4,5}; %# Cell array instead of standard array 
foo(bar{:});  %# Pass the contents of each cell as a separate argument 

El {:} crea una comma-separated list de una serie de células. Probablemente sea lo más cercano que pueda tener al formulario de "operador" que tiene en su ejemplo, además de anular uno de los existing operators (ilustrados here y here) para que genere una lista separada por comas de una matriz estándar o cree su propia clase para almacenar sus índices y definir cómo operan los operadores existentes para él (¡ninguna opción para los débiles de corazón!).

Para su ejemplo específico de la indexación de una serie ND arbitraria, también se puede calcular un índice lineal de sus índices subindicadas utilizando la función sub2ind (como se detalla here y here), pero que podría terminar haciendo más trabajo de lo que lo haría para mi lista de soluciones separadas por comas arriba. Otra alternativa es compute the linear index yourself, que dejaría de lado converting to a cell array y usará solo operaciones de matriz/vector. Aquí hay un ejemplo:

% Precompute these somewhere: 
scale = cumprod(size(Q)).'; %' 
scale = [1; scale(1:end-1)]; 
shift = [0 ones(1, ndims(Q)-1)]; 

% Then compute a linear index like this: 
indices = [3 4 5]; 
linearIndex = (indices-shift)*scale; 
Q(linearIndex) % Equivalent to Q(3,4,5) 
Cuestiones relacionadas