Comment puis-je appliquer une fonction à chaque ligne/colonne d'une matrice dans MATLAB?
Vous pouvez appliquer une fonction à chaque élément d'un vecteur en disant, par exemple, v + 1
, ou vous pouvez utiliser la fonction arrayfun
. Comment puis-je faire pour chaque ligne/colonne d'une matrice sans l'aide d'une boucle for?
Vous devez vous connecter pour publier un commentaire.
De nombreuses fonctions dans des opérations comme
somme
etprod
sont déjà en mesure de fonctionner dans des lignes ou des colonnes, de sorte que vous pouvez être en mesure de revoir la fonction que vous postulez pour profiter de cette.Si ce n'est pas une option viable, une façon de le faire est de recueillir des lignes ou des colonnes dans des cellules à l'aide de
mat2cell
ounum2cell
, puis utilisezcellfun
pour fonctionner sur la cellule de tableau.Comme un exemple, disons que vous souhaitez additionner les colonnes d'une matrice
M
. Vous pouvez le faire simplement à l'aide desomme
:Et voici comment vous pourriez le faire en utilisant le plus compliqué
num2cell
/cellfun
option:true = false
déclaration est valable, je suis sûr qu'il ya une façon pour vous de le faire (:cellfun
etnum2cell
?sum(M, 1)
. Les débutants peuvent pensersum
peut être utilisé de cette façon pour arbitraire de la taille des matrices et puis obtenez perplexe lorsque la matrice d'une journée est1-by-n
.for
semble légèrement plus rapide (j'ai cellfun calendrier: 0.223 +/- 0.014; et sur le timing: 0.157 +/- 0.005); pour les réf., l'obscur one-liner utilisé pour le test:n = 1e5; m = rand(n, 10); func = @sum; rep = 32; for k=rep:-1:1, tic; x = cellfun(func, num2cell(m,2)); et(k) = toc; end; fprintf("cellfun timing: %.3f +/- %.3f\n", mean(et), std(et)); for k=rep:-1:1, tic; x = nan(1,n); for i=1:n, x(i) = func(m(i,:)); end; et(k) = toc; end; fprintf(" for timing: %.3f +/- %.3f\n", mean(et), std(et))
Vous souhaitez peut-être le plus obscur de la fonction Matlab bsxfun. À partir de la documentation Matlab, bsxfun "s'applique à l'élément par élément binaire de l'opération spécifiée par la fonction gérer plaisir aux tableaux A et B, avec singleton extension activée."
@gnovice indiqué ci-dessus le montant de cette somme et d'autres fonctions de base sont déjà en fonctionnement sur le premier non-singleton dimension (c'est à dire, les lignes s'il y a plus de lignes, de colonnes si il n'y a qu'une seule ligne, ou les dimensions supérieures, si la réduction des dimensions de taille==1). Cependant, bsxfun fonctionne pour toutes les fonctions, y compris (et surtout) des fonctions définies par l'utilisateur.
Par exemple, disons que vous avez une matrice A et un vecteur ligne B. E. g., disons:
Vous voulez une fonction power_by_col qui rentre dans un vecteur C de tous les éléments de la puissance de la colonne correspondante de B.
À partir de l'exemple ci-dessus, C est une matrice de 3x3:
c'est à dire,
Vous pourrait faire la force brute chemin à l'aide repmat:
Ou vous pourriez faire le chic de façon à l'aide de bsxfun, qui prend soin de la repmat étape:
Donc bsxfun vous permet d'économiser quelques pas (vous n'avez pas besoin de calculer explicitement les dimensions d'Une). Toutefois, dans certains tests informels de la mine, il s'avère que repmat est environ deux fois plus rapide si la fonction à appliquer (comme ma fonction puissance, ci-dessus) est simple. Donc vous aurez besoin de décider si vous voulez la simplicité ou de la vitesse.
Je ne peux pas commenter sur la façon efficace c'est, mais voici une solution:
Bâtiment sur Alex réponse, ici, c'est plus de la fonction générique:
Ici est une comparaison entre les deux fonctions:
Pour l'exhaustivité ou l'intérêt, je tiens à ajouter que matlab ne disposent d'une fonction qui vous permet d'opérer sur des données par ligne plutôt que par élément. Il est appelé
rowfun
(http://www.mathworks.se/help/matlab/ref/rowfun.html), mais le seul "problème" est qu'il fonctionne sur tables (http://www.mathworks.se/help/matlab/ref/table.html) plutôt que de matrices.Ajoutant à l'évolution de la nature de la réponse à cette question, en commençant par r2016b, MATLAB sera implicitement développez singleton dimensions, en supprimant la nécessité pour
bsxfun
dans de nombreux cas.De la r2016b notes de version:
Avec les récentes versions de Matlab, vous pouvez utiliser le Tableau de la structure de données à votre avantage. Il y a même un "rowfun' opération, mais je l'ai trouvé plus facile de faire ceci:
ou voici un vieux que j'ai eu qui ne nécessite pas de tables, pour les anciennes versions de Matlab.
Aucune des réponses ci-dessus, travaillé "out of the box" pour moi, cependant, la fonction suivante, obtenue par copier les idées des autres réponses œuvres:
Elle prend une fonction
f
et l'applique à chaque colonne de la matriceM
.Ainsi, par exemple:
Accepté la réponse semble être de convertir de cellules de premier et ensuite utiliser
cellfun
de fonctionner sur toutes les cellules. Je ne sais pas le spécifique de l'application, mais en général, je pense que l'utilisation d'bsxfun
de fonctionner au cours de la matrice serait plus efficace. Fondamentalementbsxfun
s'applique à une opération de l'élément par élément sur deux tableaux. Donc si vous voulez multiplier chaque élément dans unn x 1
vecteur par chaque élément dans unm x 1
vecteur pour obtenir unn x m
tableau, vous pouvez utiliser:Cela vous donnera la matrice appelée
result
dans lequel le (i, j) d'entrée sera le ième élément devec1
multiplié par la j-ème élément devec2
.Vous pouvez utiliser
bsxfun
pour toutes sortes de fonctions intégrées, et vous pouvez déclarer votre propre. La documentation a une liste de nombreuses fonctions intégrées, mais, fondamentalement, vous pouvez nommer une fonction qui accepte les deux tableaux (vecteur ou d'une matrice) comme arguments, et de le faire fonctionner.Suis tombé sur cette question/réponse, tout en cherchant comment faire pour calculer la ligne de sommes d'une matrice.
Je voudrais juste ajouter que Matlab la fonction SOMME effectivement en charge de sommation pour une dimension donnée, j'.e une norme de matrice à deux dimensions.
Donc, pour calculer la colonne sommes ne:
et pour la ligne des sommes, tout simplement
Mon pari est que c'est plus rapide que la programmation d'une boucle for et la conversion de cellules 🙂
Tout cela peut être trouvé dans le matlab de l'aide pour la SOMME.
si vous connaissez la longueur de vos lignes, vous pouvez faire quelque chose comme ceci: