Добавил:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

1-2 Моделирование / Matlab. Практический подход. Самоучитель

.pdf
Скачиваний:
765
Добавлен:
31.01.2021
Размер:
12.72 Mб
Скачать

 

 

Глава 3. Элементы программирования

 

 

 

 

Оператор

Функция

Описание

 

 

 

 

 

==

eq()

Равно. Выражение A==B истинно, если значение перемен-

ной A равно значению переменной B. Тот же результат мо-

 

 

 

жет быть получен с помощью команды eq(A,B)

 

~=

ne()

Не равно. Выражение A~=B истинно, если значение пере-

 

менной A не равно значению переменной B. Тот же резуль-

 

 

 

тат может быть получен с помощью команды ne(A,B)

 

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

Сначала переменным A и B присваиваются соответственно значения 5 и 9. Затем командой C=A+2*(A<B) переменной C присваивается значение (результатом переменная C получает значение 7). Объяснение простое: поскольку выражение A<B является истинным, то значением этого выражения фактически есть 1. После умножения на 2 и прибавления текущего значения переменной A получаем 7.

Командами X=[1 2 5;5 4 -1] и Y=[-2 2 -7;3 3 -1] задаются числовые матрицы одинаковых размеров, после чего к этим матрицам применяются операции сравнения. В частности, использована команда X==Y, в результате выполнения которой создается матрица того же размера, что и сравниваемые матрицы X и Y. Матрица-результат состоит из нулей и единиц. Это результаты сравнения соответствующих элементов матриц X и Y (единица соответствует ситуации, когда соответствующие элементы, в соответствии с использованным оператором == матриц совпадают, а нули соответствуют ситуации, когда соответствующие элементы различны). Если в качестве одного из операндов в операции сравнения указать вместо матрицы скаляр (как, например, в команде A~=X), то скаляр сравнивается с каждым из элементов матрицы-операнда. Результатом является матрица из нулей и единиц того же размера, что и матрица-операнд. Принцип заполнения матрицы-результата такой: если результат сравнения скалярного операнда и элемента матрицы-операнда истинен, в соответствующем месте матрицы-результата стоит единица, в противном случае – нуль.

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

131

Самоучитель Matlab

Рис. 3.30. Логические операторы и функции

Рис. 3.29. Использование операторов сравнения

Табл. 3.2. Логические операторы и функции

Оператор

Функция

Описание

 

 

 

&

and()

Логическое и. Результатом является единица, если оба опе-

ранда (или аргумента) равны единице

 

 

 

|

or()

Логическое или. Результатом является единица, если хотя

бы один операнд (или аргумент) равен единице

 

 

 

 

xor()

Логическое исключающее или. Результатом является еди-

 

ница, если один и только один операнд (или аргумент) равен

 

 

единице

 

 

 

132

 

 

Глава 3. Элементы программирования

 

 

 

 

Оператор

Функция

Описание

 

 

 

 

 

~

not()

Логическое отрицание. Если операнд (аргумент) равен еди-

 

нице, результатом будет ноль, и наоборот

 

 

 

 

 

&&

 

Логическое сокращенное и. Отличие состоит в способе вы-

 

 

числения результата. Если первый операнд нулевой, второй

 

 

 

операнд не вычисляется

 

 

 

 

 

||

 

Логическое сокращенное или. Отличие состоит в способе

 

 

вычисления результата. Если первый операнд единичный,

 

 

 

второй операнд не вычисляется

 

 

 

 

 

Для логических операторов и функций существуют побитовые аналоги – это функции, которые выполняют соответствующие операции на битовом уровне, то есть операнды представляются в виде последовательности битов, и для каждой пары битов выполняется нужная операция. Например, с помощью функции bitor() операция логического или применяется на побитовом уровне. Для вычисления исключающего побитового или используется функция bitxor(). Функцией bitand() вычисляется побитовое и. Полезными могут быть и другие побитовые функции. Например, у функции bitget() два числовых аргумента. В качестве результата возвращается значение бита в первом аргументе на позиции, определяемой вторым аргументом. У функции bitset() два или три аргумента. Значение функции вычисляется следующим образом. В числе, указанном первым аргументом функции на позиции, определяемой вторым аргументом, устанавливается значение бита, указанное третьим аргументом функции. Если третий аргумент не указан, по умолчанию он полагается равным единице. Некоторые примеры использования логических операторов и функций приведены в документе на рис. 3.30.

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

Обработка исключительных ситуаций

Если мы будем предполагать невозможное, тогда Вы ошиблись адресом.

К/ф "Семнадцать мгновений весны"

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

133

Самоучитель Matlab

полняться и дальше. Как он будет выполняться – это уже другой вопрос. В любом случае, проблема остается – необходим механизм, позволяющий минимизировать влияние прогнозируемых или непрогнозируемых ошибок (которые обычно называют исключениями или исключительными ситуациями). Такой механизм в Matlab есть, и реализуется он с помощью оператора try-catch.

На заметку

Данная конструкция должна быть хорошо знакома программистам Java и C++.

Общий синтаксис оператора следующий:

try

основные_команды catch объект_ошибки команды_обработки end

Программный код, подозреваемый на предмет непредсказуемого поведения, указывается в блоке try. Начало блока маркируется соответствующим ключевым словом. Признаком окончания try-блока (и начала catch- блока) является ключевое слово catch. Если при выполнении кода между ключевыми словами try и catch никаких ошибок не возникает, команды catch-блока игнорируются и далее выполняются команды, размещенные после ключевого слова end, которым завершается catch-блок и, тем самым, весь оператор try-catch. В случае если при выполнении команд в try-блоке ошибка все-таки возникает, то выполнение команд try-блока прекращается, и начинают выполняться команды catch-блока (вплоть до ключевого слова end). После этого выполняются команды после оператора try-catch. Таким образом, оператор try-catch в некотором смысле представляет собой аналог условного оператора, только условием служит возникновение ошибки. Если ошибки нет, выполняется только блок try. Если ошибка возникает, выполняются команды catch-блока.

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

На заметку

Дело в том, что при возникновении ошибочной ситуации (или исключения) автоматически создается объект класса MException. Этот объект содержит описание возникшей ошибки, и заложенная в объекте информация может использоваться в программном коде при обработке ошибки. Именно для формального обозначения данного объекта вводится соответствующая объектная переменная, которая и указывается после ключевого слова catch. Однако если в коде обработки ошибочной ситуации обращение к объекту ошибки не планируется, после ключевого слова catch соответствующую переменную можно не указывать.

134

Глава 3. Элементы программирования

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

function ShowPlot(x,y) try plot(x,y,'LineWidth',2) grid on

catch

disp('Неверно указаны аргументы функции!') end

disp('Выполнение функции завершено!') end

У функции два аргумента (массивы), на основе которых строится график функции. Главная проблема состоит в том, что массивы могут иметь разные размеры. Поскольку в функции это условие (равенство размеров массивов) не проверяется, при вызове функции возможно возникновение ошибки. Как раз для такого случая предусмотрена обработка исключительных ситуаций. Команды по созданию графика функции заключены в блок try. Если ошибки при построении графика не возникает, то после создания графика выводится сообщение 'Выполнение функции завершено!' (аргумент функции disp()), после чего выполнение функции завершается. При возникновении ошибки выполняются команды catch-блока (команда disp('Неверно указаны аргументы функции!')), после чего выполняется команда disp('Выполнение функции завершено!'). Окно редактора m-файлов с кодом функции показано на рис. 3.31.

Рис. 3.31. Редактор m-файлов с кодом функции, содержащей обработку исключительных ситуаций

На рис. 3.32 показано командное окно приложения с командами, иллюстрирующими работу созданной функции.

135

Самоучитель Matlab

Рис. 3.32. Команды с вызовом функции, содержащей обработку исключительной ситуации

Вот эти команды (жирным шрифтом выделены вводимые пользователем команды):

>>x=-4*pi:0.01:4*pi;

>>y=(1-cos(x))./x;

>>z=0:0.02:4*pi;

>>ShowPlot(x,y)

Выполнение функции завершено! >> ShowPlot(z,y)

Неверно указаны аргументы функции! Выполнение функции завершено!

Первыми тремя командами создаются массивы x, y и z. Массив y создается на основе массива x, и оба они имеют одинаковые размеры, чего не скажешь о массиве z. Поэтому если график функции строится с помощью команды ShowPlot(x,y), результатом является график функции (рис. 3.33).

После создания графика в командном окне выводится сообщение о завершении выполнения функции. Если же попытаться выполнить команду ShowPlot(z,y), возникнет ошибка, поскольку исходные массивы (аргументы функции) имеют разные размеры. В этом случае при вычислении функции ShowPlot() выполняется catch-блок, в результате чего появляется сообщение о неверно указанных аргументах функции. При этом код функции продолжает выполняться, то есть экстренного завершения не происходит. Это важно, и именно это является главной целью всего процесса обработки исключительных ситуаций (ошибок).

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

136

Глава 3. Элементы программирования

Рис. 3.33. Результат выполнения функции, если ее аргументы указаны корректно

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

function ShowPlot2(x,y) try plot(x,y,'LineWidth',2) grid on

