MATLAB Language
MATLAB Best Practices
Suche…
Bemerkungen
In diesem Thema werden bewährte Methoden beschrieben, die die Community im Laufe der Zeit gelernt hat.
Halten Sie die Zeilen kurz
Verwenden Sie das Fortsetzungszeichen (Ellipse) ...
, um die lange Anweisung fortzusetzen.
Beispiel:
MyFunc( parameter1,parameter2,parameter3,parameter4, parameter5, parameter6,parameter7, parameter8, parameter9)
kann ersetzt werden durch:
MyFunc( parameter1, ...
parameter2, ...
parameter3, ...
parameter4, ...
parameter5, ...
parameter6, ...
parameter7, ...
parameter8, ...
parameter9)
Code richtig einrücken
Die richtige Einrückung gibt nicht nur das ästhetische Aussehen, sondern erhöht auch die Lesbarkeit des Codes.
Betrachten Sie zum Beispiel den folgenden Code:
%no need to understand the code, just give it a look
n = 2;
bf = false;
while n>1
for ii = 1:n
for jj = 1:n
if ii+jj>30
bf = true;
break
end
end
if bf
break
end
end
if bf
break
end
n = n + 1;
end
Wie Sie sehen, müssen Sie genau prüfen, welche Schleife und if
Anweisungen enden.
Mit der intelligenten Einrückung erhalten Sie diesen Look:
n = 2;
bf = false;
while n>1
for ii = 1:n
for jj = 1:n
if ii+jj>30
bf = true;
break
end
end
if bf
break
end
end
if bf
break
end
n = n + 1;
end
Dies zeigt deutlich den Beginn und das Ende der Schleife / if
Anweisung an.
Sie können die intelligente Einrückung folgendermaßen vornehmen:
• Auswählen des gesamten Codes ( Strg + A )
• und drücken Sie dann Strg + I oder klicken Sie auf aus der Bearbeitungsleiste.
Verwenden Sie Assert
Matlab lässt zu, dass einige sehr triviale Fehler unbemerkt bleiben, was dazu führen kann, dass später ein Fehler auftritt - was das Debuggen schwierig macht. Wenn Sie etwas zu Ihren Variablen vermuten , überprüfen Sie es.
function out1 = get_cell_value_at_index(scalar1,cell2)
assert(isscalar(scalar1),'1st input must be a scalar')
assert(iscell(cell2),'2nd input must be a cell array')
assert(numel(cell2) >= scalar1),'2nd input must have more elements than the value of the 1st input')
assert(~isempty(cell2{scalar1}),'2nd input at location is empty')
out1 = cell2{scalar1};
Vermeiden Sie Schleifen
Meistens sind Schleifen bei Matlab rechenintensiv. Ihr Code wird um Größenordnungen schneller, wenn Sie die Vektorisierung verwenden. Außerdem wird Ihr Code häufig modularer, einfacher zu ändern und einfacher zu debuggen. Der größte Nachteil ist, dass Sie sich Zeit für die Planung der Datenstrukturen nehmen müssen und dass Dimensionsfehler einfacher zu finden sind.
Beispiele
Schreibe nicht
for t=0:0.1:2*pi
R(end+1)=cos(t);
end
aber
t=0:0.1:2*pi;
R=cos(t)
Schreibe nicht
for i=1:n
for j=1:m
c(i,j)=a(i)+2*b(j);
end
end
Aber etwas ähnliches
c=repmat(a.',1,m)+2*repmat(b,n,1)
Weitere Einzelheiten finden Sie unter Vektorisierung
Erstellen Sie einen eindeutigen Namen für die temporäre Datei
Beim Codieren eines Skripts oder einer Funktion kann es vorkommen, dass eine oder mehrere temporäre Dateien benötigt werden, um beispielsweise Daten zu speichern.
Um das Überschreiben einer vorhandenen Datei oder das Spiegeln einer MATLAB-Funktion zu vermeiden , kann mit der Funktion Tempname ein eindeutiger Name für eine temporäre Datei im temporären Systemordner erstellt werden.
my_temp_file=tempname
Der Dateiname wird ohne die Erweiterung generiert. Es kann hinzugefügt werden, indem die gewünschte Erweiterung mit dem von tempname
generierten Namen tempname
my_temp_file_with_ext=[tempname '.txt']
Die Position des temporären Systemordners kann durch Kalendern der Tempdir- Funktion abgerufen werden.
Wenn die temporäre Datei während der Ausführung der Funktion / des Skripts nicht mehr benötigt wird, kann sie mit der Funktion delete gelöscht werden
Da delete
fragt nicht nach Bestätigung, könnte es sinnvoll sein, zu setzen on
die Möglichkeit , die Datei zu bewegen , um in der gelöscht werden recycle
- Ordner.
Dies kann durch Verwendung der Funktion recycle auf diese Weise geschehen:
recycle('on')
Im folgenden Beispiel wird eine mögliche Verwendung der Funktionen tempname
, delete
und recycle
vorgeschlagen.
%
% Create some example data
%
theta=0:.1:2*pi;
x=cos(theta);
y=sin(theta);
%
% Generate the temporary filename
%
my_temp_file=[tempname '.mat'];
%
% Split the filename (path, name, extension) and display them in a message box
[tmp_file_path,tmp_file_name, tmp_file_ext]=fileparts(my_temp_file)
uiwait(msgbox(sprintf('Path= %s\nName= %s\nExt= %s', ...
tmp_file_path,tmp_file_name,tmp_file_ext),'TEMPORARY FILE'))
%
% Save the varaibles in a temporary file
%
save(my_temp_file,'x','y','theta')
%
% Load the varaibles from the temporary file
%
load(my_temp_file)
%
% Set the reclycle option on
%
recycle('on')
%
% Delete the temporary file
%
delete(my_temp_file)
Vorbehalt
Der temporäre Dateiname wird mithilfe der Methode java.util.UUID.randomUUID
( randomUUID ) generiert .
Wenn MATLAB ohne JVM ausgeführt wird, wird der temporäre Dateiname mithilfe von generiert
matlab.internal.timing.timing
basierend auf dem CPU-Zähler und der Uhrzeit. In diesem Fall ist der temporäre Dateiname nicht garantiert eindeutig.
Verwenden Sie gültige Attribute
Die Funktion validateattributes kann verwendet werden, um ein Array anhand einer Reihe von Spezifikationen zu überprüfen
Es kann daher verwendet werden, um die Eingabe einer Funktion zu überprüfen.
Im folgenden Beispiel erfordert die Funktion test_validateattributes
drei Eingaben
function test_validateattributes(input_1,input_2,input_3)
Die Eingabespezifikation ist:
Array_1:
- Klasse: doppelt
- Größe: [3,2]
- Werte: Elemente dürfen nicht NaN sein
char_array:
- Klasse: char
- Wert: Die Zeichenfolge darf nicht leer sein
array_3
- Klasse: doppelt
- Größe: [5 1]
- Werte: Elemente müssen echt sein
Um die drei Eingaben zu validateattributes
können die Funktion validateattributes
mit der folgenden Syntax aufgerufen werden:
validateattributes(A,classes,attributes,funcName,varName,argIndex)
woher:
-
A
ist das zu vaidierende Array -
classes
: ist dertype
des Arrays (zBsingle
,double
,logical
) -
attributes
: sind die Attribute, die das Eingangsarray abgleichen muss (z. B.[3,2], size
, um die Größe des Arrays anzugeben,nonnan
um anzugeben, dass das Array keine NaN-Werte haben soll.) -
funcName
: ist der Name der Funktion, in der die Überprüfung erfolgt. Dieses Argument wird bei der Generierung der Fehlermeldung verwendet (falls vorhanden) -
varName
: ist der Name des zuvarName
Arrays. Dieses Argument wird bei der Generierung der Fehlermeldung verwendet (falls vorhanden) -
argIndex
: ist die Position des Inpurt-Arrays in der Eingabeliste. Dieses Argument wird bei der Generierung der Fehlermeldung verwendet (falls vorhanden)
Falls eine oder mehrere Eingaben nicht der Spezifikation entsprechen, wird eine Fehlermeldung generiert.
Bei mehr als einer ungültigen Eingabe wird die Validierung angehalten, wenn die erste Nichtübereinstimmung gefunden wird.
Dies ist die function test_validateattributes
in der die Eingabevalidierung implementiert wurde.
Da für die Funktion drei Eingaben erforderlich sind, wird eine erste Überprüfung der Anzahl der eingegebenen Eingaben unter Verwendung der Funktionstring durchgeführt .
function test_validateattributes(array_1,char_array_1,array_3)
%
% Check for the number of expected input: if the number of input is less
% than the require, the function exits with an error message
%
if(nargin ~= 3)
error('Error: TEST_VALIDATEATTRIBUTES requires 3 input, found %d',nargin)
end
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Definition of the expected characteristics of the first input %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% INPUT #1 name (only used in the generation of the error message)
%
input_1_name='array_1';
%
% INPUT #1 position (only used in the generation of the error message)
%
input_1_position=1;
%
% Expected CLASS of the first input MUST BE "double"
%
input_1_class={'double'};
%
% Expected ATTRIBUTES of the first input
% SIZE: MUST BE [3,2]
%
input_1_size_attribute='size';
input_1_size=[3,2];
%
% VALUE CHECK: the element MUST BE NOT NaN
%
input_1_value_type='nonnan';
%
% Build the INPUT 1 attributes
%
input_1_attributes={input_1_size_attribute,input_1_size, ...
input_1_value_type};
%
% CHECK THE VALIDITY OF THE FIRST INPUT
%
validateattributes(array_1, ...
input_1_class,input_1_attributes,'', ...
input_1_name,input_1_position);
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Definition of the expected characteristics of the second input %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% INPUT #1 name (only used in the generation of the error message)
%
input_2_name='char_array_1';
%
% INPUT #2 position (only used in the generation of the error message)
%
input_2_position=2;
%
% Expected CLASS of the first input MUST BE "string"
%
input_2_class={'char'};
%
% VALUE CHECK: the element must be not NaN
%
input_2_size_attribute='nonempty';
%
% Build the INPUT 2 attributes
%
input_2_attributes={input_2_size_attribute};
%
% CHECK THE VALIDITY OF THE SECOND INPUT
%
validateattributes(char_array_1, ...
input_2_class,input_2_attributes,'', ...
input_2_name,input_2_position);
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Definition of the expected characteristics of the third input %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% INPUT #3 name (only used in the generation of the error message)
%
input_3_name='array_3';
%
% INPUT #3 position (only used in the generation of the error message)
%
input_3_position=3;
%
% Expected CLASS of the first input MUST BE "double"
%
input_3_class={'double'};
%
% Expected ATTRIBUTES of the first input
% SIZE: must be [5]
input_3_size_attribute='size';
input_3_size=[5 1];
% VALUE CHECK: the elements must be real
input_3_value_type='real';
%
% Build the INPUT 3 attributes
%
input_3_attributes={input_3_size_attribute,input_3_size, ...
input_3_value_type};
%
% CHECK THE VALIDITY OF THE FIRST INPUT
%
validateattributes(array_3, ...
input_3_class,input_3_attributes,'', ...
input_3_name,input_3_position);
disp('All the three input are OK')
Das folgende Skript kann verwendet werden, um die Implementierung des Validierungsverfahrens zu testen.
Es generiert die drei erforderlichen Eingaben und macht sie nach dem Zufall ungültig.
%
% Generate the first input
%
n_rows=randi([2 3],1);
n_cols=2;
input_1=randi([20 30],n_rows,n_cols);
%
% Generate the second input
%
if(rand > 0.5)
input_2='This is a string';
else
input_2='';
end
%
% Generate the third input
%
input_3=acos(rand(5,1)*1.2);
%
% Call the test_validateattributes function with the above generated input
%
input_1
input_2
input_3
%
test_validateattributes(input_1,input_2,input_3)
Dies sind einige Beispiele für falsche Eingaben, die von der Funktion validateattributes
erkannt wurden:
Falsche Eingabe
input_1 =
23 22
26 28
input_2 =
''
input_3 =
0.0000 + 0.4455i
1.2420 + 0.0000i
0.4063 + 0.0000i
1.3424 + 0.0000i
1.2186 + 0.0000i
Error using test_validateattributes (line 44)
Expected input number 1, array_1, to be of size 3x2 when it is actually
size 2x2.
Falsche Eingabe
input_1 =
22 24
21 25
26 27
input_2 =
This is a string
input_3 =
1.1371 + 0.0000i
0.6528 + 0.0000i
1.0479 + 0.0000i
0.0000 + 0.1435i
0.0316 + 0.0000i
Error using test_validateattributes (line 109)
Expected input number 3, array_3, to be real.
Gültige Eingabe
input_1 =
20 25
25 28
24 23
input_2 =
This is a string
input_3 =
0.9696
1.5279
1.3581
0.5234
0.9665
All the three input are OK
Kommentaroperator blockieren
Es empfiehlt sich, Kommentare hinzuzufügen, die den Code beschreiben. Es ist hilfreich für andere und sogar für den Codierer, wenn es später zurückgegeben wird. Eine einzelne Zeile kann mit dem Symbol %
oder mit der Tastenkombination Ctrl+R
kommentiert werden. Um eine Kommentarzeile zu kommentieren, entfernen Sie das %
-Symbol oder verwenden Sie die Tastenkombination Crtl+T
Das Kommentieren eines Codeblocks kann durch Hinzufügen eines %
-Symbols am Anfang jeder Zeile erfolgen. In neueren Versionen von MATLAB (nach 2015a) können Sie den Blockkommentaroperator %{ code %}
. Dieser Operator erhöht die Lesbarkeit des Codes. Es kann sowohl für die Codekommentierung als auch für die Funktionshilfedokumentation verwendet werden. Der Block kann gefaltet und aufgefaltet werden , um die Lesbarkeit des Codes zu erhöhen.
Wie zu sehen ist, müssen die Operatoren %{
und %}
in den Zeilen alleine angezeigt werden. Fügen Sie keinen anderen Text in diese Zeilen ein.
function y = myFunction(x)
%{
myFunction Binary Singleton Expansion Function
y = myFunction(x) applies the element-by-element binary operation
specified by the function handle FUNC to arrays A and B, with implicit
expansion enabled.
%}
%% Compute z(x, y) = x.*sin(y) on a grid:
% x = 1:10;
y = x.';
%{
z = zeros(numel(x),numel(y));
for ii=1:numel(x)
for jj=1:numel(y)
z(ii,jj) = x(ii)*sin(y(jj));
end
end
%}
z = bsxfun(@(x, y) x.*sin(y), x, y);
y = y + z;
end