Ajout d'un vecteur à une matrice MATLAB vide
J'ai le code MATLAB de l'insertion de n-dimensionnelle de points (n >1) dans une matrice (myPointMatrix
) et je suis d'avoir des pensées sur la façon d'insérer le premier point.
Maintenant le programme vérifie la taille de myPointMatrix
avant d'insérer un point. Si c'est 1x1, myPointMatrix
est égal au point actuel. Sinon, le point courant est ajouté. Cette if
-énoncé n'est vrai qu'une fois, mais est évalué à chaque fois que j'insère un point, ce qui est très très souvent.
Retrait de la if
et en essayant de les ajouter à myPointMatrix
fait MATLAB naturellement se plaindre de la matrice de dimensions n'étant pas conformes. Retrait de la if
-déclaration et de la inialization de myPointMatrix = 0
causes MATLAB pour trouver myPointMatrix
pas défini. Aussi compréhensible.
Comment initialiser myPointMatrix
afin que je puisse retirer le if
-déclaration? Ou est-il une autre solution intelligente?
myPointMatrix = 0;
for x=0:limit
for y=0:limit
for z=0:limit
tempPoint = [x y z];
if (length(myPointMatrix) == 1)
myPointMatrix = tempPoint;
else
myPointMatrix = [myPointMatrix; tempPoint];
end
end
end
end
source d'informationauteur AnnaR
Vous devez vous connecter pour publier un commentaire.
Il existe plusieurs façons d'ajouter une matrice ou d'un vecteur quelconque de la matrice, vide ou pas. Cela dépend beaucoup de la taille de la matrice, et à quelle fréquence vous allez faire de l'ajouter. (Notez que les matrices creuses sont un tout autre animal. Ils ont besoin d'être traiter séparément.)
Le système simple consisterait à utiliser la concaténation. Par exemple, je vais créer un ensemble aléatoire. Même si je sais qu'un appel à rand serait la bonne solution ici, je le fais uniquement pour des fins de comparaison.
Voir que le temps nécessaire est assez grande, bien plus que j'avais juste appelé rand directement.
D'autres façons d'ajouter sont similaires dans le temps. Par exemple, vous pouvez ajouter par l'indexation de trop.
Ce sera similaire en termes de temps à ajouter par concaténation. Un fait intéressant est de comprendre que l'ajout de nouvelles lignes à un tableau est subtilement différent que d'ajouter de nouvelles colonnes. Elle prend un peu plus de temps pour ajouter une ligne qu'une colonne. C'est à cause de la façon dont les éléments sont stockés dans MATLAB. Ajout d'une nouvelle ligne désigne les éléments doivent être mélangées dans la mémoire.
Le problème avec toute opération d'ajout à tous, c'est que MATLAB doit réaffecter la mémoire nécessaire pour Un, et de le faire à CHAQUE fois la matrice augmente en taille. Étant donné que la taille d'Un croît linéairement, le temps nécessaire augmente quadratiquement avec n. Donc si on double la taille de n, l'dynamiquement grandi prend quatre fois plus de temps pour construire. Ce comportement quadratique est pourquoi les gens vous disent de pré-allouer vos MATLAB tableaux quand ils seront cultivés de façon dynamique. En fait, si vous regardez la mlint drapeaux dans l'éditeur de MATLAB vous avertit lorsqu'il voit ce qui se passe.
Une meilleure solution, si vous savez la taille finale de l'Un, est à pré-allouer Un à sa taille finale. Ensuite, juste à l'index.
Alors que c'est beaucoup mieux que l'dynamiquement cultivé tableau, il est encore bien pire qu'un vectorisé utilisation de rand. Donc, dans la mesure du possible, utilisez le vectorisé forme de fonctions de ce genre.
Le problème est que, parfois, tu ne sais tout simplement pas comment de nombreux éléments, vous allez vous retrouver avec. Il y a encore plusieurs astuces que l'on peut utiliser pour éviter le méchant de croissance quadratiques.
Une astuce consiste à faire deviner la taille finale de A. Maintenant, l'utilisation de l'indexation pour insérer de nouvelles valeurs dans Un, mais regardez attentivement pour quand les nouvelles entrées de déversement sur les limites de A. Lorsque cela est sur le point de se produire, le DOUBLE de la taille d'Une, l'ajout d'un gros bloc de zéros à la fin. Maintenant de retour à l'indexation de nouveaux éléments dans A. Garder un décompte de la façon dont de nombreux éléments ont été "ajouté". À la fin de ce processus, supprimer les éléments non utilisés. Cela évite beaucoup de cochonne quadratique comportement, depuis seulement quelques ajouter des étapes sera jamais fait. (Rappelez-vous, vous êtes doublement de la taille d'Une lorsque vous devez faire un append.)
Une deuxième astuce est d'utiliser des pointeurs. Alors que MATLAB n'a pas vraiment d'offre beaucoup de possibilités dans la façon de pointeurs, une cellule de tableau est un pas dans cette direction.
Cela a pris moins de temps à faire que de l'adulte tableau. Pourquoi? Nous étions seulement à la construction d'un tableau de pointeurs vers les cellules. Une bonne chose à propos de ceci est que si chaque ajout étape comporte un nombre variable de lignes, il fonctionne encore très bien.
Un problème avec le tableau de cellule, il n'est pas très efficace quand il y a des MILLIONS d'éléments à ajouter. C'est encore une équation du second degré de l'opération après tout, parce que nous sommes de plus le tableau de pointeurs à chaque étape.
Une solution à ce problème est d'utiliser un amalgame des deux styles indiqué ci-dessus. Ainsi, chaque cellule de la matrice de cellules de modérément de grande taille. Maintenant, l'utilisation de l'indexation de choses nouvelles lignes de Un dans la cellule. Lorsque la cellule doit être augmenté par le prochain ajout de l'étape, il suffit d'ajouter une nouvelle cellule à la cellule de tableau.
Il y a quelques années, ce débat a eu lieu sur le MATLAB groupe de discussion, et plusieurs solutions le long de ces lignes ont été proposées. J'ai posté les solutions growdata & growdata2 en tant que fichiers sur le MATLAB Central d'Échange de Fichiers. Growdata2 utilisé la fonction poignées pour résoudre le problème:
À l'époque, c'était un peu plus rapide approche de l'utilisation persistante des variables.
Depuis la mise en œuvre de la fonction de poignées s'est nettement améliorée dans MATLAB, de sorte que la fonction de poignée est maintenant plus rapide.
Une vertu de ces régimes, ils ne seront pas avoir un quadratiques sur les performances, tout en permettant à des millions d'ajouter des étapes.
Oh, eh bien, c'est sûrement le plus d'informations que ce qui avait été demandé, lorsque la question a été posée. Peut-être que quelqu'un va obtenir quelque chose hors de lui.
Utilisation
myPointMatrix = [];
pour initialiser la matrice.Le plus grand
myPointMatrix
est, le plus lent, ajoutant sera. Il devient plus lent et plus lent, car à chaque fois que vous ajoutez un point de matlab alloue une nouvelle matrice de la nouvelle taille et copie les informations de votre ancien matrice + votre nouveau point dans la nouvelle matrice.Il est alors préférable d'initialiser
MyPointMatrix
avec sa taille finale, et en insérant des points de donnée positions dans la matrice.Votre meilleure option est de pré-alocate la matrice et l'utilisation d'une variable de boucle. Cela devrait être nettement plus rapide.
Je crois que la solution que vous cherchez est d'initialiser le myPointMatrix à une matrice de 0 lignes et 3 colonnes, c'est à dire
Puis à la première affectation
fonctionne correctement, ainsi que les suivants. De manière équivalente à écrire l'affectation est
Cependant, gardez à l'esprit que la croissance d'une matrice qui n'est pas efficace et, comme AnnaR dit, l'initialisation de
myPointMatrix
avec les fi taille finale, si elle est connue, est une meilleure solution.C'est ce que vous avez besoin
mais seulement dans le cas où vous faites une opération non linéaire avec [ x y z ], avant de vous l'attribuer. Si non, alors vous pouvez écrire les lignes ci-dessus comme suit:
Le dessus est entièrement vectorisée, bien que l'on pourrait vouloir
edit kron.m
et de remplacer certainesfind
aveclogical
... mais vous pouvez le faire vous-même, je suppose... 😀