d9e5a92d

Другие структуры данных

- оператор if
- оператор switch
- циклы for
- циклы while
- оператор break
Оператор if вычисляет логическое выражение и выполняет группу операторов, если выражение истинно. Необязательные ключевые слова elseif и else служат для выполнения альтернативных групп операторов. Ключевое слово end, которое согласуется с if, завершает последнюю группу операторов.

Таким образом, все группы операторов заключены между четырех ключевых слов, без использования фигурных или обычных скобок.
Алгоритм MATLAB для создания магического квадрата порядка п включает три разных случая : п нечетное, п четное, но не делится на 4, и п четное и делится на 4. Ниже приведен пример соответствующего кода.
if rem(n,2) ~= 0 M = odd_magic(n) elseif rem(n,4) ~= 0
M = single_even_magic(n) else
M = double_even_magic(n) end
В этом примере три случая являются взаимно исключающими, но если бы это было не так, то выполнялось бы первое истинное условие.
Важно понять, как оператор отношения и оператор if работают с матрицами. Когда вы хотите узнать, равны ли две переменные, нужно использовать следующую конструкцию
if A == B, . . .
Это правильный код MATLAB и он осуществляет то, что вы ожидаете, если A и B являются скалярами. Но когда A и B - матрицы, A == B не работает, если они не равны. Равенство матриц означает поэлементное равенство.

Фактически, если A и B имеют различные размеры, MATLAB выдаст ошибку.
Правильный способ определения равенства между двумя переменными - это использование функции isequal
if isequal(A,B), . . .
Далее приведен другой пример, который исследует этот вопрос. Если A и B являются скалярами, то нижеприведенная программа никогда не приведет к неожиданной ситуации.

Но для большинства пар используемых матриц, включая наши магические квадраты с переставленными столбцами, ни одно из условий A B, A B или A ==B не является истинным для всех элементов и поэтому выполняется случай else.
if A B ' greater ' elseif A B ' less'
elseif A == B ' equal ' else
error ( ' Непредвиденная ситуация ' ) end
Некоторые функции могут быть полезны для матричного сравнения при использовании с оператором if, например
isequal
isempty
all
anyswitch и case
Оператор switch выполняет группу операторов, базируясь на значении переменной или выражения. Ключевые слова case и otherwise разделяют эти группы. Выполняется только первый соответствующий случай.

Необходимо использовать end для согласования с switch.
Логика алгоритма магических квадратов может быть описана на следующем примере
switch (rem(n,4)==0) + (rem(n,2)==0) case 0
M = odd_magic(n) case 1
M = single_even_magic(n) case 2
M = double_even_magic(n) otherwise
error( ' Это невозможно ' ) end
Замечание для программистов Си. В отличие от языка Си, оператор switch в MATLAB не проваливается.

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

for

Цикл for повторяет группу операторов фиксированное, предопределенное число раз. Ключевое слово end очерчивает тело цикла.
for n = 3:32
r(n) = rank(magic(n)); end r
Точка с запятой после выражения в теле цикла предотвращает повторения вывода результатов на экран, а r после цикла выводит окончательный результат.
Хорошим стилем являются отступы при использовании циклов для лучшей читаемости, особенно, когда они вложенные.
for i = 1:m forj = 1:n
H(ij) = 1/(i+j);
end
end

while

Цикл while повторяет группу операторов определенное число раз, пока выполняется логическое условие. Ключевое слово end очерчивает используемые операторы.
Ниже приведена полная программа, иллюстрирующая работу операторов while, if, else и end, которая использует метод деления отрезка пополам для нахождения нулей полинома.
a = 0; fa = -Inf; b = 3; fb = Inf; while b-a eps*b x = (a+b)/2; fx = x^3-2*x-5; if sign(fx) == sign(fa) a = x; fa = fx; else
b = x; fb = fx; end end x
Результатом будет корень полинома x3-2x-5
x =
2.09455148154233
Для оператора while верны те же предостережения относительно матричного сравнения, что и для оператора if, которые обсуждались ранее.

break

Оператор break позволяет досрочно выходить из циклов for или while. Во вложенных циклах break осуществляет выход только из самого внутреннего цикла.
Ниже представлен улучшенный вариант предыдущего примера. Почему использование оператора break в данном случае выгодно?
a = 0; fa = -Inf; b = 3; fb = Inf; while b-a eps*b x = (a+b)/2; fx = x^3-2*x-5; if fx ==0 break
elseif sign(fx) == sign(fa)

