6

Se si dispone di un array (di lunghezza sconosciuta fino al runtime), esiste un modo per chiamare una funzione con ciascun elemento dell'array come parametro separato?Esiste un operatore splat (o equivalente) in Matlab?

Come così:

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

Contesto: Ho una lista di indici ad una matrice -d n, Q. Quello che voglio è qualcosa come Q(a,b,:), ma ho solo [a,b]. Dal momento che non conosco n, non posso semplicemente codificare l'indicizzazione.

risposta

7

Nessun operatore in MATLAB lo farà. Tuttavia, se i vostri indici (cioè bar nel tuo esempio) sono state conservate in un cell array, allora si potrebbe fare questo:

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

Il {:} crea un comma-separated list da un array di celle. Questa è probabilmente la cosa più vicina che puoi ottenere dal modulo "operatore" che hai nell'esempio, oltre a sostituire uno dei modelli existing operators (illustrato here e here) in modo da generare un elenco separato da virgole da un array standard o creare il tuo classe per memorizzare i tuoi indici e definire come operano gli operatori esistenti (nessuna opzione per i deboli di cuore!).

Per esempio specifico di indicizzazione di un array ND arbitraria, si potrebbe anche calcolare un indice lineare ai tuoi indici con indice utilizzando la funzione sub2ind (come dettagliato here e here), ma si potrebbe finire per fare più lavoro di quanto si farebbe per la mia lista di soluzioni separate da virgola sopra. Un'altra alternativa è compute the linear index yourself, che aggirerebbe lo converting to a cell array e utilizzerà solo le operazioni matrice/vettoriale. Ecco un esempio:

% 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)