Comment remplacer "trouver" des commandes avec la " logique de l'indexation` (MATLAB), pour la recherche d'vecteur de valeur des positions de valeurs uniques?
Dans MATLAB, j'ai un for loop
qui a beaucoup d'interaction de passer et de remplir un sparse
de la matrice. Le programme est très lent et j'aimerais l'optimiser pour le voir terminer dans quelques temps. En deux lignes, j'utilise la commande find
, et l'éditeur de MATLAB, me prévient que l'utilisation de logical indexing
au lieu de find
permettra d'améliorer les performances. Mon code est assez similaire à celui présenté à la mathworks newreader, mathworks lecteur de news recommandation, où y est un vecteur de valeurs et d'un vecteur de valeur unique généré à partir d'elle. Utilise find
pour obtenir l'indice dans les valeurs uniques (pour mettre à jour les valeurs dans une matrice). Pour être bref, le code est:
positions = find(X0_outputs == unique_outputs(j,1));
% should read
positions = X0_outputs == unique_outputs(j,1);
Mais la dernière ligne n'est pas l'indice, mais un vecteur de zéros et de uns.
J'ai un exemple illustratif, faire une série d'indices; tt=round(rand(1,6)*10)
:
tt = 3 7 1 7 1 7
Faire un vecteur unique; ttUNI=unique(tt)
ttUNI = 1 3 7
Utiliser find pour obtenir la position de l'index de la valeur dans l'ensemble de valeurs uniques; find(ttUNI(:) == tt(1))
ans = 2
Comparer avec l'aide de logiques d'indexation; (ttUNI(:) == tt(1))
ans =
0
1
0
Ayant la valeur 2
est beaucoup plus utile que celui vecteur binaire quand j'ai besoin de mettre à jour les indices d'une matrice. Pour ma matrice, je peux dire mat(find(ttUNI(:) == tt(1)), 4)
et qui fonctionne. Tandis que l'utilisation de (ttUNI(:) == tt(1))
besoins de post-traitement.
Est-il soigné et efficace de faire ce qui est nécessaire? Ou est l'utilisation de find
inévitables dans de telles circonstances?
Mise à JOUR: je vais inclure le code ici, comme recommandé par l'utilisateur: @Jonas, pour donner de mieux comprendre le problème que je vais avoir et de faire rapport à certains de l'outil générateur de profils de résultats.
ALL_NODES = horzcat(network(:,1)',network(:,2)');
NUM_UNIQUE = unique(ALL_NODES);%unique and sorted
UNIQUE_LENGTH = length(NUM_UNIQUE);
TIME_MAX = max(network(:,3));
WEEK_NUM = floor((((TIME_MAX/60)/60)/24)/7);%divide seconds for minutes, for hours, for days and how many weeks
%initialize tensor of temporal networks
temp = length(NUM_UNIQUE);
%making the tensor a sparse 2D tensor!!! So each week is another replica of
%the matrix below
Atensor = sparse(length(NUM_UNIQUE)*WEEK_NUM,length(NUM_UNIQUE));
WEEK_SECONDS = 60*60*24*7;%number of seconds in a week
for ii=1:size(network,1)%go through all rows/observations
WEEK_NOW = floor(network(ii,3)/WEEK_SECONDS) + 1;
if(WEEK_NOW > WEEK_NUM)
disp('end of weeks')
break
end
data_node_i = network(ii,1);
Atensor_row_num = find(NUM_UNIQUE(:) == data_node_i)...
+ (WEEK_NOW-1)*UNIQUE_LENGTH;
data_node_j = network(ii,2);
Atensor_col_num = find(NUM_UNIQUE(:) == data_node_j);
%Atensor is sparse
Atensor(Atensor_row_num,Atensor_col_num) = 1;
end
Ici UNIQUE_LENGTH = 223482
et size(network,1)=273209
. Je rand la profiler tool
pendant quelques minutes, ce qui n'était pas assez de temps nécessaire pour que le programme termine, mais d'atteindre un état d'équilibre lorsque le ratio de fois ne serait pas trop changer. Atensor_row_num = find(NUM_UNI..
est de 45,6% et Atensor_col_num = find(NUM_UNI...
est de 43,4%. La ligne avec Atensor(Atensor_row_num,Atenso...
qui attribue des valeurs à la sparse
de la matrice, n'est de 8,9%. La longueur de la NUM_UNIQUE
vecteur est assez grand, donc find
est un aspect important du code, et, encore plus important que la matrice creuse de manipulation. Toute amélioration doit être important. Je ne sais pas si il est plus efficace en progression logique pour cet algorithme de procéder ainsi plutôt que de prendre l'approche simple de remplacer find
.
- Je voulais juste ajouter que, autant que je peux dire, ce message d'avertissement est plus ou moins déclenché par chaque appel à trouver. J'ai récemment rencontré une situation où l'logiquement la version indexée a été nettement plus lente que celle où j'ai appelé find(). Si c'est dans une situation critique, j'essayerais de deux manières.
Vous devez vous connecter pour publier un commentaire.
find
est en effet inévitable dans certaines circonstances. Par exemple, si vous souhaitez faire une boucle sur les indices, c'est à direou si vous voulez faire du multi-niveau de l'indexation
ou si vous souhaitez que le premier n de bonnes valeurs
Dans votre cas, vous pourriez être en mesure d'éviter l'appel à
find
en utilisant les sorties supplémentaires deunique
Avant de vous essayez d'optimiser votre code par la fixation de ce que vous pensez prend du temps, je vous suggère d'exécuter le générateur de profils sur votre code pour vérifier ce qui prend vraiment du temps. Et puis vous pouvez éventuellement poster le code de votre boucle, pourrait être en mesure de vous aider.
Si vous souhaitez trouver l'indice de la valeur réelle dans une logique de vecteur, vous pouvez effectuer les opérations suivantes: