Поиск…


замечания

В этом разделе представлены лучшие практики, которые сообщество узнало с течением времени.

Стройте короткие строки

Используйте символ продолжения (многоточие) ... для продолжения длинного оператора.

Пример:

MyFunc( parameter1,parameter2,parameter3,parameter4, parameter5, parameter6,parameter7, parameter8, parameter9)

могут быть заменены на:

MyFunc( parameter1, ...
        parameter2, ...
        parameter3, ...
        parameter4, ...
        parameter5, ...
        parameter6, ...
        parameter7, ...
        parameter8, ...
        parameter9)

Код отступа правильно

Правильный отступ дает не только эстетический вид, но и повышает читаемость кода.

Например, рассмотрим следующий код:

%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

Как вы можете видеть, вам нужно внимательно посмотреть, какой цикл и if утверждения заканчиваются где.
С умным отступом вы получите этот вид:

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

Это явно указывает начало и конец инструкции loop / if .

Вы можете делать интеллектуальные отступы:
выбор всего кода ( Ctrl + A )
а затем нажмите Ctrl + I или нажмите SmartIndentIcon из панели редактирования. редактор

Использовать assert

Matlab позволяет совершать очень простые ошибки, что может привести к тому, что ошибка будет поднята намного позже в ходе выполнения, что затруднит отладку. Если вы примете что-то о своих переменных, подтвердите его.

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};

Избегайте циклов

Большую часть времени, петли вычислительно дорого с Matlab. При использовании векторизации ваш код будет быстрее на порядок. Он также часто делает ваш код более модульным, легко изменяемым и легче отлаживать. Основной недостаток заключается в том, что вам нужно потратить время на планирование структур данных, а ошибки измерения легче найти.

Примеры

Не пишите

for t=0:0.1:2*pi
    R(end+1)=cos(t);
end

но

t=0:0.1:2*pi;
R=cos(t)

Не пишите

for i=1:n
    for j=1:m
        c(i,j)=a(i)+2*b(j);
    end
end

Но что-то похожее

c=repmat(a.',1,m)+2*repmat(b,n,1)

Для получения дополнительной информации см. Векторизация

Создание уникального имени для временного файла

При кодировании скрипта или функции может потребоваться один или несколько временных файлов, чтобы, например, хранить некоторые данные.

Чтобы избежать перезаписи существующего файла или тени функции MATLAB, функция tempname может использоваться для создания уникального имени временного файла в системной временной папке.

my_temp_file=tempname

Имя файла генерируется без расширения; его можно добавить, объединяя желаемое расширение с именем, созданным tempname

my_temp_file_with_ext=[tempname '.txt']

Локатор временной папки системы можно восстановить, выполнив функцию tempdir .

Если во время выполнения функции / скрипта временный файл больше не нужен, его можно удалить, используя функцию delete

Поскольку delete не требует подтверждения, это может быть полезно установить on опцию , чтобы переместить файл , который будет удален в recycle папке.

Это можно сделать, используя функцию recycle следующим образом:

recycle('on')

В следующем примере предлагается возможное использование функций tempname , delete и recycle .

%
% 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)

Предостережение

Временное имя файла создается с помощью метода java.util.UUID.randomUUID ( randomUUID ).

Если MATLAB запускается без JVM, временное имя файла генерируется с помощью
matlab.internal.timing.timing на основе счетчика и времени процессора. В этом случае временное имя файла не гарантируется быть уникальным.

Использовать validateattributes

Функция validateattributes может использоваться для проверки массива по набору спецификаций

Поэтому он может использоваться для проверки ввода, предоставляемого функции.

В следующем примере функция test_validateattributes требует три ввода

function test_validateattributes(input_1,input_2,input_3)

Спецификация входа:

  • array_1:

    • класс: двойной
    • размер: [3,2]
    • значения: элементы должны быть не NaN
  • char_array:

    • class: char
    • value: строка не должна быть пустой
  • array_3

    • класс: двойной
    • размер: [5 1]
    • значения: элементы должны быть реальными

Чтобы проверить три входа, функцию validateattributes можно вызвать со следующим синтаксисом:

validateattributes(A,classes,attributes,funcName,varName,argIndex)

где:

  • A - это массив, подлежащий обложению
  • classes : type массива (например, single , double , logical )
  • attributes : это attributes которые должен иметь входной массив (например, [3,2], size чтобы указать размер массива, nonnan чтобы указать, что массив не должен иметь значения NaN)
  • funcName : имя функции, в которой происходит проверка. Этот аргумент используется при генерации сообщения об ошибке (если есть)
  • varName : имя массива при проверке. Этот аргумент используется при генерации сообщения об ошибке (если есть)
  • argIndex : позиция массива inpurt в списке ввода. Этот аргумент используется при генерации сообщения об ошибке (если есть)

Если один или несколько входных данных не соответствуют спецификации, генерируется сообщение об ошибке.

В случае более одного недопустимого ввода проверка прекращается, когда обнаружено первое несоответствие.

Это function test_validateattributes в которой реализована проверка ввода.

Так как функция требует трех входных сигналов, первая проверка количества вводимых данных выполняется с использованием nargin .

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')

Следующий сценарий можно использовать для проверки реализации процедуры проверки.

Он генерирует три необходимых ввода и, случайно, делает их недействительными.

%
% 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)

Это несколько примеров неправильного ввода, обнаруженного функцией validateattributes :

Неверный ввод

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.

Неверный ввод

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.

Действительный ввод

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

Оператор блокировки комментариев

Хорошая практика - добавлять комментарии, описывающие код. Это полезно для других и даже для кодера при возврате позже. Одну строку можно прокомментировать с помощью символа % или с помощью сочетания Ctrl+R Чтобы раскомментировать ранее прокомментированную строку, удалите символ % или используйте короткий ключ Crtl+T

Комментируя блок кода, можно сделать, добавив символ % в начале каждой строки, более новые версии MATLAB (после 2015a) позволяют использовать блок-комментарий оператора %{ code %} . Этот оператор повышает читаемость кода. Он может использоваться как для комментирования кода, так и для справочной документации по функциям. Блок можно складывать и разворачивать для повышения удобочитаемости кода.

введите описание изображения здесь

Как видно, операторы %{ и %} должны отображаться только в строках. Не включайте другой текст в эти строки.

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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow