MATLAB LanguageНачало работы с языком MATLAB


Версии

Версия Релиз Дата выхода
1,0 1984-01-01
2 1986-01-01
3 1987-01-01
3,5 1990-01-01
4 1992-01-01
4.2c 1994-01-01
5.0 Том 8 1996-12-01
5,1 Том 9 1997-05-01
5.1.1 R9.1 1997-05-02
5,2 R10 1998-03-01
5.2.1 R10.1 1998-03-02
5,3 R11 1999-01-01
5.3.1 r11.1 1999-11-01
6,0 R12 2000-11-01
6,1 R12.1 2001-06-01
6,5 R13 2002-06-01
6.5.1 R13SP2 2003-01-01
6.5.2 R13SP2 2003-01-02
7 R14 2006-06-01
7.0.4 R14SP1 2004-10-01
7,1 R14SP3 2005-08-01
7,2 R2006a 2006-03-01
7,3 R2006b 2006-09-01
7,4 R2007a 2007-03-01
7,5 R2007b 2007-09-01
7,6 R2008a 2008-03-01
7,7 R2008b 2008-09-01
7,8 R2009a 2009-03-01
7,9 R2009b 2009-09-01
7,10 R2010a 2010-03-01
7,11 R2010b 2010-09-01
7,12 R2011a 2011-03-01
7,13 R2011b 2011-09-01
7,14 R2012a 2012-03-01
8,0 R2012b 2012-09-01
8,1 R2013a 2013-03-01
8,2 R2013b 2013-09-01
8,3 R2014a 2014-03-01
8,4 R2014b 2014-09-01
8,5 R2015a 2015-03-01
8,6 R2015b 2015-09-01
9,0 R2016a 2016-03-01
9,1 R2016b 2016-09-14
9,2 R2017a 2017-03-08

См. Также: История выпуска MATLAB в Википедии .

Анонимные функции и функции

основы

Анонимные функции являются мощным инструментом языка MATLAB. Это функции, которые существуют локально, то есть: в текущей рабочей области. Однако они не существуют на пути MATLAB, как регулярная функция, например, в m-файле. Вот почему они называются анонимными, хотя они могут иметь имя как переменную в рабочей области.

Оператор @

Используйте оператор @ для создания анонимных функций и функций. Например, чтобы создать дескриптор функции sin (sine) и использовать его как f :

>> f = @sin
f = 
    @sin
 

Теперь f является дескриптором функции sin . Как и в реальной жизни, дверная ручка - это способ использовать дверь, функциональная рукоятка - это способ использовать функцию. Для использования f аргументы передаются ему, как если бы это была функция sin :

>> f(pi/2)
ans =
     1
 

f принимает любые входные аргументы, которые принимает функция sin . Если sin будет функцией, которая принимает нулевые входные аргументы (а это не так, но другие делают, например, функцию peaks ), f() будет использоваться для вызова без входных аргументов.

Пользовательские анонимные функции

Анонимные функции одной переменной

Очевидно, не полезно создавать дескриптор существующей функции, такой как sin в приведенном выше примере. В этом примере он является избыточным. Тем не менее, полезно создавать анонимные функции, которые выполняют пользовательские вещи, которые в противном случае нужно было бы повторять несколько раз или создавать отдельную функцию. В качестве примера пользовательской анонимной функции, которая принимает одну переменную в качестве ее ввода, суммируйте синус и косинус в квадрате сигнала:

>> f = @(x) sin(x)+cos(x).^2
f = 
    @(x)sin(x)+cos(x).^2
 

Теперь f принимает один входной аргумент, называемый x . Это было задано с помощью круглых скобок (...) непосредственно после оператора @ . f теперь является анонимной функцией x : f(x) . Он используется, передавая значение x в f :

>> f(pi)
ans =
    1.0000
 

Вектор значений или переменная также может быть передан в f , если они действительным образом используются внутри f :

>> f(1:3) % pass a vector to f
ans =
    1.1334    1.0825    1.1212
>> n = 5:7;
>> f(n) % pass n to f
ans =
   -0.8785    0.6425    1.2254
 

Анонимные функции более чем одной переменной

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

>> f = @(x,y,z) x.^2 + y.^2 - z.^2
f = 
    @(x,y,z)x.^2+y.^2-z.^2
>> f(2,3,4)
ans =
    -3
 

Параметрирование анонимных функций

Переменные в рабочей области могут использоваться в определении анонимных функций. Это называется параметризацией. Например, для использования константы c = 2 в анонимной функции:

>> c = 2;
>> f = @(x) c*x
f = 
    @(x)c*x
>> f(3)
ans =
     6
 

f(3) использовала переменную c как параметр для умножения с предоставленным x . Обратите внимание, что если значение c в этой точке задано на что-то другое, тогда вызывается f(3) , результат не будет отличаться. Значение c является значением во время создания анонимной функции:

>> c = 2;
>> f = @(x) c*x;
>> f(3)
ans =
     6
>> c = 3;
>> f(3)
ans =
     6
 

Входные аргументы для анонимной функции не относятся к переменным рабочего пространства

Обратите внимание, что использование имени переменных в рабочей области в качестве одного из входных аргументов анонимной функции (т. Е. С помощью @(...) ) не будет использовать значения этих переменных. Вместо этого они рассматриваются как разные переменные в рамках анонимной функции, то есть: анонимная функция имеет свое личное рабочее пространство, где входные переменные никогда не ссылаются на переменные из основного рабочего пространства. Основное рабочее пространство и рабочая область анонимной функции не знают друг о друге. Пример, иллюстрирующий это:

>> x = 3 % x in main workspace
x =
     3
>> f = @(x) x+1; % here x refers to a private x variable
>> f(5)
ans =
     6
>> x
x =
     3
 

Значение x из основного рабочего пространства не используется в f . Кроме того, в основной рабочей области x осталось нетронутым. В пределах области f имена переменных между круглыми скобками после оператора @ не зависят от основных переменных рабочей области.

Анонимные функции хранятся в переменных

Анонимная функция (или, точнее, дескриптор функции, указывающая на анонимную функцию) сохраняется как любое другое значение в текущем рабочем пространстве: в переменной (как мы это делали выше) в массиве ячеек ( {@(x)x.^2,@(x)x+1} ) или даже в свойстве (например, h.ButtonDownFcn для интерактивной графики). Это означает, что анонимную функцию можно рассматривать как любое другое значение. Когда он хранится в переменной, он имеет имя в текущей рабочей области и может быть изменен и очищен так же, как переменные, содержащие числа.

По-разному: дескриптор функции (будь то в форме @sin или для анонимной функции) - это просто значение, которое может быть сохранено в переменной, подобно цифровой матрице.

Расширенное использование

Передающая функция обрабатывает другие функции

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

Пример: функция создается в m-файле, который принимает дескриптор функции и скалярное число. Затем он вызывает дескриптор функции, передавая ему 3 а затем добавляет скалярное число к результату. Результат возвращается.

Содержание funHandleDemo.m :

function y = funHandleDemo(fun,x)
y = fun(3);
y = y + x;
 

Сохраните его где-нибудь на пути, например, в текущей папке MATLAB. Теперь funHandleDemo можно использовать следующим образом, например:

>> f = @(x) x^2; % an anonymous function
>> y = funHandleDemo(f,10) % pass f and a scalar to funHandleDemo
y =
    19
 

Рукоятка другой существующей функции может быть передана funHandleDemo :

>> y = funHandleDemo(@sin,-5)
y =
   -4.8589
 

Обратите внимание, что @sin был быстрым способом получить доступ к функции sin без предварительного ее хранения в переменной, используя f = @sin .

Использование bsxfun , cellfun и подобных функций с анонимными функциями

MATLAB имеет встроенные функции, которые принимают анонимные функции в качестве входных данных. Это способ выполнить многие вычисления с минимальным количеством строк кода. Например, bsxfun , который выполняет bsxfun двоичные операции, то есть: он применяет функцию по двум векторам или матрицам bsxfun . Обычно для этого требуется использование for -loops, для которого часто требуется предварительное распределение скорости. Используя bsxfun этот процесс ускоряется. Следующий пример иллюстрирует это, используя tic и toc , две функции, которые можно использовать для временного использования кода. Он вычисляет разницу между каждым элементом матрицы из среднего значения столбца.

A = rand(50); % 50-by-50 matrix of random values between 0 and 1

% method 1: slow and lots of lines of code
tic
meanA = mean(A); % mean of every matrix column: a row vector
% pre-allocate result for speed, remove this for even worse performance
result = zeros(size(A));
for j = 1:size(A,1)
    result(j,:) = A(j,:) - meanA;
end
toc
clear result % make sure method 2 creates its own result

% method 2: fast and only one line of code
tic
result = bsxfun(@minus,A,mean(A));
toc
 

Выполнение приведенного выше примера приводит к двум выходам:

Elapsed time is 0.015153 seconds.
Elapsed time is 0.007884 seconds.
 

Эти строки поступают от функций toc , которые печатают прошедшее время со времени последнего вызова функции tic .

bsxfun применяет функцию в первом аргументе ввода к двум другим входным аргументам. @minus - это длинное имя для той же операции, что и знак минуса. Возможно, была указана другая анонимная функция или дескриптор ( @ ) для любой другой функции, если она принимает A и mean(A) качестве входных данных для создания значимого результата.

Специально для больших объемов данных в больших матрицах bsxfun может значительно ускорить работу. Он также делает код более чистым, хотя его может быть труднее интерпретировать для людей, которые не знают MATLAB или bsxfun . (Обратите внимание, что в MATLAB R2016a и более поздних версиях многие операции, которые ранее использовали bsxfun больше не нуждаются в них, A-mean(A) работает напрямую и может в некоторых случаях быть еще быстрее.)

Ячеистые массивы

Элементы одного и того же класса часто могут быть объединены в массивы (с несколькими редкими исключениями, например, с помощью функций). Числовые скаляры, по умолчанию класса double , могут храниться в матрице.

>> A = [1, -2, 3.14, 4/5, 5^6; pi, inf, 7/0, nan, log(0)]
A =
   1.0e+04 *
    0.0001   -0.0002    0.0003    0.0001    1.5625
    0.0003       Inf       Inf       NaN      -Inf
 

Символы, которые имеют класс char в MATLAB, также могут храниться в массиве с использованием аналогичного синтаксиса. Такой массив похож на строку во многих других языках программирования.

>> s = ['MATLAB ','is ','fun']
s =
MATLAB is fun
 

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

>> whos
  Name      Size            Bytes  Class     Attributes

  A         2x5                80  double              
  s         1x13               26  char                
 

На самом деле массив s не является массивом строк 'MATLAB ' , 'is ' и 'fun' , это всего лишь одна строка - массив из 13 символов. Вы получите те же результаты, если бы они были определены одним из следующих:

>> s = ['MAT','LAB ','is f','u','n'];
>> s = ['M','A','T','L','A','B,' ','i','s',' ','f','u','n'];
 

Обычный вектор MATLAB не позволяет хранить сочетание переменных разных классов или несколько разных строк. Здесь массив cell пригодится. Это массив ячеек, каждый из которых может содержать некоторый объект MATLAB, класс которого может быть различным в каждой ячейке, если это необходимо. Используйте фигурные скобки { и } вокруг элементов для хранения в массиве ячеек.

>> C = {A; s}
C = 
    [2x5 double]
    'MATLAB is fun'
>> whos C
  Name      Size            Bytes  Class    Attributes

  C         2x1               330  cell 
 

Стандартные объекты MATLAB любых классов могут храниться вместе в массиве ячеек. Обратите внимание, что массивы ячеек требуют больше памяти для хранения их содержимого.

Доступ к содержимому ячейки осуществляется с помощью фигурных скобок { и } .

>> C{1}
ans =
   1.0e+04 *
    0.0001   -0.0002    0.0003    0.0001    1.5625
    0.0003       Inf       Inf       NaN      -Inf
 

Заметим, что C(1) отличается от C{1} . Принимая во внимание, что последний возвращает содержимое ячейки (и имеет пример с double примером), первый возвращает массив ячеек, который является подматрицей C Точно так же, если D было массивом из 10 на 5 ячеек, тогда D(4:8,1:3) вернет подматрицу D , размер которой равен 5 на 3, а класс - cell . И синтаксис C{1:2} не имеет одного возвращенного объекта, но rater он возвращает 2 разных объекта (аналогично функции MATLAB с несколькими возвращаемыми значениями):

>> [x,y] = C{1:2}
x =
                         1                        -2                      3.14                       0.8                     15625
          3.14159265358979                       Inf                       Inf                       NaN                      -Inf
y =
MATLAB is fun
 

Типы данных

В MATLAB имеется 16 основных типов данных или классов. Каждый из этих классов имеет форму матрицы или массива. За исключением дескрипторов функций, эта матрица или массив является как минимум размером 0 на 0 и может вырасти до n-мерного массива любого размера. Функциональный дескриптор всегда скалярный (1 на 1).

Важным моментом в MATLAB является то, что вам не нужно использовать объявления типа или инструкции по размеру по умолчанию. Когда вы определяете новую переменную, MATLAB создает ее автоматически и выделяет соответствующее пространство памяти.

Пример:

a = 123;
b = [1 2 3];
c = '123';

>> whos
  Name      Size            Bytes  Class     Attributes

  a         1x1                 8  double              
  b         1x3                24  double              
  c         1x3                 6  char    
 

Если переменная уже существует, MATLAB заменяет исходные данные на новую и при необходимости выделяет новое пространство для хранения.

Основные типы данных

Основные типы данных: числовые, logical , char , cell , struct , table и function_handle .

Числовые типы данных :

  • Номера с плавающей запятой (по умолчанию )

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

    a = 1.23;
    b = single(a);
    
    >> whos
      Name      Size            Bytes  Class     Attributes
    
      a         1x1                 8  double              
      b         1x1                 4  single     
     
  • Целые

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

    MATLAB поддерживает 1-, 2-, 4- и 8-байтовые хранилища для целочисленных данных. Вы можете сохранить память и время выполнения для своих программ, если вы используете наименьший целочисленный тип, который поддерживает ваши данные. Например, для хранения значения 100 вам не нужно 32-разрядное целое число.

    a = int32(100);
    b = int8(100);
    
    >> whos
      Name      Size            Bytes  Class    Attributes
    
      a         1x1                 4  int32              
      b         1x1                 1  int8               
     

    Чтобы хранить данные как целое число, вам необходимо преобразовать из двойного значения в желаемый целочисленный тип. Если число, преобразованное в целое число, имеет дробную часть, MATLAB округляется до ближайшего целого числа. Если дробная часть равна 0.5 , то из двух одинаково близких целых чисел MATLAB выбирает ту, для которой абсолютное значение больше по величине.

    a  = int16(456);
     
  • char

    Массивы символов обеспечивают хранение текстовых данных в MATLAB. В соответствии с традиционной терминологией программирования массив (последовательность) символов определяется как строка. В розничных выпусках MATLAB нет явного строкового типа.

  • логические: логические значения 1 или 0, соответственно соответствуют true и false. Используется для реляционных условий и индексации массивов. Поскольку это только TRUE или FALSE, размер 1 байт.

    a = logical(1);
     
  • состав. Массив структуры - это тип данных, который группирует переменные разных типов данных с использованием контейнеров данных, называемых полями . Каждое поле может содержать любые типы данных. Доступ к данным в структуре с использованием точечной нотации формы structName.fieldName.

    field1 = 'first';
    field2 = 'second';
    value1 = [1 2 3 4 5];
    value2 = 'sometext';
    s = struct(field1,value1,field2,value2);
     

    Чтобы получить доступ к значению 1, каждый из следующих синтаксисов эквивалентен

    s.first or s.(field1) or s.('first')
     

    Мы можем явно получить доступ к полю, которое, как мы знаем, будут существовать с помощью первого метода или передать строку или создать строку для доступа к полю во втором примере. Третий пример - это демонстрация того, что нотация дескрипторов точек принимает строку, которая является той же самой, что и в переменной поля1.

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

    Age = [15 25 54]';
    Height = [176 190 165]';
    Name = {'Mike', 'Pete', 'Steeve'}';
    T = table(Name,Age, Height);
     
  • клетка. Это очень полезный тип данных MATLAB: массив ячеек - это массив, каждый из которых может иметь разные типы и размер данных. Это очень сильный инструмент для управления данными по вашему желанию.

    a = { [1 2 3], 56, 'art'};
     

    или же

    a = cell(3);
     
  • Функция handles хранит указатель на функцию (например, на анонимную функцию). Он позволяет передать функцию другой функции или вызвать локальные функции извне основной функции.

Существует множество инструментов для работы с каждым типом данных, а также встроенные функции преобразования типа данных ( str2double , table2cell ).

Дополнительные типы данных

Существует несколько дополнительных типов данных, которые полезны в некоторых конкретных случаях. Они есть:

  • Дата и время: массивы для представления дат, времени и продолжительности. datetime('now') возвращается 21-Jul-2016 16:30:16 .

  • Категориальные массивы: это тип данных для хранения данных со значениями из набора дискретных категорий. Полезно для хранения нечетных данных (эффективная память). Может использоваться в таблице для выбора групп строк.

    a = categorical({'a' 'b' 'c'});
     
  • Контейнеры карт представляют собой структуру данных, которая обладает уникальной способностью индексировать не только любые скалярные числовые значения, но и вектор символов. Индексы в элементы Карты называются ключами. Эти ключи вместе со значениями данных, связанными с ними, сохраняются в пределах Карты.

  • Временные ряды - это векторы данных, отобранные во времени, по порядку, часто через регулярные промежутки времени. Полезно хранить данные, связанные с timesteps, и у него есть много полезных методов для работы.

Привет, мир

Откройте новый пустой документ в редакторе MATLAB (в последних версиях MATLAB сделайте это, выбрав вкладку «Главная» на панели инструментов и нажав «Новый скрипт»). Клавиатура по умолчанию для создания нового скрипта - Ctrl-n .

В качестве альтернативы, набрав edit myscriptname.m вы откроете файл myscriptname.m для редактирования или предложите создать файл, если он не существует на пути MATLAB.

В редакторе введите следующее:

disp('Hello, World!');
 

Перейдите на вкладку «Редактор» на панели инструментов и нажмите «Сохранить как». Сохраните документ в файл в текущем каталоге helloworld.m . Сохранение файла без названия приведет к отображению диалогового окна с именем файла.

В окне команд MATLAB введите следующее:

>> helloworld
 

Вы должны увидеть следующий ответ в командном окне MATLAB:

Hello, World!
 

Мы видим, что в окне команд мы можем ввести имена функций или файлов сценариев, которые мы написали или которые поставляются вместе с MATLAB, для их запуска.

Здесь мы запустили скрипт helloworld. Обратите внимание, что набирать расширение ( .m ) не нужно. Инструкции, хранящиеся в файле сценария, выполняются MATLAB, здесь печать «Hello, World!» используя функцию disp .

Файлы сценариев могут быть записаны таким образом, чтобы сохранить ряд команд для последующего (повторного) использования.

Помощь себе

MATLAB поставляется со многими встроенными сценариями и функциями, которые варьируются от простых умножений до наборов инструментов распознавания изображений. Чтобы получить информацию о функции, которую вы хотите использовать, введите: help functionname в командной строке. Давайте возьмем функцию help в качестве примера.

Информацию о том, как ее использовать, можно получить, набрав:

>> help help

в окне команд. Это вернет информацию об использовании функции help . Если информация, которую вы ищете, все еще неясна, вы можете попробовать страницу документации этой функции. Просто введите:

>> doc help

в окне команд. Это откроет доступную для просмотра документацию на странице help по функциям, в которой содержится вся информация, необходимая для понимания того, как работает «помощь».

Эта процедура работает для всех встроенных функций и символов.

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

Пример для простой функции multiplyby2 сохраненной в файле multiplyby2.m

function [prod]=multiplyby2(num)
% function MULTIPLYBY2 accepts a numeric matrix NUM and returns output PROD 
% such that all numbers are multiplied by 2

    prod=num*2;
end
 

или же

% function MULTIPLYBY2 accepts a numeric matrix NUM and returns output PROD 
% such that all numbers are multiplied by 2

function [prod]=multiplyby2(num)
    prod=num*2;
end
 

Это очень полезно, когда вы получаете код недели / месяцев / лет после его написания.

Функция help и doc предоставляет много информации, чтобы узнать, как использовать эти функции, поможет вам быстро развиваться и эффективно использовать MATLAB.

Матрицы индексирования и массивы

MATLAB позволяет несколько методов индексировать (получать доступ) элементы матриц и массивов:

  • Индексация индексов - где вы указываете позицию элементов, которые вы хотите в каждом измерении матрицы, отдельно.
  • Линейное индексирование - где матрица рассматривается как вектор, независимо от ее размеров. Это означает, что вы указываете каждую позицию в матрице с одним номером.
  • Логическая индексация - где вы используете логическую матрицу (и матрицу true и false значений) с одинаковыми размерами матрицы, которую вы пытаетесь индексировать в качестве маски, чтобы указать, какое значение нужно вернуть.

Эти три метода теперь описано более подробно с помощью следующего 3 на 3 матрицы M в качестве примера:

>> M = magic(3)

ans = 

       8    1    6
       3    5    7
       4    9    2
 

Индексация индексов

Самый простой способ доступа к элементу - указать его индекс столбца строки. Например, доступ к элементу во второй строке и третьем столбце:

>> M(2, 3)

ans =

      7
 

Количество предоставленных индексов точно соответствует числу размеров M (два в этом примере).

Обратите внимание, что порядок индексов совпадает с порядком математического соглашения: индекс строки является первым. Более того, индексы MATLAB начинаются с 1 а не 0 как большинство языков программирования.

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

>> M(2, [1,2,3])

ans =

       3    5    7
 

В MATLAB вектор [1,2,3] легче создать с помощью оператора двоеточия, т. Е. 1:3 . Вы можете использовать это и в индексировании. Чтобы выбрать целую строку (или столбец), MATLAB предоставляет ярлык, позволяя вам просто указать : Например, следующий код также вернет всю вторую строку

>> M(2, :)

ans =

       3    5    7
 

MATLAB также предоставляет ярлык для указания последнего элемента измерения в форме ключевого слова end . Ключевое слово end будет работать точно так же, как если бы это был номер последнего элемента в этом измерении. Поэтому, если вы хотите, чтобы все столбцы от столбца 2 до последнего столбца, вы можете использовать следующее:

>> M(2, 2:end)

ans =

       5    7
 

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

>> M([2,3], [1,3])
ans =

       3    7
       4    2
 

Например, индексирование индексов не может извлекать только элементы M(2,1) или M(3,3) . Для этого мы должны рассмотреть линейную индексацию.

Линейная индексация

MATLAB позволяет обрабатывать n-мерные массивы как одномерные массивы при индексировании с использованием только одного измерения. Вы можете напрямую получить доступ к первому элементу:

>> M(1)

ans = 

       8
 

Обратите внимание, что массивы хранятся в основном порядке в MATLAB, что означает, что вы получаете доступ к элементам, сначала спустившись по столбцам. Таким образом, M(2) является вторым элементом первого столбца, который равен 3 а M(4) будет первым элементом второго столбца, т.е.

>> M(4)

ans = 

        1
 

Существуют встроенные функции в MATLAB для преобразования индексов индексов в линейные индексы и наоборот: sub2ind и ind2sub соответственно. Вы можете вручную преобразовать индексы ( r , c ) в линейный индекс на

idx = r + (c-1)*size(M,1)
 

Чтобы понять это, если мы находимся в первом столбце, линейный индекс будет просто индексом строки. Вышеприведенная формула верна для этого, поскольку для c == 1 , (c-1) == 0 . В следующих столбцах линейный индекс - это номер строки и все строки предыдущих столбцов.

Обратите внимание, что ключевое слово end прежнему применяется и теперь относится к самому последнему элементу массива, т.е. M(end) == M(end, end) == 2 .

Вы также можете индексировать несколько элементов с помощью линейной индексации. Обратите внимание: если вы это сделаете, возвращаемая матрица будет иметь ту же форму, что и матрица индексных векторов.

M(2:4) возвращает вектор строки, потому что 2:4 представляет вектор строки [2,3,4] :

>> M(2:4)

ans =

        3    4    1
 

В качестве другого примера M([1,2;3,4]) возвращает матрицу 2 на 2, потому что [1,2;3,4] является матрицей 2 на 2. Посмотрите приведенный ниже код, чтобы убедить себя:

>> M([1,2;3,4])

ans =

       8        3
       4        1
 

Обратите внимание, что индексирование с помощью : alone всегда будет возвращать вектор-столбец:

>> M(:)

ans = 

        8
        3
        4
        1
        5
        9
        6
        7
        2
 

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

Логическая индексация

Третий метод индексирования - использовать логическую матрицу, т. Е. Матрицу, содержащую только true или false значения, в качестве маски для фильтрации элементов, которые вы не хотите. Например, если мы хотим найти все элементы M , которые больше 5 мы можем использовать логическую матрицу

>> M > 5

ans =

    1    0    1
    0    0    1
    0    1    0
 

для индекса M и возвращать только значения, превышающие 5 следующим образом:

>> M(M > 5)

ans =

        8
        9
        6
        7
 

Если вы хотите, чтобы этот номер оставался на месте (т. Е. Сохранял форму матрицы), тогда вы могли бы назначить логический комплимент

>> M(~(M > 5)) = NaN

ans = 

    8      NaN    6
    NaN    NaN    7
    NaN    9      Nan
 

Мы можем уменьшить сложные кодовые блоки, содержащие операторы if и for , используя логическую индексацию.

Возьмите не-векторизованный (уже сокращенный до одного цикла с помощью линейной индексации):

for elem = 1:numel(M)
  if M(elem) > 5
    M(elem) = M(elem) - 2;
  end
end
 

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

idx = M > 5;
M(idx) = M(idx) - 2;
 

Или даже короче:

M(M > 5) = M(M > 5) - 2;
 

Подробнее об индексировании

Более высокие размерные матрицы

Все упомянутые выше методы обобщаются на n-мерные. Если мы используем в качестве примера трехмерную матрицу M3 = rand(3,3,3) , то вы можете получить доступ ко всем строкам и столбцам второго среза третьего измерения, написав

>> M(:,:,2)
 

Вы можете получить доступ к первому элементу второго среза с помощью линейной индексации. Линейное индексирование будет двигаться только ко второму срезу после всех строк и всех столбцов первого среза. Таким образом, линейный индекс для этого элемента равен

>> M(size(M,1)*size(M,2)+1)
 

Фактически, в MATLAB каждая матрица n-мерна: просто случается так, что размер большинства других n-измерений один. Итак, если a = 2 то a(1) == 2 (как и следовало ожидать), но также a(1, 1) == 2 , как и a(1, 1, 1) == 2 , a(1, 1, 1, ..., 1) == 2 и т. Д. Эти «дополнительные» размеры (размером 1 ) называются одноэлементными размерами . squeeze команды удалит их, и можно использовать permute чтобы поменять порядок размеров вокруг (и при необходимости ввести размеры синглтона).

N-мерную матрицу можно также индексировать, используя m индексов (где m <= n). Правило состоит в том, что первые индексы m-1 ведут себя обычно, в то время как последний (m'th) индекс ссылается на оставшиеся (n-m + 1) измерения, точно так же, как линейный индекс будет ссылаться на (n-m + 1) меру массив. Вот пример:

>> M = reshape(1:24,[2,3,4]);
>> M(1,1)
ans =
     1
>> M(1,10)
ans =
    19
>> M(:,:)
ans =
     1     3     5     7     9    11    13    15    17    19    21    23
     2     4     6     8    10    12    14    16    18    20    22    24
 

Возвращаемые диапазоны элементов

При индексировании индексов, если вы указываете более одного элемента в нескольких измерениях, MATLAB возвращает каждую возможную пару координат. Например, если вы попробуете M ([1,2], [1,3]), MATLAB вернет M(1,1) и M(2,3) но также вернет M(1,3) и M(2,1) . Это может показаться неинтуитивными , когда вы ищете элементы для списка пар координат , но рассмотрим пример большей матрицы A = rand(20) (заметим , теперь A 20 матрицу с размерностью 20 ), где вы хотите получить верхний правый квадрант. В этом случае вместо того, чтобы указывать каждую пару координат в этом квадранте (и этот случай равен 100 парам), вы просто указываете 10 строк и 10 столбцов, которые вы хотите, так что A(1:10, 11:end) . Нарезка такой матрицы гораздо более распространена, чем запрос списка пар координат.

В случае, если вы хотите получить список пар координат, самым простым решением является преобразование в линейную индексацию. Рассмотрим проблему, в которой у вас есть вектор индексов столбцов, который вы хотите вернуть, где каждая строка вектора содержит номер столбца, который вы хотите вернуть для соответствующей строки матрицы. Например

colIdx = [3;2;1]
 

Поэтому в этом случае вы действительно хотите вернуть элементы в (1,3) , (2,2) и (3,1) . Таким образом, используя линейное индексирование:

>> colIdx = [3;2;1];
>> rowIdx = 1:length(colIdx);
>> idx = sub2ind(size(M), rowIdx, colIdx);
>> M(idx)

ans = 

        6    5    4
 

Возвращение элемента несколько раз

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

>> M([1,1,1,2,2,2])

ans = 

        8    8    8    3    3    3
 

Вы можете использовать это, чтобы дублировать целые строки и столбец, например, чтобы повторить первую строку и последний столбец

>> M([1, 1:end], [1:end, end])

ans = 

        8    1    6    6 
        8    1    6    6
        3    5    7    7
        4    9    2    2
 

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

Матрицы и массивы

В MATLAB самым основным типом данных является числовой массив. Это может быть скаляр, одномерный вектор, двумерная матрица или многомерный массив ND.

% a 1-by-1 scalar value
x = 1;
 

Чтобы создать вектор строки, введите элементы внутри скобок, разделенные пробелами или запятыми:

% a 1-by-4 row vector
v = [1, 2, 3, 4];
v = [1 2 3 4];
 

Чтобы создать вектор-столбец, выделите элементы с точкой с запятой:

% a 4-by-1 column vector
v = [1; 2; 3; 4];
 

Чтобы создать матрицу, мы вводим строки, как и раньше, разделенные точкой с запятой:

% a 2 row-by-4 column matrix
M = [1 2 3 4; 5 6 7 8];

% a 4 row-by-2 column matrix
M = [1 2; ...
     4 5; ...
     6 7; ...
     8 9];
 

Обратите внимание: вы не можете создать матрицу с неравным размером строки / столбца. Все строки должны иметь одинаковую длину, и все столбцы должны иметь одинаковую длину:

% an unequal row / column matrix
M = [1 2 3 ; 4 5 6 7]; % This is not valid and will return an error

% another unequal row / column matrix
M = [1 2 3; ...
     4   5; ...
     6 7 8; ...
     9   10];     % This is not valid and will return an error
 

Чтобы транспонировать вектор или матрицу, мы используем .' -оператором, или ' оператор взять его эрмитово сопряжение, которое комплексно сопряженное транспонированной. Для реальных матриц эти два одинаковы:

% create a row vector and transpose it into a column vector
v = [1 2 3 4].';              % v is equal to [1; 2; 3; 4];

% create a 2-by-4 matrix and transpose it to get a 4-by-2 matrix
M = [1 2 3 4; 5 6 7 8].';     % M is equal to [1 5; 2 6; 3 7; 4 8]

% transpose a vector or matrix stored as a variable
A = [1 2; 3 4];
B = A.';                      % B is equal to [1 3; 2 4]
 

Для массивов более двух измерений нет прямого синтаксиса языка, чтобы вводить их буквально. Вместо этого мы должны использовать функции для их построения (такие как ones , zeros , rand ) или манипулировать другими массивами (используя такие функции, как cat , reshape , permute ). Некоторые примеры:

% a 5-by-2-by-4-by-3 array (4-dimensions)
arr = ones(5, 2, 4, 3);

% a 2-by-3-by-2 array (3-dimensions)
arr = cat(3, [1 2 3; 4 5 6], [7 8 9; 0 1 2]);

% a 5-by-4-by-3-by-2 (4-dimensions)
arr = reshape(1:120, [5 4 3 2]);
 

Чтение ввода и записи

Как и весь язык программирования, Matlab предназначен для чтения и записи в самых разных форматах. Собственная библиотека поддерживает большое количество форматов Text, Image, Video, Audio, Data с большим количеством форматов, включенных в каждое обновление версии. Здесь вы можете посмотреть полный список поддерживаемых форматов файлов и какую функцию использовать для их импорта.

Прежде чем пытаться загрузить файл, вы должны спросить себя, какими должны быть данные, и как вы ожидаете, что компьютер будет организовывать данные для вас. Скажем, у вас есть файл txt / csv в следующем формате:

Fruit,TotalUnits,UnitsLeftAfterSale,SellingPricePerUnit
Apples,200,67,$0.14
Bananas,300,172,$0.11
Pineapple,50,12,$1.74
 

Мы видим, что первый столбец находится в формате строк, а второй, третий - Numeric, последний столбец находится в форме Currency. Предположим, мы хотим найти, сколько дохода мы сделали сегодня, используя Matlab, и сначала мы хотим загрузить этот файл txt / csv. После проверки ссылки мы видим, что текстовые и текстовые типы файлов txt обрабатываются с помощью textscan . Поэтому мы могли бы попробовать:

fileID = fopen('dir/test.txt'); %Load file from dir
C = textscan(fileID,'%s %f %f %s','Delimiter',',','HeaderLines',1); %Parse in the txt/csv
 

где %s полагают, что этот элемент является строковым типом, %f предполагает, что этот элемент является типом Float и что файл разделен на «,». Опция HeaderLines запрашивает у Matlab пропустить первые N строк, а 1 сразу после этого означает пропустить первую строку (строку заголовка).

Теперь C - это данные, которые мы загрузили, которые находятся в форме массива ячеек из 4 ячеек, каждый из которых содержит столбец данных в файле txt / csv.

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

sold = C{2} - C{3}; %C{2} gives the elements inside the second cell (or the second column)
 

Теперь мы хотим умножить этот вектор на цену за единицу, поэтому сначала нам нужно преобразовать этот столбец строк в столбец Numbers, а затем преобразовать его в cell2mat матрицу, используя Matlab's cell2mat первое, что нам нужно сделать, с значком «$» есть много способов сделать это. Самый прямой способ - использовать простое регулярное выражение:

D = cellfun(@(x)(str2num(regexprep(x, '\$',''))), C{4}, 'UniformOutput', false);%cellfun allows us to avoid looping through each element in the cell.
 

Или вы можете использовать цикл:

for t=1:size(C{4},1)
   D{t} = str2num(regexprep(C{4}{t}, '\$',''));
end

E = cell2mat(D)% converts the cell array into a Matrix
 

Функция str2num превращает строку, в которой знаки «$» cell2mat на числовые типы, а cell2mat превращает ячейку числовых элементов в матрицу чисел

Теперь мы можем размножать единицы, продаваемые по цене за единицу:

revenue = sold .* E; %element-wise product is denoted by .* in Matlab

totalrevenue = sum(revenue);
 

Скрипты и функции

Код MATLAB можно сохранить в m-файлах для повторного использования. m-файлы имеют расширение .m которое автоматически связано с MATLAB. M-файл может содержать скрипт или функции.

Сценарии

Скрипты - это просто программные файлы, которые выполняют последовательность команд MATLAB в предопределенном порядке.

Скрипты не принимают входные данные, и сценарии не возвращают выходные данные. Функционально сценарии эквивалентны вводу команд непосредственно в командное окно MATLAB и их повторному воспроизведению.

Пример сценария:

length = 10;
width = 3;
area = length * width;
 

Этот скрипт будет определять length , width и area в текущей рабочей области со значениями 10 , 3 и 30 соответственно.

Как указано выше, приведенный выше сценарий функционально эквивалентен вводу одних и тех же команд непосредственно в командное окно.

>> length = 10;
>> width = 3;
>> area = length * width;
 

функции

Функции по сравнению со сценариями гораздо более гибкие и расширяемые. В отличие от сценариев, функции могут принимать входные и выходные данные для вызывающего. Функция имеет собственное рабочее пространство, это означает, что внутренние операции функций не изменят переменные от вызывающего.

Все функции определяются с одинаковым форматом заголовков:

function [output] = myFunctionName(input)
 

Ключевое слово function начинается с каждого заголовка функции. Далее следует список результатов. Список выходов также может быть списком переменных для запятой.

function [a, b, c] = myFunctionName(input)
 

Далее следует имя функции, которая будет использоваться для вызова. Это, как правило, то же имя, что и имя файла. Например, мы сохранили бы эту функцию как myFunctionName.m .

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

function [a, b, c] = myFunctionName(x, y, z)
 

Мы можем переписать пример скрипта из ранее как функцию многократного использования, например:

function [area] = calcRecArea(length, width)
   area = length * width;
end
 

Мы можем вызывать функции из других функций или даже из файлов сценариев. Ниже приведен пример нашей функции, используемой в файле сценария.

l = 100;
w = 20;
a = calcRecArea(l, w);
 

Как и раньше, мы создаем l , w и a в рабочей области со значениями 100 , 20 и 2000 соответственно.