Quel Est votre truc préféré de programmation MATLAB/Octave? [fermé]

je pense que tout le monde serait d'accord pour dire que le langage MATLAB n'est pas joli, ni particulièrement cohérent. Mais passons! Nous devons encore l'utiliser pour faire avancer les choses.

Quels sont vos trucs préférés pour rendre les choses plus faciles? Une par réponse pour que les gens votent s'ils sont d'accord. Aussi, essayez d'illustrer votre réponse par un exemple.

73
demandé sur Matt 2008-09-25 12:19:30

30 réponses

utilisant le profileur intégré pour voir où sont les parties chaudes de mon code:

profile on
% some lines of code
profile off
profile viewer

ou tout simplement en utilisant le construit dans tic et toc pour obtenir des minuteries rapides:

tic;
% some lines of code
toc;
39
répondu Jason Sundram 2008-10-14 19:12:23

extraction directe des éléments d'une matrice satisfaisant à une condition particulière, à l'aide de tableaux logiques:

x = rand(1,50) .* 100;
xpart = x( x > 20 & x < 35);

maintenant xpart contient seulement les éléments de x qui se trouvent dans la gamme spécifiée.

31
répondu sundar 2008-10-10 17:05:44

fournit un accès rapide à d'autres documents de fonction en ajoutant une ligne" Voir aussi " aux commentaires d'aide. Tout d'abord, vous devez inclure le nom de la fonction dans tous les bouchons comme la première ligne de commentaire. Faites vos trucs habituels d'en-tête de commentaire, puis mettez voir aussi avec une liste séparée par des virgules d'autres fonctions liées.

function y = transmog(x)
%TRANSMOG Transmogrifies a matrix X using reverse orthogonal eigenvectors
%
% Usage:
%   y = transmog(x)
%
% SEE ALSO
% UNTRANSMOG, TRANSMOG2

lorsque vous tapez "help transmog" à la ligne de commande, vous verrez tous les commentaires dans cet en-tête de commentaire, avec des hyperliens vers le commentaire les en-têtes pour les autres fonctions énumérées.

28
répondu Scottie T 2008-09-25 12:03:11

transformer une matrice en vecteur à l'aide d'un seul côlon.

x = rand(4,4);
x(:)
23
répondu Scottie T 2008-09-25 11:57:23

de la Vectorisation de boucles . Il y a beaucoup de façons de le faire, et c'est amusant de chercher des boucles dans votre code et de voir comment elles peuvent être vectorisées. La performance est étonnamment plus rapide avec les opérations vectorielles!

22
répondu Jason Sundram 2008-10-14 19:20:28

fonctions Anonymes, pour quelques raisons:

  1. pour faire une fonction rapide pour des utilisations ponctuelles, comme 3x^2+2x+7. (voir liste ci-dessous) Ceci est utile pour les fonctions comme quad et fminbnd qui prennent des fonctions comme arguments. C'est aussi pratique dans les scripts (.m fichiers qui ne commencent pas par un en-tête de fonction) car contrairement aux fonctions true, vous ne pouvez pas inclure de sous-fonctions.
  2. pour fermetures -- bien que les fonctions anonymes sont un peu limite car il ne semble pas être une voie d'assignation à muter de l'état.

.

% quick functions
f = @(x) 3*x.^2 + 2*x + 7;
t = (0:0.001:1);
plot(t,f(t),t,f(2*t),t,f(3*t));

% closures (linfunc below is a function that returns a function,
% and the outer functions arguments are held for the lifetime
% of the returned function.
linfunc = @(m,b) @(x) m*x+b;
C2F = linfunc(9/5, 32);
F2C = linfunc(5/9, -32*5/9);
20
répondu Jason S 2013-02-07 16:04:11

Matlab's bsxfun , arrayfun , cellfun , et structfun sont assez intéressants et souvent sauver une boucle.

M = rand(1000, 1000);
v = rand(1000,    1);
c = bsxfun(@plus, M, v);

ce code, par exemple, ajoute colonne-vecteur v à chaque colonne de la matrice M.

cependant, dans les parties critiques de la performance de votre application, vous devriez comparer ces fonctions par rapport à la triviale pour-boucle parce que souvent les boucles sont encore plus rapides.

19
répondu ymihere 2009-04-08 13:14:36

LaTeX mode pour les formules dans les graphiques : Dans l'une des versions récentes (R2006?) vous ajoutez les arguments supplémentaires ,'Interpreter','latex' à la fin d'un appel de fonction et il utilisera le rendu LaTeX. Voici un exemple:

t=(0:0.001:1);
plot(t,sin(2*pi*[t ; t+0.25]));
xlabel('t'); 
ylabel('$\hat{y}_k=sin 2\pi (t+{k \over 4})$','Interpreter','latex');
legend({'$\hat{y}_0$','$\hat{y}_1$'},'Interpreter','latex');

vous ne savez Pas quand ils l'ont ajouté, mais il fonctionne avec R2006b dans le texte(), title(), xlabel(), ylabel(), zlabel(), et même légende (). Assurez-vous que la syntaxe que vous utilisez n'est pas ambigu (donc, avec la légende() vous devez spécifier les chaînes comme un tableau de cellules).

18
répondu Jason S 2013-02-07 16:12:26

utilisant xlim et ylim pour tracer des lignes verticales et horizontales. Exemples:

  1. tracez une ligne horizontale à y=10:

    line(xlim, [10 10])

  2. tracer la ligne verticale à x = 5:

    line([5 5], ylim)

17
répondu Samil 2011-05-10 20:53:53

voici un exemple rapide:

je trouve la syntaxe des listes séparées par des virgules très utile pour la construction des appels de fonction:

% Build a list of args, like so:
args = {'a', 1, 'b', 2};
% Then expand this into arguments:
output = func(args{:})
16
répondu Matt 2008-09-25 08:21:34

voici un tas de fonctions non évidentes qui sont utiles de temps en temps:

  • mfilename (renvoie le nom du script MATLAB en cours d'exécution)
  • dbstack (vous donne accès aux noms et aux numéros de ligne de la pile de fonctions matlab)
  • keyboard (arrête l'exécution et donne le contrôle à l'invite de débogage; c'est pourquoi il y a un K dans l'invite de débogage K>>
  • dbstop error (vous met automatiquement en mode débogage arrêté à la ligne qui déclenche une erreur)
11
répondu Jason S 2008-12-19 21:25:41

j'aime utiliser des poignées de fonction pour beaucoup de raisons. Pour un, ils sont la chose la plus proche que J'ai trouvé dans MATLAB à pointeurs, donc vous pouvez créer le comportement de référence-comme pour les objets. Il y a aussi des choses simples que vous pouvez faire avec eux. Par exemple, le remplacement d'un énoncé de commutateur:

switch number,
  case 1,
    outargs = fcn1(inargs);
  case 2,
    outargs = fcn2(inargs);
  ...
end
%
%can be turned into
%
fcnArray = {@fcn1, @fcn2, ...};
outargs = fcnArray{number}(inargs);

je pense juste que les petites choses comme ça sont cool.

10
répondu gnovice 2009-01-08 05:25:37

en utilisant nargin pour définir les valeurs par défaut pour les arguments optionnels et en utilisant nargout pour définir les arguments de sortie optionnels. Exemple rapide

function hLine=myplot(x,y,plotColor,markerType)
% set defaults for optional paramters
if nargin<4, markerType='none'; end
if nargin<3, plotColor='k'; end

hL = plot(x,y,'linetype','-', ...  
              'color',plotColor, ...
              'marker',markerType, ...
              'markerFaceColor',plotColor,'markerEdgeColor',plotColor);

% return handle of plot object if required
if nargout>0, hLine = hL; end
10
répondu Azim 2009-01-23 20:09:02

invoquant le code Java de Matlab

10
répondu Rorick 2012-05-29 22:10:48

cellfun et arrayfun automatisée pour les boucles.

5
répondu KennyMorton 2008-09-25 12:34:15

Oh, et à l'inverse d'une matrice

v = 1:10;
v_reverse = v(length(v):-1:1);
5
répondu R. Van Hoose 2008-10-14 19:14:29

arguments conditionnels dans le côté gauche d'une cession:

t = (0:0.005:10)';
x = sin(2*pi*t);
x(x>0.5 & t<5) = 0.5;
% This limits all values of x to a maximum of 0.5, where t<5
plot(t,x);
5
répondu Jason S 2008-12-19 22:14:20

Connaître propriétés de l'axe ! Il y a toutes sortes de choses que vous pouvez régler pour modifier les propriétés de pointage par défaut pour faire ce que vous voulez:

set(gca,'fontsize',8,'linestyleorder','-','linewidth',0.3,'xtick',1:2:9);

(par exemple, place la fontsize à 8pt, les linestyles de toutes les nouvelles lignes à tous être solide et leur largeur 0,3 pt, et les points xtick à être [1 3 5 7 9])

Ligne et figure propriétés sont également utiles, mais je trouve moi-même utilisant les propriétés axis le plus.

5
répondu Jason S 2009-01-23 19:04:43

soit strict en spécifiant les dimensions lors de l'utilisation des fonctions d'agrégation comme min, max, mean, diff, sum, any, all,...

par exemple la ligne:

reldiff = diff(a) ./ a(1:end-1)

pourrait bien fonctionner pour calculer les différences relatives des éléments dans un vecteur, mais dans le cas où le vecteur dégénère en un seul élément le calcul échoue:

>> a=rand(1,7);
>> diff(a) ./ a(1:end-1)

ans =
   -0.5822   -0.9935  224.2015    0.2708   -0.3328    0.0458

>> a=1;
>> diff(a) ./ a(1:end-1)
??? Error using ==> rdivide
Matrix dimensions must agree.

Si vous spécifiez les dimensions de vos fonctions, cette ligne renvoie un matrice vide 1-by-0, ce qui est correct:

>> diff(a, [], 2) ./ a(1, 1:end-1)

ans =

   Empty matrix: 1-by-0

>> 

il en va de même pour une min-fonction qui calcule habituellement des minimums sur des colonnes sur une matrice, jusqu'à ce que la matrice se compose d'une seule rangée. - Ensuite, il retournera le minimum Au-dessus de la rangée à moins que le paramètre dimension n'indique le contraire, et cassera probablement votre application.

je peux presque vous garantir que, par conséquent, le fait de définir les dimensions de ces fonctions d'agrégation vous sauvera un certain débogage de travail par la suite.

du moins, ça aurait été le cas pour moi. :)

5
répondu ymihere 2009-04-08 13:40:54

l'opérateur du côlon pour la manipulation des tableaux.

@ScottieT812, en mentionne un: aplatir un tableau, mais il y a toutes les autres variantes de sélection des bits d'un tableau:


x=rand(10,10);
flattened=x(:);
Acolumn=x(:,10);
Arow=x(10,:);

y=rand(100);
firstSix=y(1:6);
lastSix=y(end-5:end);
alternate=y(1:2:end);
5
répondu Ian Hopkinson 2009-12-23 21:41:34

pour pouvoir tester rapidement une fonction, j'utilise nargin comme suit:

function result = multiply(a, b)
if nargin == 0 %no inputs provided, run using defaults for a and b
    clc;
    disp('RUNNING IN TEST MODE')
    a = 1;
    b = 2;
end

result = a*b;

plus tard, j'ajoute un script de test unitaire pour tester la fonction pour différentes conditions d'entrée.

5
répondu Samil 2010-10-14 09:19:22

utilisant ismember() pour fusionner des données organisées par des identificateurs de texte. Utile lorsque vous analysez différentes périodes lorsque les entrées, dans mon cas, symboles de la société, aller et venir.

%Merge B into A based on Text identifiers
UniverseA = {'A','B','C','D'};
UniverseB = {'A','C','D'};

DataA = [20 40 60 80];
DataB = [30 50 70];

MergeData = NaN(length(UniverseA),2);

MergeData(:,1) = DataA;

[tf, loc] = ismember(UniverseA, UniverseB);

MergeData(tf,2) = DataB(loc(tf));

 MergeData =

20    30
40   NaN
60    50
80    70
4
répondu R. Van Hoose 2008-10-14 19:11:26

demandant "pourquoi" (utile pour me sortir d'une trance de débogage D'exécution Matlab à 3h du matin...)

4
répondu David Cuccia 2011-04-28 04:13:31

exécute un modèle Simulink directement à partir d'un script (plutôt qu'interactivement) en utilisant la commande sim . Vous pouvez faire des choses comme prendre des paramètres à partir d'une variable d'espace de travail, et exécuter à plusieurs reprises sim dans une boucle pour simuler quelque chose tout en faisant varier le paramètre pour voir comment le comportement change, et graphique les résultats avec les commandes graphiques que vous aimez. Beaucoup plus facile que d'essayer de le faire de façon interactive, et il vous donne beaucoup plus de flexibilité que le Simulink "oscilloscope" bloque la visualisation des résultats. (bien que vous ne pouvez pas l'utiliser pour voir ce qui se passe en temps réel pendant que la simulation est en cours d'exécution)

une chose très importante à savoir est DstWorkspace et SrcWorkspace options de la commande simset . Ceux-ci contrôlent où les blocs "To Workspace" et "From Workspace" obtiennent et mettent leurs résultats. Dstworkspace par défaut à l'espace de travail actuel (par exemple si vous appelez sim de à l'intérieur d'une fonction, les blocs "to Workspace" apparaîtront comme des variables accessibles à partir de cette même fonction) mais SrcWorkspace par défaut à l'espace de travail de base et si vous voulez encapsuler votre appel à sim vous voudrez mettre SrcWorkspace à current il y a donc une interface claire pour fournir/extraire les paramètres d'entrée et de sortie de la simulation. Par exemple:

function Y=run_my_sim(t,input1,params)
% runs "my_sim.mdl" 
% with a From Workspace block referencing I1 as an input signal
% and parameters referenced as fields of the "params" structure
% and output retrieved from a To Workspace block with name O1.
opt = simset('SrcWorkspace','current','DstWorkspace','current');
I1 = struct('time',t,'signals',struct('values',input1,'dimensions',1));
Y = struct;
Y.t = sim('my_sim',t,opt);
Y.output1 = O1.signals.values;
3
répondu Jason S 2008-12-19 21:41:11

courbes de niveau avec [c,h]=contour et clabel(c,h,'fontsize',fontsize) . J'utilise habituellement le paramètre fontsize pour réduire la taille de la police de sorte que les nombres ne se rencontrent pas. C'est idéal pour visualiser la valeur des fonctions 2-D sans avoir à se faufiler avec des graphiques 3D.

3
répondu Jason S 2008-12-19 21:45:37

Vectorisation:

function iNeedle = findClosest(hay,needle)
%FINDCLOSEST find the indicies of the closest elements in an array.
% Given two vectors [A,B], findClosest will find the indicies of the values
% in vector A closest to the values in vector B.
[hay iOrgHay] = sort(hay(:)');  %#ok must have row vector

% Use histogram to find indices of elements in hay closest to elements in
% needle. The bins are centered on values in hay, with the edges on the
% midpoint between elements.
[iNeedle iNeedle] = histc(needle,[-inf hay+[diff(hay)/2 inf]]); %#ok

% Reversing the sorting.
iNeedle = iOrgHay(iNeedle);
3
répondu user36927 2009-01-18 15:01:05

utilisant persistent (static) variables lors de l'exécution d'un algorithme en ligne. Il peut accélérer le code dans des domaines comme L'apprentissage automatique bayésien où le modèle est formé de façon itérative pour les nouveaux échantillons. Par exemple, pour calculer les loglikelities indépendants, Je calcule la loglikelihood initialement à partir de zéro et le mettre à jour en faisant la somme de cette loglikelihood calculée précédemment et la loglikelihood supplémentaire.

au lieu de donner un plus problème d'apprentissage machine spécialisée, permettez-moi de donner un code général de Moyenne en ligne que j'ai pris d'ici :

function av = runningAverage(x)
% The number of values entered so far - declared persistent.
persistent n;
% The sum of values entered so far - declared persistent.
persistent sumOfX;
if x == 'reset' % Initialise the persistent variables.
    n = 0;
    sumOfX = 0;
    av = 0;
else % A data value has been added.
    n = n + 1;
    sumOfX = sumOfX + x;
    av = sumOfX / n; % Update the running average.
end

ensuite, les appels donneront les résultats suivants

runningAverage('reset')
ans = 0
>> runningAverage(5)
ans = 5
>> runningAverage(10)
ans = 7.5000
>> runningAverage(3)
ans = 6
>> runningAverage('reset')
ans = 0
>> runningAverage(8)
ans = 8
3
répondu petrichor 2011-06-27 11:27:11

je suis surpris que tandis que les gens ont mentionné l'approche du tableau logique d'indexer un tableau, personne n'a mentionné la commande find.

p.ex. si x est un tableau NxMxO

x (x>20) Fonctionne en générant un tableau logique NxMxO et en l'utilisant à l'index x (qui peut être mauvais si vous avez de grands tableaux et cherchez un petit sous-ensemble

x(find (x>20)) Fonctionne en générant la liste (i.e. 1xwhatever) des indices de x qui satisfont x>20, et indexer x Par it. "trouver" devrait être utilisé plus qu'il ne l'est, d'après mon expérience.

plus ce que j'appellerais des "trucs"

vous pouvez augmenter/Ajouter aux tableaux et aux tableaux de cellules si vous ne connaissez pas la taille dont vous avez besoin, en utilisant end + 1 (fonctionne avec des dimensions plus élevées aussi, aussi longtemps que les dimensions de la tranche correspondent -- donc vous devrez initialiser x à quelque chose d'autre que [] dans ce cas). Pas bon pour les numerics mais pour les petites listes dynamiques de choses (ou tableaux de cellules), p.ex. analyse de fichiers.

p.ex.

>> x=[1,2,3]
x =  1     2     3
>> x(end+1)=4
x =  1     2     3     4

un autre pense que beaucoup de gens ne savent pas est que pour les travaux sur n'importe quel tableau dim 1, donc de continuer l'exemple

>> for n = x;disp(n);end
     1
     2
     3
     4

, ce Qui signifie si vous n'avez besoin que les membres de x vous n'avez pas besoin de les indexer.

cela fonctionne aussi avec les réseaux de cellules mais c'est un peu ennuyeux parce que comme il les promène l'élément est toujours enveloppé dans une cellule:

>> for el = {1,2,3,4};disp(el);end
    [1]
    [2]
    [3]
    [4]

Afin d'obtenir les éléments que vous avez à indice

>> for el = {1,2,3,4};disp(el{1});end
     1
     2
     3
     4

Je ne me souviens pas s'il y a un meilleur moyen de contourner ça.

2
répondu simon 2009-04-08 15:34:27

- vous pouvez faire un raccourci Matlab vers un fichier d'initialisation appelé startup.M. Ici, je définis le formatage, la précision de la sortie, et les paramètres de la représentation graphique pour ma session Matlab (par exemple, j'utilise un plus grand axe de représentation graphique/taille de police de sorte que .les figues peuvent être vues clairement quand je les mets dans les présentations.) Voir un bon billet de blog d'un des développeurs à ce sujet http://blogs.mathworks.com/loren/2009/03/03/whats-in-your-startupm / .

- vous pouvez charger un fichier ascii numérique complet utilisant la fonction" load". Ce n'est pas particulièrement rapide, mais le travail est fait rapidement pour le prototypage (ne devrait-il pas être la devise de Matlab?)

- comme mentionné, l'opérateur du côlon et la vectorisation sont des sauveurs. Vis de boucles.

2
répondu temp2290 2009-10-01 22:27:26

x=repmat([1:10],3,1); % dire que x est un tableau de l'exemple de données

l=x>=3; % l est un vecteur logique (1s/0s) pour mettre en évidence les éléments dans le tableau qui répondraient à une certaine condition.

N = somme (somme (l));% N est le nombre d'éléments qui répondent à cette condition donnée.

hourra ... joyeux scripting!

2
répondu Y.T. 2010-12-22 02:33:52