Глава 10. Матричная лаборатория MATLAB 5.3
 
 
 
 

Система компьютерной математики MATLAB прославилась огромным числом матричных функций, высокой скоростью численных операций, мощным языком программирования, легкостью расширения пользователем, превосходными средствами графической визуализации, уникальной по объему информации справочной системой, пакетом блочного моделирования систем и устройств Simulink и др. Несмотря на свою громоздкость (MATLAB 5.3 при полной инсталляции занимает более 1 Гбайта на жестком диске), эта система широко используется в научных лабораториях и в ведущих университетах мира.

 

Начало работы с системой MATLAB 5.3

После активизации ярлыка MATLAB появляется окно системы (рис. 10.1). Вначале оно раскрыто не полностью и занимает лишь часть рабочего стола. Система сразу же готова к проведению вычислений в командном режиме, присущем самым первым реализациям ее под MSDOS.

 

Рис. 10.1. Окно системы MATLAB после запуска и выполнения простых вычислений


Сразу бросается в глаза скромность главного окна системы и его компонентов —
строки меню и панели инструментов (рис. 10.2). Строка меню MATLAB 5.3 содержит всего пять обычных для систем компьютерной математики позиций (см. главу 5).

 

Рис. 10.2. Панель инструментов системы MATLAB


Перечислим назначение десяти кнопок панели инструментов (слева направо):

• New file — вывод пустого окна редактора;

• Open file — открытие окна загрузки файла;

• Cut — перенос выделенного фрагмента в буфер обмена;

• Сору — копирование выделенного фрагмента в буфер обмена;

• Paste — вставка фрагмента из буфера обмена в текущую строку ввода;

• Undo — отмена предыдущей операции;

• Workspace Browser — вывод окна просмотра ресурсов рабочей области;

• Path Browser — вывод окна просмотра файловой структуры;

• New Simulink Model — открытие окна приложения Simulink;

• Help Windows — открытие окна справочной системы.

ПРИМЕЧАНИЕ

Обратите особое внимание на применение клавиш ­ и ¯. Они используются для подстановки после маркера строки ввода (символа ») ранее введенных строк, например для их исправления, дублирования или дополнения. При этом указанные клавиши обеспечивают круговое перелистывание ранее введенных строк снизу вверх или сверху вниз. Такая возможность существует благодаря организации специального программного стека, хранящего строки с введенными ранее командами.

Даже из нескольких простых примеров, показанных на рис. 10.1, можно сделать некоторые выводы:

• для указания места ввода исходных данных используется символ »;

• для блокировки вывода результата вычислений некоторого выражения в конце выражения надо ввести знак ; (точка с запятой);

• если не указана переменная со значением результата вычислений, MATLAB назначает такую переменную, дав ей имя ans;

• знаком присваивания является привычный математикам знак равенства =, а не комбинированный знак :=, как во многих других математических системах;

• встроенные функции (например, sin) записываются строчными буквами, и их аргументы указываются в круглых скобках;

• результат вычислений выводится в строках вывода (без знака »);

• диалог происходит в стиле “задал вопрос — получил ответ”.

Следующий пример иллюстрирует выполнение простых векторных операций:

» V=[1 234]
V =
    1  2  3  4
» sin(V)
ans
    0.8415  0.9093  0.1411  -0.7568
» exp(V)
ans
    2.7183  7.3891  20.0855  54.5982

В этот раз (и в дальнейшем) использована запись копий экрана, полученных в сеансе работы. Мы будем применять такую запись ради уменьшения числа рисунков при описании системы. При этом пробелы между строками опускаются. В приведенном примере задается четырехэлементный вектор V со значениями элементов 1,2,3 и 4. А далее (сосредоточьте на этом внимание!) вычисляются функции синуса и экспоненты с аргументом в виде вектора, а не скаляра. Векторы задаются списком своих элементов, разделяемым пробелами или запятыми. Список заключается в квадратные скобки. Для выделения n-го элемента вектора V используется выражение V(n). Оно задает соответствующую индексированную переменную. Будучи матричной системой, MATLAB любое число воспринимает как матрицу размера 1´1, а вектор с длиной n как матрицу размера n´1.

Полезно сразу усвоить некоторые команды управления окном в режиме командной строки:

• clc — очищает экран и размещает курсор в левом верхнем углу пустого экрана;

• home — возвращает курсор в левый верхний угол окна;

• echo имя_файла on — включает режим вывода на экран текста файла сценария (скрипта);

• echo имя_файла off — выключает режим вывода на экран текста файла сценария;

• echo имя_файла — меняет режим вывода файла сценария на противоположный;

• echo on all — включает режим вывода на экран текста всех m-файлов;

• wcho off all — отключает режим вывода на экран текста всех m-файлов;

• mоrе on — включает режим постраничного вывода (полезен при просмотре больших m-файлов);

• more off — отключает режим постраничного вывода (в этом случае для просмотра больших файлов надо пользоваться полосой прокрутки).

Для завершения работы с системой можно использовать команды quit, exit или комбинацию клавиш Ctrl+Z. Если необходимо сохранить значения всех переменных (векторов, матриц) системы, то перед этим следует ввести команду save нужной формы. Команда load после загрузки системы считывает значения этих переменных и позволяет начать работу с системой с того момента, когда она была прервана.

 

Файловая система MATLAB

Система MATLAB состоит из множества файлов, находящихся в различных папках. Наиболее важны файлы двух типов — с расширениями .mat и .m. Первые являются бинарными файлами, представляющими запись параметров рабочей области в сеансе работы системы. Вторые представляют собой текстовые файлы, содержащие внешние определения команд и функций системы. Особое значение имеет папка MATLAB/TOOLBOX/MATLAB. В ней содержится набор m-файлов стандартного расширения системы, называемый Toolbox. Просмотр этих файлов позволяет детально оценить возможности конкретной версии системы. Ниже перечислены основные папки набора Toolbox.

Команды общего назначения:

• General — команды общего назначения.

Операторы, конструкции языка и системные функции:

• ops — операторы и специальные символы;

• lang — конструкции языка программирования;

• strfun — строковые функции;

• iofun — функции ввода/вывода;

• timefun — функции времени и дат;

• datatypes — типы и структуры данных.

Основные математические и матричные функции:

• elmat — команды создания элементарных матриц и операций с ними;

• elfun — элементарные математические функции;

• specfun — специальные математические функции;

• matfun — матричные функции линейной алгебры;

• datafun — анализ данных и преобразования Фурье;

• polyfun — полиномиальные функции и функции интерполяции;

• funfun — функции функций и функции решения ОДУ;

• soarfun — функции разреженных матриц.

Команды графики:

• graph2d — команды двухмерной графики;

• graph3d — команды трехмерной графики;

• specgraph — команды специальной графики;

• graphics — команды графики Handle Graphics;

• uitools — графика пользовательского интерфейса.

Полный список файлов любой вложенной папки можно вывести на просмотр с помощью команды help имя, где имя — название соответствующей вложенной папки (см. выше).

 

Сохранение рабочей области

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

• save fname — сохраняется рабочая область со значениями всех переменных в файле бинарного формата с именем fname и расширением .mat;

• save fname X — сохраняется только значение переменной X;

• save fname X Y Z — сохраняются значения переменных X, Y и Z.

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

• -mat — двоичный формат, используемый по умолчанию;

• -ascii — формат ASCII единичной точности (8 цифр);

• -ascii -double — формат ASCII двойной точности (16 цифр);

• -ascii -double -tabs — формат с разделителем и метками табуляции;

• V4 — запись mat-файла в стандарте версии MATLAB;

• -append — добавление в существующий mat-файл.

Возможно задание необходимости сохранения в формате функции, например:

save('fname','var1','var2')

В этом случае имена файлов и переменных задаются строковыми константами.

 

Ведение дневника

Для записи всего сеанса работы или его фрагментов служит команда diary:

• diary имя_файла — запись на диск текстового файла с указанным именем всех команд в строках ввода и полученных результатов;

• diary off — приостанавливает запись в файл;

• diary on — вновь начинает запись в файл.

Таким образом, чередуя команды diary off и diary on, можно сохранять нужные фрагменты сеанса в их формальном виде. Команду diary можно задать и в виде функции diary('file'), где строка 'file' определяет имя файла. Рекомендуется записывать файл сеанса с расширением иным, чем .m.

 

Загрузка рабочей области

Для загрузки рабочей области предыдущего сеанса работы можно использовать команду load fname с указанием спецификаций. Она обеспечивает загрузку ранее сохраненных в mat-файле определений со спецификациями, подобными описанным для команды save (включая ключ -mat для загрузки файлов с расширением .mat обычного бинарного формата, используемого по умолчанию). Допускается также команда load('fname',...) — загрузка файла fname в форме функции. Если команда (или функция) load вводится в ходе сеанса работы, произойдет замена значений текущих переменных теми значениями, которые были сохранены в считываемом mat-файле. Правила задания имен файлов самые обычные.

 

Средства работы с файлами расширений

Полноценные программные модули позволяет создавать редактор/отладчик (editor/ debugger) файлов сценариев (скриптов). Окно редактора/отладчика (рис. 10.3) открывается при выборе команды New меню File и выборе в качестве создаваемого файла m-файла.

 

Рис. 10.3. Окна редактора/отладчика, а также программ просмотра файловой системы и рабочей области


Редактор/отладчик является полноценным
Windows-приложением и позволяет готовить и отлаживать m-файлы. Назначение кнопок его панели инструментов приводится ниже:

• New — создание нового пустого окна для ввода m-файла;

• Open — вывод окна загрузки файла;

• Save — запись файла на диск под текущим именем;

• Cut — перенос выделенного фрагмента в буфер обмена;

• Сору — копирование выделенного объекта в буфер обмена;

• Paste — вставка фрагмента из буфера обмена на место расположения курсора;

• Print — печать содержимого текущего окна редактора/отладчика;