a = x; fa = fx;
else
b = x; fb = fx;
end
end
x

Другие структуры данных

Этот раздел познакомит вас с некоторыми структурами данных в MATLAB, включая


- Многомерные массивы
- Массивы ячеек
- Символы и текст
- Структуры

Многомерные массивы

Многомерные массивы в MATLAB - это массивы более чем с двумя индексами. Они могут быть созданы вызовом функций zeros, ones, rand или randn с более чем двумя аргументами. Например
R = randn(3,4,5)
создает Зх4х5 массив с 3*4*5=60 нормально распределенными случайными элементами.
Трехмерные массивы могут представлять трехмерные физические данные, например, температуру в комнате. Результат представляется последовательностью матриц A(k) или зависящей от времени матрицей A(t).

В этих случаях, элемент (i,j) k-ой матрицы или tk-ой обозначается A(i,j,k).
Версии магического квадрата MATLAB и Дюрера отличаются переставленными столбцами. Оператор
p = perms(1:4);
генерирует 4! = 24 перестановки чисел от 1 до 4. k-ая перестановка - это вектор-строка, p(k,:). Тогда
A = magic(4);
M = zeros(4,4,24); for k = 1:24
M(:,:,k) = A(:,p(k,:)); end
хранит последовательность 24 магических квадратов в трехмерном массиве M. Размер M равен
size(M)
ans =
4 4 24
Оказывается, что 22-ая матрица в этой последовательности - матрица Дюрера:
M(:,:,22)

ans =
16
3 2 13
5 10 11 8
9 6 7 12
4 15 14 1
Функция
sum(M,d)

вычисляет суммы, изменяя индекс d. Так
sum(M,1)
- это 1x4x24 массив, содержащий 24 копии вектора-строки
34 34 34 34
А
sum(M,2)
является массивом 4x1x24, содержащим 24 копии вектора-столбца
34
34
34
34
И наконец,
S = sum(M,3)
добавляет 24 матрицы в последовательность. Результат имеет размерность 4x4x1, поэтому он выглядит как массив 4x4,
s =

204 204 204 204
204 204 204 204
204 204 204 204
204 204 204 204

Массивы ячеек

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

Но более часто они создаются путем заключения разнообразной группы объектов в круглые скобки. Круглые скобки также используются с индексами для получения доступа к содержанию различный ячеек. Например,
C = { A sum(A) prod(prod(A)) }
дает массив ячеек 1x3. Эти три клетки содержат: магический квадрат, вектор-строку с суммами в столбцаx и произведение его элементов. Если отобразить C на экране, то вы увидите следующее
C =
[4x4 double] [1x4 double] [2.0923e+013]
Это происходит потому, что первые две ячейки слишком большие для вывода в этом ограниченном пространстве, а третья ячейка содержит только отдельное число, 16!, и для него есть необходимая область вывода.
Очень важно запомнить два важных момента. Первое, для получения содержания одной ячейки, используйте индекс в круглых скобках. Например, C{1} возвращает магический квадрат, а C{3} - 16!. Второе, массивы ячеек содержат копии других массивов, а не их указатели.

Поэтому, если вы впоследствии измените матрицу A, с C ничего не произойдет.
Трехмерные массивы могут быть использованы для хранения последовательности матриц одинакового размера. А массивы ячеек могут применяться для хранения последовательности матриц различного размера. Например,
M = cells(8,1); for n =1:8
M{n} = magic(n); end M
создает последовательность магических квадратов в определенной последовательности
м =
[ 1]
[2x2 double]
[3x3 double]
[4x4 double]
[5x5 double]
[6x6 double]
[7x7 double]
[8x8 double]
Вы можете найти нашего старого друга, просто набрав M{4}

Символы и текст