catch ME disp(ME.message)

disp('Неверно указаны аргументы функции!') end

disp('Выполнение функции завершено!') end

На заметку

Объекты и классы – основа концепции любого объектно-ориентированного языка программирования. По большему счету класс – это специальный шаблон, который определяет способ группировки данных и функций для их обработки. Данные называются свойствами класса, а функции – методами класса. Класс – это абстракция. Хорошая аналогия для класса – чертеж автомобиля, например. По этому чертежу можно сделать один автомобиль, два, три и т.д. У каждого автомобиля есть один и тот же набор свойств, как, например, цвет или тип обшивки. Значение

137

Самоучитель Matlab

На заметку

этих свойств у разных автомобилей разное, но набор свойств один и тот же. У автомобилей есть "методы": они могут ехать, сигналить, светить фарами. Если чертеж – это класс, то автомобиль, созданный по чертежу, – экземпляр класса, или объект.

Использованная в приведенном выше коде переменная ME обозначает объект класса MException, то есть объект ошибки. У этого класса, кроме прочего, имеется свойство message, которое содержит текстовое описание произошедшей ошибки. Другими словами, у каждого объекта класса MException есть свойство message, но значение этого поля для каждого объекта разное и зависит от типа возникшей ошибки. Этим свойством мы и воспользовались для вывода информации о том, что же произошло. В частности, чтобы узнать значение свойства message объекта ME, необходимо указать имя объекта (объектной переменой) и, через точку, название свойства, то есть ME.message. Именно эта инструкция указана аргументом функции disp(). На рис. 3.34 показано окно с кодом функции с измененным кодом обработки исключительной ситуации.

Рис. 3.34. Код функции содержит обработку исключительной ситуации с явным обращением к объекту исключения

Результат обработки исключительной ситуации проиллюстрирован на рис. 3.35.

Рис. 3.35. Результат обработки исключительной ситуации

138

Глава 3. Элементы программирования

При попытке выполнить команду ShowPlot2(z,y) в командном окне отображаются три сообщения:

Vectors must be the same lengths. Неверно указаны аргументы функции! Выполнение функции завершено!

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

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

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

К/ф "Клуб самоубийц, или Приключения титулованной особы"

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

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

function MyPlots(varargin) n=length(varargin);

if n<2

disp('Недостаточное количество аргументов!') else

x=varargin{1};

y=varargin{2};

plot(x,y,'LineWidth',1,'Color','red') grid on

hold on

139

Самоучитель Matlab

colors=['b' 'g' 'r']; for i=3:n y=varargin{i};

plot(x,y,'LineWidth',1+mod(i,2),'Color',colors(mod(i,3)+1)) end

hold off end

end

Переменная varargin указана единственным аргументом функции MyPlots. Первой командой n=length(varargin) в теле функции вычисляется количество аргументов, переданных функции. Это значение записывается в переменную n. Далее с помощью условного оператора проверяется ситуация, когда количество аргументов меньше двух: в этом случае выводится сообщение о том, что функции передано недостаточное количество аргументов. В противном случае выполняютсякоманды,предназначенныедлясозданияграфики.Первыйграфик создается, что называется, в явном виде. Для этого командами x=varargin{1} и y=varargin{2} из списка аргументов varargin считываются первый и второй массивы и записываются соответственно в переменные x и y. Обращаем внимание читателя, что индексация элементов в данном случае выполняется с помощью фигурных скобок. Дело в том, что переменная varargin представляет собой массив ячеек. Массивы ячеек предназначены для хранения элементов разного типа. Доступ к элементам таких массивов осуществляется с помощью фигурных скобок: после имени массива ячеек в фигурных скобках указывается номер элемента (ячейки). Именно такой подход использован в данном случае. Так, первый элемент переменной-массива varargin возвращается инструкцией varargin{1}, второй – инструкцией varargin{2}, и так далее.

На заметку

Некоторую полезную информацию о массивах ячеек читатель может найти в Приложении Б.

Командой plot(x,y,'LineWidth',1,'Color','red') создается первый график. Координатная сетка устанавливается командой grid on. Чтобы следующий график отображался в том же графическом окне, используем команду hold on. Кроме этого, командой colors=['b' 'g' 'r'] создается массив из трех элементов с буквенными значениями (буквы заключаются в одинарные кавычки) для последующего использования в качестве идентификаторов цвета кривых для разных графиков.

Все прочие графики создаются в теле оператора цикла, в котором индексная переменная i пробегает значения от 3 до n (с шагом единица по умолчанию). Командой y=varargin{i} считывается массив значений функции для очередногографика,асамграфиксоздаетсякомандойplot(x,y,'LineWidth',

140