• About — вывод данных о версии редактора/отладчика;

• Set/Clear Breakpoint — установка/удаление точки останова;

• Clear All Breakpoint — удаление всех точек останова;

• Step In — установка точки входа в m-файл;

• Single Step — выполнение одного шага;

• Continue — продолжение работы;

• Quit Debugging — завершение отладки.

В меню View редактора/отладчика имеются команды для доступа к программам просмотра файловой системы (Path Browser) и рабочей области (Workspace Browser). Первая позволяет работать с файловой системой MATLAB, а вторая — контролировать заполнение рабочей области, в которой хранятся определения данного сеанса работы (см. рис. 10.3). Команды для доступа к этим программам имеются также в меню File главного окна системы MATLAB.

Редактор/отладчик позволяет вводить тексты программ построчно. Для наглядности программ их основные элементы раскрашиваются разными цветами. Можно вводить в программы точки останова, в которых контролируется работа программ, например, путем вывода значений переменных. Проводится синтаксический контроль вводимой программы. Обратите особое внимание на выбор имен m-файлов — они должны быть уникальными и не повторять имен уже имеющихся m-файлов.

Работать с редактором/отладчиком достаточно просто, и его легко освоить самостоятельно. На первых порах достаточно пользоваться кнопками панели инструментов. Созданный файл (рис. 10.4) можно запустить командой Run меню Tools редактора/отладчика.

 

Рис. 10.4. Задание m-файла в редакторе/отладчике и его запуск


Иногда возникает необходимость просмотра заданного
m-файла. Для этого можно использовать команду type имя_m-файла. Однако для редактирования файла надо пользоваться описанным выше редактором/отладчиком.

Специальное приложение notebook.m после его загрузки в текстовый редактор Word 95/97 обеспечивает объектную связь редактора с системой MATLAB и обеспечивает подготовку высококачественных текстов с “живыми” примерами из MATLAB.

 

Входной язык системы MATLAB

 

Понятие о математическом выражении и числах

В MATLAB математические выражения записываются построчно, как это принято в большинстве языков программирования:

2+3
2.301*sin(x)
4+ехр(3)/5
sqrt(y)/2
sin(pi/2)

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

0         2             -3            2.301
0.00001   123.456е-24   -234.456е10   3i
2j        2+3i          -3.141i       
-123.456+2.7е-3

Функция real(z) возвращает действительную часть комплексного числа z, a функция imag(z) — мнимую. Для получения модуля комплексного числа используется функция abs(z), а для вычисления фазы — angle(z). Действие этих функций очевидно.

Операции над числами выполняются в формате с двойной точностью. Такой формат удовлетворяет подавляющему большинству требований к численным расчетам. Символьные вычисления MATLAB может выполнять с помощью специального пакета расширения Symbolic. В нем используется ядро системы Maple V R5 (см. главу 8), поэтому в этой главе символьные вычисления не описаны. Для переноса длинных строк используется многоточие (3 или более точек), например:

s = 1 - 1/2 + 1/3 - 1/4 + 1/5 -1/6 + 1/7 ...
1/8 + 1/9 - 1/10 + 1/11 - 1/12;

Этот прием может быть весьма полезным для обеспечения наглядности документов (чтобы строки не оказывались вне видимой области окна). Вообще говоря, максимальное число символов в одной строке — 4096 (в ранних версиях оно ограничивалось 256), но со столь длинными строками работать неудобно.

 

Системные переменные и символьные константы

В MATLAB используются следующие системные переменные:

• i или — мнимая единица (корень квадратный из -1);

• pi — число “пи” 3,1415926...;

• eps — погрешность для операций над числами с плавающей точкой (2-52);

• realmin — наименьшее число с плавающей точкой (2-1022);

• realmax — наибольшее число с плавающей точкой (21023);

• inf — значение машинной бесконечности;

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

• NaN — указание на нечисловой характер данных (Not a Number).

Системные переменные могут переопределяться. Так, можно задать системной переменной eps иное значение, например eps=0.0001. Важно то, что значения системных переменных по умолчанию задаются сразу после загрузки системы. Поэтому неопределенными, в отличие от обычных переменных, системные переменные не могут быть никогда.

Символьная константа — это цепочка символов, заключенных в символы одиночной кавычки, например:

'Hello, my friend! '
'Привет'
'2+3'

Если в одиночные кавычки помещено математическое выражение, оно не вычисляется, а рассматривается просто как цепочка символов. Таким образом, выражение '2+3' не будет возвращать число 5. Однако с помощью специальных функций преобразования символьные выражения могут быть преобразованы в вычисляемые.

 

Текстовые комментарии

Текстовые комментарии вводятся с помощью оператора %, например:

%Ниже представлено задание функции вычисления факториала

Обычно в определениях m-файлов первые строки определений служат для их описания, которое выводится на экран дисплея после команды

» help Имя_файла

Считается правилом хорошего тона вводить достаточно подробные текстовые комментарии, в частности, в m-файлы.

 

Переменные и работа с ними

В системе MATLAB можно задавать переменным определенные значения. Для этого используется операция присваивания, вводимая оператором равенства = (например, х=123). Типы переменных заранее не объявляются, а определяются выражением, значение которого присваивается переменной. Имя переменной (ее идентификатор) может содержать сколько угодно символов, но сохраняются и идентифицируются только первые 31 символ.

В памяти переменные занимают определенное место, называемое рабочей областью (workspace). Средство для ее просмотра уже описывалось. Для очистки рабочей области используется функция clear в разных формах, например:

• clear — удаление определений всех переменных;

• clear х — удаление определения переменной х;

• clear a, b, с — удаление определений переменных списка и т. д.

Для дефрагментации всей рабочей области памяти служит команда pack. Удаленная переменная становится неопределенной.

 

Операторы и функции MATLAB

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

» help ops

Постепенно мы рассмотрим все операторы системы MATLAB и обсудим особенности их применения. А пока приведем только арифметические операторы:

» help ops
Operators and special characters.
Arithmetic operators.
    plus     - Plus
    uplus    - Unary plus
    minus    - Minus
    uminus   - Unary minus
    mtimes   - Matrix multiply
    times    - Array multiply
    mpower   - Matrix power
    power    - Array power

Функции в общем случае имеют список аргументов (параметров), заключенный в круглые скобки. Например, функция Бесселя записывается как bessel(NU, X). В данном случае список параметров содержит два аргумента — NU в виде числа и X в виде вектора. Многие функции допускают ряд форм записи, например, различающихся списком своих параметров. Если функция возвращает несколько значений, то она записывается в виде

[Y1, Y2,...]=func(X1, X2,...),

Здесь Y1, Y2, ... — список выходных параметров и Х1, Х2, ... — список входных параметров.

Со списком элементарных функций можно ознакомиться, выполнив команду help elf un, а со списком специальных функций — команду help specfun.

Функции могут быть встроенными (внутренними) и внешними (М-функциями). Так, встроенными являются наиболее распространенные элементарные функции, например sin(x) и ехр(у), тогда как функция sinh(x) является внешней. MATLAB поддерживает также множество специальных математических функций, пользоваться которыми так же просто, как и элементарными.

 

Оператор двоеточие

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

Начальное_значение:Шаг:Конечное_значение

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

• Начальное_значение < Конечное_значение, если Шаг > 0;

• Начальное_значение > Конечное_значение, если Шаг < 0.

Если шаг не задан, то он принимается равным 1 или -1 в указанных соотношениях Примеры применения оператора : даны ниже:

» 1:5
ans =
    1   2   3   4   5
» i=0:2:10
i =
    0   2   4   6   8   10
» j=10:-2:2
j =
    10   8   6   4   2
» V=0:pi/2:2*pi;
» V
V =
    0   1.5708   3.1416   4.7124   6.2832
» Х=1:-.2:0
X =
    1.0000   0.8000   0.6000   0.4000   0.2000   0

Как отмечалось, принадлежность MATLAB к матричным системам вносит коррективы в назначение операторов и приводит, при неумелом их использовании, к казусам. Рассмотрим следующий характерный пример:

» х=0:5
х =
    0   1   2   3   4   5
» cos(x)
ans =
    1.0000   0.5403   -0.4161   -0.9900   -0.6536   0,2837
» sin(x)/x
ans =
    -0.0862

Вычисление массива косинусов здесь прошло корректно. А вот вычисление массива функции sin(x)/x дает “неожиданный” эффект — вместо массива с шестью элементами вычислено единственное значение. Причина “парадокса” здесь в том, что оператор / вычисляет отношение двух матриц, векторов или массивов. Если они одной размерности, то результат будет одним числом, что в данном случае и выдала система. Чтобы действительно получить массив значений sin(x)/x, надо использовать специальный оператор почленного деления массивов — ./. Тогда будет получен массив чисел:

» sin(x)./x
Warning: Divide by zero.
ans =
    NaN   0.8415   0.4546   0.0470   -0,1892   -0.1918

Впрочем, и тут без особенностей не обошлось. Так, при х=0 значение sin(x)/x дает устранимую неопределенность вида 0/0=1. Однако, как и всякая численная система, MATLAB классифицирует попытку деления на 0 как ошибку и выводит соответствующее предупреждение. А вместо ожидаемого численного значения выводится символьная константа NaN, означающая, что неопределенность 0/0 — это все же необычное число.

Выражения с оператором : могут использоваться в качестве аргументов функций для получения множественных их значений. Например, в приводимом ниже примере вычислены функции Бесселя порядка от 0 до 5 со значением аргумента х=0.5:

х=1/2:
» bessel(0:1:5,1/2)
ans =
    0.9385   0.2423   0.0306   0.0026   0.0002   0.0000

А в следующем примере вычислено шесть значений функции Бесселя нулевого порядка для значений аргумента от 0 до 5 с шагом 1:

» bessel(0,0:1:5)
ans =
    1.0000   0.7652   0.2239   -0,2601   -0.3971   -0.1776

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

 

Сообщения об ошибках и исправление последних

Важное значение при диалоге с системой MATLAB имеет диагностика ошибок. Пример вывода предупреждения об ошибке (деление на 0) только что приводился. Рассмотрим еще ряд примеров. Введем, к примеру, ошибочное выражение:

» sqr(2)

Теперь нажмем клавишу Enter. Система сообщит об ошибке:

??? Undefined function or variable 'sqr'.

Это сообщение говорит, что не определена переменная или функция, и указывает, какая именно — sqr. В данном случае, разумеется, можно просто набрать правильное выражение. Однако в случае громоздкого выражения лучше воспользоваться редактором. Для этого достаточно нажать клавишу перелистывания строк ¯. В результате появится выражение

» sqr(2)

Теперь с помощью клавиши ® следует установить курсор после буквы r и нажать клавишу t на нижнем регистре, а затем — клавишу Enter. Выражение примет вид

» sqrt(2)
ans =
    1.4142

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

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

» hsin(1)
??? Undefined function or variable 'hsin'.
» sinh(1)
ans =
    1.1752

Иногда, что уже отмечалось, в ходе вывода данных вычислений появляется сокращение NaN (от слов Not a Number — не число). Оно обозначает операцию неопределенности, например вида 0/0 или Inf/Inf. Могут появляться и различные предупреждения об ошибках (на английском языке). Например, при делении на 0 конечного числа появляется предупреждение Warning: Dievide by Zero. (Внимание: Деление на 0). Весь диапазон представления чисел в системе лежит от 10-308 до 10+308.

Вообще говоря, в MATLAB надо отличать предупреждение об ошибке от сообщения о ней. Предупреждения (обычно после слова Warning) не останавливают вычисления и лишь предупреждают пользователя о том, что диагностируемая ошибка способна повлиять на ход вычислений. Сообщение об ошибке (после знаков ???) останавливает вычисления.

 

Форматы чисел

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

х=[4/3 1.2345е-6]
format short    1.3333                   0.0000
format short e  1.3333E+000              1.2345E-006
format long     1.333333333333338        0.000001234500000
format long e   1.333333333333338E+000   1.234500000000000E-006
format bank     1.33                     0.00

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

 

Основы работы с векторами и матрицами

 

Особенности задания векторов и матриц

Мы уже рассмотрели задание векторов в квадратных скобках. Задание матрицы требует указания различных строк. Для разделения строк используется знак ; (точка с запятой). Этот же знак (или знак запятой) в конце ввода предотвращает вывод матрицы или вектора на экран дисплея. Рассмотрим следующий ввод:

» М=[1 2 3; 4 5 6; 7 8 9];

Это выражение задает квадратную матрицу, которую можно вывести:

» М
M =
    1   2   3
    4   5   6
    7   8   9

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

» V= [2+2/(3+4) ехр(5) sqrt(10)];
» V
V =
    2.2857   148.4132   3.1623

Для указания отдельного элемента вектора или матрицы используются выражения вида V(i) или М(i;j). Например:

» М(2;2)
ans =
    5

Если нужно присвоить элементу M(i;j) новое значение х, следует использовать выражение M(i;j)=x. Например, если элементу М(2;2) надо присвоить значение 10, следует записать следующее:

» М(2;2)=10

Выражение М(i) с одним индексом дает доступ к элементам столбцов матрицы. Такая матрица образуется из исходной, если подряд выписать ее столбцы. Следующий пример поясняет такой доступ к элементам матрицы М:

» М=[1 2 3; 4 5 6; 7 8 9]
М =
    1   2   3
    4   5   6
    7   8   9
» М(2)
ans =
    4
» M(8)
ans =
    6
» M(9)
ans =
    9
» M(5)=100;
» M
М =
    1   2    3
    4   100  6
    7   8    9

Возможно задание векторов и матриц с комплексными элементами, например:

» i=sqrt(-1);
» СМ = [1 2; 3 4] + 1*[5 6; 7 8]

Еще пример:

» СМ = [1+5*i 2+6*i; 3+7*i 4+8*i]

Последнее выражение создает следующую матрицу:

1+5*i   2+6*i
3+7*i   4+8*i

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

Имеется также ряд особых функций для задания векторов и матриц. Например, функция magic(n) задает магическую матрицу размера n´n, у которой сумма всех столбцов, всех строк и даже диагоналей равна одному и тому же числу:

» M=magic(4)
М =
    16   2    3    13
    5    11   10   8
    9    7    6    12
    4    14   15   1
» sum(M)
ans =
    34   34   34   34
» sum(M')
ans =
    34   34   34   34
» sum(diag(M))
ans =
    34
» M(1,2)+M(2,2)+M(3,2)+M(4,2)
ans =
    34

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

 

Объединение малых матриц в большую

Описанный способ задания матриц позволяет выполнить операцию конкатенации — объединения малых матриц в большую. Например, создадим вначале магическую матрицу размера 3´3:

» A=magic(3)
А =
    8   1   6
    3   5   7
    4   9   2

Теперь можно построить матрицу, содержащую четыре матрицы:

» В=[А А+16;А+32 А+16]
В =
    8    1    6    24   17   22
    3    5    7    19   21   23
    4    9    2    20   25   18
    40   33   38   24   17   22
    35   37   39   19   21   23
    36   41   34   20   25   18

Полученная матрица имеет уже размер 6´ 6. Вычислим сумму ее столбцов:

» sum(B)
ans =
    126   126   126   126   126   126

Любопытно, что она одинакова для всех столбцов. А для вычисления суммы строк используем команду

» sum(B')
ans =
    78   78   78   174   174   174

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

» D=magic(6)
D =
    35   1    6    26   19   24
    3    32   7    21   23   25
    31   9    2    22   27   20
    8    28   33   17   10   15
    30   5    34   12   14   16
    4    36   29   13   18   11
» sum(D)
ans =
    111   111   111   111   111   111
» sum(D')
ans =
    111   111   111   111   111   111

Более того, одинаковой является и сумма элементов по основным диагоналям.

 

Удаление столбцов и строк матриц

Для формирования матриц и выполнения ряда матричных операций возникает необходимость удаления отдельных столбцов и строк матрицы. Для этого используются пустые квадратные скобки [ ]. Проделаем это над матрицей М:

» М=[1 2 3; 4 5 6; 7 8 9]
М =
    1   2   3
    4   5   6
    7   8   9

Удалим второй столбец:

» М(:,2)=[ ]
М =
    1   3
    4   6
    7   9

А теперь удалим вторую строку:

» М(2,:)=[ ]
М =
    1   3
    7   9

 

Обзор матричных функций

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

• еуе(n) — единичная матрица размера n´n;

• ones(n) — матрица с единичными элементами;

zeros(n) — матрица с нулевыми элементами;

• rand(n) — матрица со случайными элементами;

• hadamar(n) — матрица Адамара;

• hilb(n) — матрица Гильберта;

• magic(N) — магическая матрица;

• pascal(n) — матрица Паскаля;

• toeplitz(n) — матрица Теплица;

• wilkinson(n) — матрица Уилкинсона и др.

Для одиночной квадратной матрицы А существует ряд функций:

• diag(А) — главная диагональ матрицы;

• fliplr(A) — матрица с переставленными относительно вертикальной оси элементами;

• flipud(A) — матрица с переставленными относительно горизонтальной оси элементами;

• prod(А) — вектор произведений элементов каждого столбца;

• sum(A) — вектор сумм элементов каждого столбца;

• rot90(A) — поворот матрицы на 90°;

• tril(A) — нижняя треугольная часть матрицы;

• triu(A) — верхняя треугольная часть матрицы и др.

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

• cond(A) — число обусловленности, основанное на второй норме;

• condeig(A) — вектор чисел обусловленности для собственных значений матрицы;

• det(A) — детерминант (определитель) матрицы;

• rank(A) — ранг матрицы;

• norm(A) — наибольшее сингулярное значение;

• orth(A) — ортонормальный базис матрицы;

• null(А) — ортонормальный базис для нулевого пространства;

• rref(A) — треугольная форма (приведение по методу исключения Гаусса с частичным выбором ведущего элемента);

• trace(А) — след матрицы;

• сhol(А) — верхняя треугольная матрица, полученная по методу разложения Холецкого;

• inv(A) — обращенная матрица (А-1);

• lu(A) — LU-разложение матрицы;

• qr(А) — QR-разложение матрицы;

• eig(A) — вектор собственных значений матрицы;

• hess(A) — верхняя форма Хессенберга;

• schur(A) — матрица Шура и т. д.

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

Следующий пример дает решения системы из четырех линейных уравнений А•Х=В тремя точными методами:

А=[2    1    0    1;
   1   -3    2    4;
  -5    0   -1   -7;
   1   -6    2    6];
В=[8    9   -5    0];
Х1=В/А
Х2=В*А
^-1
X3=B*inv(A)
Х1 =
    
3.0000   -4.0000   -1.0000   1.0000
Х2 =
    3.0000   -4.0000   -1.0000   1.0000
X3 =
    3.0000   -4.0000   -1.0000   1.0000

Функция nnls(A, В) и ряд ее вариантов решают систему линейных уравнений с минимизацией ошибки по методу наименьших квадратов (см. пример ниже):

» С=[4 3;12 5;3 12];b=[1,45,41];D=nnls(C, b')
D =
    2.2242
    2.6954

Для решения систем линейных уравнений с разреженными матрицами MATLAB предлагает ряд функций, реализующих различные методы решения:

• bicg (А, В) — двунаправленный метод сопряженных градиентов;

• bicgstab(A, В) — устойчивый двунаправленный метод;

• cgs(A, В) — квадратичный метод сопряженных градиентов;

• gmres(A, В, restart) — метод минимизации обобщенной невязки;

• рсg(А, В) — метод сопряженных градиентов;

• qmr(A, В) — метод квазиминимизации невязки.

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

 

Графическая визуализация вычислений

 

Построение графиков функций одной переменной

В режиме непосредственных вычислений доступны практически все возможноcти системы. Широко используется, например, построение графиков различных функций, дающих наглядное представление об их поведении в широком диапазоне изменения аргумента. При этом графики строятся в отдельных масштабируемых и перемещаемых окнах (см. рис. 10.4). Попытаемся построить графики сразу трех функций: sin(x), cos(x) и sin(x)/x. На рис. 10.5 показан один из вариантов построения графика трех функций.

 

Рис. 10.5. Построение на одном рисунке графиков трех функций

 

Построение гистограммы

В прикладных расчетах часто встречаются графики, именуемые гистограммами. Чаще всего используются столбиковые гистограммы (или диаграммы), отражающие содержание некоторого вектора V. При этом каждый элемент вектора представляется столбиком, высота которого пропорциональна значению элемента (рис. 10.6). Столбики нумеруются и масштабируются по отношению к максимальному значению наиболее высокого столбика. Реализует построение команда bar(V).

 

Рис. 10.6. Построение гистограммы значений элементов вектора


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

 

Построение трехмерных графиков поверхностей

Столь же просто обеспечивается построение графиков сложных поверхностей (рис. 10.7).

 

Рис. 10.7. Окно с трехмерным графиком поверхности и ее проекции на плоскость под фигурой


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

 

Построение на одном рисунке графиков разного типа

MATLAB поддерживает возможность построения многих десятков типов графиков, которые можно разнообразить дополнительными параметрами и средствами описательной (дескрипторной) графики. Разумеется, в небольшой главе по этой системе невозможно упомянуть все типы графиков. Так что ограничимся еще одним примером — построением на одном рисунке графиков четырех типов: функции в декартовой системе координат, двух параметрически заданных функций в полярной системе координат, контурного графика поверхности и самой поверхности с функциональной окраской. Рис. 10.8 иллюстрирует реализацию этого примера с оформлением построений в виде файла-сценария в редакторе/отладчике с последующим запуском программы.

 

Рис. 10.8. Построение графиков четырех типов


Для разбивки окна графики на 4 подокна используется графическая функция
subplot (m, n, р), где m и n — число подокон по горизонтали и вертикали, р — порядковый номер графика.

 

Работа с интерактивной справочной системой

 

Команда help

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

» help

Ниже этот список приводится частично:

HELP topics:
MATLAB\general   - General purpose commands.
MATLAB\ops       - Operators and special characters.
MATLAB\lang      - Programming language constructs.
.........................................................
simulink\dee     - Differential Equation Editor
toolbox\tour     - MATLAB Tour
toolbox\local    - Preferences.
For more help on directory/topic, type "help topic".

Этот список (в полном виде весьма внушительный) дает наглядное представление о пакетах прикладных программ, расширяющих возможности системы MATLAB и содержащих массу серьезных примеров применения системы. Для получения справки по какому-либо конкретному объекту используется команда

» help имя

Здесь имя — имя объекта, для которого требуется вывод справочной информации. Мы уже приводили пример помощи по разделу операторов — папки ops. Ниже дается пример для функции вычисления гиперболического синуса, намеренно введенного с неверным указанием имени:

» help hsin
hsin.m not found.

Система помощи сообщает, что для функции с именем hsin соответствующий m-файл отсутствует. Если ввести имя верно, то полученное сообщение будет содержать информацию о функции sinh:

» help sinh
    SINHHyperbolic sine.
        SINH(X) is the hyperbolic sine of the elements of X.
        Overloaded methods
        help sym/sinh.m

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

Аналогичным образом можно получить справку по константам и другим объектам языка MATLAB. Ниже дан пример обращения к справке о числе “пи”:

» help pi
    PI    3.1415926535897... .
        PI = 4*atan(1) = imag(log(-1)) = 3.1415926535897... .

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

 

Справка по ключевому слову

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

• lookfor Ключевое слово;

• lookfor 'Ключевые слова'.

В первом случае ищутся все m-файлы, в заголовках которых встречается заданное ключевое слово, а сами заголовки обнаруженных файлов выводятся на экран. Следует отметить, что широкий поиск по одному ключевому слову может привести к выводу подчас многих десятков определений. Для уточнения и сокращения поиска следует использовать вторую форму команды lookfor. Вот пример ее применения:

» lookfor 'inverse sin'
ASIN   Inverse sine.
ASIN   Symbolic inverse sine.

В данном случае для поиска использованы слова 'inverse sin', то есть задан поиск арксинуса. Система поиска нашла только два вида арксинуса ASIN — обычного и в символьной форме. Число найденных определений зависит от того, с каким числом пакетов прикладных программ (расширений) поставляется версия системы MATLAB.

 

Некоторые дополнительные справочные команды

В командном режиме можно получить справочные данные с помощью ряда команд:

• computer — выводит сообщение о типе компьютера, на котором установлена текущая версия MATLAB;

• script — выводит сообщение о назначении m-файлов сценариев;

• function — выводит сообщение о назначении и структуре m-файлов — функций;

• info — выводит информацию о применяемых вычислительных системах и наборе компонентов системы MATLAB;

• ver — выводит информацию об установленной версии системы MATLAB и ее компонентах;

• version — выводит краткую информацию об установленной версии MATLAB;

• what — выводит имена файлов текущей папки;

• what name — выводит имена файлов в заданной папке с именем name;

• whatsnew name — выводит на экран содержимое файлов readme заданного именем name класса для знакомства с последними изменениями в системе и в пакетах прикладных программ;

• which name — выводит данные о функции с именем name и пути доступа к ней.

Как правило, эти команды выводят довольно обширные сообщения. Ниже показан пример применения двух команд этой группы:

» computer
ans =
    PCWIN
» version
ans =
    5.2.1.1420

 

Работа с демонстрационными примерами

 

Вызов списка демонстрационных примеров

Система MATLAB содержит многие сотни примеров — практически на каждый оператор или функцию. Наиболее поучительные примеры можно найти в разделе demos, выполнив команду

» help demos

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

 

Иллюстрация работы с расширением Simulink

MATLAB позволяет работать с десятками внешних расширений, охватывающих все сферы математических расчетов и машинного моделирования систем и устройств. Одно из них — Simulink. Оно удостоено особой чести — включения в поставку систем MATLAB. Simulink — это программная система с визуально-ориентированным программированием, предназначенная для моделирования поведения систем и устройств, представленных своими блочными моделями.

Работа с Simulink напоминает игры с детскими конструкторами. Из обширной библиотеки блоков выбираются нужные и переносятся в главное окно построения модели. Делается это настолько естественно, что не требует особых усилий по изучению. Блоки соединяются друг с другом связями, и их параметры устанавливаются с помощью окон установок параметров (двойной щелчок на блоке вызывает появление окна параметров). Остается запустить модель щелчком на кнопке с изображением треугольника.

Сила Simulink в большой библиотеке блоков и простоте подготовки моделей. Кроме того, Simulink автоматически составляет математические уравнения, описывающие работу моделей, и позволяет с помощью регистрирующих виртуальных измерительных приборов просматривать изменения тех или иных параметров во времени или при изменении других параметров.

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

 

Реализация численных методов в среде MATLAB

 

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

Для нахождения значений аргумента х функции f(х) одной переменной, при котором значение функции равно нулю, служит функция fzero('fun', х, [0]). Она возвращает уточненное значение х, при котором достигается нуль функции fun, представленной строкой, при начальном значении аргумента х. Возвращенное значение близко к точке, где функция меняет знак, или равно NaN, если такая точка не найдена.

Для поиска корня в интервале [х1, х2] надо задать х в виде вектора х=[х1 х2]. Допускается задание различных необязательных параметров (на такую возможность указывают квадратные скобки [0]). Например, fzero('fun', х, tol) возвращает результат с заданной погрешностью tol, a fzero('fun', х, tol, trace) выдает на экран информацию по каждой итерации.

Рассмотрим следующий пример. Пусть задана следующая функция:

function f=fun1(x)
f=0.25*x+sin(x)-1;

Если построить график этой функции (сделайте это самостоятельно), можно сделать вывод, что значения корней заключены примерно в интервалах [0.5 1 ], [2 3] и [5 6]. Найдем их, используя функцию fzero:

» x1=fzero('fun1',[0.5 1]).
х1 =
    
0.8905
» x2=fzero('fun1',[2 3])
х2 =
    
2.8500
» x3=fzero('fun1',[5,6])
х3=
    
5.8128
» x3=fzero('fun1',5,0.001)
х3 =
    5.8111

Обратите внимание на то, что корень х3 найден двумя способами и что его значения в третьем знаке после десятичной точки отличаются в пределах заданной погрешности tol=0.001. К сожалению, разом найти все корни функция fzero не в состоянии. Для решения систем нелинейных уравнений следует использовать функцию solve из пакета Symbolic. Эта функция способна выдать результат в символьной форме, а если такого нет — получить решение в численном виде.

 

Решение задач по поиску экстремальных элементов массивов

В системе MATLAB определены следующие функции для нахождения минимальных и максимальных элементов массивов. Для поиска максимальных элементов используется функция max в ряде форм:

• max(А) — возвращает наибольший элемент, если А — вектор, или возвращает вектор-строку, содержащую максимальные элементы каждого столбца, если А — матрица;

• mах(А, В) — возвращает массив того же размера, что А и В, каждый элемент которого есть максимальный из соответствующих элементов этих массивов;

• mах(А, [ ], dim) — возвращает наибольший элемент по столбцам или по строкам матрицы в зависимости от значения скаляра dim (например, mах(А, [ ], 1) возвращает максимальные элементы каждого столбца матрицы А);

• [C,I] = max(А) — кроме максимальных значений, возвращает вектор индексов этих элементов.

Для быстрого нахождения элемента массива с минимальным значением служит функция min с теми же параметрами, что и у функции max. Работа указанных функций базируется на сравнении численных значений элементов массива А, что и обеспечивает высокую скорость выполнения операций.

 

Минимизация функции одной переменной

Еще одна важная задача численных методов — поиск минимума функции f (х) в некотором интервале изменения х — от х1 до х2. Если нужно найти максимум такой функции, то достаточно поставить знак минус перед функцией. Для решения этой задачи используется функция fmin в следующих вариантах:

• fmin('fun', х1, х2) — возвращает значение х, которое является локальным минимумом функции fun(x) на интервале х1<х<х2;

• fmin('f un', х1, х2, options) — сходна с описанной выше функцией, но использует контрольные параметры options (см. ниже) для управления ходом решения;

• fmin('fun', х1, х2, options, Р1, Р2, ...) — сходна с описанной выше, но передает аргументы в целевую функцию fun(x, Р1, Р2,...), если options — пустая матрица, то используются параметры по умолчанию;

• [х, options] = fmin(...) — дополнительно возвращает вектор контрольных параметров options, в десятом столбце которого содержится число выполненных итераций.

В этих представлениях х1, х2 — интервал, на котором ищется минимум функции, Р1, Р2... — передаваемые в функцию аргументы, fun — строка, содержащая название функции, которая будет минимизирована, options — вектор контрольных параметров, имеющий 18 компонент. Только 3 из них используются функцией fmin:

• options(1) — если параметр не равен 0, то отображаются промежуточные шаги решения (по умолчанию значение options(1) равно 0);

• options(2) — задается итерационная погрешность, по умолчанию она равна 1.е-4;

• options(14) — задается максимальное число итераций, по умолчанию равное 500.

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

» fmin('cos',3,4,[0,1.6-10])
х =
    3.1416

 

Минимизация функции ряда переменных

Значительно сложнее задача минимизации функций ряда переменных f(x1,x2,...). При такой минимизации значения переменных представляются вектором х, причем начальные значения задаются вектором х0. Для минимизации функций ряда переменных MATLAB использует симплекс-метод Нелдера—Мида. Реализующая его функция записывается в виде:

• fmins('fun', х0) — возвращает вектор х, который является локальным минимумом функции fun(x) вблизи точки х0;

• fmins('fun', х0, options) — аналогична описанной выше функции, но использует вектор контрольных параметров options.

• fmins( 'fun', х0, options, [], Р1, Р2, ...) — сходна с описанной выше функцией, но передает аргументы в целевую функцию fun(x, Р1, Р2, ...), если options — пустая матрица, то используются параметры по умолчанию;

• [х, options] = fmins(...) — дополнительно возвращает вектор контрольных параметров options, в десятом столбце которого содержится число выполненных итераций.

Можно использовать 4 параметра:

• options(1) — вывод промежуточных результатов (0 — вывода нет, 1 — вывод есть);

• options(2) — задание итерационной погрешности для аргумента (по умолчанию 1е-4);

• options(3) — задание итерационной погрешности для функции (по умолчанию 1е-4);

• options(14) — задание максимального количества итераций (по умолчанию 0, максимум 200´n, где n — число переменных).

Классическим примером применения функции fmins является поиск минимума тестовой функции Розенброка, точка минимума которой находится в овраге с “плоским дном”:

% Тестовая функция Розенброка
function f=rb(x,a)
if nargin<2 a=1; end
f=100*(x(2)-x(1)^2)^2+(a-x(1))^2;

Минимальное значение этой функции равно нулю и достигается в точке [а а2]. В качестве примера уточним значения х1 и х2 в точке [-1.2 1 ]:

» [xmin, opt]=fmins('rb',[-1.2 1],[0 1e-6]);
» xmin
xmin =
    1.0000   1.0000

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

Для минимизации функций ряда переменных можно использовать также функции fminu и leastsq. Первая из них позволяет задать в списке параметров вектор градиентов, вторая реализует метод наименьших квадратов и, как правило, дает наименьшее число итераций при минимизации. Ограничимся приведением примеров их применения для функции Розенброка:

» [xmin, opt]=fminu('rb',[-1.2 1],[0 1e-6]);
» xmin
xmin =
    1.0000   1.0000
» [xmin, opt]=leastsq('rb',[-1.2 1],[0 1e-6]);
maximum number of iterations has been exceeded
» xmin
xmin =
    -0.9151   0.8412

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

 

Аппроксимация производных конечными разностями

Одним из важнейших приложений конечно-разностных методов является приближенное представление производных функций — численное дифференцирование. Оно реализуется функцией diff:

• dif f(X) — возвращает конечные разности смежных элементов массива X (если — вектор, то diff(X) возвращает вектор разностей соседних элементов [Х(2)-Х(1) Х(3)-Х(2) ... Х(n)-Х(n-1)], у которого количество элементов на единицу меньше, чем у исходного вектора X, если — матрица, то diff(X) возвращает матрицу разностей столбцов: [Х(2:m,:)-Х(1:m-1,:)]);

• diff(X,n) — возвращает конечные разности порядка n (например, diff(X, 2) — это то же самое, что и diff(diff(X))).

Пример:

» Х=[1 2 4 6 7 9 3 45 6 7]
X =
    1   2   4   6   7   9   3    45   6   7
» Y = diff(X)
Y =
    1   2   2   1   2  -6   42  -39   1

Пакет расширения Symbolic позволяет выполнять дифференцирование функций в аналитическом виде, то есть точно. Это, однако, не всегда нужно.

 

Численное интегрирование

Численное интегрирование таблично заданной функции методом трапеций с накоплением выполняет функция cumtrapz(Y), а просто по методу трапеций — функция trapz(Y). Шаг отсчетов при этом принимается равным 1. Пример:

» Х=0:pi/70:pi/2;
» Y=cos(X);
» Z = trapz(Y)
2 =
    22.2780

Более удобные и точные функции quad и quad8 реализуют два различных алгоритма квадратуры для вычисления определенного интеграла. Функция quad выполняет интегрирование по методу низкого порядка, используя рекурсивное правило Симпсона:

• quad('fun', a, b) — возвращает вычисленное значение определенного интеграла от заданной функции 'fun' на отрезке [а b] (используется адаптивный метод Симпсона);

• quad('fun', a, b, tol) — возвращает вычисленное значение определенного интеграла с заданной относительной погрешностью tol (по умолчанию tol=1.е-3, можно также использовать вектор, состоящий из двух элементов, tol = [rel_tol abs_tol], чтобы точно определить комбинацию относительной и абсолютной погрешностей);

• quad('fun', a, b, tol, trace) — возвращает вычисленное значение определенного интеграла и при значении trace, не равном нулю, строит график, показывающий ход вычислений интеграла.

Примеры:

» q = quad('exp',0,2,1е-4)
q =
    6.3891
» q = quad('sin',0, pi, 1e-3)
q =
    2.0000

Функция quads выполняет интегрирование по методу более высокого порядка, используя квадратурные формулы Ньютона—Котеса 8-го порядка.

 

Операции над полиномами

MATLAB имеет обширные средства для проведения операций с полиномами: сложения, вычитания, умножения и деления полиномов. Функция conv(u, v) возвращает свертку векторов и и v. Функция polyval(p,x) возвращает значения полинома р в точках, заданных в массиве х, а функция polyder(p) возвращает производную полинома р. Еще одна функция [X, е] = polyeig(A0, A1, ..., Ар) решает задачу собственных значений для матричного полинома. Для отношения полиномов b и а функция [r, р, k] = residue(b, а) возвращает вычеты, полюса и многочлен целой части отношения двух полиномов b(s) и a(s).

Особо отметим функцию roots(c), которая возвращает вектор-столбец, чьи элементы являются корнями полинома с. Вектор-строка с содержит коэффициенты полинома, упорядоченные по убыванию степеней. Если с имеет n+1 компоненту, то представленный им полином имеет вид c1sn+...+cns+cn+1. Пример:

» x=[7,45,12,23];d=roots(x)
d =
    -6.2382
    -0.0952 + 0.7195i
    -0.0952 - 0.7195i

Для полиномиальной регрессии данных, заданных векторами х и у при степени полинома n, используется функция polyfit(x, у, n). Она возвращает вектор коэффициентов полинома р(х) степени n, который с наименьшей среднеквадратичной погрешностью аппроксимирует функцию у(х). Функция [р, s] = polyfit(x, у, n) возвращает коэффициенты полинома р и структуру S для использования вместе с функцией polyval при оценке или предсказании погрешности. Пример (полиномиальная регрессия для функции sin(x)):

» x=(-3:0.2:3)';y=sin(x);p=polyfit(x,y,3)
Р =
    -0.0953   0.0000   0.8651   -0.0000

 

Интерполяция и аппроксимация функций

MATLAB имеет ряд функций для интерполяции и аппроксимации данных. Так, функция interpft(x, n) возвращает вектор у, содержащий значения периодической функции, определенный в n равномерно расположенных точках. Точность интерполяции этой функцией невысока.

Для одномерной табличной интерполяции используется функция yi = interp1 (х,Y,xi[,method]). Она возвращает вектор yi, содержащий элементы, соответствующие элементам xi и полученные интерполяцией векторов х и Y. Параметры method позволяют задать метод интерполяции:

• 'nearest' — ступенчатая интерполяция;

• 'linear' — линейная интерполяция (принята по умолчанию);

• 'spline' — кубическая сплайн-интерполяция;

• 'cubic' — кубическая интерполяция.

Для более быстрой интерполяции, когда х — вектор равномерно распределенных точек, лучше использовать методы '*linear', '*cubic', '*nearest' или '*spline'. Обратите внимание на то, что в данном случае наименованию метода предшествует знак звездочки. Пример (интерполяция функции косинуса) дан на рис. 10.9.

 

Рис. 10.9. Пример применения функции interpl


Узловые точки на рис. 10.9 обозначены кружками с наклонными крестиками. Одна из кривых соответствует линейной интерполяции, другая — сплайн-интерполяции. Нетрудно подметить, что сплайн-интерполяция в данном случае дает гораздо лучшие результаты, чем линейная интерполяция.

Двухмерная интерполяция существенно сложнее, чем рассмотренная выше одномерная, хотя смысл ее тот же — найти промежуточные точки вблизи расположенных в пространстве узловых точек некоторой зависимости z(x,у). Для двухмерной табличной интерполяции используется функция ZI = interp2(X,Y,Z,XI,YI). Она возвращает матрицу ZI, содержащую элементы, соответствующие элементам XI и YI, и полученную интерполяцией двухмерной функции, заданной матрицами X, Y и Z. X и Y должны быть монотонными и иметь тот же формат (plaid), как если бы они были получены с помощью функции meshgrid. Матрицы X и Y определяют точки, в которых задано значение Z. XI и YI могут быть матрицами, в этом случае interp2 возвращает значения Z, соответствующие точкам (XI(i,j),YI(i,j)). В качестве альтернативы можно передать вектор-строку и вектор-столбец xi и yi соответственно. В этом случае interр2 представляет эти векторы, как если бы использовалась команда meshgrid(xi,yi). Рис. 10.10 иллюстрирует применение функции interp2 для двухмерной интерполяции (на примере функции peaks).

 

Рис. 10.10. Применение функции interp2


В данном случае поверхность снизу получена в результате двухмерной линейной интерполяции, которая реализуется по умолчанию, когда не указан параметр
method. Для трехмерной табличной интерполяции используется функция interp3, а для многомерной интерполяции — функция interpn. В связи с редкостью такого вида интерполяции предоставим заинтересованному читателю возможность самостоятельно разобраться с ее применением.

Кубическая сплайн-интерполяция также реализуется функцией yi = spline(x,y,xi). Она использует векторы х и у, содержащие значения функции в точках х, и вектор xi, задающий новые точки, для нахождения элементов вектора yi на основе кубической сплайн-интерполяции. Функция рр = spline(x.y) возвращает рр-форму сплайна, применяемую в функции ppval и других сплайн-функциях.

Ввиду важности сплайн-интерполяции и аппроксимации в обработке и представлении сложных данных в Toolbox системы MATLAB входит пакет расширения Spline Toolbox, содержащий около 70 дополнительных функций, относящихся к реализации сплайн-интерполяции и аппроксимации, а также графического представления сплайнами их результатов. Для вызова данных об этом пакете используйте команду help splines.

 

Решение обыкновенных дифференциальных уравнений

 

Методы решения дифференциальных уравнений

Для решения систем ОДУ в MATLAB поддерживаются различные методы, которые носят обобщенное название solver (буквально — “решатель”):

• ode45 — одношаговые явные методы Рунге—Кутта 4-го и 5-го порядков. Это классические методы решения, рекомендуемые в качестве первого шага. Во многих случаях они дают хорошие результаты.

• ode23 — одношаговые явные методы Рунге—Кутта 2-го и 4-го порядка. При умеренных требованиях к жесткости системы ОДУ и к точности решения эти методы могут дать выигрыш в скорости решения.

• ode113 — многошаговый метод Адамса—Башворта—Мултона переменного порядка. Это адаптивный метод, который может обеспечить высокую точность решения.

• ode15s — многошаговый метод переменного порядка (от 1-го до 5-го по умолчанию), использующий формулы численного дифференцирования. Это адаптивный метод, его стоит применять, если метод ode45 не обеспечивает решение.

• ode23s — одношаговый метод, использующий модифицированную формулу Розенброка 2-го порядка. Может обеспечить высокую скорость вычислений при низкой точности.

• ode23t — метод трапеций с интерполяцией. Этот метод дает хорошие результаты при решении задач, описывающих осцилляторы с почти гармоническим выходным сигналом.

• ode23tb — неявный метод Рунге—Кутта в начале решения и метод, использующий формулы обратного дифференцирования 2-го порядка, в последующем. При низкой точности этот метод может оказаться более эффективным, чем ode15s.

Все указанные методы позволяют решать системы уравнений явного вида у' = F(t,у). Методы ode15s, ode23s, ode23t и ode23tb обеспечивают решение уравнений неявного вида My' = F(t,у). И наконец, все методы, за исключением ode23s, позволяют решить уравнения вида M(t)y'= F(t,y).

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

• F — название ODE-файла, то есть функции от t и у, которая возвращает вектор-столбец;

• tspan — вектор, определяющий интервал интегрирования [t0 tfinal], для получения решений в конкретные моменты времени t0, t1, ..., tfinal (расположенные в порядке уменьшения или увеличения) нужно использовать tspan= [t0 t1 ... tfinal];

• y0 — вектор начальных условий;

• options — аргумент, создаваемый функцией odeset (функция odeget позволяет вывести параметры, установленные по умолчанию или с помощью функции odeset);

• р1, р2... — произвольные параметры, передаваемые в F;

• Т, — матрица решений Y, где каждая строка соответствует времени, возвращенном в векторе-столбце Т.

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

• [T,Y] = solver('F', tspan, y0) с tspan = [t0 tfinal] — интегрирует систему дифференциальных уравнений вида у' = F(t,у) от времени t0 до tfinal с начальными условиями у0, где 'F' — строка, содержащая имя ODE-файла. Функция F(t,у) должна возвращать вектор-столбец. Каждая строка в массиве решений у соответствует времени, возвращаемому в векторе-столбце t. Для получения решений в конкретных точках t0, t1, ..., tfinal (расположенных в порядке уменьшения или увеличения) нужно использовать tspan = [t0 t1 ... tfinal].

• [T,Y] = solver('F', tspan, y0, options) — дает решение, подобное описанному выше, но с параметрами, определяемыми значениями аргумента options, созданного функцией odeset. Обычно используемые параметры включают допустимое значение относительной погрешности RelTol (1e-3 по умолчанию) и вектор допустимых значений абсолютной погрешности AbsTol (все компоненты равны 1е-6 по умолчанию).

• [T,Y] = solver( 'F', tspan, y0, options, p1,p2...) — дает решение, подобное описанному, помещая дополнительные параметры р1, р2... в m-файл F всякий раз, когда он вызывается. Используйте options = [ ], если никаких параметров не установлено.

• [Т, Y, TE, YE, IE] = solver('F', tspan, y0, options) — в дополнение к описанному решению содержит свойства Events, установленные в структуре options в положение 'on'. ODE-файл должен быть кодирован так, чтобы функция F(t,y, 'events') возвращала соответствующую информацию (см. функцию odefile для подробного ознакомления). Выходной аргумент ТЕ — вектор-столбец времен, в которые происходят события (events), строки YE являются соответствующими решениями, и индексы в векторе IE определяют, какое событие (event) произошло. Когда происходит вызов функции без выходных аргументов, по умолчанию вызывается выходная функция odeplot для построения вычисленного решения. В качестве альтернативы можно установить свойство OutputFcn в значение 'odeplot'. Можно установить свойство OutputFcn в значение 'odephas2' или 'odephas3' для построения двух- или трехмерных фазовых плоскостей (см. функцию odef ile для подробного ознакомления).

• [T,X,Y] = solver('model', tspan, y0, options, ut, p1, p2, ...) — использует модель Simulink, вызывая соответствующий метод решения из нее: [Т, X, Y] = =sim (solver, 'model',...).

Параметры интегрирования (options) могут быть определены и в ODE-файле, и в командной строке. Если параметры определены в обоих местах, определение в командной строке имеет приоритет.

Покажем применение методов решения ОДУ на ставшем классическим примере — решении уравнения Ван дер Поля, записанного в виде системы из двух дифференциальных уравнений:

у'12
У'2=100*(1-у12)*у21
У1(0)=0; у2(0)=1

Вначале подготовим m-файл vdpl00.m, содержащий систему ОДУ. Он имеет вид

function dy = vdp100(t,y)
dy = zeros(2,1); % a column vector
dy(1) = y(2);
dy(2) = 2*(1
- У(1)^2)*у(2) - y(1);

 

Описание системы ОДУ

Особый объект, m-файл odefile, представляет собой не просто функцию, а запись справки о том, как создать m-файл, определяющий правую часть системы уравнений, которая будет решена. Это определение — первый шаг в использовании любого из перечисленных методов решения ОДУ в системе MATLAB. В описании MATLAB этот m-файл упоминается как odefile, хотя вместо него можно использовать любое имя. В объекте odefile помимо правой части системы ОДУ можно задать начальные условия и пределы интегрирования.

Можно использовать m-файл odefile, чтобы определить систему дифференциальных уравнений в одной из явных (первая формула) или неявных форм:

У'= F(t,y)
Му'= F(t,y)
M(t)y'= F(t,y)

Здесь — независимая переменная (скаляр), которая обычно представляет время, у — вектор зависимых переменных, — функция от t и у, возвращающая вектор-столбец такой же длины, как и у. М и M(t) — матрицы, которые не должны быть вырожденными. М может быть и константой.

Шаблон odefile для использования ODE-файла задайте следующим образом:

1. Введите команду help odefile для отображения записи справки.

2. Вырежьте нужную часть файла и оформите ее в отдельный файл со своим именем.

3. Отредактируйте файл, оставив в нем только нужные фрагменты.

4. Вставьте соответствующие данные туда, где указано в файле.

Мы не приводим вид шаблона odefile, поскольку этот шаблон довольно большой и рассчитан на все случаи жизни. Рассмотрим пример решения уравнения вида у''1=2*(1-у12)*у1-у'1. Оно сводится к системе уравнений

y'1=y2
y'1=2*(1-y12)*y1-y2

Используя шаблон, подготовим m-файл vdp.m .

Обратите внимание на то, что файл vdp.m — типичная программа с управляющими структурами класса if-else-then и case. Однако вам ее не требуется создавать — достаточно заполнить упомянутый шаблон файла odefile.

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

 

Информация о пакете Partial Differencial Equations Toollbox

Специалистов в области численных методов решения дифференциальных уравнений с частными производными несомненно заинтересует пакет Partial Differencial Equations Toollbox (PDETB). Хотя этот пакет является самостоятельным приложением и в ядро MATLAB не входит, мы приведем его краткое описание с примером. Поскольку ряд применений пакета PDETB связан с проблемами анализа и оптимизации трехмерных поверхностей и оболочек, в пакет введены удобные функции для построения их графиков. Они могут использоваться совместно с функцией pdeplot.

Средства графики пакета дают высококачественное изображение поверхностей (оболочек) с функциональной окраской (увы, невидимой во всей красе на черно-белых рисунках). В состав пакета входит ряд полезных демонстрационных примеров с именами от pdedemo1 до pdedemo8. Их можно запустить из командной строки указанием имени.

 

Быстрые преобразования Фурье

Для одномерного быстрого преобразования Фурье в MATLAB используется функция fft.

• fft (X) — возвращает для вектора X дискретное преобразование Фурье, используя FFT-алгоритм быстрого преобразования Фурье. Если — матрица, fft возвращает преобразование Фурье для каждого столбца матрицы.

• fft(X,n) — возвращает n-точечное преобразование Фурье. Если длина вектора X меньше n, то недостающие элементы заполняются нулями. Если длина X больше n, то лишние элементы удаляются. Когда — матрица, длина столбцов корректируется аналогично.

• fft(X,[ ],dim) и fft(X, n, dim) — применяют преобразование Фурье к одной из размерностей массива в зависимости от величины dim.

Для иллюстрации применения преобразования Фурье создадим трехчастотный сигнал на фоне сильного шума, создаваемого генератором случайных чисел. Этот сигнал имеет среднюю частоту в 200 рад/с и два боковых сигнала с частотами 150 и 250 рад/с, что соответствует амплитудно-модулированному сигналу с частотой модуляции 50 рад/с и глубиной модуляции 0.8. На рис. 10.11 сверху показан график этого сигнала. Из него не видно, что полезный сигнал — амплитудно-модулированное колебание. Настолько оно забито шумами.

 

Рис. 10.11. Пример фильтрации сигнала с применением БПФ


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

Для двухмерного прямого преобразования Фурье используется функция fft2, a для многомерного — функция fftn(X). Кроме того, есть функция Y = fftshift(X), которая перегруппировывает выходные массивы функций fft и fft2, размещая нулевую частоту в центре спектра, что иногда более удобно.

В случае одномерного преобразования возможно обратное преобразование Фурье, реализуемое функцией iffft, параметры которой задаются по правилам, приведенным для функции fft. Аналогичные функции, которые есть для двухмерного и многомерного преобразований (ifft2(F) и ifftn(F.SIZ)), возвращают результат обратного дискретного преобразования для массива F с ограничением размера, заданным переменной SIZ. Если любой элемент SIZ меньше, чем соответствующая размерность F, то массив F будет урезан до размерности SIZ. Кроме того, имеется функция свертки conv и обратная ей функция deconv.

MATLAB может использоваться для моделирования работы цифровых фильтров. Чтобы обеспечивать дискретную одномерную фильтрацию, может использоваться функция filter. С ее работой можно ознакомиться по демонстрационному примеру (файл filtdem.m) из пакета расширения Signal Processing Toolbox, посвященного обработке сигналов. Имеется также функция filter2, обеспечивающая решение задач двухмерной фильтрации.

 

Основы программирования

 

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

Структура типов данных системы MATLAB представлена ниже.

Типы данных array и numeric являются виртуальными, поскольку к ним нельзя отнести какие-либо переменные. Они служат для определения и комплектования некоторых типов данных. Таким образом, в MATLAB определены следующие шесть основных типов данных, представляющих собой многомерные массивы:

• double — числовые массивы с числами удвоенной точности;

• char — строчные массивы с элементами — символами;

• sparse — разреженные матрицы с элементами — числами удвоенной точности;

• cell — массивы ячеек, которые, в свою очередь, могут быть массивами;

• struct — массивы записей с полями, которые также могут содержать массивы;

• unit8 — массивы 8-разрядных целых чисел без знаков (математические операции с ними не предусмотрены).

Кроме того, предусмотрен еще один тип данных, UserObject, который относится к типам данных (объекты), определяемых пользователем. Типы данных double, char и sparse были рассмотрены ранее. Что касается чисел класса unit8, то они представляют значения от 0 до 255 и занимают в памяти 1/8 часть от размера единичного числа с двойной точностью. В основном этот тип данных применяется в служебных целях.

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

К сложным типам данных в MATLAB относятся многомерные массивы, массивы записей и массивы ячеек. Их описание выходит за рамки данной главы.

 

Файлы-сценарии

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

%0сновной комментарий
%Дополнительный комментарий
Тело файла с любыми выражениями

Важны следующие свойства файлов-сценариев:

• они не имеют входных и выходных аргументов;

• работают с данными из рабочей области;

• в процессе выполнения не компилируются;

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

Основным комментарием является первая строка текстовых комментариев, а дополнительным — последующие строки. Основной комментарий выводится при исполнении команд lookfor и help имя_каталога. Полный комментарий выводится при исполнении команды help Имя_файла. Рассмотрим следующий файл-сценарий:

%Plot with color red
%Строит график синусоиды линией красного цвета
%с выведенной масштабной сеткой в интервале
[xmin.xmax]
x=xmin:0.1:xmax;
plot(x,sin(x),'r')
grid on

Первые три строки здесь — это комментарий, остальные — тело файла. Обратите внимание на возможность задания комментария на русском языке. Знак % в комментариях должен начинаться с первой позиции строки. В противном случае команда help name не будет воспринимать комментарий (иногда это может понадобиться) и возвращать сообщение вида

No help comments found in name.m.

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

 

Файлы-функции

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

function var=f_name(Cписок_параметров)
%0сновной комментарий
%Дополнительный комментарий
Тело файла с любыми выражениями
var=выражение

М-файл-функция имеет следующие свойства:

• он начинается с объявления типа function, после которого указывается имя переменной var — выходного параметра, имя самой функции и список ее входных параметров;

• функция возвращает свое значение и может использоваться в виде name(Список_параметров) в математических выражениях;

• все переменные, имеющиеся в теле файла-функции, являются локальными, то есть действуют только в пределах тела функции;

• файл-функция является самостоятельным программным модулем, который общается с другими модулями через свои входные и выходные параметры;

• правила вывода комментариев те же, что и у файлов-сценариев;

• файл-функция служит средством расширения системы MATLAB;

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

Последняя конструкция vаr=выражение вводится, если требуется, чтобы функция возвращала результат вычислений. Если файл-функция завершается строкой с точкой с запятой (;), то для возврата значения функции используется инструкция return.

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

function [var1, var2, ...]=f_namе(Список_параметров)
%0сновной комментарий
%Дополнительный комментарий
Тело файла с любыми выражениями
var1=выражение
var2=выражение
.....................

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

[var1,var2,...]=f_name(Список_параметров)

После его применения переменные выхода var1, var2,.. становятся определенными и их можно использовать в последующих математических выражениях и иных сегментах программы. Если функция задана в виде f_namе(Список_параметров), то возвращается значение только первого выходного параметра — переменной var1. Файлы-функции допускают задание глобальных переменных инструкцией global:

global var1 var2 ...

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

Начиная с версии 5.0, в функции системы MATLAB можно включать подфункции. Они объявляются и записываются в теле основных функций и имеют идентичную им конструкцию. Не следует путать эти функции с внутренними функциями, встроенными в ядро системы MATLAB. Подфункции определены и действуют локально, то есть только в пределах m-файла, определяющего основную функцию. Команда help name выводит комментарий, относящийся только к основной функции, тогда как команда type name выводит весь листинг m-файла. Так что заданные в некотором m-файле подфункции нельзя использовать ни в командном режиме, ни в других m-файлах.

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

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

Однако, начиная с версии MATLAB 5.0, появилась возможность в родительских папках создавать частные папки (private). Входящие в них m-файлы доступны только файлам родительской папки. Файлы частных папок просматриваются интерпретатором системы MATLAB в первую очередь. Применение частных папок позволяет изменять исходные файлы, сохраняя оригиналы в родительской папке в неизменном виде.

Если вы решили отказаться от применения измененного файла, достаточно стереть его в частной папке. Такая возможность связана с тем, что интерпретатор при обнаружении имени m-файла прежде всего просматривает частную папку данного файла и интерпретирует найденный в ней файл. И только если файл не найден, ищется файл в родительской папке.

 

Обработка ошибок

Для вывода ошибок служит инструкция error('Сообщение об ошибке'). Пример ее применения дан ниже:

function f=sd(x)
if x==0 error(
'Ошибка - деление на 0'), end
f=sin(x)/x

Для выявления ошибочной ситуации использована инструкция условного перехода if, которая будет описана позднее. Результат выполнения данной функции приводится ниже:

» sd(1)
f =
    0.8415
ans =
    0.8415
» sd(0)
??? Error using ==> sd
Ошибка - деление на 0

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

warning('Предупреждающее сообщение')

Эта команда выводит стоящее в апострофах сообщение, но не препятствует дальнейшей работе программы. Признаком того, что является ошибкой, а что предупреждением, являются символы ??? и слово Warning в соответствующих сообщениях. Опытные программисты должны предусматривать ошибочные ситуации. К примеру, при х=0 выражение sin(x)/x=0/0=1, и правильным решением было бы вместо его вычисления использовать значение 1.

В данном простом примере приводится функция sd0, исключающая вычисление sin(x)/x при х=0:

function f=sd0(x)
if x==0 f=1; else f=sin(x)/x; end
return

При этом вычисления пройдут корректно при любом х:

» sd0(1)
ans =
    0.8415
» sd0(0)
ans =
    1

Для вывода сообщения о последней сделанной ошибке служит функция lasterr (см. пример ниже):

» ааа
??? Undefined function or variable 'aaa'.
» 2+3
ans =
    5
» 1/0
Warning: Divide by zero.
ans =
    Inf
» lasterr
ans =
Undefined function or variable 'aaa'.

Как нетрудно заметить, функция lasterr возвращает текстовое сообщение, следующее за знаками ??? сообщения об ошибке.

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

eval('try','catch')

Один из них — это строковое выражение, которое преобразуется в исполняемую форму и выполняется при отсутствии ошибки. Если же происходит ошибка, то строка 'catch' вызывает обращение к функции обработки ошибки.

 

Функции подсчета числа входных и выходных аргументов

При создании функций со специальными свойствами весьма полезны две приведенные ниже функции:

• nargin — возвращает число входных параметров данной функции;

• nargout — возвращает число выходных параметров данной функции.

Пусть, к примеру, мы хотим создать функцию, вычисляющую сумму квадратов пяти аргументов х1, х2, х3, х4 и х5. Обычный путь — создание функции с именем sum2_5:

function f=sum2_5(x1,х2,х3,х4,х5);
f=x1^2+x2^2+x3^2+x4^2+x5^2;

Теперь проверим функцию в работе:

» sum2_5(1,2,3,4,5)
ans =
    55
» sum2_5(1,2)
??? Input argument
'х3' is undefined.
Error in ==> C:\MATLAB\bin\sum2_5.m
On line 2 ==> f=x1^2+x2^2+x3^2+x4^2+x5^2;

Итак, при всех пяти аргументах функция работает корректно. Но если аргументов менее пяти, она выдает сообщение об ошибке. С помощью функции nargin можно создать функцию sum2_5m, которая работает корректно при любом числе заданных входных аргументов в пределах от 1 до 5:

function f=sum2m_5(x1,х2,х3,х4,х5);
n=nargin;
if n==1 f=x1^2; end
if n==2 f=x1^2+x2^2; end
if n==3 f=x1^2+x2^2+x3^2; end
if n==4 f=x1^2+x2^2+x3^2+x4^2; end
if n==5 f=x1^2+x2^2+x3^2+x4^2+x5^2; end

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

» sum2_5m(1)
ans =
    1
» sum2_5m(1,2)
ans =
    5
» sum2_5m(1,2,3)
ans =
    14
» sum2_5m(1,2,3,4)
ans =
    30
» sum2_5m(1,2,3,4,5)
ans =
    55
» sum2_5m(1,2,3,4,5,6)
??? Error using ==> sum2_5m
Too many input arguments.

Итак, при изменении числа входных аргументов от 1 до 5 вычисления проходят корректно. При большем числе аргументов выводится сообщение об ошибке. Это уже действует встроенная в интерпретатор MATLAB система диагностики ошибок.

 

Условная инструкция

Практически любая серьезная программа имеет нелинейную структуру. Для создания таких программ необходимы специальные управляющие структуры. Они имеются в любом языке программирования и, в частности, в MATLAB. Так, условная инструкция if в MATLAB записывается следующим образом:

if Условие
    Инструкции_1
        
elseif Условие
            Инструкции_2
        else
            Инструкции_3
end

Эта конструкция допускает несколько частных вариантов. В простейшем, типа if-end, пока Условие возвращает логическое значение 1 (то есть верно), выполняются Инструкции, составляющие тело структуры if-end:

if Условие Инструкции end

При этом инструкция end указывает на конец перечня инструкций. Инструкции в списке разделяются оператором , (запятая) или ; (точка с запятой). Если Условие не выполняется (дает логическое значение 0), то Инструкции также не выполняются.

Еще одна конструкция выполняет Инструкциям, если выполняется Условие, или Инструкции_2 в противном случае:

if Условие Инструкции_1 else Инструкции_2 end

Условия записываются в виде

Выражение_1 Оператор_отношения Выражение_2

В качестве Операторов_отношения используются операторы: ==, <, >, <=, >= или ~=. Все эти операторы представляют собой двойные символы без пробела между ними.

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

 

Циклы for

Циклы for-end обычно используются для организации вычислений с заданным числом повторений. Конструкция такого цикла имеет вид

for vаr=Выражение, Инструкция, ..., Инструкция end

Выражение чаще всего записывается в виде s:d:е, где — начальное значение переменной цикла variable, d — приращение этой переменной и е — конечное значение управляющей переменной, при достижении которого цикл завершается. Возможна и запись в виде s:е (в этом случае d=1). Список выполняемых в цикле инструкций завершается инструкцией end. Следующие примеры поясняют применение цикла для получения квадратов значений переменной цикла:

» for i=1:5 i^2, end;
ans =
    1
ans =
    4
ans =
    9
ans =
    16
ans =
    25
» for x=0:.25:1 x^2, end;
ans =
    0
ans =
    0.0625
ans =
    0.2500
ans =
    0.5625
ans =
    1

Инструкция break может использоваться для прерывания выполнения цикла. Как только она встречается в программе, цикл прерывается. Возможны циклы в цикле, например:

for 1=1:3
    for j=1:3
        A(i,j)=i+j;
    end
end

В результате исполнения этого цикла (файл for2.m) формируется матрица А:

» for2
» А
А =
    2   3   4
    3   4   5
    4   5   6
»

Следует отметить, что формирование матриц с помощью оператора : (двоеточие) обычно занимает намного меньше времени, чем с помощью цикла. Однако применение цикла нередко оказывается более наглядным и понятным. MATLAB допускает использование в качестве выражения переменной цикла массива А размером mxn. При этом цикл выполняется столько раз, сколько столбцов в массиве А, и на каждой итерации переменная var представляет вектор, соответствующий текущему столбцу массива А:

» А=[1 2 3;4 5 6]
А =
    1   2   3
    4   5   6
» for var=A; var, end
var =
    1
    4
var =
    2
    5
var =
    3
    6

 

Циклы while

Цикл while выполняется до тех пор, пока выполняется Условие:

while Условие
    Инструкции
end

Досрочное завершение цикла реализуется инструкцией break.

 

Инструкции множественного выбора

Для осуществления множественного выбора (или ветвления) используется конструкция с переключателем типа switch:

switch switch_Bыражениe
    case
саsе_Выражение
        Список_инструкций
    
case {саsе_Выражение1, cаsе_выражение2, саsе_Выражение3, ...}
        Список_инструкций
        ...
    otherwise
        Список_инструкций

end

Если выражение после заголовка switch имеет значение логической единицы, то выполняется блок инструкций case, в противном случае — список инструкций после инструкции otherwise. Если выполнение блока case разрешено, то выполняются те списки инструкций, для которых саsе_Выражение совпадает со swith_Выражением. Обратите внимание на то, что саsе_Выражение может быть числом, константой, переменной или вектором ячеек.

Поясним применение инструкции switch на примере m-файла sw1.m:

switch var
case {1,2,3}
    disp(
'Первый квартал')
case {4,5,6}
    disp('
Второй квартал')
case {7,8,9}
    disp(
'Третий квартал')
case {10,11,12}
    disp(
'Четвертый квартал')
otherwise
    disp(
'Ошибка в задании')
end

Эта программа в ответ на значения переменной var — номера месяца — вычисляет, к какому кварталу относится заданный месяц, и выводит сообщение:

» var=2;
» sw1
Первый квартал
» var=4;sw1
Второй квартал
» var=7;sw1
Третий квартал
» var=12;sw1
Четвертый квартал
» var=-1;sw1

Для приостановки программы используется инструкция pause в следующих формах:

• pause — приостанавливает вычисления до нажатия любой клавиши;

• pause(N) — приостанавливает вычисления на N секунд;

• pause on — включает режим создания пауз;

• pause off — выключает режим создания пауз.

Применение этой инструкции достаточно очевидно.

 

Организация диалога

Приведем простой пример диалоговой программы, которую легко поймут приверженцы доброго старого Бейсика:

% Вычисление длины окружности с диалоговым вводом радиуса
r=0;
while r>=0,
    r=input(
'Введите радиус окружности r=');
    if r>=0 disp(
'Длина окружности l='); disp(2*pi*r), end
end

Диалог организован с помощью команды

r=input("Введите радиус окружности r=');

При выполнении этой команды вначале выводится запрос в виде строки, затем происходит останов работы программы и ожидается ввод значения радиуса (в общем случае числа). Ввод, как обычно, подтверждается нажатием клавиши Enter, после чего введенное число присваивается значению переменной r. Следующая строка с помощью команды disp при r>=0 выводит надпись Длина окружности l= и вычисленное значение длины окружности:

if r>=0 disp('Длина окружности l='); disp(2*pi*r), end

Эта строка представляет собой одну из наиболее простых управляющих структур типа if-end. В данном случае она нужна для остановки вычислений, если вводится отрицательное значение r (прием, который любят начинающие программисты).

Приведенные строки включены в управляющую структуру while-end. Это необходимо для циклического повторения вычислений с вводом значений r. Пока r>=0, цикл повторяется. Но стоит задать r<0, вычисление длины окружности перестает выполняться, а цикл завершается.

Если данная программа записана в виде m-файла circ.m, то работа с ней будет выглядеть следующим образом:

» circ
Введите радиус окружности R=1
Длина окружности l=
    6.2832
Введите радиус окружности R=2
Длина окружности l=
    12.5664
Введите радиус окружности R=-1
»

Итак, на примере даже простой программы мы видим пользу применения управляющих структур типа if-end и while-end, а также функций диалогового ввода input('String') и вывода disp. Обратите внимание на завершение работы программы при вводе любого отрицательного числа для радиуса окружности.

Функция input может использоваться и для ввода произвольных строковых выражений. При этом она задается в виде

input('Комментарий','s')

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

» S=input('Введите выражение','s')

Введите выражение 2*sin(1)
S =
2*sin(1)
» eval(S)
ans =
    1.6829

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