Введите текст в MATLAB, используя одинарные кавычки. Например,
s = 'Hello'
Результатом не будет являться численная матрица или массив, которые мы рассматривали ранее. Это будет символьный массив 1х5.
Внутренне, символы хранятся как числа, но не в формате с плавающей точкой. Оператор
a = double(s)
преобразует массив символов в числовую матрицу, содержащую представление с плавающей точкой ASCII кода для каждого символа. Результатом будет
a =
72 101 108 108 111
А выражение s = char(a)
осуществляет обратное превращение.
Преобразование чисел в символы делает возможным присутствие различных шрифтов на вашем компьютере. Печатаемые символы в ASCII коде представляются целыми числами от 32 до 127. (Целые числа меньше 32 представляют непечатаемые символы.) Эти числа расположены в соответствующем массиве 6х16
F = reshape(32:127,16,6)‘;
Печатаемые символы в расширенном ASCII наборе представлены F+128. Когда эти числа интерпретируются как символы, результат зависит от того, какой шрифт в данный момент используется. Наберите следующее
char(F)
char(F+128)
и потом поизменяйте шрифты в командном окне MATLAB. Ниже представлен один из примеров того, что может получиться.
ans =
!#$%'()*+,-./
0123456789:,- =?
@ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\]^_
'abcdefghijklmno pqrstuvwxyz{|}~^ ans =
yyjnr:§Ёе^-®1
±Iii'viVSejSs:L
АБВГДЕЖЗИЙКЛМНОП
РСГУФХЦЧІІІІЦЪЫЬЭЮЯ
абвгдежзийклмноп
рстуфхцчшщъыьэюя
Соединение квадратными скобками конкатенирует текстовые переменные вместе в большую строку.
h = [s, ‘ world1]
объединяет строки по горизонтали и дает
h =
Hello world
Оператор
v = [s; 'world']
объединяет строки вертикаль, что приводит к
v =
Hello
world
Заметьте, что перед символом w в переменной h необходимо поставить пробел, а оба слова в переменной v должны быть равной длины. Результирующие массивы являются снова массивами символов: переменная h - 1х11, а переменная v - 2х5.
Есть два способа, чтобы управлять группой текста, содержащей строки разной длины: формировать заполненный массив символов или клеточный массив строк. Функция char принимает любое число строк, добавляет пробелы в каждую строку, чтобы все они были равной длины, и формирует массив строк с символьной строкой в каждой строке. Например,
S = char('A' , 'rolling' , 'stone' , 'gathers' , 'momentum.')
выдает
S =
A
rolling
stone
gathers
momentum.
Присутствует достаточное количество пробелов в первых четырех строках, чтобы все строки были равной длины. Другой способ - это сохранить текст в массиве ячеек.
C = {'A' ; 'rolling' ; 'stone' ; 'gathers' ; 'momentum.' }
будет массив ячеек 1х5
c =
'A'
'rolling'
'stone'
'gathers'
'momentum.'
Вы можете преобразовать заполненный символьный массив в массив ячеек из строк следующим образом
C = cellstr(S)
Обратное преобразование S = char(C)

Структуры

Структуры - это многомерные массивы MATLAB с элементами, доступ к которым осуществляется через поля. Например,
S.name = ‘Ed Plum';
S.score = 83;
S.grade = 'B+';
создает скалярную структуру с тремя полями
S =
name: 'Ed Plum' score: 83 grade: 'B+'
Как и всё в MATLAB, структуры являются массивами, поэтому вы можете добавлять в них элементы. В этом случае каждый элемент массива является структурой с несколькими полями. Поля могут добавляться либо по одному
S(2).name = 'Toni Miller';
S(2).score = 91;
S(2).grade = 'A-' ;
либо полностью
S(3) = struct( 'name', 'Jerry Garcia', . . .
'score', 70, 'grade', 'C' )
Сейчас структура стала достаточной большой, поэтому печатается лишь её сводка.
s =
1x3 struct array with fields: name score grade
Есть несколько способов перетранслировать различные поля в другие массивы MATLAB. Все они базируются на записи списка, разделенного запятыми. Если вы наберете
S.score
- это будет равносильно следующему S(1).score, S(2).score, S(3).score
Это и есть список, разделенный запятыми. Правда, без другой пунктуации он не очень полезен.

В этой строке происходит присваивание трех счетов (score) переменной по умолчанию ans и вывод результатов каждого присваивания. Но если вы включаете выражение к квадратные скобки,
[S.score]
то же самое, что
[S(1).score, S(2).score, S(3).score]
результатом будет численный вектор-строка, содержащий все счета (score)
ans =
83 91 70
Аналогично,
S.name
просто присваивает имена (names), по одному, переменной ans. Однако, заключение этого выражения в круглые скобки
{S.name}
создает массив ячеек 1x3, содержащий три имени (names)
ans =
'Ed Plum' 'Toni Miller' 'Jerry Garcia'
И функция
char(S.name)
с тремя аргументами создает массив символов из поля name.
ans =
Ed Plum Toni Miller Jerry Garcia

Сценарии и функции

MATLAB - это мощный язык программирования, также как и интерактивная вычислительная среда. Файлы, которые содержат код на языке MATLAB, называются М-файлами.

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

Для этого вам необходимо добавить их маршрут поиска MATLAB.
Если вы повторяете имя функции, то MATLAB вызывают только ту, которая встречается первой.
Чтобы увидеть содержание М-файла, например, myfunction.m необходимо набрать
type myfunction

Сценарии

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

В добавление к сказанному, сценарии могут осуществлять графический вывод, используя такие функции как plot.
В качестве примера, создадим файл magicrank.m, который содержит эти команды MATLAB:
% Investigate the rank of magic squares r = zeros(1,32); for n = 3:32
r(n) = rank(magic(n)); end r
bar(r)



это М-файлы, которые могут иметь входные и выходные возвращать. Имя М-файла и функции должно быть одним и тем же.

Функции работают с переменными в пределах их собственного рабочего пространства, отделенного от рабочего пространства, с которым вы оперируете в командной строке MATLAB.
Хорошим примером является функции rank. М-файл rank.m находится в директории
toolbox/matlab/matfun
Вы можете просмотреть его содержание, введя
type rank
function r = rank(A,tol)
%RANK Matrix rank.
% RANK(A) provides an estimate of the number of linearly
% independent rows or columns of a matrix A.
% RANK(A,tol) is the number of singular values of A % that are larger than tol.
% RANK(A) uses the default tol = max(size(A)) * norm(A) * eps.
% Copyright (c) 1984-98 by The MathWorks, Inc.
% $Revision: 5.7 $ $Date: 1997/11/21 23:38:49 $
S = Svd(A); if nargin==1
tol = max(size(A)') * max(s) * eps;
end
r = sum(s tol);
Первая строка функции М-файла начинается со слова function. Здесь происходит задание имени со списком аргументов.

В нашем случае, используется до двух входных аргументов и один выходной.
Следующие несколько строк, до первой пустой или выполняемой строки, являются комментариями, которые предоставляют справочную информацию. Эти строки будут выведены на экран, если вы наберете
help rank
Первая строка справочного текста - это H1 строка, которую MATLAB отображает при использовании команды lookfor или при запросе help по всей директории.
Остальное содержание файла составляет исполняемый код MATLAB. Переменная s, представленная в теле функции, также как и переменные в первой строке, r, A и tol, все являются локальными.

Они отделены от других переменных в рабочем пространстве MATLAB.
Этот пример показывает важную особенность функций MATLAB, которая обычно не встечается в других языках програмирования, - переменное число аргументов. Функция rank может быть использована в нескольких различных формах:
rank(A) r = rank(A) r = rank(A, 1.e-6)
Многие функции MATLAB работают таким образом. Если нет выходного аргумента, то результат сохраняется в переменной ans. Если нет второго входного аргумента, то функция вычисляет значение по умолчанию.

Внутри тела функции присутствуют две величины nargin и nargout, которые выдают число входных и выходных аргументов при каждом использовании функции. Функция rank использует переменную nargin , но не использует nargout.

Глобальные переменные

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

Определение global должно быть до самой переменной, используемой в функции. Хотя это не обязательно, использование больших букв для имени глобальной переменной поможет отличить их от других переменных. Например, создадим М-файл falling.m:
function h = falling(t) global GRAVITY h = ^*GRAVITY*t.A2;
Затем введем следующие строки
global GRAVITY GRAVITY = 32; y = falling((0: .1: 5)' );
Таким образом, строки определения GRAVITY в командной строке делают её доступной внутри функции. Вы можете после изменить GRAVITY и получить новое решение, не редактируя какие-либо файлы.

Командно-функциональная двойственность.

Примеры команд MATLAB - это
load
help
Многие команды имеют управляющий параметр, который определяет последующее действие.
load August17.dat help magic type rank
Другой метод использования командных параметров - это создание строки аргументов функций.
load( 'August17.dat' ) help( 'magic' ) type( 'rank' )
Это и есть командно-функциональная двойственность. Любая команда типа command argument
также может быть переписана в функциональной форме command( 'argument' )
Преимущество функционального подхода проявляется, когда строка аргумента создается из отдельных частей. Следующий пример обрабатывает многочисленные файлы с данными: August1.dat, August2.dat и т.д.

Он использует функцию int2str, которая преобразует целые числа в строку символов для создания имени файла.
for d = 1:31
s = [ 'August' int2str(n) '.dat'] load(s)
% Обработка содержания d-го файла end

Функция eval

Функция eval работает с текстовыми переменными для вычисления и реализации текстовых строк.
eval(s)
использует интерпретатор MATLAB для вычисления и выполнения выражения, содержащегося в текстовой строке s.
Пример из предыдущего раздела может быть также реализован следующим образом (хотя это будет менее эффективно, т.к. используется полный интерпретатор, а не вызов функции).
for d = 1:31
s = [ 'load August' int2char(n) '.dat' ] eval(s)
% Обработка содержания d-го файла end

Векторизация

Чтобы добиться максимальной скорости вне MATLAB, очень важно векторизо-вывать алгоритм в М-файлах. Там где другие языки программирования могут использовать циклы for или do, MATLAB может применять векторные или матричные операции.

Простым примером является создание таблицы логарифмов.
x = 0
for k = 1:1001 y(k) = log10(x); x = x + .01; end
(Опытные пользователи MATLAB любят говорить Жизнь слишком коротка чтобы тратить время на запись циклов)
А векторизованная версия этого кода выглядит следующим образом
x = 0: .10:10; y = log10(x);
Для более сложных программ возможности векторизации не так очевидны. Однако, когда важна скорость, вы должны всегда искать способы векторизации вашего алгоритма.

Предварительное выделение

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

Это позволяет циклу for работать заметно быстрее.
r = zeros(32,1) for n = 1:32
r(n) = rank(magic(n)); end
Без предварительного выделения в предыдущем примере интерпретатор MATLAB увеличивает вектор r по одному элементу каждый раз внутри цикла. Предварительное выделение вектора устраняет это действие, и результат получается быстрее.

Функция от функций

Класс функций, называемый функция от функций, работает с нелинейными функциями скалярных переменных. То есть одна функция работает с другой . Функции от функций включают в себя
- Нахождения нуля
- Оптимизация
- Интегрирование
- Обыкновенные дифференциальные уравнения
MATLAB представляет нелинейные функции через М-файлы. Например, ниже приведена упрощенная версия функции humps из директории matlab/demos
function y = humps(x)
y = 1. / ( (x - .3). Л2 + .01) + 1. / ( (x - .9) л2 + .04) - 6;
Вычислим эту функцию в нескольких точках интервала [0,1]
x = 0: .002:1;
y = humps(x);
Затем построим график
plot(x,y)



приближенное положение минимума
p = fmins( 'humps', .5)
Р =
0.6370
Чтобы найти значение функции в минимуме,
humps(p)
ans =
11.2528
Специалисты используют термины квадратура и интегрирование, чтобы различать численную аппроксимацию определенных интегралов и численное интегрирование обыкновенных дифференциальных уравнений. quad и quad8 -это подпрограммы MATLAB по вычислению квадратуры.
Q = quad8( 'humps', 0, 1)
вычисляет площадь под кривой на графике и выдает
Q =
29.8583
В заключение, на графике видно, что заданная функция не имеет нулей на этом интервале. Поэтому, если мы попытаемся отыскать нуль
z = fzero( 'humps', .5)
то мы найдем его вне нашего интервала
z =
-0.1316

Управляемая графика

MATLAB предоставляет комплекс функций низкого уровня, которые позволяют создавать и обрабатывать линии, поверхности и другие графические объекты. Эта система называется управляемая графика (Handle Graphics®).

Графические объекты

Графические объекты - это базисные элементы системы управляемой графики в MATLAB. Они сформированы в дерево структурной иерархии.

Этим отражается связь графических объектов. Например, объекты Line (линия) нуждаются в объектах Axes (оси) как в системе отсчета.

В свою очередь объекты Axes существуют только с объектами Figure.
Есть одиннадцать видов объектов управляемой графики:
- Объекты Root являются вершиной иерархии. Они соответствуют экрану компьютера.

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

Они включают в себя pushbutton, radio button и slider.
- Объекты Axes определяют область в окне Figure и ориентацию дочерних объектов в этой области.
- Объекты Uimenu представляют собой меню пользовательского интерфейса, которое расположено в верхней части окна Figure.
- Объекты Image - это двумерные объекты, которые выводит MATLAB, используя элементы прямоугольного массива как индексы в палитре.
- Объекты Line являются основными графическими базисными элементами для большинства двумерных графиков.
- Объекты Surface - это трехмерное представление данных матрицы, созданное путем графического отображения данных как высот над плоскостью x-y.
- Объекты Text - это строки символов.
- Объекты Light определяют источник света, действующий на все объекты в пределах Axes.

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

Каждый отдельный графический объект имеет свой уникальный идентификатор, называемый handle (манипулятор), который MATLAB присваивает объекту при создании.



Содержание раздела