2015-10-24 1 views
1

I ont une matrice de taille FD-by-N et un vecteur de longueur AN d'entiers aléatoires dans la plage [1,a]. Je veux créer une matrice M de taille D * a telle que chaque colonne M(:,i) a le vecteur F(:,i) à partir de l'index (A(i)-1)*D+1 à (A(i)-1)*D+D.Loopless affectation de sous-matrice dans Matlab

Exemple:

F = [1 2 3 10 
    4 5 6 22] 

A = [3 2 1 2] 

a = 4 

M = [0 0 3 0 
    0 0 6 0 
    0 2 0 10 
    0 5 0 22 
    1 0 0 0 
    4 0 0 0 
    0 0 0 0 
    0 0 0 0] 

je peux le faire avec une simple boucle

 for i = 1 : N 
      M((A(i)-1)*D+1:(A(i)-1)*D+D,i) = F(:,i); 
     end 

mais pour les grandes N cela pourrait prendre un certain temps. Je cherche un moyen de le faire sans boucle.

+0

Je dirais que cela est assez rapide. Avez-vous même chronométré pour de grandes valeurs de 'a/N' à vérifier pour voir si votre déclaration est correcte? – rayryeng

+0

Eh bien, ce n'est pas vraiment lent, mais je voudrais quelque chose de plus rapide si possible, car cette partie de mon code est exécutée à chaque itération de mon algorithme principal. Sur mon ordinateur, il faut '3s' quand' a = 3', 'D = 6' et' N = 1e6'. – Simon

+0

Comment 'a' peut-il être' 4' si 'A = [3 2 1 2]'? 'A' a des éléments de' 1' '' 3'. – Divakar

Répondre

2

Vous pouvez utiliser bsxfun pour une approche basée sur linear-indexing -

[D,N] = size(F); %// Get size of F 

start_idx = (A-1)*D+1 + [0:N-1]*D*a;   %// column start linear indices 
all_idx = bsxfun(@plus,start_idx,[0:D-1]'); %//'# all linear indices 

out = zeros(D*a,N); %// Initialize output array with zeros 
out(all_idx) = F; %// Insert values from F into output array 

run échantillon -

F = 
    1  2  3 10 
    4  5  6 22 
A = 
    3  2  1  2 
a = 
    4 
out = 
    0  0  3  0 
    0  0  6  0 
    0  2  0 10 
    0  5  0 22 
    1  0  0  0 
    4  0  0  0 
    0  0  0  0 
    0  0  0  0 
+0

Merci, votre code est vraiment rapide (10 fois plus rapide que ma boucle). Cependant, cela donne des résultats incorrects si, par exemple, tous les éléments de 'A' sont des uns. Je teste en utilisant 'D = 2; N = 1e2; a = 4; F = rand (D, N); A = uns (1, N); ' – Simon

+0

@Simon Oh, je suppose que' A' serait '1: N', mon mauvais! Pourriez-vous ajouter un exemple avec quelque chose d'aussi simple que '[1,2,3]' dans la question en tant qu'échantillon? – Divakar

+0

Vous avez raison, l'exemple dans la question était trop trivial et n'a pas précisé que 'A' contient un entier aléatoire dans la plage' [1, a] '. J'ai édité ma question. – Simon