Вы находитесь на странице: 1из 753

Юлий Кетков

Александр Кетков
Михаил Шульц

M A T L A B 7

ПРОГРАММИРОВАНИЕ,
ЧИСЛЕННЫЕ МЕТОДЫ

Санкт-Петербург
«БХВ-Петербург»
2005
УДК 681.3.06
ББК 32.973.26-018.2
К37

Кетков Ю . Л . , Кетков А. Ю., Шульц М . М .


К37 MATLAB 7: программирование, численные методы. — СПб.:
БХВ-Петербург, 2005. — 752 с : ил.
ISBN 5-94157-347-2
Книга посвящена описанию программных средств разработки математи-
ческого обеспечения в среде MATLAB. Особое внимание уделяется вопро-
сам проектирования пользовательских приложений, представления данных
с максимальным использованием средств программирования и отладки
приложений, а также увязке программ решения задач линейной алгебры,
дискретной математики, математического анализа с основными идеями со-
ответствующих алгоритмов.

Для инженеров, студентов и преподавателей вузов

УДК 681.3.06
ББК 32.973.26-018.2

Группа подготовки издания:

Главный редактор Екатерина Кондукова


Зам. главного редактора Евгений Рыбаков
Зав. редакцией Григорий Добин
Редактор Анна Кузьмина
Компьютерная верстка Натальи Смирновой
Корректор Наталия Першакова
Дизайн обложки Игоря Цырульникова
Зав. производством Николай Тверских

Лицензия ИД Na 02429 от 24.07.00. Подписано в печать 22.03.05.


Формат 70x1001/ie. Печать офсетная. Усл. печ. л. 60,63.
Тираж 3000 экз. Заказ № 899
"БХВ-Петербург", 194354, Санкт-Петербург, ул. Есенина, 5Б.
Санитарно-эпидемиологическое заключение на продукцию № 77.99.02.953.Д.006421.11.04
от 11.11.2004 г. выдано Федеральной службой по надзору
в сфере защиты прав потребителей и благополучия человека.
Отпечатано с готовых диапозитивов
в ГУП "Типография "Наука"
199034, Санкт-Петербург, 9 линия, 12

ISBN 5-94157-347-2 © КстковЮ. Л., Кетков А. Ю„ ШульцМ. М„ 2005


© Оформление, издательство "БХВ-Петербург", 2005
Оглавление

Предисловие 1

Глава 1. Краткий обзор 3


1.1. Немного истории 3
1.2. Пакет MATLAB 7 и его расширения 5

Глава 2. Пошаговые вычисления в командном окне 13


2.1. Путешествие по среде MATLAB 7 13
2.2. Переменные рабочего пространства 20
2.3. Скаляры или массивы? Индексированные переменные 22
2.4. Выбор формата отображения числовых данных 25
2.5. Арифметические выражения 29
2.5.1. Некоторые свойства вещественных данных 29
2.5.2. Специфика использования комплексных величин 30
2.5.3. Числовые матрицы и векторы, специфика представления 33
2.5.4. Специфика выполнения арифметических и логических
операций 37
2.5.5. Использование элементарных математических функций 39
2.6. Построение графиков функций одной переменной 43
2.6.1. Простые графики в декартовых координатах 43
2.6.2. График функции в полярных координатах 50
2.6.3. Использование логарифмического масштаба 52
2.6.4. Построение графика функции на заданном интервале 52
2.6.5. Средства управления в графическом окне 55
2.6.6. Редактирование графиков 60
Меню Edit 60
Меню View 67
Меню Insert 69
Меню Tools 69
2.6.7. Включение графиков в отчетную документацию 76
2.7. Деловая графика 77
2.7.1. Плоские столбиковые диаграммы 77
2.7.2. Объемные столбиковые диаграммы 81
2.7.3. Круговые диаграммы 83
2.7.4. Площадные диаграммы 86
IV Оглавление

Глава 3. Типы данных 89


3.1. Иерархия типов данных в MATLAB 89
3.1.1. Символьные массивы (char arrays) 90
3.1.2. Целочисленные данные в MATLAB 92
3.1.3. Вещественные данные с одинарной точностью (single arrays) 98
3.1.4. Разреженные матрицы (sparse arrays) 100
3.1.5. Структуры и массивы структур (struct arrays) 101
3.1.6. Массивы ячеек (cell arrays) 104
3.1.7. Массивы указателей на функции (function handle arrays) 105
3.1.8. Логические массивы (logical arrays) 106
3.1.9. Создание массивов из данных разного типа 107
3.2. Программа тестирования данных 108
3.3. Анализ типа данных и состояния элементов массивов 113
3.4. Редактирование массивов 119

Глава 4. Программирование вычислительных процессов 123


4.1. Скрипты и функции 123
4.2. Специфика выполнения операций 127
4.3. Синтаксис операторов MATLAB 127
4.4. Ввод числовых и символьных данных 133
4.5. Вывод результатов вычислений 134
4.6. Типы функций 135
4.7. Параметры функций 137
4.8. Функции eval vifeval 144
4.9. Специфика работы в редакторе m-файлов 146
4.9.1. Меню Text 148
4.9.2. Меню Debug 149
4.9.3. Меню Edit 152
4.10. Отладочные команды 155
4.11. Анализ эффективности программы 160

Глава 5. Обработка символьных данных 165


5.1. Создание символьных объектов 165
5.2. Конкатенация строк 171
5.3. Сравнения символьных данных 174
5.4. Поиск и замена 178
5.5. Преобразования к верхнему и нижнему регистрам 183
5.6. Преобразования строк и чисел 183
5.7. Форматные преобразования (sprint/, sscanf) 192
5.8. Регулярные выражения и поиск 198

Глава 6. Работа с файлами 207


6.1. Подготовка файла к работе 209
6.2. Завершение работы с файлами : 212
Оглавление

6.3. Контроль за исчерпанием данных 212


6.4. Работа с двоичными файлами 213
6.4.1. Чтение данных из двоичного файла 214
6.4.2. Запись в двоичный файл 220
6.5. Работа с текстовыми файлами 223
6.5.1. Последовательное чтение строк из текстового файла 224
6.5.2. Последовательное чтение нескольких символов из файла 224
6.5.3. Форматирование выводимой строки 225
6.5.4. Чтение данных из текстового файла 234
6.6. Форматные преобразования в оперативной памяти 238
6.7. Анализ ошибок в файловых операциях 238
6.8. Альтернативный доступ к текстовым файлам 239
6.9. Числовые файлы с разделителями 250

Глава 7. Иерархия графических объектов и их свойства 255


7.1. Объект Root 260
7.2. Объект Figure 266
7.3. Объект Axes 274
7.4. Объект Line 283
7.5. Объект Rectangle 287
7.6. Объект Text 291
7.7. Объект Image 298
7.8. Поиск объектов 312

Глава 8. Проектирование интерфейса 315


8.1. Динамическое создание интерфейсных элементов 321
8.1.1. Командная кнопка 328
8.1.2. Кнопка, фиксирующаяся в утопленном состоянии 335
8.1.3. Рамки, индикаторы альтернативных и неальтернативных
комбинаций 336
8.1.4. Ввод, редактирование и отображение текстов 341
8.1.5. Списки строк 345
8.1.6. Полоса прокрутки 347
8.2. Создание всплывающего меню 350
8.3. Проектирование интерфейса в среде GUIDE 352
8.3.1. Вызов редактора GUIDE .' 353
8.3.2. Управление конструктором графического интерфейса 360
8.3.3. Размещение интерфейсных элементов 365
8.3.4. Инспектор свойств (Property Inspector) 371
8.3.5. Просмотр объектов (Object Browser) 372
8.3.6. Создание меню (Menu Editor) 372
8.3.7. Анатомия файла, создаваемого в среде GUIDE 380
8.3.8. Использование контейнеров 387
Vl_ Оглавление

Глава 9. Стандартные диалоговые окна 393


9.1. Диалоговое окно общего назначения (dialog) 394
9.2. Окно с сообщением об ошибке (errordlg) 395
9.3. Окно со справочной информацией (helpdlg) 396
9.4. Стандартное окно для ввода строк (inputdlg) 397
9.5. Окно выбора из списка (listdlg) 399
9.6. Диалоговое окно с сообщением (tnsgbox) 402
9.7. Интерактивная настройка параметров страницы (pagedlg) 403
9.8. Диалоговая страница (pagesetupdlg) 405
9.9. Окно настройки параметров печати (printdlg) 406
9.10. Диалоговое окно с запросом (questdlg) 408
9.11. Выбор имени файла для чтения (uigetfile) 409
9.12. Выбор имени файла для записи (uiputfile) 412
9.13. Диалоговое окно для выбора цвета (uisetcolor) 413
9.14. Диалог по выбору параметров шрифта (uisetfont) 415
9.15. Диалоговое окно с предупреждением (warndlg) 416
9.16. Полоса прогресса 417

Глава 10. Визуализация трехмерных объектов 421


10.1. Некоторые задачи и алгоритмы трехмерной визуализации 421
10.1.1. Аффинные преобразования и однородные координаты 421
10.1.2. Растеризация векторных изображений 423
10.1.3. Воспроизведение утолщенных линий 424
10.1.4. Устранение невидимых частей изображения 424
10.1.5. Окрашивание граней полигональных моделей 425
10.2. Создание и отображение криволинейных поверхностей 427
10.2.1. Объект типа Surface и его свойства 427
10.2.2. Отображение проволочного каркаса поверхности 432
10.2.3. Отображение закрашенных поверхностей 436
10.2.4. Управление точкой зрения : 437
10.2.5. Выбор алгоритма визуализации 438
10.2.6. Освещение поверхностей 440
10.2.7. Построение линий уровня 442
10.3. Формирование и отображение полигональных тел 448
10.3.1. Объект типа Patch и его свойства 448
10.3.2. Закрашивание объектов типа Patch 455
10.4. Специальные способы закраски. Прозрачность 460
10.4.1. Нанесение изображения на поверхность 460
10.4.2. Прозрачные поверхности 462

Глава 11. Полиномы 465


11.1. Представление полиномов 465
11.2. Операции над полиномами, представленными вектором
коэффициентов 466
Оглавление Vll_

11.2.1. Значение полинома 466


11.2.2. Сложение и вычитание , 467
11.2.3. Умножение и деление 468
11.2.4. Дифференцирование и интегрирование 469
11.2.5. Корни полинома 470
11.3. Операции над полиномами, заданными в символьном виде 471
11.3.1. Значение полинома 471
11.3.2. Сложение и вычитание 472
11.3.3. Умножение и деление 473
11.3.4. Дифференцирование и интегрирование 474
11.3.5. Корни и разложение полинома на множители 476

Глава 12. Линейная алгебра 479


12.1. Основные матричные операции 479
12.2. Скалярное и векторное произведение 481
12.3. Стандартные матрицы, фрагменты и блоки 487
12.4. Простые преобразования матриц 488
12.5. Некоторые классы матриц 490
12.5.1. Симметричные и кососимметричные матрицы 490
12.5.2. Эрмитовы и косоэрмитовы матрицы , 490
12.5.3. Ортогональные (унитарные) матрицы 490
12.6. Специальные матрицы 490
12.6.1. Матрица Гильберта и обратная к ней 490
12.6.2. Матрица Адамара 491
12.6.3. Матрица Паскаля 491
12.6.4. Матрица Теплица 492
12.6.5. Матрица Ганкеля 492
12.6.6. Матрица Вандермонда 493
12.6.7. Магический квадрат 494
12.7. Разложение матриц 494
12.7.1. Разложение Эрмита 494
12.7.2. Скелетное разложение 496
12.7.3. LU-разложение 498
12.7.4. Разложение Холецкого 500
12.7.5. QR-разложение 500
12.7.6. Сингулярное разложение 503
12.7.7. Полярное разложение 504
12.7.8. Разложение Шура 505
12.7.9. Разложение Хессенберга 507
12.7.10. Разложение Жордана 509
12.8. Системы линейных уравнений 511
12.8.1. Основные понятия 511
Существование и единственность решения 511
Обратная и псевдообратная матрицы 511
VIII Оглавление

12.8.2. Решение совместной системы 512


12.8.3. Псевдорешение несовместной системы 515
12.8.4. Некоторые приложения 517
Линейные матричные уравнения 517
Система уравнений с формируемой матрицей 519
12.9. Проблема собственных значений 522
12.9.1. Характеристический полином 522
Собственные векторы 523
12.9.2. Вычисление собственных значений 524
Случай кратных корней 525
Случай комплексных корней 526
12.9.3. Обусловленность матрицы 527
12.10. Линейная алгебра и новые типы данных 529

Глава 13. Интерполяция и аппроксимация 535


13.1. Интерполяционный полином 535
13.2. Сплайны 539
13.2.1. Стандартные сплайны MATLAB 543
13.2.2. Сглаженные сплайны 544
13.2.3. Сплайны с заданными условиями на концах 546
13.3. Параметрическая аппроксимация 549
13.4. Двумерная аппроксимация 553
13.4.1. Аппроксимация на прямоугольной сетке 553
13.4.2. Аппроксимация с помощью триангуляции 555

Глава 14. Численное дифференцирование и интегрирование 559


14.1. Конечные разности 559
14.2. Численное дифференцирование функций одной переменной 560
14.3. Численное дифференцирование функций двух переменных 562
14.4. Численное интегрирование 563
14.5. Задача Коши для обыкновенных дифференциальных уравнений 572
14.6. Краевая задача для обыкновенных дифференциальных уравнений 580
14.7. Дифференциальные уравнения неявного типа 588

Глава 15. Нелинейные уравнения и оптимизация 595


15.1. Корень уравнения с одним неизвестным 595
15.2. Решение систем нелинейных уравнений 599
15.3. Минимизация унимодальной функции одной переменной 611
15.4. Многомерная безусловная минимизация 614
15.4.1. Функция fminsearch 614
15.4.2. Функция /minunc 618
15.4.3. Функция hqnonlin 624
15.4.4. Функция fminimax 629
Оглавление IX_

15.5. Условная минимизация 637


15.5.1. Функция fmincon 638
15.5.2. Функции hqnonlin wfminimax 646
15.6. Управление итерационными процессами 649

Глава 16. Математическое программирование 653


16.1. Линейное программирование 653
16.2. Бинарное линейное программирование 658
16.3. Решение матричных игр 662
16.4. Квадратичное программирование 667

Глава 17. Метод Монте-Карло 675


17.1. Генерация случайных данных 676
17.2. Элементы математической статистики 677
17.3. Линейная интерполяция в многомерном кубе 678
17.4. Вычисление кратных интегралов 683
17.5. Решение уравнений в частных производных 686
17.6. Моделирование случайных процессов 695
17.7. Случайный поиск 699

ПРИЛОЖЕНИЯ 705

Приложение 1. Помощь в системе MATLAB 707


Поиск по ключевым словам 708
Использование Help-навигатора 710
Поиск функций 713

Приложение 2. Указатель свойств графических объектов 715

Литература и интернет-источники 723


MATLAB 723
Методы вычислений 725
Интернет 727

Предметный указатель 728


Предисловие

Система MATLAB представляет собой уникальный сплав универсальных


программных и алгоритмических средств с широкой гаммой специализиро-
ванных приложений. Входной язык и среда программирования MATLAB
очень близки к современным системам визуального программирования на
базе универсальных алгоритмических языков типа Basic, C++, Java, Object
Pascal. По ряду аспектов MATLAB уступает указанным системам (режим ин-
терпретации, небольшой запас визуальных компонентов). Однако с его биб-
лиотекой численных методов ни по объему, ни по качеству не может срав-
ниться ни одна из систем программирования. Кроме того, в пакете MATLAB
тщательно отработаны средства визуализации результатов вычислений и ото-
бражения различных графических объектов. На базе ядра MATLAB созданы
многочисленные расширения, обеспечивающие моделирование и анализ сис-
тем в разнообразных сферах человеческой деятельности.
Многие учебные заведения у нас и за рубежом используют MATLAB при
подготовке специалистов различного профиля. Для современного инженера
и научно-технического работника MATLAB является незаменимым инстру-
ментом моделирования и исследования различных прикладных систем,
прежде всего, за счет использования готовых решений. Но не менее важно
научиться создавать новые приложения, используя программные и алгорит-
мические средства MATLAB, а также возможность объединения модулей,
разработанных в разных системах программирования. Использование систе-
мы MATLAB в учебном процессе позволит сблизить дисциплины, связан-
ные с информатикой и численными методами, которые зачастую читаются
автономно.
Авторы выражают признательность М. В. Шашкову, который на протяже-
нии ряда лет успешно использует систему MATLAB для проектирования и
исследования сложных динамических систем. Именно он привлек наше
внимание к выразительности программных средств и богатству численных
методов пакета MATLAB. Мы очень обязаны и нашим коллегам, специали-
зирующимся в различных разделах прикладной математики, которые помог-
ли нам в формировании глав, связанных с численными методами, и в под-
Предисловие

боре соответствующих приложений. Среди них преподаватели факультета


ВМиК Нижегородского университета — М. А. Антонец, А. И. Гавриков,
С. Ю. Городецкий, Н. В. Дерендяев, В. А. Зорин, А. П. Мальцев, В. П. Са-
вельев. Особой благодарности заслуживает А. И. Кузнецов — сотрудник на-
учно-исследовательского института прикладной математики и кибернетики
Нижегородского университета, который тщательно прочитал рукопись и
проверил практически все примеры программ. Многие его замечания были
учтены при подготовке настоящего издания.
Глава 1

Краткий обзор
Пакет MATLAB 7 — последняя версия одного из наиболее популярных про-
дуктов фирмы MathWorks, появившаяся на рынке программного обеспече-
ния в июне 2004 г. Его основное назначение — моделирование, анализ и
визуализация динамических процессов, имеющих отношение к разнообраз-
ным сферам человеческой деятельности.

1.1. Немного истории


Историю появления пакета MATLAB связывают с именем профессора
Клива Б. Моулера (Cleve В. Mouler). До перехода в фирму MathWorks он
занимался преподавательской и научно-исследовательской деятельностью на
кафедрах математики и в компьютерных центрах ряда университетов США
(Нью-Мехико, Мичиган, Стэнфорд). Он соавтор ряда книг, переведенных
на русский язык ([66, 67]). Примерно 30 лет назад Моулер принимал участие
в разработке пакетов программ на языке Fortran для решения задач линей-
ной алгебры (LINPACK) и исследованиях проблемы собственных значений
матриц (EISPACK). В 1980 г. на международной конференции AFIPS он
представил доклад "Design of an interactive matrix calculator", в котором, по-
видимому, впервые было озвучено название MATLAB. В реферативном
журнале "Автоматика и вычислительная техника" (реферат 6Б200 за 1980 г.) по
поводу этого доклада появилась следующая аннотация:
"Приведено формальное описание (с помощью синтаксических диа-
грамм) входного языка интерактивной программы MATLAB, предна-
значенной для матричных вычислений. Программа MATLAB обрабатывает
прямоугольные матрицы, элементами которых являются комплексные
числа. Данные вводятся либо перечислением элементов, либо в цикле
при помощи операторов FOR И WHILE, либо считыванием из внешнего
файла, либо после выполнения внешней программы. Для выполнения
матричных вычислений помимо 37 встроенных функций программы
MATLAB предусмотрен простой способ обращения к пакету ПП
EISPACK (70 программ выполнения матричных вычислений) и пакету
_4 Глава 1

UNPACK (40 программ анализа и решения систем линейных алгебраи-


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

Второе рождение пакета MATLAB связывают с Джеком Литтлом (Jack Little) —


нынешним президентом фирмы MathWorks, который в начале 80-х годов
прошлого века перенес программу MATLAB на более современные вычис-
лительные платформы VAX, Macintosh и IBM PC. Дальнейшее развитие па-
кета происходило под эгидой MathWorks, однако к расширению состава па-
кета и сфер его применения были привлечены коллективы высококва-
лифицированных математиков и инженерно-технических работников Ста-
рого и Нового света. Об этом свидетельствуют ссылки на многочисленные
книги и перечень благодарностей, которые можно обнаружить в справочных
файлах по всем продуктам пакета. С момента основания фирмы (1984 г.)
К. Моулер является ее бессменным научным руководителем. Модерниза-
цию и программное сопровождение пакета MATLAB обеспечивают более
1000 сотрудников MathWorks.
К концу 2004 г. реализации пакета MATLAB насчитывают следующие версии:
1. MATLAB 5 - декабрь 1996 г.
2. MATLAB 5.1 - май 1997 г.
3. MATLAB 5.3 (Release 11, Rll) - январь 1999 г.
4. MATLAB 6.0 (R12) - ноябрь 2000 г.
5. MATLAB 6.1 (R12.1) - июнь 2001 г.
6. MATLAB 6.5 (R13) - июнь 2002 г.
7. MATLAB 6.51 (R13SP1) — август 2003 г.
8. MATLAB 7.0 (R14) — июнь 2004 г.
Пакет MATLAB распространяется в двух модификациях — профессиональ-
ная версия и облегченный вариант, ориентированный на использование в
учебном процессе. На самом деле даже в профессиональной версии некото-
рые расширения пакета приобретаются по отдельной лицензии.
В нашей стране информация по вопросам использования и распространения
пакета доступна на сайтах www.softline.ru, www.matlab.ru и www.exponenta.ru.
Регулярные научные семинары, посвященные возможностям пакета MATLAB,
проводятся Институтом Проблем Управления РАН РФ и Консультацион-
ным центром MATLAB компании Softline.
О популярности пакета MATLAB свидетельствуют более 600 монографий,
учебных и практических пособий, изданных за рубежом. Отечественная ли-
Краткий обзор

тература насчитывает примерно в 15 раз меньше наименований (см. список


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

1.2. Пакет MATLAB 7 и его расширения


Перечислим принципиальные новинки MATLAB 7:
П 12 новых компонентов, расширяющих сферу приложений пакета
MATLAB и повышающих функциональные возможности прежних ком-
понентов;
• 28 компонентов предыдущей версии подверглись существенной модифи-
кации;
П в ряде приложений (линейная алгебра, быстрые преобразования Фурье,
моделирование в среде Simulink) реализована поддержка вычислений с
вещественными данными одинарной точности;
• появилась возможность обрабатывать целочисленные массивы большой
размерности за счет использования целочисленной арифметики;
• существенно изменен интерфейс среды MATLAB и некоторых сервисных
систем;
• расширились возможности по управлению графическими окнами;
П исправлены замеченные ошибки.
Полный перечень нововведений и исправлений составляет документ
"MATLAB 7.0 Release Notes" объемом 274 с.
Пакет MATLAB 7 предъявляет повышенные требования к РС-совместимому
оборудованию и программному обеспечению:
• персональный компьютер на базе процессоров Pentium III, Pentium 4,
Pentium M, Xeon, AMD Athlon, Athlon XP, Athlon MP;
• операционная система Microsoft Windows XP, Windows NT 4.0 (Service
Pack 5 или 6a) , Windows 2000 (Service Pack 3 или 4);
• CD-ROM для инсталляции с оптического диска;
• оперативная память не менее 256 Мбайт (рекомендуется 512 Мбайт);
• размер дисковой памяти зависит от количества установленных расшире-
ний и объема документации в формате PDF. Программа установки ин-
формирует вас об объеме дисковой памяти, необходимой для включения
6 Глава 1

того или иного компонента пакета. В средней комплектации MATLAB


займет на винчестере порядка 1 Гбайт;
• монитор с поддержкой минимум 256 цветов, рекомендуется графический
адаптер (16, 24 или 32 битов), поддерживающий стандарт OpenGL.
В состав дополнительных рекомендаций входят: ,
• операционная система должна поддерживать карту графического ускори-
теля, принтер и звуковую карту;
• Microsoft Word (Office 2000) или Office XP необходимы для функциони-
рования MATLAB Notebook;
• протокол TCP/IP требуется на всех платформах для использования ли-
цензионного сервера.
Для генерации собственных mex-файлов понадобится один из следующих
трансляторов:
• Compaq Visual Fortran (версии 5.0, 6.1 или 6.5);
• Microsoft Visual C/C++ (версии 5.0, 6.0 или 7.0);
• Borland C/C++ (версии 5.0 или 5.02);
• Borland C++Builder (версии 3.0, 4.0, 5.0 или 6.0);
• WATCOM (версии 10.6 или 11);
П Lcc 2.4 (bundled with MATLAB).
Для чтения и/или печати online-документации потребуется Netscape
Navigator (версия 4.0 или выше) или Microsoft Internet Explorer (версия 4.0
или выше), Adobe Acrobat Reader (версия 3.0 или выше).
Одним из наиболее важных приложений пакета MATLAB является проекти-
рование, имитация и анализ различных динамических систем. До появления
первых цифровых вычислительных машин (ЦВМ) большинство задач, свя-
занных с созданием и исследованием различных систем автоматического
регулирования, решались на аналоговых вычислительных машинах (АВМ).
В основе АВМ лежали динамические аналогии между поведением различ-
ных акустических, электрических и механических звеньев, описываемых
однотипными системами дифференциальных уравнений. АВМ представляли
собой набор электронных блоков (усилителей, сумматоров, умножителей,
интеграторов, задержек и различных нелинейностей), которые с помощью
коммутационной панели соединялись в схему, эквивалентную исследуемой
конструкции. А затем с помощью осциллографов и самописцев фиксирова-
лось и изучалось поведение напряжений и токов в различных узлах элек-
трической модели исследуемого объекта.
В середине 50—60-х годов прошлого столетия пользовались большой попу-
лярностью настольные интеграторы типа ИПТ-5 и МПТ-9, относительно
небольшие лабораторные установки ЭМУ-8, ЭМУ-10 и такие гиганты, как
Краткий обзор

МН-8, занимавшие площади по 60—80 кв. м. Самой главной оценкой мощ-


ности АВМ был максимальный порядок системы дифференциальных урав-
нений, которую можно было собрать из имеющихся блоков. И колебался он
в диапазоне от 5—6 до 30—40. К основным недостаткам АВМ относились
большая трудоемкость в коммутации блоков, нестабильность их поведения
(дрейф нуля усилителей), относительно малая точность результатов и затяж-
ной характер исследования. Однажды собранная и отлаженная схема комму-
тации блоков должна была сохраняться на протяжении времени исследования
данной системы. На более поздних АВМ появились сменные коммутацион-
ные панели. Повышению эффективности моделирования содействовали
гибридные аналого-цифровые вычислительные системы (ГВС "Русалка").
Однако точность вычислений, обеспечиваемая аналоговыми компонентами,
оставляла желать лучшего.
Пакет Simulink, самый родной среди расширений системы MATLAB
(кнопка для его запуска вынесена на панель инструментов системы), повто-
ряет идею АВМ на самом современном уровне. Он использует богатую биб-
лиотеку динамических звеньев с различными передаточными функциями,
располагает визуальными средствами сборки эквивалентной модели, облада-
ет большим набором вычислительных алгоритмов, обеспечивает высокую
точность и качественное отображение характеристик изучаемых процессов.
Наибольшее количество отечественных публикаций посвящено именно это-
му пакету [1, 2, 7, 8, 12, 14, 19, 20, 39]. На его базе построено довольно
много расширений системы MATLAB. Их наименования, как правило,
включают фирменную аббревиатуру Blockset, что можно трактовать как на-
бор блоков — моделей (файлы с расширением mdl), участвующих в конст-
руировании моделируемых систем.
Другие расширения MATLAB используют более распространенную аббре-
виатуру Toolbox (дословно — ящик с инструментами). Как правило, основ-
ными компонентами таких расширений являются средства решения различ-
ных задач — математические методы, визуализация результатов вычислений.
Большая часть этих приложений представлена m-файлами — программами
на входном языке MATLAB.
Полный перечень дополнительных компонентов версии MATLAB 7 приве-
ден в табл. 1.1. Некоторые из них являются автономными продуктами, дру-
гие эксплуатируются в комбинации с определенным подмножеством расши-
рений. По номеру версии компонента можно судить как о его "возрасте",
так и об интенсивности его поддержки. Из приведенного перечня видно,
что старейшими приложениями системы MATLAB являются средства обра-
ботки сигналов, моделирования управляющих систем, имитации различных
устройств в режиме реального времени. В первой колонке символом * отме-
чены компоненты, подвергшиеся серьезной модификации. Новые компо-
ненты отмечены символами **.
8 Глава 1

Таблица 1.1

№ Компонент MATLAB Назначение


п/п

1* Simulink, ver6.0 Моделирование и анализ динамических систем


2 Aerospace Blockset, Моделирование летательных аппаратов, ракет и
ver 1.6 двигательных установок (на базе Simulink)
3** Bioinformatics Tool- Математические методы анализа эксперименталь-
box, ver 1.1 ных данных в биологии и генетике
4 CDMA Reference Проектирование и моделирование беспроводных
Blockset, ver 1.1 коммуникационных систем в соответствии со стан-
дартом IS-95A (code division multiple access, CDMA)
5* Communications Библиотеки функций для Communications Toolbox
Blockset, ver 3.0 (модуляция, кодирование, декодирование)
6* Communications Tool- Разработка коммуникационных систем и их моде-
box, ver 3.0 лирование в реальном масштабе времени
7 Control System Tool- Моделирование, анализ и проектирование систем
box, ver 6.0 автоматического регулирования с обратной связью
8 Curve Fitting Toolbox, Обработка экспериментальных данных (аппрокси-
ver 1.1.1 мация, сглаживание, интерполяция, экстраполяция)
9 Data Acquisition Tool- Среда для поддержки измерительных комплексов,
box, ver 2.5 подключенных к персональному компьютеру (ПК).
Организация обмена данными с аналоговыми и
цифровыми подсистемами, включая цифроанало-
говые преобразования
10* Database Toolbox, Анализ и визуализация информации, хранящейся в
ver 3.0 базе данных (БД). Отбор данных с использованием
запросов на языке SQL
11 Datafeed Toolbox, Организация связи с серверами финансовых
ver 1.5 данных
12 Dials & Gauges Block- Библиотека графических примитивов для форми-
set, ver 1.2 рования панелей управления с изображениями
различных шкал и измерительных приборов
13 Embedded Target Проектирование и моделирование измерительно-
Infineon C166 Micro- управляющих комплексов на базе микроконтрол-
controllers, ver 1.1 леров С166
14 Embedded Target for Проектирование и моделирование измерительно-
Motorola HC12, ver 1.1 управляющих комплексов на базе микроконтрол-
леров фирмы Motorola
15* Embedded Target for Проектирование и моделирование измерительно-
Motorola MPC555, управляющих комплексов на базе микроконтрол-
ver 2.0 леров фирмы Motorola
Краткий обзор

Таблица 1.1 (продолжение)

№ Компонент MATLAB Назначение


п/п

16 Embedded Target for Проектирование и моделирование измерительно-


OSEC/VDX, ver1.1 управляющих комплексов на базе микроконтрол-
леров OSEC/VDX
17** Embedded Target for Проектирование и моделирование измерительно-
Texas Instruments управляющих комплексов на базе микроконтрол-
C2000 DSP, ver 1.0 леров фирмы Texas Instruments
18* Embedded Target for Проектирование и моделирование измерительно-
Texas Instruments управляющих комплексов на базе микроконтрол-
C6000DSP,ver2.1 леров фирмы Texas Instruments
19 Excel Link, ver 2.2 Организация взаимодействия между функциями
MATLAB и электронной таблицей Microsoft Excel
20 Extended Symbolic Расширенный пакет аналитических вычислений
Math, ver 3.1
21** Filter Design HDL HDL-кодирование в цифровых фильтрах
Coder, ver 1.0
22* Filter Design Toolbox, Проектирование, имитация и анализ цифровых
ver 3.0 фильтров
23* Financial Derivatives Анализ и визуализация процентных ставок, финан-
Toolbox, ver 3.0 совых производных и рисков
24 Financial Time Series Анализ данных финансовых рынков методом вре-
Toolbox, ver 2.1 менных рядов
25 Financial Toolbox, Интегрированная среда для решения задач управ-
ver 2.4 ления финансами и графического представления
результатов анализа
26 Fixed-Income Toolbox Прогнозирование фиксированного дохода
ver 1.0.1
27** Fixed Point Toolbox, Выполнение арифметических операций над не-
ver 1.0 стандартными форматами чисел (целочисленные,
длиной 1, 2, 4 байта; вещественные с одинарной
точностью)
28 Fuzzy Logic Toolbox, Моделирование и анализ систем на базе аппарата
ver 2.1.3 "нечеткой логики"
29 GARCH Toolbox, Анализ изменчивости на финансовых рынках с ис-
ver 2.0.1 пользованием одномерных GARCH-моделей (Gene-
ral Autoregressive Conditional Heteroscedasticity)
30** Genetic Algorithm and Генетический алгоритм и прямой поиск
Direct Search Toolbox
ver 1.0.1
10 Глава 1

Таблица 1.1 (продолжение)

№ Компонент MATLAB Назначение


п/п
31 Image Acquisition Организация обмена графическими данными
Toolbox, ver 1.5
32 Image Processing Обработка изображений (анализ, фильтрация,
Toolbox, ver 3.2 двумерные преобразования, восстановление и т. п.'
33* Instrument Control Обмен данными и управляющими сигналами с пе-
Toolbox, ver 2.9 риферийными приборами в формате протоколов
IEEE-488, HPIB, VISA
34 LMI Control Toolbox, Моделирование и анализ систем, описываемых
ver 1.0.9 линейными матричными неравенствами (Linear Ma-
trix Inequality, LMI)
35 Link for Code Com- Организация связи между MATLAB и интегриро-
poser Studio, ver 1.3.1 ванной средой разработки (IDE) фирмы Texas In-
struments (Code Composer Studio, CCS)
36** Link for ModelSim, Организация связи между MATLAB и средой твер-
ver 1.1.1 дотельного моделирования ModelSim
37 MATLAB Builder for Компилятор проектов MATLAB в СОМ-обьекты
COM, ver 1.1
38 MATLAB Builder for Конвертирование программ MATLAB в модули
Excel, ver 1.2 Excel
39* MATLAB Compiler, Компилятор m-файлов в коды С, C++
ver 4.0
40* MATLAB Report Gen- Создание отчетов в различных форматах (RTF,
erator, ver 2.0 HTML, XML, SGML), включая специфику представ-
ления данных и моделей
41 MATLAB Web Server, Сервис Web-сервера, позволяющий пользователям
ver 1.2.3 Интернета выполнять на сервере MATLAB-приложения
42* Mapping Toolbox, Обработка и визуализация цифровых карт
ver 2.0.2 местности
43* Model Predictive Con- Анализ и управление сложными системами с
trol Toolbox, ver 2.0 большим количеством входных и выходных данных
44 Model-Based Calibra- Проектирование эксперимента, статистическое
tion Toolbox, ver 2.1 моделирование и калибровка сложных систем
45 Mu-Analysis and Syn- Современные методы анализа и синтеза устойчи-
thesis Toolbox, вых линейных систем управления высокого порядка
ver 3.0.8
46 Neural Network Tool- Применение искусственных нейронных сетей для
box, ver 4.0.3 решения трудноформализуемых задач
Краткий обзор 11

Таблица 1.1 (продолжение)

№ Компонент MATLAB Назначение


п/п
47** ОРС Toolbox, ver 1.0 Поддержка промышленных стандартов для обмена
данными в системах реального времени (OLE for
Process Control, OPC)
48* Optimization Toolbox, Поиск экстремумов функций многих переменных
ver 3.0 при наличии ограничений, решение нелинейных
уравнений
49 Partial Differential Поиск и визуализация решений систем дифферен-
Equation Toolbox, циальных уравнений в частных производных
ver 1.0.5
50** RFBIockset, ver 1.0 Моделирование и исследование беспроводных
систем связи
51** RF Toolbox, ver 1.0 Моделирование и исследование беспроводных
систем связи
52 Real-Time Windows Создание моделей с интерфейсом в стиле Simulink
Target, ver 2.5 и управление ими в режиме реального времени
53* Real-Time Workshop, Генерация программ в расширенном С-формате по
ver 6.0 блочным диаграммам пакета Simulink
54* Real-Time Workshop Оптимизация программ, изготовленных пакетом
Embedded Coder, Real-Time Workshop, по использованию памяти, по
ver 4.0 скорости работы, по простоте интерфейса, по удо-
бочитаемости кода
55 Robust Control Tool- Анализ и синтез систем управления, устойчивых по
box, ver 2.0.10 отношению к случайным воздействиям (робастное
управление)
56* Signal Processing Библиотеки Simulink, предназначенные для проек-
Blockset, ver 6.0 тирования и моделирования систем цифровой об-
работки сигналов. Прежнее название — DSP Block-
set (Digital Signal Processing, DSP)
57 Signal Processing Обработка цифровых и аналоговых сигналов
Toolbox, ver 6.0
58 SimMechanics, ver 2.2 Моделирование твердотельных механических сис-
тем на базе аппарата Simulink
59 SimPowerSystems, Моделирование электрических силовых систем на
ver 3.1 базе аппарата Simulink
60 Simulink Accelera-tor, Повышение производительности программ, создан-
ver 6.0 ных в среде Simulink
61** Simulink Control De- Управление процессом построения моделей в сре-
sign, ver 1.0 де Simulink
12 Глава 1

Таблица 1.1 (окончание)

№ Компонент MATLAB Назначение


п/п
62* Simulink Fixed Point, Обеспечение расчетов с одинарной точностью в
ver 1.0 среде Simulink (прежнее название Fixed-Point
Blockset)
63** Simulink Parameter Подбор параметров моделей в среде Simulink
Estimation, ver 1.0
64* Simulink Report Создание отчетов с включением данных и моделей
Generator, ver 2.0 пакета Simulink
65* Simulink Response Проектирование, имитация и анализ систем авто-
Optimization, ver 2.0 матического регулирования с нелинейными огра-
ничениями (прежнее название Nonlinear Control
Design Blockset)
66** Simulink Verification Контроль за правильностью и допустимостью мо-
and Validation, ver 1.0 делей в среде Simulink
67 Spline Toolbox, Библиотека процедур для сплайн-аппроксимации
ver 3.2.1 плоских кривых и криволинейных поверхностей
68* Stateflow, ver 6.0 Моделирование систем, управляемых событиями,
на базе теории конечных автоматов
69* Stateflow Coder, Оптимизация программ, построенных на базе мо-
ver 6.0 делей Stateflow
70* Statistics Toolbox, Набор методов вероятностного анализа и визуали-
ver 5.0 зации результатов статистических исследований
71 Symbolic Math Tool- Символьные вычисления на базе ядра пакета Maple
box, ver 3.1
72* System Identification Идентификация систем (восстановление математи-
Toolbox, ver 6.0.1 ческой модели) на основе анализа входных и вы-
ходных сигналов
73* Virtual Reality Toolbox, Создание трехмерных сцен виртуальной реально-
ver 4.0 сти на базе языка VRML (Virtual Reality Modeling
Language)
74* Wavelet Toolbox, Непрерывные и дискретные вейвлет-
ver 3.0 преобразования для анализа и синтеза сигналов и
изображений различной природы
75 xPC Target, ver 2.5 Моделирование и тестирование систем реального
времени в автономном режиме на целевом компь-
ютере или в связке с сервером
76 xPC Target Embedded
Option, ver 2.5
Глава 2

Пошаговые вычисления
в командном окне
2.1. Путешествие по среде MATLAB 7
По умолчанию после запуска пакета MATLAB 7 на экране появляется ком-
бинированное окно, включающее четыре наиболее важные панели — Com-
mand Window (Окно команд), Command History (История команд), Workspace
(Рабочее пространство) и Current Directory (Текущий каталог). Две послед-
ние панели закрывают друг друга, и для выдвижения нужной панели на пе-
редний план следует щелкнуть по соответствующей вкладке. Три окна, впи-
санные в главное окно системы (рис. 2.1), "поставлены на якоря". Они
передвигаются вместе с главным окном системы, вместе с ним изменяют
свои размеры, границы между окнами можно передвигать. Каждое из них
можно снять с якоря (кнопки Undock (Отстыковать) 1 3 . размешенные в
правых верхних углах окон), и тогда оно может занимать автономную пози-
цию на экране.
Вообще, самой используемой панелью является Command Window (Окно
команд). В ней набираются команды пользователя, подлежащие немедлен-
ному исполнению. Здесь же выдаются результаты выполненных команд.
В командном окне можно обратиться за помощью по поводу того или иного
термина с помощью одной из команд — doc, help или lookfor. Присутст-
вие двух других окон во время сеанса работы только загромождает экран, и
их целесообразно закрыть (такого рода операции выполняются не только
кнопками, но и командами меню Desktop (Рабочий стол)).
Окно Workspace (Рабочее пространство) отображает текущий набор пере-
менных, заведенных пользователем в командном окне. Здесь можно увидеть
их имена (колонка Name (Имя)), значения скалярных переменных (колонка
Value (Значение)) и тип представляемых данных (колонка Class (Тип дан-
ных)). Точно такую же информацию можно увидеть в командном окне по-
сле исполнения команды whos. Поэтому постоянное присутствие окна
Workspace (Рабочее пространство) на экране вряд ли оправдано. В него
14 Глава 2

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


значения элементов какого-либо массива с помощью Array Editor (Редактор
массивов). Это новый инструмент, появившийся в 7-й версии. Для его вы-
зова достаточно щелкнуть по имени переменной в поле Workspace (Рабочее
пространство).

kAMATLAB
File Edit Debug Desktop Window Help
Shortcuts \f} How to Add i>] What's New : . .

s=3in(0.5)
» c=cos (0.5)
5*S+C*C

ans =
1

5=sin(0.5)

c=cos (0.5)
s*s+c*c

Рис. 2 . 1 . Общий вид главного окна пакета MATLAB 7

Окно Command History (История команд) хранит все команды, набираемые


пользователем, однако в отличие от содержимого Command Window (Окно
команд) сюда не попадают сообщения системы и результаты вычислений.
Эта информация может оказаться полезной для формирования программы,
исполняемой в автоматическом режиме.
Совершим беглый экскурс по командам главного меню. Команды меню File
(Файл) (рис. 2.2) выполняют обычные функции для большинства систем
программирования. Первая группа команд обеспечивает переход в режим
ввода новой программы (New (Создать)) или извлечение из дискового файла
ранее сохраненной программы (Open (Открыть)). Команда Close Command
Window (Закрыть окно команд) дублирует соответствующую кнопку в Com-
mand Window (Окно команд).
Команды второй группы позволяют сохранить значения всех переменных
рабочего пространства в дисковом файле (Save Workspace As (Сохранить ра-
бочее пространство как)) или импортировать ранее сохраненные данные
(Import Data (Импортировать данные)).
Пошаговые вычисления в командном окне 15

Open... ; Ctrl+O
Clcse Command Window
Importbata... , ,
:
Save Workspace As.., Ctrl+S
Set Path..,
Preferences...
Page Setup.,.
Print... ."•• :•; • ' ••:'• ;;

1 C:\...p5\work\array2vec.rn
2 H:\,..AB7\work\untitled.m
3 C:\MATLAB6p5\wcrk\diff2.m
4 C:\MATLAB6p5\workl\test.rn
Exit MATLAB Ctrl+Q

Рис. 2.2. Команды меню File

Команда Set Path (Задать путь) позволяет пополнить список каталогов,


просматриваемых системой, или изменить порядок их просмотра. Настрой-
ка параметров системы выполняется в окне Preferences (Предпочтения).
Четвертая группа команд — традиционная для большинства систем. Она
обеспечивает получение твердой копии с предварительной настройкой па-
раметров бумаги и принтера.
Под ними расположена часть меню со списком последних файлов, с
которыми работал пользователь. Размер этого списка регулируется, и его
основное назначение — ускорить выборку файлов, открывавшихся в пре-
дыдущем сеансе.
Меню Edit (Правка) (рис. 2.3) содержит характерный для любого редактора
набор команд по вырезанию (Cut (Вырезать)), копированию (Сору
(Копировать)), вставке (Paste (Вставить)), Paste Special (Специальная встав-
ка)) и удалению (Delete (Удалить)) выделенных фрагментов текстов или
графических объектов. Команда Select All (Выделить все) выделяет тексто-
вый или графический объект целиком.
Команды Undo (Отменить) и Redo (Повторить) используются, соответствен-
но, для отмены только что совершенного действия или отказа от предшест-
вующей отмены.
С помощью команды Find (Найти) можно найти текстовый фрагмент и, при
необходимости, произвести его замену.
Последняя группа команд позволяет произвести очистку соответствующих
окон. Выполнение команд Clear Command Window (Очистить окно команд),
16 Глава 2

Clear Command History (Очистить окно истории команд) и Clear Workspace


(Очистить переменные рабочего пространства) по умолчанию сопровожда-
ется запросом о подтверждении. Эти сообщения системы можно подавить,
устанавливая соответствующие параметры в окне Preferences (Предпоч-
тения).

Undo Ctrl+Z

Сору Alt+W
Paste Ctrl+Y
Paste Special...
Select All
Delete • Ctrl+D
Find...
; Find Files...
Clear Command Window
Clear Command History
Clear Workspace

Рис. 2 . З . Команды меню Edit

На командах меню Debug (Отладка) мы остановимся подробнее в разд. 4.9.


Из главного меню MATLAB 7 исчез привычный для пользователей преды-
дущих версий набор команд меню View (Вид). Большинство из них переко-
чевало в меню Desktop (Рабочий стол) — рис. 2.4.
Команда Undock Command Window (Снять с якоря окно команд) разъединяет
состыкованные окна и позволяет Command Window (Окно команд) переме-
щаться самостоятельно.
Команда Desktop Layout (Разметка рабочего стола) определяет количество и
расположение одновременно видимых панелей среды. Вы можете выбрать
конфигурацию среды по умолчанию (Default), которая была приведена на
рис. 2.1, или сохранить на экране только окно команд (Command Window
Only). Команда History and Command Window (Окна истории и команд) по-
зволяет сохранить два окна — историю команд и окно команд. Команда All
Tabbed (Co вкладками) располагает на экране все окна (рис. 2.5).
При этом одно из окон находится на переднем плане, а любое из оставших-
ся выходит на передний план после щелчка по соответствующей вкладке.
В MATLAB 7 появилась возможность сохранить ту или иную конфигурацию
окон на экране, воспользовавшись командой Save Layout (Сохранить раз-
метку). Файлы, в которых запоминались те или иные конфигурации, могут
Пошаговые вычисления в командном окне 17

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


из ранее сохраненных файлов, необходимо прибегнуть к команде Organize
Layouts (Организовать разметку).

Desktop
» Undock Command Window Default : -'•-:• ; ;;
Desktop Layout Command Window Only
Save Layout... History and Command Window
Organize Layouts... All Tabbed:. ;
«• Command Window
<f Command History ..•..;
•• Current Directory
«"Workspace
Help
Profiler
'Toolbar
•• Shortcuts Toolbar
«•Titles. ' • ' •• • '.' :.
Рис. 2.4. Команды меню Desktop

-j=.MATLAB
File Edit Debug Desktop Window Help
D GJF ! i. -Si Ш •-': CJ : % Of : f \ Current Directory | H:WA
I TLAB7\work
Command Window
» s=sin(0.5);
» c=cos (D.5) ;
» S*S+C*C
ans =
1

Command Wn
idow [Command Hs
i tory j Current Driectory | Workspace [ Hep
l | Profiler j

Рис. 2.5. Конфигурация всех окон с вкладками

Следующая группа команд (Command Window (Окно команд), Command


History (История команд), Current Dictionary (Текущий каталог), Workspace
(Рабочее пространство), Help (Справка), Profiler (Профайлер)) позволяет из
меню установить комбинацию окон, которые должны присутствовать на эк-
ране. Включение или отмена галочки у соответствующей строки меню
управляет появлением или исчезновением того или иного окна.
18 Глава 2

Команды последней группы управляют видимостью панели инструментов


(Toolbar), заголовков окон (Titles). С помощью команды Shortcuts Toolbar
(Пользовательская панель) можно создавать пользовательские панели инст-
рументов.
На панель инструментов вынесены наиболее употребительные команды
главного меню (рис. 2.6). Только три из них дополняют главное меню.
Кнопка Simulink обеспечивает вызов самого популярного расширения паке-
та MATLAB — системы имитационного моделирования. Кнопка GUIDE вы-
зывает конструктор интерфейса, с помощью которого в диалоговом режиме
формируется интерфейс приложения. В правой части панели расположены
две кнопки, обеспечивающие просмотр каталогов (Browse for Folder) и пере-
ход по каталогам на один уровень вверх (Go up one level).

Undo
r Redo
1 MATLAB
File Edit Debug desktop Window Help
>r
D Or I « Ч-я Ш > "• ' Щ tf | f 1 ; Current Directory | H:WATLABT\work Ё?
1 L

L
L -Paste
Copy
L
L
GUIDE
Help Browse for folder
Go up one level
Cut Simulink
u
Open file
New M-File

Рис. 2.6. Кнопки быстрого запуска команд меню

На панель окна Workspace (Рабочее пространство) тоже вынесено несколько


кнопок (рис. 2.7), ускоряющих выполнение некоторых операций по сохра-
нению и восстановлению переменных рабочего пространства, по очистке
рабочего пространства и снятию окна с якоря.
Command Window (Окно команд) превращает MATLAB в великолепный
калькулятор практически с неограниченной памятью. Для того чтобы мно-
гочисленные окна пакета не загромождали экран, можно выполнить коман-
ду Desktop | Command Window Only (Рабочий стол | Только окно команд).
В левом верхнем углу командного окна находятся два знака » , символизи-
рующие начало текущей строки. В этой строке можно набирать формулы
или команды, удовлетворяющие синтаксису языка MATLAB и завершаю-
щиеся нажатием клавиши <Enter>. Длинные команды, не помещающиеся
целиком в одной строке, можно продолжать в одной или нескольких еле-
Пошаговые вычисления в командном окне 19

дующих, используя условный знак переноса в виде трех подряд идущих то-
чек ( . . . ) . Вслед за знаком переноса необходимо нажимать клавишу
<Enter>.

— New variable
Open selection

Print "- L Plot selection


L- Save Undock Workspace -
— Load data file
Рис. 2.7. Панель кнопок в окне Workspace

Если все операнды формулы известны, то MATLAB вычисляет значение вы-


ражения, помещая его в системную переменную с именем ans (от англ. an-
swer — ответ):
» 2*2

Если в выражении указан операнд, значение которого неизвестно, MATLAB


выдает сообщение об ошибке:
» (х-1)*(х+1)
??? Undefined function or variable 'x'.

Точка с запятой, завершающая набор командной строки, подавляет автома-


тический режим вывода результата вычислений. Это позволяет производить
многошаговые вычисления, сохраняя промежуточные результаты в соответ-
ствующих переменных:
» s=sin(0.5);
» c=cos(0.5);
» s*s+c*c

Если формула для вычислений, располагаемая в правой части оператора


присваивания, достаточно длинная, то ее часть может быть перенесена на
следующую строку. Признаком завершения строки, у которой имеется про-
20_ Глава 2

должение в следующей строке, являются три подряд идущих точки. Все, что
располагается в этой же строке правее знака переноса, MATLAB 7 воспри-
нимает как комментарий:
» x=sin(0.2)*cos(0.5)+ sin(0.5)*cos(0.2)...формула будет продолжена
+cos(0.2)*cos(0.5)-sin(0.2)*sin(0.5) % продолжение предыдущей строки
х =
1.4091

2.2. Переменные рабочего пространства


Значения всех промежуточных переменных, использованные в многошаго-
вых вычислениях, MATLAB запоминает в рабочем пространстве (Work-
space). На выбор имен переменных накладываются примерно такие же огра-
ничения, как и в других системах программирования:
• можно использовать латинские буквы, цифры и символ подчеркивания;
• большие и малые буквы в именах различаются;
• имя должно начинаться с буквы;
• длина имени не должна превышать 63 символов.
Информацию о переменных рабочего пространства можно получить, набрав
команду who или whos. Первая из них выводит только список имен пере-
менных, а вторая сообщает более подробную информацию об именах пере-
менных (Name), их размерности (size), количестве занятых байтов в опера-
тивной памяти (Bytes) и классе объектов, представляющих соответствую-
щий тип данных (class):
» whos
Name Size Bytes Class
ans lxl 8 double array
с lxl 8 double array
s lxl 8 double array
Grand total is 3 elements using 24 bytes

Детали этой информации будут рассмотрены немного позже. Если мы соби-


раемся продолжить сеанс общения с MATLAB в другой раз, то имена и зна-
чения переменных рабочего пространства можно запомнить в файле, при-
бегнув к услугам команды главного меню File | Save Workspace As (Файл
Сохранить рабочее пространство как) либо набрав аналогичную команду в
текущей строке:
>> save qq
Пошаговые вычисления в командном окне 21

MATLAB добавит к имени нашего файла расширение mat и запомнит все


переменные и их значения в файле qq.mat. В начале следующего сеанса до-
статочно выполнить команду load:
»load qq
За время сеанса в рабочем пространстве может оказаться довольно много
уже использованных переменных. Они занимают оперативную память и за-
медляют работу системы. Поэтому время от времени рабочее пространство
стоит чистить, либо удаляя все переменные, либо только те, которые в даль-
нейшем не понадобятся.
Команда clear без параметров удаляет все переменные рабочего простран-
ства, не задавая никаких вопросов. Однако, будучи набрана с указанием
списка имен, удаляет из рабочего пространства только заданные перемен-
ные (пример 2.1).

i Пример 2.1. Команда c l e a r :

» х=1;
» У=2;
» z=3;
» whos
Name BytesSize Class
X 8lxl double array
У lxl 8 double array
z lxl 8 double array
Grand total is 3 elements using 24 bytes
» clear x у
» whos
Name Size Bytes Class
z lxl 8 double array
Grand total is 1 elements using 8 bytes

При выполнении команды clear возможна ошибка, не замечаемая систе-


мой, — если список имен удаляемых переменных задан через запятые, то
будет удалена только первая переменная списка (пример 2.2). Содержимое
остальных переменных списка будет отображено, если список не заканчива-
ется точкой с запятой.
. , . , . . . . . . . . . , ,. • . — - • ; . • • — • • ' — ;

Пример 2.2. Команда c l e a r (продолжение) \

» х=1;
» у=2;
22 Глава 2

» z=3;
» clear x,y, z
У =
2
z =
3
» whos
Name Size Bytes Class
У lxl 8 double array
z lxl 8 double array
Grand total is 2 elements using 16 bytes

Полную очистку рабочего пространства можно выполнить и командой Clear


Workspace (Очистить рабочее пространство) из меню Edit (Правка). Правда,
в этом случае система потребует подтвердить запрос на удаление (рис. 2.8).

1\ Are you sure you wanttoclear your workspace?

Рис. 2.8. Запрос подтверждения


на очистку рабочего пространства

2.3. Скаляры или массивы?


Индексированные переменные
Своим названием пакет MATLAB обязан сокращению от английского на-
звания Matrix Laboratory — дословно "матричная лаборатория". Поэтому
можно догадаться, что основным видом данных, которые используются в
пакете, являются матрицы. Даже общепринятые скалярные переменные
MATLAB рассматривает как матрицы размерности lxl 1 . До поры до време-
ни на скалярных переменных пользователь эту специфику не чувствует, т. к.

1
Традиционно в математической литературе обозначение 1x1 (или, в общем случае,
тх.п) соответствует размеру матрицы, а размерность при этом равна 2. Однако в этом
издании указанное обозначение трактуется в понимании авторов. — Ред.
Пошаговые вычисления в командном окне 23_

для единственного элемента массива размерности 1x1 указывать индексы не


обязательно:
» х=2
х =

Однако никто не мешает обратиться к единственному элементу массива с


двумя и даже с одним индексом, задавая его в круглых скобках:
» х(1,1)
ans =
2
» х(1)
ans =
2

Последнее требует объяснения. Дело в том, что вместо обычных индексов,


принятых в математике и алгоритмических языках, в компиляторах исполь-
зуют так называемые приведенные индексы, определяющие позицию соответ-
ствующего элемента массива в оперативной памяти. Так какiоперативная
память использует линейную адресацию своих ячеек, то для одномерного
массива приведенный индекс совпадает с обычньш. Для двумерного масси-
ва А с количеством элементов mxn (m — число строк, п — число столбцов)
приведенный индекс к элемента A1#j зависит от способа распределения эле-
ментов в памяти. MATLAB по аналогии с Fortran использует отсчет индек-
сов в массивах от 1 и располагает элементы матрицы по столбцам. Поэтому
элементу A 1; J в памяти предшествуют (j-1) столбцов по m элементов в каж-
дом, и этот элемент расположен на месте с номером k=(j-l) *m+i. MATLAB,
наряду с традиционными индексами в многомерных массивах, позволяет
пользоваться и единственным приведенным индексом, что несколько по-
вышает скорость вычислений.
Попытка обратиться к несуществующему элементу массива приведет к вы-
даче сообщения об ошибке:
» х(2)
??? Index exceeds matrix dimensions.

Векторы и матрицы в MATLAB могут быть не только числовыми, но и сим-


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

2 Зак. 899
24_ Глава 2

\ Пример 2.3. Символьные векторы и матрицы !

» a=['abcdefghijk';'ABCDEFGHIJK';'1234567890']
??? Error using ==> vertcat
All rows in the bracketed expression must have the same
number of columns.
» a=['abcdefghijk';'ABCDEFGHIJK1;'1234567890 ']
a =
abcdefghijk
ABCDEFGHIJK
1234567890
>> whos
Name Size Bytes Class
a 3x11 66 char array
Grand total is 33 elements using 66 bytes

Попытка разделить строковые значения пробелами или запятыми приведет


к конкатенации этих строк, т. е. к созданию символьного вектора-строки:
» b=['ABCDEF' 42345']
Ь =
ABCDEF12345
» whos
Name Size Bytes Class
b lxll 22 char array
Grand total is 11 elements using 22 bytes

Как и в других алгоритмических языках, в MATLAB допускается существо-


вание пустых массивов, не содержащих ни одного элемента (пример 2.4).

Пример 2.4. Задание пустых массивов ;

» а=[]

» b=char([ ]
b =

» c=uint8 ( [
с =
Пошаговые вычисления в командном окне 25

» whos
Name Size Bytes Class
а 0x0 0 double a r r a y
b 0x0 0 char array
с 0x0 0 uint8 array
Grand total is 0 elements using 0 bytes

Пустыми массивами считаются и такие, у которых максимальное значение


любого индекса равно нулю.

2.4. Выбор формата отображения


числовых данных
Числовые данные, с которыми оперирует MATLAB на IBM-совместимом
ПК, в памяти компьютера представлены вещественными или комплексны-
ми значениями в формате double. Это означает, что каждое вещественное
число занимает 8 байтов в оперативной памяти и принимает по модулю
значения из диапазона [10~308, 10 + 3 0 8 ]. Количество значащих десятичных
цифр при этом достигает 16—17. Комплексное число, представленное дейст-
вительной и мнимой частями в таком же формате, занимает, соответствен-
но, 16 байтов. Именно с такой точностью MATLAB выполняет все вычисле-
ния. Однако при отображении числовых результатов на дисплее часть
значащих цифр отбрасывается в соответствии с установленным форматом
вывода.
Обычно числа выводятся с небольшим количеством значащих цифр. Целые —
не более чем с 9 цифрами, вещественные с фиксированной запятой — не
более чем с 4 цифрами в дробной части, очень большие или очень малень-
кие числа — в формате с плавающей запятой и пятью значащими цифрами.
Отображаемые значения округляются по общепринятым в математике пра-
вилам (табл. 2.1).

Таблица 2.1
Пример отображения Пример отображения Пример отображения
числа числа числа
» х=123456789 » х=10/6 » х=1/1000
х = х = х =
123456789 1.6667 0.0010
» х=1234567890 » х=100/6 » х=1/10000
х = х = х =
1.2346е+009 16.6667 1.0000е-004
26 Глава 2

Таблица 2.1 (окончание)

Пример отображения Пример отображения Пример отображения


числа числа числа
» х=1/60 » х=1000/6 » х=123.456789
X = х = х =
0.0167 166.6667 123.4568
» х=1/б » х=10000/6 » х=1234.56789

X = х =

0.1667 1.6667е+003 1.2346е+003

По умолчанию система использует формат, обозначаемый служебным сло-


вом short (укороченный). Однако формат вывода числовых данных может
быть и другим (табл. 2.2).

Таблица 2.2

Пример отображения числа Пример отображения числа


» format short » format short e
» x=sqrt(2) » X

х= X =

1.4142 1.4142e+000
» format long » format long e
» X » X

! 1.41421356237310 1.414213562373095e+000
» format rational
! » x
x=
j 1393/985

В табл. 2.2 использованы основные форматы вывода числовых данных с


фиксированной и плавающей запятой. Последний формат позволяет ото-
бражать числовые значения в виде подходящих рациональных дробей с ми-
нимально возможными числителями и знаменателями. Следует заметить,
что значение переменной х не зависит от установленного формата вывода.
Формат вывода результатов вычислений может быть установлен как про-
граммным путем (именно это и продемонстрировано в табл. 2.2), так и с
помощью изменения параметров Command Window (Окно команд). Для
этого следует войти в меню File (Файл), выбрать команду Preferences (Пред-
Пошаговые вычисления в командном окне 27

почтения) и в раскрывшемся диалоговом окне выделить пункт Command


Window (Окно команд) — рис. 2.9.

Ujt. Preferences
SGeneral Command Window Preferences
m
IB-fonts
| г Text display

'•-Keyboard * Indenting j Numeric format: | short *" |


j Command History
:t> Editor/Debugger • Numeric display:
[—Help 1
' -Web • Display—- —
Current Directory I Г~ Wrap lines
—Workspace
-Array Editor I Limit matrix di eighty columns
•GUIDE
г-Figure Copy Template Number of lines ndow scroll buffer: 00CHJ

: Accessibility | rational
Г Arrow keys navigate instead of recalling history

; • • . ' • : • . / • - ' • • • • •••••• .•:: • • • ,

O K C a n c e l A p p l y H e l p

Рис. 2.9. Выбор формата для вывода числовых данных в командном окне

Форматы short g и long g представляют собой гибрид между соответст-


вующими форматами вывода с фиксированной и плавающей запятой. В за-
висимости от отображаемого значения они выбирают то или иное представ-
ление числа (пример 2.5).
•••• 1
Пример 2.5. Формат s h o r t

» format short g
» x=sqrt(2)
x =
1.4142
» x=sqrt(2000000)
x =
1414.2
28_ Глава 2

» x=sqrt(2e+20)
х=
1.4142е+010

Формат bank позволяет оперировать с финансами, сохраняя в дробной части


числа два знака, соответствующие мелким денежным единицам:
» format bank
» х=1000

1000.00
Формат + обеспечивает вывод только знаков чисел, сами значения при этом
не выводятся:
» format +
» х=[-1 2 - 3 4 -5] ;
» х
х=

Формат hex обеспечивает вывод числовых данных в шестнадцатеричном


формате:
» format hex
» х=1
X=
3ff0000000000000

Согласитесь, что наблюдать вещественные данные в шестнадцатеричном


формате во многих случаях смысла не имеет. Эта система счисления хороша
только для целочисленных форматов компьютерных чисел.
В языке MATLAB существуют и другие возможности по изменению форма-
та выводимых данных. Они построены на базе функции sprintf, хорошо
известной программистам по языку С. С этими возможностями мы позна-
комимся позже.
Для выделения результата вычислений или значения переменной MATLAB
вставляет пустую строку перед выводимым значением. В приводившихся
выше примерах с целью экономии места эта пустая строка удалялась вруч-
ную. Однако ее отсутствие в командном окне тоже может оказаться полез-
ным, т. к. позволит разместить на экране большее количество результатив-
ных строк. Такой режим вывода обеспечивается установкой параметра
Numeric display = compact в соответствующем раскрывающемся списке ок-
на Preferences (Предпочтения) в разделе Command Windows (Окно команд) —
см. рис. 2.9. Возврат в режим разреженного вывода происходит после уста-
новки Numeric display = loose.
Пошаговые вычисления в командном окне 29

2.5. Арифметические выражения


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

2.5.1. Некоторые свойства


вещественных данных
В отличие от большинства алгоритмических языков, MATLAB довольно
спокойно реагирует на переполнение разрядной сетки. Он выдает преду-
преждение, например, о делении на 0, но предлагает в качестве результата
внутреннее представление самого большого (inf = i.8e+308) или самого
маленького (-inf = -l.8e+308) вещественного числа, допустимого в форма-
те double!
» х=1/0
Warning: Divide by zero.
x =
Inf
» y=-l/0
Warning: Divide by zero.
У =
-Inf

Когда вычисление степенной функции, например, экспоненты, приводит к


переполнению, то в качестве результата возвращается "машинная бесконеч-
ность", но сообщение о переполнении уже не выдается:
» w=exp(710)
w =
Inf

А в тех случаях, когда математический результат не определен, например,


при делении 0 на 0, в соответствующую переменную засылается специаль-
ный признак NaN (от англ. Not a Number — "не число"):
» z=0/0
Warning: Divide by zero,
z =
NaN
3£ Глава 2

Дальнейшее использование неопределенного операнда в последующих вы-


числениях будет приводить также к неопределенному результату:
» x=z+l
X =
NaN

Среди полезных системных числовых переменных и констант отметим


(пример 2.6):
• eps — относительную погрешность при вычислениях с плавающей за-
пятой;
О reaimax — наибольшее положительное число с плавающей запятой;
• reaimin — наименьшее положительное число с плавающей запятой;
• pi — число п.
;......,.............................................,......„.........................,......... j
: Пример 2.6. Отображение значений системных переменных и констант |

» eps
ans =
2.2204 4 604 9250313e-016
» reaimin
ans =
2.225073858507201е-308
» reaimax
ans =
1.797693134862316e+308
» pi
ans =
3.14159265358979

Изменение системной переменной eps оказывает влияние на точность вы-


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

2.5.2. Специфика использования


комплексных величин
Запись комплексных величин, используемых в формулах, напоминает обще-
принятые математические стандарты.
Пошаговые вычисления в командном окне 31

Мнимые части комплексных чисел сопровождаются либо буквой i, либо


буквой j :
» x=1.5-0.5i
х =
1.5000 - 0.5000i
» y=1.5-0.5j
У=
1.5000 - 0.5000i

Если "переменным" i или j не присвоены какие-либо значения, то их мож-


но применять для формирования комплексных данных, используя знак умно-
жения и располагая такой "сомножитель" до или после мнимой части:
» а-1;
» x=i*a
х=
0 + l.OOOOi
» y=(i) *а;
» У
У=
0 + l.OOOOi
» z=a*i
z=
0 + l.OOOOi
Однако если i или j представляют настоящие переменные, которым уже
присвоены какие-либо значения, то их использование в подобных выраже-
ниях не приводит к появлению комплексных данных:

х=
1

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


деления или возведения в степень, то для устранения неоднозначности их
заключают в круглые скобки:
» z=(1.5-0.5i)42.5+0.8j)
z=
4.1500 - 0.0500i
_32 Глава 2

С помощью стандартных функций real и imag можно выделить веществен-


ную и мнимую части комплексного значения:
» real(z)
ans =
4.1500
» imag(z)
ans =
-0.0500

Функция complex позволяет сконструировать комплексное значение по паре


вещественных чисел:
» complex(1,-1)
ans =
1.0000 - l.OOOOi

Функцией conj можно воспользоваться для получения комплексного со-


пряженного числа:
» conj(z)
ans =
4.1500 + 0.0500i

Такого же результата можно добиться, располагая апостроф вслед за ком-


плексным значением:
» x=4.15+0.05i'
х =
4.1500 - 0.0500i
» у=х'
У =
4.1500 + 0.0500i

Математики довольно часто используют и другие формы представления


комплексных чисел:
1ф -
z = х + i • у = р-е = р ( c o s cp + i sincp).
2 2 2
Здесь р — модуль комплексного числа (р = х + у ), а ср — угол наклона ради-
ус-вектора, проведенного из начала координат в точку (х,у). Значения этих
параметров можно определить с помощью стандартных функций abs и
angle (величина угла выдается в радианах).
Над комплексными данными определены все арифметические операции —
сложение, вычитание, умножение, деление, возведение в степень. Ком-
плексные операнды и выражения могут выступать в качестве аргументов
стандартных функций. Одним словом, в пакете MATLAB реализовано все, с
чем нас знакомили в курсе "Теория функций комплексных переменных".
Пошаговые вычисления в командном окне 33

2.5.3. Числовые матрицы и векторы,


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

a 2 2 x 2 + a 2 3 x 3 = b2; (2.1)
= Ьз.

Если обозначить матрицу коэффициентов через А, вектор-столбец неизвест-


ных — через х, а вектор-столбец правых частей — через в, то система (2.1) в
векторной форме имеет вид:
А*Х = в. (2.2)
В матричной же форме решение системы (2.2) получается умножением обе-
их частей равенства на обратную матрицу А" 1 :
х = А-^В. (2.3)
Для задания значений компонентов вектора-строки (т. е. элементов матри-
цы размерности 1хл) используются квадратные скобки, в которых числовые
данные отделяются друг от друга пробелами или запятыми:
» у=[1 2 3]
У=
1 2 3
» у=[4,5,6]
У=
4 5 6

Количество пробелов, которое MATLAB вставляет при выводе компонент


вектора-строки, регулируется параметром Tab size (Табуляция) (см. окно
Preferences | Command Window | Keyboard & Indenting (Предпочтения | Окно
команд | Клавиатура и Отступы)). По умолчанию оно равно 4.
Для задания значений компонентов вектора-столбца (т. е. элементов матри-
цы размерности лх1) используется тот же прием, но в качестве разделителей
данных выступают точки с запятыми:
» Ь=[1; 4; 2]
b =
1
4
2
34 Глава 2

Комбинируя оба варианта разделителей, можно сформировать двумерный


массив коэффициентов:
» а=[1 -1 1; 2 0 2; 0 1 1]
а =
1 - 1 1
2 0 2
0 1 1
Формула (2.3) позволяет найти решение системы, написав всего одну стро-
ку, воспользовавшись стандартной функцией обращения квадратной матри-
цы (пример 2.7).

\ Пример 2.7. Решение системы линейных уравнений I


• ;
» x=inv(a)*b
х =
1
1
1
» whos
Name Size Bytes Class
a 3x3 72 double array
b 3x1 24 double array
x 3x1 24 double array
Grand total is 15 elements using 120 bytes

Как и в других алгоритмических языках, к элементам матриц и векторов


обращаются, используя индексы. В отличие от языка С, в системе MATLAB
индексы отсчитываются от 1 и заключаются в круглые скобки — х (1),
а (2,3). Довольно интересной особенностью языка MATLAB является воз-
можность выполнения однотипных операций над подмножеством компо-
нентов векторов или матриц. Для этого вместо индекса указывается диапа-
зон индексов, разделяемых двоеточием:
» z(2:5)=3

MATLAB предлагает разнообразные средства для создания типовых матриц.


Функции zeros и ones используются для заполнения квадратных или пря-
моугольных матриц нулями или единицами соответственно. С помощью
Пошаговые вычисления в командном окне 35

функции eye формируется единичная квадратная или прямоугольная матри-


ца. Заполнение элементов матриц случайными числами с равномерным или
нормальным распределением обеспечивают функции rand и randn. В состав
пакета входят и специализированные функции, позволяющие создавать маги-
ческие квадраты и матрицы, названные именами известных математиков —
Адамара, Гильберта, Паскаля, Уилкинсона, Ханкеля. Пример 2.8 демонстри-
рует несколько простейших вариантов заполнения матриц.

Пример 2.8. Формирование типовых матриц

a=zeros(5)

0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
с .0 0 0 .0
b=zeros(3, 4)
b =
0 0 0 0
0 0 0 с
0 0 0 0
c=ones([2 3])

1 1 1
1 1 1
d=eye(4)
d =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
e=rand(4)

0. 9501 0.8913 0 .8214 0 .9218


0.2311 0.7621 0 .4447 0 .7382
0.6068 0.4565 0 .6154 0 .1763
0.4860 0.0185 0 .7919 0 .4057
f=randn(4)
36 Глава 2

f =
-0.4326 -1.1465 0.3273 -0.5883
-1.6656 1.1909 0.1746 2.1832
0.1253 1.1892 -0.1867 -0.1364
0.2877 -0.0376 0.7258 0.1139

Ранее сформированные массивы могут участвовать в конструировании но-


вых массивов в качестве их клеток (пример 2.9).

: Пример 2.9. Объединение матриц по вертикали

g=[e;f]
g=
0.9501 0.8913 0.8214 0.9218
0.2311 0.7621 0.4447 0.7382
0.6068 0.4565 0.6154 0.1763
0.4860 0.0185 0.7919 0.4057
-0.4326 -1.1465 0.3273 -0.5883
-1.6656 1.1909 0.1746 2.1832
0.1253 1.1892 -0.1867 -0.1364
0.2877 -0.0376 0.7258 0.1139

Еще больше возможностей по формированию блочно-диагональных матриц


предоставляет функция bikdiag.
В отличие от большинства систем программирования на базе других алго-
ритмических языков, MATLAB хранит матрицы в оперативной памяти по
столбцам. Такой способ в свое время использовали все трансляторы с языка
Fortran.
Очень важной особенностью практически всех функций MATLAB является
возможность обработки аргументов, заданных векторами (пример 2.10).
А значения компонентов вектора, образованные по закону арифметической
прогрессии, формируются примерно так же, как и параметры цикла типа
for (начальное значение: шаг: конечное значение).

Пример 2.10. Использование векторных аргументов

» х=[0:0.2:1]
х=
0 0.2000 0.4000 0.6000 0.8000 1.0000
» y=sin(x)
Пошаговые вычисления в командном окне 37

У =
О 0.1987 0.3894 0.5646 0.7174 0.8415

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


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

2.5.4. Специфика выполнения арифметических


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

Таблица 2.3

Символы Выполняемое действие

Операции над числовыми величинами


+ Покомпонентное сложение числовых массивов
одинаковой размерности;
добавление скалярной величины к каждому элементу массива

Операции над числовыми величинами


Покомпонентное вычитание числовых массивов одинаковой размерности;
вычитание скалярной величины из каждого элемента массива
* Умножение матриц в соответствии с правилами линейной алгебры (чис-
ло столбцов первого сомножителя должно быть равно числу строк вто-
рого сомножителя);
умножение всех компонентов массива на скаляр
•* Покомпонентное умножение элементов массивов одинаковой размерности
/ Деление скаляра на скаляр;
покомпонентное деление всех элементов массива на скаляр:
А/В = А*В~1 = А * i n v ( B )
(А, В — квадратные матрицы одного порядка)
•/ Покомпонентное деление элементов массивов одинаковой размерности
\ А\в = А"'*в — левое матричное деление (А — квадратная матрица)
•\ А. \в — покомпонентное деление элементов в на А (левое поэлементное
деление)
Возведение скаляра в любую степень;
вычисление целой степени квадратной матрицы
' Вычисление сопряженной матрицы
•' Транспонирование матрицы
38 Глава 2

Таблица 2.3 (окончание)

Символы Выполняемое действие

Логические операции
& Логическое умножение скаляров;
логическое покомпонентное умножение массивов
одинаковой размерности;
логическое умножение массива на скаляр
I Логическое сложение скаляров;
логическое покомпонентное сложение массивов одинаковой размерности;
логическое сложение массива со скаляром
Логическое отрицание скаляра или всех элементов массива

Операции отношения
Проверка на равенство
Проверка на неравенство
> Проверка на "больше"
>= Проверка на "больше или равно"
< Проверка на "меньше"
<= Проверка на "меньше или равно"

Но даже такие традиционные операции, как сложение, в выражениях MATLAB


выполняются особым способом. Самым привычным является сложение ска-
лярных величин (т. е. массивов размерности 1x1), соответствующее анало-
гичному действию в большинстве алгоритмических языков. Если обоими
операндами являются массивы одинаковой размерности, то осуществляется
покомпонентное сложение элементов с одинаковыми индексами. Такой
подход в свое время применялся в ранних версиях Basic, включавшего опе-
раторы типа МАТ А=В+С. Однако если в MATLAB к массиву любой размерно-
сти добавляется скалярная величина, то она добавляется к каждому элемен-
ту массива. По сути дела, добавляемое скалярное значение преобразуется в
массив такой же размерности, что и первое слагаемое (аналог приведения
типов в выражениях с разнокалиберными операндами), и каждый элемент
расширенного массива равен этому значению. Попытку сложить массивы
разной размерности (за исключением случая, когда один из операндов —
массив 1x1) система пресекает с выдачей соответствующего сообщения об
ошибке.
Аналогичное приведение типов выполняется для большинства операций,
когда одним из операндов является массив, а вторым — скаляр.
Пошаговые вычисления в командном окне 39

Впервые знак операции возведения в степень в виде х**у появился в Fortran


(1954 г.). Вертикальная стрелка Т как знак возведения в степень был пред-
ложен спустя несколько лет в проекте языка Algol 58. Символ Л для этой же
цели взял на вооружение Basic, откуда он и перекочевал в MATLAB. К со-
жалению, ни С, ни Pascal не включили аналогичную операцию в набор эле-
ментарных действий (здесь приходится прибегать к услугам библиотечной
функции pow).
Кроме знаков логических операций, приведенных в табл. 2.3, можно ис-
пользовать системные функции and(x,y), or(x,y), хог(х,у) И not(x). При
выполнении логических операций над числами действует соглашение, при-
нятое в С, — ненулевые значения рассматриваются как истина, а нулевые
как ложь. Если операндами логической формулы являются массивы, то опе-
рация производится над элементами с одинаковыми индексами. Результатом
такой операции является массив такой же размерности, что и операнды, за-
полненный нулями и единицами в зависимости от исхода поэлементного
действия.
Аналогичный результат формируется при сравнении матричных операндов
(пример 2.11).

Пример 2.11. Сравнение матричных операндов -'.-ШШ=.? л£ьч£ЯВ8 ?Г. <-££&••-г-л;


....Г...,.,....Г;....:...; " Г. " " ;
» а=[1 2 3; 4 5 6]
а =
1 2 3
4 5 6
» Ь=[2 2 2; 5 5 5]
b =
2 2 2
5 5 5
» с=а >=Ь
с =
0 1 1
0 1 1

2.5.5. Использование элементарных


математических функций
В ряде приводившихся выше примеров мы использовали элементарные ма-
тематические функции типа sin(x), cos(x), sqrt(x) и др. В этом разделе
систематизированы библиотечные функции (табл. 2.4), которые доступны
пользователю MATLAB. Обозначения многих функций MATLAB совпадают
40 Глава 2

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


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

Таблица 2.4

Категория функций Наименования функций


Тригонометрические, аргумент cos, cot, csc, sec, sin, tan
в радианах
Тригонометрические, аргумент cosd, cotd, cscd, seed, sind, tand
в градусах
Обратные тригонометрические, acos, acot, acsc, asec, asin, atan, atan2
результат в радианах
Обратные тригонометрические, acosd, acotd, acscd, asecd, asind, atand
результат в градусах
Гиперболические cosh, coth, csch, sech, sinh, tanh
Обратные гиперболические acosh, acoth, acsch, asech, asinh, atanh
Степени, логарифмы, корни exp, expml, log, loglp, Iog2, loglO,
nextpow2, pow2, reallog, realsqrt, sqrt
Округления ceil, fix, floor, round
Наибольший общий делитель gcd
Наименьшее общее кратное lem
Модуль числа abs
Знак числа sign
Остаток от деления с учетом знака mod
делимого
Остаток от деления rem
Разложение числа на простые factor
множители
Вычисление факториала factorial
Дробно-рациональная аппроксима- rats
ция вещественного числа
Генерация простых чисел, primes
не превосходящих аргумента

В некотором уточнении нуждаются функции округления, их немного


больше, чем в С. Функция round, отсутствующая в С (но существующая в
Пошаговые вычисления в командном окне 41

Pascal), производит округление по математическим правилам. О функции


c e i l говорят, что она округляет в сторону +°° (точнее, до ближайшего
большего числа). В отличие от нее, функция floor округляет в сторону -°°
(точнее, до ближайшего меньшего числа). Функция fix просто отбрасыва-
ет дробную часть. Результаты работы функций округления приведены в
табл. 2.5.

Таблица 2.5

Результат работы Результат работы Результат работы


функции функции функции
ceil(l.l) = 2 ceil (1.5) = 2 ceil(1.8) = 2
ceil(-1.1) = -1 ceil (-1.5) = -1 ceil(-1.8) - -1

fix(l.l) = 1 fix(1.5) = 1 fix(1.8) = 1


fix(-l.l) = -1 -1 fix(-1.8) = -1

floor(l.l) = 1 floor(1.5) = 1 floor(1.8) = 1


Q
floor(-1.1) = -2 floor (-1.5) = -2 floor (-1.8)

round(1.1) = 1 round(1.5) = 2 round(1.8) = 2


round(-1.1) = -1 round(-1.5) = -2 round(-1.8) = -2

Для функций gcd (от англ. greatest common divisor — наибольший общий де-
литель) и km (от англ. least common multiple — наименьшее общее кратное)
приведем очевидные результаты их работы:
gcd(100,25) = 25
lcm(100,25) = 100

Функции, вычисляющие остаток от деления, обычно применяются к целым


числам (хотя и представленным в формате double). Результаты их работы
проще понять на примерах, приведенных в табл. 2.6.

Таблица 2.6
Результат ра- Результат работы Результат работы Результат работы
боты функции функции функции функции
mod(7,5)= 2 mod(-7,5) = 3 mod(7,-5) = -3 mod(-7,-5) = -2
rem(7, 5)= 2 rem(-7,5) = -2 rem(7,-5) = 2 rem(-7,-5) = -2
42 Глава 2

Функция sign (знак) принимает одно из трех значений: -1 (если аргумент


отрицателен), о (если аргумент равен 0) и +1 (если аргумент положителен).
В MATLAB 7 появилась группа прямых и обратных тригонометрических
функций, работающих с углами в градусах.
Наряду с хорошо знакомыми программистам функциями ехр(х), log(x) и
sqrt (x) в системе MATLAB представлены некоторые их разновидности:
П функция expmi (x) вычисляет значение ехр (х-и ;
П функция logip(x) вычисляет значение iog(x+u;
• функция pow2 (x) возводит 2 в степень х;
• функция nextpow2(x) определяет наименьшую степень двух, ограничи-
вающую х сверху (nextpow2 (looo) =10). Такая функция полезна при рабо-
те с быстрыми преобразованиями Фурье.
Функции reailog и reaisqrt вычисляют, соответственно, натуральный ло-
гарифм и корень квадратный для каждого элемента матрицы:
» х=[1 2 4 8 ] ;
» reailog(х)
ans =
0 0.6931 1.3863 2.0794
» reaisqrt(x)
ans =
1.0000 1.4142 2.0000 2.8284

С помощью функции primes можно сгенерировать последовательность про-


стых чисел:
» primes(25)
ans =
2 3 5 7 11 13 17 19 23
Функции perms и nchoosek позволяют генерировать перестановки и сочета-
ния из заданных элементов:
» perms([1 2 4])
ans =
4 2 1
4 1 2
2 4 1
2 1 4
1 2 4
1 4 2
» nchoosekf['А' 'В' 'С'],2)
Пошаговые вычисления в командном окне 43_

ans =
АВ

АС

ВС

Следует заметить, что список функций, приведенных в этом разделе, со-


ставляет крохотную часть от набора библиотечных функций, встроенных в
ядро MATLAB. Об этом можно судить по объему документации, посвящен-
ной описанию функций. Она представлена в виде трех файлов — refbook.pdf,
refbook2.pdf и refbook3.pdf. Их общий объем превышает 15 Мбайт, а в печат-
ном виде документ занимает порядка 2000 страниц, на которых приведены
достаточно подробные сведения примерно о 850 функциях и командах с
примерами их использования, графиками и таблицами.

2.6. Построение графиков функций


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

2.6.1. Простые графики


в декартовых координатах
Для того чтобы построить график функции y=f(x), достаточно тем или
иным способом сформировать два вектора одинаковой размерности — век-
тор значений аргументов (х) и вектор соответствующих значений функции
(у), и обратиться к функции plot (пример 2.12).
: ._
Пример 2.12. Построение графика функции y^ein(x)>,f**? - - .. :
; ....:.. ....,...;.;
» х=0:0.1:6.28;
» y=sin{x).*ехр(-х);
» p l o t (х, у)
44 Глава 2

В простейшем случае, которым мы воспользовались при вызове функции


plot, MATLAB автоматически создает окно с заголовком Figure 1, размеща-
ет в нем стандартное меню и панель инструментов, выделяет в области кли-
ента прямоугольное поле с графиком функции, производит соответствующее
масштабирование и разметку по обеим координатам (рис. 2.10). Собственно
график функции получен путем соединения смежных точек таблицы отрез-
ками прямых. Чем меньше точек было бы в таблице отображаемой функ-
ции, тем заметнее была бы кусочно-линейная структура графика.

•^ Figure 1
File Edit View Insert Tools Desktop Window Help
:
D'.'B? a "a \\ | Д <M"> © i se'T'D Ш'Г'в'й
35
..•: °-
I
\

03 I

0.25 1

U-Jt
:•• • : • .

0 . 1 5 \

i \

0 . 1
j

0 . 0 5

\ ^

. . . 0

1 f i l l

- 0 . 0 5

Рис. 2 . 1 0 . График затухающей синусоиды на интервале [0, 2л]

Если мы обратимся к функции p l o t повторно, то она создаст новое окно с


заголовком Figure 2 и разместит в нем следующий график. Мы могли бы
совместить оба ф а ф и к а в одном окне двумя разными способами. В первом
случае перед вызовом функции p l o t мы должны построить таблицы обеих
функций, например, ( x i , y i ) и (х2,у2). А при вызове функции p l o t указать
их в списке аргументов (пример 2.13).
|............... ........................V....V.V.»......V........ ;
; Пример 2.13. Построение двух графиков в одном окне i

» xl=0:0.2:6.28;
>> y l = s i n ( x l ) ;
Пошаговые вычисления в командном окне 45

» y2=cos(xl);
» plot(xl,yl,xl,y2)

Результат работы этого фрагмента приведен на рис. 2.11.

• •'•>

у
' •';""•• 4'
I

-1 \\\ 1
/\\\ /
/
0.5
/
I \ \\ /1 i1 i
\\ \ / j
g

-0.5

\ v/4\. /
"1
-1 J 1 23 56 7
Рис. 2.11. Совместное отображение графиков
двух функций в одном окне

Второй способ заключается в блокировании режима создания нового графи-


ческого окна с помощью функции hold on (дословно — заморозить преды-
дущее окно) — пример 2.14.

Пример 2.14. Использование функции h o l d on


.....,..: i
» plot(xl,yl)
» hold on
» plot(xl,y2)

При выполнении примера 2.14 в командном окне обратите внимание на то,


что график второй функции отображен зеленым цветом, тогда как первая
кривая имела синий цвет. MATLAB автоматически сменил цвет отображе-
ния следующего графика. Однако на выбор цвета того или иного графика
может повлиять и пользователь, указав в функции plot дополнительный
параметр — символ, ассоциированный с одним из 8 предусмотренных цве-
тов (табл. 2.7):
» plot(х,у,'д')
46 Глава 2

Таблица 2.7

Символ Цвет графика Символ Цвет графика


цвета цвета
У Желтый (от англ. yellow) g Зеленый (от англ. green)
га Малиновый (от англ. magenta) ь Синий (от англ. blue)
с Циановый (от англ. cyan) w Белый (от англ. white)
г Красный (от англ. red) к Черный (от англ. black)

На вид графика пользователь может дополнительно повлиять, задав стиль


линии и форму маркера, которым метятся табличные точки. Стиль линии
предусматривает выбор одной из четырех возможностей — сплошная линия
(по умолчанию управляющий символ — тире), пунктирная линия (управ-
ляющий символ — двоеточие), штрих-пунктирная линия (управляющие
символы — тире и точка), штриховая линия (управляющие символы — два
тире). Управляющие символы, определяющие стиль линии, задаются в стро-
ке третьего параметра вместе с цветом. Порядок следования символов —
любой:
» plot(х,у.'д:')

ИЛИ
» p l o t (х, у, ' : д ' )
Тип маркера задается еще одним символом в этой же управляющей строке.
Всего таких символов — 13, и соответствующие им маркеры приведены в
табл. 2.8.
Таблица 2.8

Символ Маркер Символ Маркер


Жирная точка d Ромбик
о Кружок V Треугольник вершиной вниз
л
х Косоугольный крестик Треугольник вершиной вверх
+ Прямоугольный крестик < Треугольник вершиной влево
* Восьмиконечная снежинка > Треугольник вершиной вправо
s Квадратик Р Пятиконечная звезда
попе Отсутствие маркера h Шестиконечная звезда

Если в стилевой строке указан тип маркера, но не задан стиль линии, то


табличные точки маркером метятся, но друг с другом отрезками прямых не
соединяются (пример 2.15).
Пошаговые вычисления в командном окне 47

Пример 2.15. Использование маркеров

» х=[1 2 3 4 ] ;
» у=[1 2 2 4] ;
» p l o t (х, у, ' s — ' )

Соответствующий график с маркерами на штриховой линии приведен на


рис. 2.12.

Рис. 2.12. График с маркерами, стиль линии — штриховой

Дополнительные украшения графика заключаются в возможности снабдить


его заголовком (ФУНКЦИЯ t i t l e ) , Подписать ОСИ (фуНКЦИИ x l a b e l , y l a b e l ) ,
нанести координатную сетку (функция grid on) и разместить легенду
(функция legend). Используем все эти возможности на графике синуса и
косинуса (пример 2.16, рис. 2.13).

I Пример 2.16. Оформление графиков :

» х=0:0.2:6.28;
» yl=sin(x);
» y2=cos(x);
» plot(x,yl,'-\х,у2, ' .')
» legend('sin', 'cos', 4)
» ylabel('y-axis')
48 Глава 2

» xlabel('x-axis')
» grid on
» title('Function sin & cos''

:;: -;.;• • J:' *

7^ ч, 4
/ \ т

0.5 /

. *

(Л \
'Я : П
га и
•••. > • > . • ...

\ 1
1

- 0 . 5
\
in \
OS * J

.:•:,:.": • ч : Р ч • 1 , . 2
3 4 5 6 7
• • • • • , • . :

x-axs
i
Рис. 2.13. График функций с подписями, легендой и сеткой

Легенда позволяет внести ясность в анализ изображения с несколькими


графикам. Третий параметр в функции legend (на самом деле этот числовой
параметр можно написать в любом месте списка) управляет размещением
легенды в графическом окне:
• -1 — легенда размещается вне поля графика, вверху справа;
• о — система выбирает лучшее место в поле графика, не перекрываемое
данными;
• 1 — легенда размещается в правом верхнем углу (по умолчанию — там же);
• 2 — легенда размещается в левом верхнем углу поля графика;
• з - легенда размещается в правом нижнем углу поля графика;
• 4 — легенда размещается в левом нижнем углу поля графика.
В некоторых случаях совмещение двух графиков в общем окне может вы-
звать проблемы, связанные с тем, что диапазоны изменения аргументов или
значений функций не совпадают. Для разрешения этих проблем MATLAB
предлагает функцию piotyy, которая производит двойную оцифровку осей
(пример 2.17). Для первой функции цифруются ось х внизу, ось у слева, а
для второй функции ось х размечается вверху, ось у — справа (рис. 2.14).
Цвет оцифровки при этом совпадает с цветом кривых.
Пошаговые вычисления в командном окне 49
• :

Пример 2.17. Двойная оцифровка осей

» х=0:0.1:6.28;
» yl=sin(x);
» y2=sin(x)+cos (x);
» plotyy(x,yl,x,y2)

Рис. 2 . 1 4 . Графики с двойной оцифровкой осей

Может оказаться, что в одном графическом окне необходимо отобразить


большее число графиков. Тогда следует прибегнуть к функции subplot, ко-
торая позволяет разделить область рисования на несколько прямоугольных
областей равного размера, расположенных подобно элементам матрицы
(пример 2.18):
subplot(fow,col,cur);

Первые два аргумента задают количество рядов (row) и колонок (col). Тре-
тий параметр (cur) объявляет порядковый номер подобласти, в котором
очередная функция plot будет строить свой график (рис. 2.15).

; Пример 2.18. Деление области рисования ;

x=0:0.2:2*pi;
yl=sin(x);
y2=cos(x);
y3=yl.*exp(-x);
y4=yl.*у2;
50 Глава 2

» subplot(2,2,1);plot(x,yl);
» subplot(2,2,2);plot(x,y2);
» subplot(2,2,3) ,-plot(x,y3);
» subplot(2,2,4);plot(x,y4);

Рис. 2.15. Четыре подобласти в одном графическом окне

2.6.2. График функции


в полярных координатах
Полярными координатами (р,9) точки Р (рис. 2.16) называются длина р ра-
диус-вектора, проведенного из начала координат в точку Р, И угол 9, образо-
ванный между осью х и этим вектором. Угол отсчитывается от положитель-
ного направления оси х к радиус-вектору против часовой стрелки.
Довольно многие математические кривые с целью устранения неоднознач-
ности принято задавать в полярной системе координат. Например, уравне-
ние кардиоиды имеет вид:
р = а- (1 + coscp).

Для построения графиков функций, заданных в полярной системе коорди-


нат, вместо функции plot используется функция polar (пример 2.19).
Пошаговые вычисления в командном окне 51

Рис. 2.16. Полярные координаты

Пример 2.19. Г- графика в полярных координатах

» phi=0:0.1:2*pi;
» ro=5*(1+cos(phi));
» polar(phi,ro)
» title('Кардиоида')

Результат построения кардиоиды для а=5 приведен на рис. 2.17.

: Кардиоида
90 1 0
120

30

- - ) — , — j- — -t —I О

240
270

Рис. 2.17. График кардиоиды


в полярной системе координат
52 Глава 2

2.6.3. Использование
логарифмического масштаба
Единицы измерения значений ординат и абсцисс далеко не всегда соответ-
ствуют друг другу, и для создания более обозримого графика вдоль одной
или обеих координатных осей приходится выбирать логарифмический мас-
штаб. Для построения таких графиков используются функции loglog
(логарифмический масштаб по обеим осям), semilogx (логарифмический
масштаб по оси х), semiiogy (логарифмический масштаб по оси у) — при-
мер 2.20, рис. 2.17.

! Пример 2.20. Использование логарифмического масштаба ;


;....." ....Г. .....~...~ ;
» х=0:10:100;
» у=ехр(х);
» semiiogy(х,у)

Рис. 2.18. График с логарифмическим масштабом по оси у

2.6.4. Построение графика функции


на заданном интервале
Довольно интересной модификацией функции p l o t является функция
f p i o t , которая строит график функции y=f (х) без предварительного вычис-
ления векторов ( x i , x 2 , . . . ) и ( y i , y 2 , . . . ) . Базовый формат вызова этой
функции включает два аргумента:
fplot(@name_fun, [limits])
fplotCname fun', [limits])
Пошаговые вычисления в командном окне 53

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


нем name_fun, во втором случае — строка с именем обрабатываемой функ-
ции. Аргумент limits может быть представлен либо двухкомпонентным век-
тором [xmin xmax] , Либо четырехкомпонентным вектором [xmin xmax ymin
ymax]. Укороченный вариант задает пределы изменения аргумента х, рас-
ширенный — дополнительно представляет пределы изменения функции.
Например:
fplot(@sin, [0 2*pi])
fplot('sin', [0 2*pi])

По сравнению с plot функция fpiot берет на себя вычисление таблицы


значения функции, проявляя при этом некоторый интеллект — в местах
резкого изменения функции значения аргумента х выбираются с более мел-
ким шагом. Функция fpiot гарантирует, что относительное уклонение вос-
производимой функции отличается от ее идеального графика не более чем
на 0,2%. Если вам нужен более точный или более грубый график, то после
двух обязательных аргументов в функции fpiot можно задать желаемую от-
носительную погрешность — число, меньшее 1:
fpiot(@sin, [0 2 * p i ] , 0.05)

В этом случае гарантировано построение графика, отличающегося от иде-


альной кривой не более чем на 5%. Еще один дополнительный параметр —
целое натуральное число N требует, чтобы функция fpiot использовала при
построении не менее чем N+I точку. Относительная погрешность и количе-
ство точек могут задаваться в любом порядке:
fpiot(@sin, [0 2 * p i ] , 0 . 0 5 , 20)
fpiot(@sin, [0 2 * p i ] , 20, 0.05)

Наконец, как и в функции plot, среди дополнительных параметров могут


находиться строки, управляющие цветом и маркировкой графика. Последо-
вательность задания всех дополнительных параметров — произвольная. Ре-
зультат выполнения следующего оператора приведен на рис. 2.19:
f p i o t (@sin, [0 2 * p i ] , 0.05, 's—')

Функция fpiot умеет возвращать значения компонентов векторов х и у, ес-


ли к ней обратиться следующим образом:
[х у ] = f p i o t ( @ s i n , [0 2*pi]);

Функция f, указываемая в качестве первого аргумента fpiot, кроме незави-


симой переменной х может содержать дополнительные параметры, напри-
мер, y=f (x,ai,a2). Тогда эти параметры указываются среди дополнитель-
ных аргументов после задания относительной погрешности и минимального
числа точек:
fpiot('name_fun', [xl x 2 ] , 0 . 0 5 , 20, a l , a2)
54 Глава 2

Рис. 2.19. Синусоида, построенная по f p l o t

Довольно интересный пример, демонстрирующий ряд возможностей функ-


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

100
Л 10
50

0.5
5 1
1
0 А" >/
1 Г"
i 1 i
-5 •

0.02 0.04 0.06 0.08 0.1


Рис. 2 . 2 0 . Примеры работы функции f p l o t
Пошаговые вычисления в командном окне 55_

: Пример 2.21. Использование функции f p l o t i

» subplot(2, 2,1) , fplot(@humps, [0 1])


» f = inline Cabs(exp(-j*x*(0:9))*ones(10,1)) ') ;
» subplot(2,2,2), fplot(f,[0 2*pi])
» subplot(2,2,3), fplotC[tan(x),sin(x),cos(x)]',2*pi*[-l 1 - 1 1 ] )
» subplot(2,2,4), fplot('sin(l ./ x) \ [0.01 0.1],le-3)

2.6.5. Средства управления


в графическом окне
Из приводившихся выше примеров видно, что графики функций выдаются
в специальном окне, снабженном меню и панелью инструментов. Это окно
соответствует всем стандартам Windows — его можно перемещать по экрану,
изменять размеры, сворачивать и разворачивать, удалять. По терминологии
MATLAB оно представляет объект типа Figure и как пуповиной связано с
пакетом MATLAB через встроенное меню. Так как термин фигура не очень
удачно передает смысл и свойства этого объекта, мы будем пользоваться
термином графическое окно. В принципе, каждое графическое окно в момент
своего создания кроме автоматически формируемого заголовка (Figure 1,
Figure 2 и т. д.) может быть идентифицировано с помощью специального
указателя (в английской терминологии — handle):
hGWl = p l o t ( х , у , . . . )

Имя указателя выбирает пользователь. В дальнейшем, при работе с несколь-


кими одновременно существующими графическими окнами указатель ис-
пользуется для выделения и редактирования компонентов соответствующего
окна.
Если нам нужно поработать с текущим графическим окном, то вместо сво-
его указателя можно пользоваться соответствующим системным указателем.
Его выдает функция gcf (от англ. get handle to current figure — получить ука-
затель текущего графического окна). Существуют и другие системные функ-
ции, возвращающие указатели, например, на оси графика дса (от англ. get
handle to current axis — получить указатель текущего объекта типа axis (ось)),
на текущий графический объект дсо (от англ. get handle to current object —
получить указатель текущего объект) и др. Использование указателей по-
добного рода более подробно рассматривается в гл. 7.
Меню, встроенное в графическое окно, позволяет:
• обратиться к довольно мощному редактору свойств графических объектов;
П сохранить графическое окно в файле с расширением fig;
• перейти в среду MATLAB и выполнить любые действия в командном окне.
3 Зак 899
56 Глава 2

На рис. 2.21 приведены развернутые меню наиболее важных пунктов глав-


ного меню графического окна.

Ste] Щ Vlew| Insert | Tools |


New • «•Fg i ure Toolbar/;: X Label -- Edit Plot
Open.,, : Camera Toolbar : Y Label Zoom In . :
Close ..gut;. ••• Plot Edit Toolbar'• Zo om Out
Save ...'.:' Figure Palette Title •Pa „'•
n:
Save As... ••.' C o py Plot Browser Legend Rotate 3D
Generate M-Flle... Property Editor Colorbar Data Cursor :
: '
Import Data... C l
e ar
SelectAII Ctrl+A Line : . . ResetVlew .
Save Workspace As... Copy Figure Arrow ; Options >
Preferences... Copy Options... Text Arrow Pin to Axes
Export Setup... Figure Properties... Double Arrow Snap To Layout Grid
Page Setup... . - • :•Axes Properties...: TextBox View Layout Grid
Print Setup...' ••>• Current Object Properties... Rectangle Smart Align and Distribute
Print Preview,.. Colormap... Elipse Align Distribute Tool ...
Print.. Find Files... Axes Align . .•
Clear Figure • ' Light Distribute •
: B
Clear Command Wn i dow asci Fitting ..... :
Clear Command History : Data Statistics
Clear Workspace .'••:'
Рис. 2.21. Основные команды меню графического окна

Первая группа команд в меню File (Файл) позволяет закрыть графическое


окно (Close (Закрыть)), вызвать в него ранее сохраненный графический
файл (Open (Открыть)) или начать вручную создавать новый график, ис-
пользуя при этом возможности Property Editor (Редактор свойств) графиче-
ского объекта (New Figure (Новый графический объект)).
Команды второй группы позволяют сохранить графическое окно под преж-
ним (Save (Сохранить)) или новым (Save As (Сохранить как)) именем, а
также экспортировать его в нужном вам фафическом формате (Export Setup
(Параметры экспорта)). Список фафических форматов, который доступен
пользователю MATLAB, приведен в табл. 2.9.
Таблица 2.9

№ Наименование графического формата Расширение файла


1 Enhanced metafiles emf
2 Bitmap files bmp
3 EPS (Enhanced PostScript) files eps
Пошаговые вычисления в командном окне 57

Таблица 2.9 (окончание)

№ Наименование графического формата Расширение файла

4 EPS Color files eps


5 EPS Level 2 eps
6 EPS Level 2 Color eps
7 Adobe Illustrator files ai
8 JPEG images jpg
9 TIFF images tif
10 TIFF no compression images tif
11 Portable Network Graphics files png
;
12 Paintbrush 24-bit files pcx
13 Portable Bitmap files pbm
14 Portable Graymap files pgm
15 Portable Pixmap files ppm

Очень интересен результат выполнения команды Generate M-File (Гене-


рировать М-файл) — в предыдущих версиях такой команды не было. Она
позволяет автоматически создать функцию построения графиков, располо-
женных в графическом окне. Например, для графика двух кривых, пред-
ставленного на рис. 2.10, MATLAB автоматически генерирует следующий
файл:
function createfigure(xl, yl, y2)
%CREATEFIGURE(XI,Yl,Y2)
% XI: vector of x data
% Yl: vector of у data
% Y2: vector of у data

% Auto-generated by MATLAB on 03-Sep-2004 22:35:57

%% Create figure
figurel = figure('PaperPosition1, [0.6345 6.345 20.3 15.23], ...
'PaperSize', [20.98 29.68]);

%% Create axes
axesl = axes(...
'YColor1, [0 0 1], . . .
58 Глава 2

•YTick',[-1 -0.5 0 0.5 1 ] , . . .


' Parent' , figure!.) ;
axis(axes1,[0 7 -1 1] ) ;
hold(axes1,'all');

%% Create plot
plotl = plot(xl,yl,'Parent',axesl);

%% Create axes
axes2 = axes (. . .
'YColor',[0 0.5 0], . . .
'YAxisLocation','right',...
'YTick', [-2 -1 0 1 2]., . . .
'Parent',figurel);
axis(axes2,[0 7 -2 2 ] ) ;
hold(axes2,'all');

%% Create plot
plot2 = plot(xl,y2,'Parent',axes2);

Если этой функции передать в качестве параметров векторы xl, yi и у2, то


она воспроизведет указанный график. Заметим, что наше построение потре-
бовало всего 3—4 команды. Изобилие строк в автоматически созданной
программе объясняется тем, что в ней предусмотрено создание всех элемен-
тов фигуры — собственно графического окна, осей и их разметки, графика
кривых. Может быть, к такого рода процедуре следует прибегать только в
том случае, когда пользователь провел вручную достаточно большую редак-
торскую правку.
Команды Import Data (Импортировать данные) и Save Workspace As
(Сохранить рабочее пространство как) уже упоминались при описании
главного меню.
Команда Preferences (Предпочтения) выводит нас в окно установок пара-
метров системы MATLAB, но целесообразность ее включения в меню гра-
фического окна вызывает сомнение. Аналогичная возможность входит в со-
став меню File (Файл) командного окна.
Команда Export Setup (Параметры экспорта) вызывает диалоговое окно, в ко-
тором можно просмотреть и изменить значения текущих параметров графиче-
ского окна и графика — размеры (Size), способ визуализации (Rendering),
характеристики шрифта (Font) и свойства линий (Lines). После этого откор-
ректированный фафик можно сохранить в файле с расширением fig.
Пошаговые вычисления в командном окне 59

Оставшиеся команды последней группы меню File (Файл) связаны с подго-


товительными работами по настройке параметров графика, листа бумаги и
принтера перед выдачей окончательной команды вывода (Print (Печать)).
Команда Page Setup (Параметры страницы) вызывает диалоговое окно,
снабженное четырьмя вкладками. Первая вкладка (рис. 2.22) позволяет
вручную (Use manual size and position (Ручная установка размеров и полей
страницы)) установить размеры полей (Тор (Сверху), Left (Слева), Width
(Ширина) и Height (Высота)) поля графика в удобных для пользователя
единицах измерения (Units (Единицы измерения)). В противовес ручной
установке размеров и позиций имеется возможность разместить экранный
образ в центре страницы (Use screen size, centered on page (Использовать
размер экрана, разместить по центру)).

IPage Setup - Figure 1


Size and Position | paper j Lines and Text j Axes and Figure
pMode - ;
j С use screen size, centered on page
I • <* Use manual size and position

^Manual sizeand position


Top: |8HO jjj
Use defaults
Left:. 0.63
Fill page
Width: 20.30 Fix aspect ratio
Height: 15.23 i Center
Units :|centimeters

Help.. OK Cancel

Рис. 2 . 2 2 . Установка размеров и позиций графика на странице

Вкладка Paper (Бумага) позволяет выбрать формат листа бумаги (в наших


условиях чаще всего А4) и установить его ориентацию (в высоту — Portrait
(Книжная), в ширину — Landscape (Альбомная)). На вкладке Lines and Text
(Линии и текст) можно отказаться от конвертирования цветов, если ваш
принтер умеет печатать в цвете.
Более интересные возможности предлагает вкладка Axes and Figure (Оси и
рисунок) — рис. 2.23. Она позволяет изменить пределы и разметку осей по
60 Глава 2

отношению к образу на экране, изменить фон графика на белый цвет,


включить печать элементов управления, установленных в области графиче-
ского окна, произвести пересчет фафического образа в зависимости от вы-
бранного инструмента (ZBuffer, OpenGL и др.).

Page Setup - Figuie 1


Size and Position | Paper | Lines and Text Axes and Figure |

r Axes limits and ticks —• - —


I & Recompute limits and ticks i" •
|. '"Keep screen limits and ticks ]

! I* Print UlControls ' I Sampel

г Background color _-_.._,


•.)••<* Force white background i Гок1
i <"" Keep screen background color •

j I Default (auto mode) *r| •


\ ' -r'V.;1, '- ' • !

Help.. OK Cancel

Рис. 2 . 2 3 . Изменение параметров графика

2.6.6. Редактирование графиков


Меню Edit
Меню Edit (Правка) — см. рис. 2.21 — включает набор стандартных команд,
присутствующих в любом текстовом или фафическом редакторе — Undo
(Отменить ввод), Cut (Вырезать), Сору (Копировать), Paste (Вставить), Clear
(Очистить) и Select All (Выделить все).
Команда Edit | Figure Properties (Правка | Свойства фафического объекта)
вызывает Property Editor (Редактор свойств), который пристыковывается к
фафическому окну (рис. 2.24) и предварительно настроен на изменение
свойств фигуры (Figure). В появившихся окнах редактора отображены наи-
более употребительные параметры фигуры. Вы можете изменить заголовок
фафического объекта (Figure Name), сменить цветовую палитру (Colormap),
Пошаговые вычисления в командном окне 61

указать цвет окаймления поля графика (Figure Color), включить или отклю-
чить воспроизведение порядкового номера графического окна (Show Figure
Number). С помощью кнопки Inspector (Инспектор) вызывается Property
Inspector (Инспектор свойств), в котором отображаются все свойства фигу-
ры. Любое из них, не включенное в наиболее употребительный набор, тоже
может быть изменено. Более подробная информация о свойствах всех гра-
фических компонентов и технике работы с Property Inspector (Инспектор
свойств) приводится в гл. 7 и 8.
Из окна Property Editor (Редактор свойств) можно вызвать диалоговое окно
Export Setup (Параметры экспорта).

Property Editor - Figure


Fg
i ure Name: Show Fg
i ure Number Inspector...
Cool rmap; «•Jet ТЩ
Export Setup..
Fg
i ure Color:

Рис. 2.24. Редактор свойств графического окна (Figure)

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


нах Property Editor (Редактор свойств) появляются свойства осей (рис. 2.25)
и меняется заголовок (Property Editor — Axes). Вы можете изменить заголо-
вок, расположенный над полем графика (Title), установить цвета осей, под-
писей и фона поля графика (Colors), включить или отключить изображение
координатной сетки по любой из осей (Grid), включить или отключить об-
водку рамки поля графика (Box). Для каждой из координатных осей можно
62 Глава 2

изменить наименование оси (X Label, Y Label, Z Label), минимальный и


максимальный пределы изменения соответствующей переменной (X Limits,
Y Limits, Z Limits), способ масштабирования по каждой из осей (X Scale, Y
Scale, Z Scale), сменить направление оси на противоположное (Reverse).
Кнопка Ticks (Штрихи) вызывает Edit Axes Ticks (Редактор штрихов), вид
которого приведен на рис. 2.26. С его помощью можно выбрать один из трех
вариантов размещения штрихов — автоматический (Auto), ручной (Manual)
или с заданным шагом (Step by), задать автоматический или ручной способ
индикации каждого штриха (X Tick Labels), включить или отключить режим
отображения малых штрихов (Show minor ticks). Кнопка Inspector
(Инспектор) в окне Property Editor (Редактор свойств) вызывает инспектор,
отображающий значения всех свойств координатных осей.

-/ Figure 1 U5ra
File Edit View Insert Tools Desktop Window Help
rJtfTg фЩ\ C<3lW® | S Ш SI ° •
• .-»•" ~S -t В •
—я
/ \\
0.5 \
/ \ \\ '''

0i \ \

\ \
\ /
/

\ /

0.5 4 \
/

/
A

-1I S 1 u_ _j js 1 —•
0 1
Property Editor - Axes
Title: X Axis у Axis Z Axis j Font | Inspector..

X Label: | Ticks... 1
Colors: g • JL- X Limits: |o" to 7 Г" Auto
Grid: Г X Г У Г1
X Scale; |u... jJ Г" Reverse
Г Box

Рис. 2 . 2 5 . Редактор свойств осей координат (Axes)

Выделение той или иной кривой (рис. 2.27) приводит к перенастройке ре-
дактора свойств на параметры указанного графика (Property Editor — Line-
series). Раскрывающиеся списки X/Y/Z Label Data Source (Источник дан-
ных) позволяют изменить значения векторов х, у и z, задающих табличную
Пошаговые вычисления в командном окне 63

функцию. После изменения любого из этих элементов необходимо нажать


кнопку Refresh Data (Обновить данные), и тогда новые числовые значения
вступят в силу.

«•A Edit Axes Ticks


[X. AxisJ у Axis | Z Axis |

X Tick Locations: X Tick Labels:

<? Auto № Auto

С Manual Г Manual

Г Step by:

Locations: L a b e l s :

0 0
I n s e r t

1 1

2 2 . . _ 1 Delete
3 3

I *_ 4

5
6 G

_ .„Л. 7

: :
' ' . . . ' ' , ' . . . • . ' > '. : ' • • : ; • ; . . • • . • • .

I™ Show minor ticks

OK Apply Cancel

Рис. 2.26. Редактор штрихов на координатных осях

На рис. 2.28 показаны раскрывающиеся списки и подсказки к соответст-


вующим окнам. В раскрывающемся списке Plot Type (Тип графика) вы мо-
жете выбрать один из пяти способов отображения графика функции. По
умолчанию фафик воспроизводится линией (Line, отсюда и фрагмент заго-
ловка окна — Lineseries). Четыре других способа воспроизведены на рис. 2.29.
В раскрывающемся списке Line (Линия) задается тип линии (сплошная,
штриховая, пунктирная или штрих-пунктирная). Значение no line (нет) за-
меняет линию графика маркерами в заданных точках. Цвет линии и ее тол-
щина регулируются значениями, установленными при помощи кнопок-
списков, выделяемых подсказками Color (Цвет) и LineWidth (Толщина ли-
нии) соответственно. В списке Marker можно выбрать подходящую конфи-
64 Глава 2

гурацию маркера, размер которого задается значением в раскрывающемся


списке MarkerSize. Цвета контура маркера и его внутренней области уста-
навливаются с помощью кнопок-списков MarkerEdgeColor и MarkerFace-
Color соответственно.

U> Figure 1
File Edit View insert Tools Desktop Window Help

\
- • / • - ,

Jtll / •
I \
• i
\
/ i
/ •
0 •

05 / j

л •

0 :• 1 2 3 4 5 6 7
Property Editor - Lmeseries
Display Name: Plot Type: Line
:
X Data Source.' ] auto J^J |—— 1 i —i
Y Data Source: UnK | zj |05 j j
Matter | no... j j . 16Л zi :
t£'\
1 Data Source:

Рис. 2.27. Редактор свойств


выделенного графика (Lineseries)

Команды Edit | Axes Properties (Правка Свойства осей) и Edit | Current Ob-
ject Properties (Правка| Свойства объекта) вызывают Property Editor (Редак-
тор свойств) с одновременной настройкой на параметры соответствующего
объекта.
Команда Edit | Find Files (Правка | Найти файлы) появилась только в
MATLAB 7. Она позволяет устроить поиск заданного контекста во всех
файлах текущего каталога. Аналогичным инструментом обладают практиче-
ски все оболочки операционных систем и достаточно развитые системы
программирования.
Команды последней группы обеспечивают очистку поля фигуры, команд-
ного окна, окна истории команд и рабочего пространства. По умолчанию
очистка трех последних компонентов сопровождается запросом подтвержде-
ния на выполнение операции.
Пошаговые вычисления в командном окне 65

Color

Property Editor - Linesenes


Dsip
aly Nome: j Plot Type:(Line J J
r Inspector..
XDat Source: [auto —Line: p—3 ) 0.5 2J Refresh Data
Y Dat Source: | Marker:fno~£l I - "'I
s0

Z Dat Source:
- MarkerEdgeColor
L
MarkerFaceColor
LineWidth
L
MarkerSize

Рис. 2 . 2 8 . Средства редактирования выделенного графика

:
v
Bar
'-

\
Area

W/
Stairs
.SiS
e
tm
Рис. 2 . 2 9 . Способы отображения табличных функций

Кроме кнопок, обеспечивающих создание, открытие, сохранение и печать


графического объекта, на панели инструментов находятся следующие кноп-
ки (рис. 2.30):
• Edit Plot — включение режима выделения фафического объекта;
П Zoom In — увеличение масштаба изображения;
• Zoom Out — уменьшение масштаба изображения;
66 Глава 2

- New Figure
- Open File -Pan
- Save Figure - Rotate 3D .
r- Print Figure r-Data Cursor

•jk F i g u r e 1
[tile I Edit [view Insert TpoljT-Desktop'Window Help
.+ . I — I I—„ 7 .. I I— — ^ 4 ~— - • . ~r .

D c ^ H ^ I fe I ^ ^ О ® i ^S !• Q 13 j ш •
"-Ч

Zoom Out Show Plot Tools
L L
Zoom In Hide Plot Tools
L
• Edit Plot Insert Legend
L
Insert Colorbar

Рис. 2.30. Панель инструментов графического окна

•/ Figure I
File Edit View Insert Tools Desktop: Window Help
о & a m\ i*~ « t ' C f ) ] ® ; к i а "и '•••••и

Рис. 2 . 3 1 . Вращение плоской кривой

• Pan — захват кривой с целью ее перемещения в поле графика;


О Rotate 3D — вращение изображения (больший эффект достигается для
ЗО-поверхностей, пример вращения плоской синусоиды приведен на
рис. 2.31);
Пошаговые вычисления в командном окне 67

• Data Cursor — включение режима, при котором точка графика, попав-


шая под курсор, сопровождается отображением значений координат
(рис. 2.32);
• Insert Colorbar — включение столбика с палитрой цветов (Colormap), от-
ражающего распределение высот z;
П Insert Legend — вставка автоматической легенды;
• Show Plot Tools — пристыковка к графическому окну средств редактиро-
вания и просмотра (Figure Palette (Редактор графического окна), Property
Editor (Редактор свойств), Plot Browser (Просмотр графика));
О Hide Plot Tools — удаление средств редактирования и просмотра.

•JP" F i g u r e I
File Edit View Insert Tools Desktop Window Help

1
0.8
0.6 X: 24
Y: 0 6755
0.4
0.2
0
-0.2
-0.4
-0.6
-0.8
-1

Рис. 2.32. Идентификация точки на кривой

Меню View
Команды меню View (Вид) позволяют отобразить (команда помечена га-
лочкой) на экране или скрыть следующие средства редактирования (см.
рис. 2.21):
• Figure Toolbar — панель инструментов графического окна;
• Camera Toolbar — панель инструментов для управления камерой;
68 Глава 2

О Plot Editor Toolbar — панель инструментов для редактирования графика;


П Figure Palette — редактор графического окна;
• Plot Browser — средство просмотра графических объектов;
• Property Editor — редактор свойств графических объектов.
Перечисленные средства, исключая описанный выше Property Editor (Редак-
тор свойств), приведены на рис. 2.33.

•Л Figure 1
File Edit View Insert Jpols Desktop Window Help
О i* В в]Л*|'®L Q.J5 .® ! ^ P. Ш! D n
Camera Toolbar [
* i л к / i H- •? ?J \ \ \ ^ T Q G | - f i 4 [Plot Edit Toolbar
(Figure P. Plot Browser
"*• New Subpo
l ts A 1
Axes (no title)
О 2D Axes ffl*"" 0.8
Ц^, 3D Axes EH
0.6

• Variables 0.4

EB* ix63
0,2
Щу 1X63

0
• Armotetions
-0.2
\Lina

^ Arrow -0.4

^ Double Arrow
-0.6
^ ^ Text Arrow
: -0.8
T Text Box
i >
• Rectangle '~ -1

О Ellipse !

Рис. 2.33. Графическое окно со средствами редактирования

Камера (Camera), или точка зрения, определяет позицию человека, наблю-


дающего за объектом, расположенным в поле графика, параметры источни-
ка света, способы распространения и отражения лучей света. Более подроб-
но свойства камеры описываются в гл. 10.
Редактор графического окна (Figure Palette) и соответствующая панель ин-
струментов (Plot Editor Toolbar) рассматриваются ниже.
Окно Plot Browser (Просмотр графика) отображает список графических объ-
ектов, расположенных в поле графика.
Пошаговые вычисления в командном окне 69

Меню Insert
Меню Insert (Вставка) — см. рис. 2.21 — содержит набор команд по вставке
в графическое окно различных элементов оформления — легенды (Legend),
разноцветной полоски (Colorbar), линии (Line), различных стрелок (Arrow,
Double Arrow, Text Arrow), пояснительной подписи (Text Box), прямоуголь-
ников (Rectangle) и эллипсов (Ellipse). Все эти команды дублируют возмож-
ности Figure Palette (Редактор графического окна) и Plot Edit Toolbar
(Панель инструментов редактирования графика). Команда Insert | Light
(Вставка | Свет) подключает к графическому окну Property Editor (Редактор
свойств) источника света (Property Editor — Light), с помощью которого
можно изменить позицию (Position — х, у, г), стиль (Style) распространения
лучей света (бесконечно удаленный — Infinite, локальный — Local) и цвет
лучей (Color).

Меню Tools
Значительно расширен по сравнению с предыдущими версиями набор
команд меню Tools (Сервис) — см. рис. 2.21. Команды Edit Plot (Редакти-
ровать график), Zoom In (Увеличить масштаб), Zoom Out (Уменьшить мас-
штаб), Pan (Захватить), Rotate 3D (ЗО-поворот) и Data Cursor (Данные под
курсором) продублированы аналогичными кнопками на панели инструмен-
тов Figure Toolbar (Панель графического объекта). Команда Reset View
(Восстановить вид) возвращает на исходное место график, перемешенный в
режиме Pan (Захватить). Команда Options (Параметры) открывает список
команд (рис. 2.34), с помощью которых можно изменить режим масштаби-
рования, траекторию перемещения графика, захваченного в режиме Pan
(Захватить), и способ отображения координат точки, выделенной курсором:
• Unconstrained Zoom, Unconstrained Pan — естественное масштабирование
(одновременно по всем координатам) или естественное перемещение
графика (по траектории движения мыши);
• Horizontal Zoom, Horizontal Pan — масштабирование или перемещение по
горизонтали;
• Vertical Zoom, Vertical Pan — масштабирование или перемещение по вер-
тикали;
П Display Cursor as Datatip — значения координат точки, находящейся под
курсором, отображаются рядом с курсором;
П Display Cursor in Window — координаты помеченной точки отображаются
под полем графика.
Для удаления неудачно оцифрованной точки можно прибегнуть к услугам
всплывающего меню (рис. 2.35). Кроме удаления только что сделанной по-
метки (Delete Current Datatip), можно удалить все метки (Delete All Datatip),
70 Глава 2

изменить точку привязки цифровой отметки (Mouse Position — в позиции


мыши или Snap to Nearest Data Vertex — в ближайшей табличной точке) и
ее местоположение.

» Unconstrained Zoom
Horizontal Zoom
Vertical Zoom
* Unconstrained Pan
Horizontal Pan \
Vertical Pan
•> Display Cirsor as Datatip— 4-\ X
Y:-0.3
0.52837
Display Cursor in Window - •
-0.2 \
-0.4 \
\
-0.6
-0.8

Рис. 2.34. Дополнительные возможности команды Options

Display Style
Create New Datatip Alt-Click
Delete Current Datatip Delete
Delete All Datatips

Mouse Position
* Snap to Nearest Data Vertex

Window Jnslde Figure


' Datatip

Рис. 2 . 3 5 . Всплывающее меню

Очень интересные возможности предлагает команда Pin to Axes (Прикре-


пить к осям), которой на панели инструментов соответствует кнопка, напо-
минающая современную кнопку, используемую для закрепления объявле-
ний. Например, можно направить кончик стрелки с пояснительным текстом
(Text Arrow) в особую точку графика и "кнопкой" закрепить его. Если теперь
воспользоваться режимом Pan (Захватить) для захвата графика и его пере-
Пошаговые вычисления в командном окне 71

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


кой. Пояснительная надпись, расположенная на другом конце стрелки, при
этом будет оставаться на месте. Если с помощью "кнопки" закрепить и на-
чало стрелки, то перемещения кривой будут сопровождаться параллельными
перемещениями стрелки и надписи.
С возможностями выравнивания (Align) нескольких графических объектов
по вертикали или горизонтали, выбора вертикальных или горизонтальных
зазоров (Distribute) между объектами, привязки объектов к узлам коорди-
натной сетки (Grid) вы познакомитесь более подробно в разд. 8.3.
Команда Tools | Data Statistics (Сервис | Статистика данных) позволяет по-
лучить стандартные статистические данные о кривой, представленной в по-
ле графика. Результат исполнения этой команды для функции из примера
2.22 приведен на рис. 2.36.

: Пример 2.22. Аппроксимация графика i

» х=[0:0.8:6.28];
» y=sin(x);
» plot(х,у)

kfcData Statisti. i Figure 1


File Edit View Insert Tools Desktop Window Help
Check to ptot statistics on figure:
I * M v И
mn ! оГ -0 9962 :Г~ 1
max ; 5.6 Л 6.9996 Г"
datai
mean 2aTj -0.006277 Г 0.8
Ti'r' -0.0291 i l l ™
• '
Тэб'Г; D.7499 ; Г 0.6
range 1 1 996 i

0.4
Save to workspace. 0.2
0
-0.2
-0.4
-0.6
-0.8
-1
1 2

Рис. 2.36. Статистика по графику синусоиды с редко заданными точками


72 Глава 2

Представим, что при построении графика мы неудачно распорядились ша-


гом по аргументу и получили неудовлетворительную кусочно-линейную ап-
проксимацию исследуемой функции.
Конечно, можно переделать соответствующую команду и получить хорошую
синусоиду. Но график функции мог получиться в результате довольно
сложных манипуляций, повторять которые не очень то и хочется. В этом
случае можно поправить дело с помощью команды Tools | Basic Fitting
(Сервис | Базовое сглаживание). В результате ее выполнения появляется
диалоговое окно для выбора способа интерполяции таблично заданной
функции. На рис. 2.37 выбрана интерполяция кубическим сплайном, а
справа отображен результат применения этого метода.

UJkBasic
See
l ct data: jdatai File Edit View Insert Tools Desktop Window Help
Г Center and scale X data D caTo a iЦГ| ®> Q. f? ©, w а Ш а о ^
Plot f i t s — — - -—
• Check to display fits on figurB 1
• W spline interpolant
:
] P shape-preserving interpolant
datai
• \Г linear spline
', I P quadratic
\ Г" cubic
• Г" 4th degree polynomial
! Г" 5th degree polynomial
• f~* 6th degree polynomial
; Г" 7th degree polynomial
j 1Г" 8th degree polynomial
;
1Г" 9th degree polynomial
j |j 10th degree polynomial
i Г" Show equations .. .
I Significant digits: j 2 J^j
::
! Г™ Ptot residuals •

| Bat plot _£]


(Subplot 3
Г" Show norm of residuals

Help/ Close I '

Рис. 2 . 3 7 . Интерполяция графика кубическими сплайнами

Довольно много средств оформления графиков представлено в окне Figure


Palette (Редактор графического окна) и продублировано соответствующими
кнопками на панели инструментов Plot Edit Toolbar (Панель инструментов
редактирования графика) — рис. 2.38.
С помощью кнопок, обеспечивающих быстрый запуск действий, можно ус-
тановить цвет фона на поле графика (Color Face), цвет выделенной линии
(Color Edge), цвет пояснительных подписей (Color Text).
Пошаговые вычисления в командном окне 73

г Insert Line
- Font - Insert Arrow
- Bold Insert Double Arrow
г Italic г Insert Text Arrow

-/ Figuni 1
irsert Tools Desktop Wndow Help

Align/Distribute

Pin to axes
Insert Textbox
Insert Rectangle
Insert Ellips

Рис. 2.38. Панель инструментов Plot Edit Toolbar

Шесть следующих кнопок очень напоминают средства управления характе-


ристиками текста, используемые в редакторе MS Word. Однако диалоговые
окна здесь несколько иные. Например, диалоговое окно выбора шрифта и
его характеристик представлено на рис. 2.39. Кнопки по изменению харак-
теристик выделенного текста (Bold — жирный, Italic — курсив) и выравни-
ванию строки в прямоугольнике Textbox (Align Left, Align Right и Align Cen-
ter) имеют значки в стиле MS Word.
Очередная группа из семи кнопок дублирует соответствующие строки Figure
Palette (Редактор графического окна) и позволяет вставить на любое место
графического окна отрезок прямой (Insert Line), стрелку (Insert Arrow), дву-
направленную стрелку (Insert Double Arrow), стрелку с пояснительным тек-
стом (Insert Text Arrow), текст в прямоугольнике (Insert Textbox), прямо-
угольник (Insert Rectangle), эллипс (Insert Ellipse). Для вставки нужного
элемента следует выбрать соответствующую команду в Figure Palette (Ре-
дактор графического окна) или нажать аналогичную кнопку на панели ин-
струментов, переместить курсор мыши в начальную точку графического ок-
на и, удерживая левую кнопку мыши, протянуть элемент до конечной точки
(примерно такая же технология используется в графическом редакторе
Paint).
На рис. 2.40 продемонстрирован результат работы Figure Palette (Редактор
графического окна).
74 Глава 2

Шрифт

Шрифт: Начертание: Размер:


ок
ав
'«Г @PMingLiU A I обычный 8 ж
7Г @SimSun курсив Отмена
*Г Academy Engraved LET жирный 10
t Amaze жирный курсив 11
12
j 0 Arial Black i и
j 0 Arial Narrow _^J
16 ZL

.--Образец •

Hafiop символов:
Кириллический

Рис. 2 . 3 9 . Выбор характеристик шрифта

•> Figure 1
File Edit View Insert Tools Desktop Window Help
h as у *: n a• •

w
' ' New Subpolts
-Ш Hello. MATLAB
L_- 3D Axes 0.5
Create tiled subplots j
•*• Variables
\ /
1x63 Ч j D
Ь63
0 0.5

1.11
\l-ine

\ Arrow

^ Double Arrovv 0.5 0.5i


X Terf Arrow 12
T Text Box

I I Rectangle

О Ellipse
0.5 0 0.5

Рис. 2 . 4 0 . Результат работы редактора Figure Palette


Пошаговые вычисления в командном окне 75

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


щелкнуть по кнопке с пояснительной подписью "Create tiled subplots" и в
появившемся поле выделить нужное количество клеток по горизонтали и
вертикали (очень напоминает технику формирования таблиц в MS Word).
В каждом из появившихся окон вставлены описанные выше графические
примитивы.
Подключение русских текстов доставит головную боль отечественным поль-
зователям MATLAB 7. В примере с воспроизведением кардиоиды (рис. 2.17)
мы слукавили. Обычно результат работы команды t i t l e с кардиоида') вы-
глядит так, как показано на рис. 2.41.

•gk Figure I
File Edit View insert Tools Desktop Window yelp

Property Editor - Text


Line Style: |

Line Width: \05


Edge Color р Д Font: | Hevletc
ia _»j j 10.0 J
»| j Normal •*] j Normal
Background ,&, •

Рис. 2.41. Так MATLAB 7 отображает русские надписи

Объяснение тому достаточно простое. В шрифте Helvetica не совпадает ко-


дировка русских букв. Для восстановления справедливости выделяем над-
пись и выполняем команду View | Property Editor (Вид | Редактор свойств).
К фафическому окну пристыкуется редактор свойств текста, в котором сле-
дует изменить шрифт. К сожалению, не все шрифты, которые доступны в
76 Глава 2

MS Windows (например, Times New Roman), видны из Property Editor


(Редактор свойств). Поэтому приходится остановить свой выбор на шрифте
Courier с установкой подходящей высоты символов (рис. 2.42). Также можно
воспользоваться такими шрифтами, как Arial Cyr, MS Sans Serif, Small Font.

*> Figure 1
File Edit View Insert Tools Desktop Window Help
о & а а;ри Ф. «a, f?. ®Г*Е 1 -p gjjlpv_~L;l
•Kapguouga"
" " "
15

Property Editor - Text


Ln
i e Style:
U» Width:
Edge Coo lr
Background:

Рис. 2 . 4 2 . Замена шрифта для русификации подписи

2.6.7. Включение графиков


в отчетную документацию
После того как вы построили и отредактировали график, отражающий тот
или иной процесс, его можно включить в состав отчетного документа, на-
пример, набираемого в редакторе MS Word. Делается это следующим об-
разом:
1. В момент, когда графическое окно находится на экране, нажимается
комбинация клавиш <Alt>+<Print Screen>, копирующая содержимое эк-
рана в буфер обмена (clipboard).
Пошаговые вычисления в командном окне 77

2. В редакторе, в котором готовится отчет, необходимо выполнить команду


Edit | Paste (Правка | Вставить). Средства MS Word позволяют после
этого выполнить обрезку изображения, поворот, корректировку яркости
и контраста и др.
Более простой вариант копирования области графика в буфер обмена вы-
полняет команда Edit | Copy Figure (Правка | Копировать рисунок). В этом
случае вам не понадобится удалять лишние фоновые фрагменты, т. к. в бу-
фер обмена попадет только поле графика без заголовка графического окна.

2.7. Деловая графика


Довольно много различных приложений, связанных с экономическими, ста-
тистическими и социологическими исследованиями, используют для визуа-
лизации результатов различного рода диаграммы — столбиковые и круго-
вые, плоские и объемные. Иногда их связывают с термином "деловая
графика". В библиотеке фафических функций MATLAB для этой цели реа-
лизована фуппа Следующих функций: bar, barh, ЬагЗ, bar3h, pie, pie3,

2.7.1. Плоские столбиковые диаграммы


В простейшем случае плоская столбиковая диафамма, отражающая значения
компонентов вектора у, строится с помощью функции bar (пример 2.23).

! Пример 2.23. Столбиковая диаграмма I


'.......... , , , .-
» у=[1 2 4 ] ;
>> length(у)
ans =
3
» bar(y); colormap(cool)

Функция colormap, к которой мы обратились с аргументом cool, осуществ-


ляет подмену стандартной цветовой палитры, закрепленной за фафическим
окном. Палитра, по умолчанию приписываемая фафическому окну, отлича-
ется довольно мрачными тонами. Новая палитра представляет набор более
светлых оттенков от бирюзового (cyan) до малинового цвета (magenta). На
рис. 2.43 показана построенная диафамма. По умолчанию ее столбики рас-
положены над целочисленными координатами х, принадлежащими интер-
валу [i, length (у)]. Ширина столбиков по умолчанию равна 0,8 см (этот
размер точно выдерживается только при выводе на принтер). Надписи внут-
ри столбиков сделаны вручную с помощью средств управления фафическим
78 Глава 2

окном. Виц диаграммы не изменится, если вектор у будет представлен


столбцом с такими же значениями (у= [ 1; 2; 4 ]).

Рис. 2 . 4 3 . Диаграмма значений вектора у = [ 1 , 2 , 4 ]

Обращение к функции barh с тем же аргументом строит столбики, развер-


нутые по горизонтали (рис. 2.44):
» barh(y); colormap(cool)

Рис. 2 . 4 4 . Горизонтальная диаграмма

Обращение к функциям bar (пример 2.24) или barh с двумя аргументами (х,
у) позволяет изменить маркировку оси х (рис. 2.45). Правда при этом требу-
Пошаговые вычисления в командном окне 79

ется, чтобы вектор х был представлен монотонно изменяющимися значе-


ниями (возрастающими или убывающими).

; Пример 2.24. Маркировка оси у диаграммы i

» х=[-1.5,0,2.5] ;
» у=[1,2,4];
>> bar(x,у);
>> colormap(cool)

'•• 3.5
3
2.5

1.5 —

0.5

"-Э ' : : -2 - 1 - 0 1 ' 2 3 4

Рис. 2.45. Диаграмма с заданной разметкой оси х

Аргумент w в обращениях bar(y,w) или bar(x,y,w) управляет шириной


столбцов диаграммы. В зависимости от маркировки оси х и заданной шири-
ны столбиков w соседние прямоугольники могут накладываться друг на
друга.
Аргумент у может быть представлен не только вектором, но и матрицей
значений (пример 2.25).

; Пример 2.25. Построение нескольких диаграмм одновременно :

» у=[1 2 4; 1.5 3 5]
У =
1.0000 2.0000 4.0000
1.5000 3.0000 5.0000
80 Глава 2

В этом случае функции bar и barh предлагают два способа группировки


столбиков, представляющих компоненты матрицы:
» bar(у,'grouped'); colormap(cool)

ИЛИ
» bar(y); colormap(cool)
Любая из приведенных выше строк генерирует две группы столбиков (рис. 2.46).

Рис. 2.46. Матричная диаграмма, вариант 1

У= 15

Рис. 2.47. Матричная диаграмма, вариант 2


Пошаговые вычисления в командном окне 81

Второй способ группировки элементов этой же матрицы позволяет размес-


тить столбики друг над другом (рис. 2.47):
» bar(у,'stacked'); colormap(cool)

2.7.2. Объемные столбиковые диаграммы


Объемные столбиковые диаграммы строятся с помощью функций ЬагЗ и
Ьагзь, разница между которыми заключается только в вертикальном или
горизонтальном расположении столбцов.
Функция bar3(z) превращает простую плоскую диаграмму в объемную
(рис. 2.48):
» z=[l,2,3];
» b a r 3 ( z ) ; colormap(cool)

2, ч

s
К
,-•

-

4.

Рис. 2.48. Простая объемная диаграмма

Если аргумент z представлен матрицей, то столбики размещаются как вдоль


оси у, так и вдоль оси х (рис. 2.49):
» z=[2,3,4;l,2,3];
» b a r 3 ( z ) ; colormap(cool)
Столбики двумерной матрицы могут быть перегруппированы двумя раз-
ными способами с использованием аргументов grouped (рис. 2.50) и
stacked (рис. 2.51):
» z=[2, 3,4;1,2,3],•
» ЬагЗ(z,'grouped'); colormap(cool)
» ЬагЗ(z,'stacked'); colormap(cool)
82 Глава 2

4
т
Зч.

2,

1,

olj
J t l V I
N .

Рис. 2 . 4 9 . Матричная объемная диаграмма

Рис. 2.50. Способ группировки g r o u p e d

В приведенных выше примерах разметка осей у и х выполнялась автомати-


чески. Однако функции ЬагЗ и ЬагЗЬ допускают задание монотонно возрас-
тающего или убывающего вектора у, с помощью которого может быть изме-
нена разметка диаграммы вдоль оси у — ЬагЗ (у, z ) . С помощью еще одного
параметра w можно управлять шириной столбцов — bar3(z,w) или
ЬагЗ (у, z,w). По умолчанию ширина столбиков равна 0,8 см.
Пошаговые вычисления в командном окне 83

Рис. 2 . 5 1 . Способ группировки s t a c k e d

2.7.3. Круговые диаграммы


Круговые диаграммы, состоящие из плоских или объемных секторов
(аналогов кусков пирога), строятся с помощью функций pie и pie3 (пример
2.26). В простейшем случае вектор q, содержащий к положительных компо-
нентов, генерирует к секторов, центральный угол которых пропорционален
вкладу каждого компонента в общую сумму. По умолчанию против каждого
сектора помещается его процентный вклад.
••••• ••••••

Пример 2.26. Круговая диаграмма

» q = [1,2,4];
>> colormap cool
» pie(q)
» pie3(q)

Построение секторов в плоской диаграмме начинается с "севера" и осуще-


ствляется против часовой стрелки. Для объемных диаграмм начало отсчета
располагается на "северо-западе". Результаты работы указанных команд при-
ведены на рис. 2.52 и 2.53.
На рис. 2.53 видно, что некоторые надписи расположены не очень удачно.
Для того чтобы обратить внимание на отдельный сектор или группу секто-
ров, их принято немного выдвигать из "пирога".
84 Глава 2

14%

S i к
1
57%
29% V
В?

Рис. 2.52. Плоская круговая диаграмма

Рис. 2.53. Объемная круговая диаграмма

Создание таких выделяющихся элементов обеспечивается заданием еще од-


ного аргумента такой же размерности, что и вектор q. Выдвигаемым секторам
в новом векторе должны соответствовать ненулевые элементы. Например:
» v=[0,l,0];
» pie(q,v); % результат на рис. 2.54

» т= [ 1, 0, 0 ] ;
» pie3(q,m) % результат на рис. 2.55

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


тельно сформированные в массиве ячеек (пример 2.27).
Пошаговые вычисления в командном окне 85

Рис. 2.54. Выделен второй сектор

Рис. 2.55. Выделен первый сектор

: '••'• ••

\ Пример 2.27. Метки на круговой диаграмме

» z=fl,249,1,249,1,249,1, 249] ;
» s={'Север','','Запад ','','Юг', " , ' Восток 1 , 1 1 };
>> pie(z,s); colormap(cool)

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


бы надписи сторон света были точно расположены на своих местах, при-
шлось завести для них очень узкие секторы и довести общее количество
секторов до 8. Во-вторых, чтобы надписи запад и Восток не сливались с
изображением, к ним пришлось добавить по паре пробелов. Результат при-
веден на рис. 2.56.
86 Глава 2

Р и с . 2 . 5 6 . Стороны света на круговой диаграмме

2.7.4. Площадные диаграммы


В площадных диафаммах фафик первой функции yi(x) строится обычным
образом, отмеряя ординаты yi(xi) от оси х. График второй функции у2(х)
как бы наслаивается на предыдущий фафик, отмеряя свои ординаты от ор-
динат предыдущей функции — yi(xi)+у 2 (х х ). График следующей функции
суммируется с ранее накопленной суммой и т. д. Площадь каждого фафика
выделяется своим цветом, чтобы продемонстрировать вклад очередного
слагаемого в общую сумму.
Пусть, например, итоговый фафик задан значениями элементов двумерного
массива (пример 2.28).

Пример 2.28. Задание площадных диаграмм с помощью массива

у =

Его столбцы определяют значения функций-слагаемых. Это означает, что


график первой функции задан точками (1, 1), (1, 7) и (1, 4), график второй
функции — точками (1, 8), (2, 5) и (3, 2), фафик третьей функции — точка-
ми (1, 3), (2, 9) и (3, 6). Каждый из компонентов в отдельности представлен
фафиками в отдельных подокнах (рис. 2.57). Соответствующая площадная
диаграмма воспроизведена в правом нижнем подокне с помощью функции
area:

» у=[1 8 3; 7 5 9 ; 4 2 6] ;
» yl=[l,7,4];
Пошаговые вычисления в командном окне 87

» у2=[8,5,2];
» уЗ=[3,9,6];
» subplot(2,2,1); plot(yl);grid on
» subplot(2,2,2); plot(y2);grid on
» subplot(2,2,3); plot(y3);grid on
» subplot(2,2,4); area(y); grid on; colormap(cool)

y1 = [1,7,4] = [8,5,2]

/ - • >

7
ч
1 1 6 I 25 3 1 1 5 2

2 5 3

25
20
" ^

15 4 > T
/ 10 _——~*
• — .
, - — — "

- — -
-.
• ~ • — - . ' ^

1 1.
5 2 2 . 5 3 1 1.5 2 2.5 3
= [ 3 . 9 . 6 ] у = [1.3.8; 7,5,9, 4, 2, Б]

Рис. 2.57. Площадная диаграмма и ее составляющие

4 Зак 899
Глава 3

Типы данных
3.1. Иерархия
типов данных в MATLAB
В справочных файлах приведена схема (рис. 3.1), на которой представлены
16 фундаментальных типов данных (или классов), определенных в MATLAB.
Из схемы явствует, что базовым классом данных является массив (ARRAY). На-
ряду с пустыми, неинициализированными массивами язык MATLAB позволя-
ет обрабатывать векторы (массивы размерности 1хл или лх1), квадратные и
прямоугольные матрицы (массивы размерности пхт), массивы более высокой
размерности.

ARRAY

char cell stucture


I
NUMERIC user class Java class LOGICAL

function handle

int8, uint8, single double


int16, uint16,
int32, uint32,
int64, uint64 sparse

Рис. З . 1 . Схема иерархии типов данных

В гл. 2 довольно подробно обсуждалась специфика представления числовых


массивов с элементами типа double, положенных в основу большинства вы-
числительных процессов и сочетающих в себе представление как вещест-
90 Глава 3

венных, так и комплексных чисел. В этой главе мы остановимся более под-


робно на других классах данных.

3.1.1. Символьные массивы (char arrays)


Символьные векторы (массивы размерности 1хл) представляют собой обыч-
ные строки. Для задания их значений в правой части оператора присваива-
ния записывают цепочку символов, заключенную в одинарные кавычки
(пример 3.1).

; Пример 3.1. Символьный вектор I


•. ,....,,....... .....;:
>> sv='abcdefgh'
sv =
abodefgh
» whos
Name Size Bytes Class
sv 1x8 16 char array
Grand total is 8 elements using 16 bytes

Мы уже упоминали, что каждый элемент типа char занимает в памяти


2 байта и представлен в кодировке ASCII Unicode. В MATLAB 7 устранены
моменты, имевшие место в ранних версиях и связанные с неприятием рус-
ских букв "с" и "я":
>> гз='пуля'
rs =
пуля
» rs='условие'
rs =
условие

Символьная матрица (массив размера тх-п) должна состоять из строк равной


длины (пример 3.2).

: Пример 3.2. Символьная матрица

» sm=['abcdefgh1;'12345678'
sm =
abcdefgh
12345678
>> whos
Типы данных 91_

Name Size Bytes Class


sm 2x8 32 char array
Grand total is 16 elements using 32 bytes

Для определения текущих длин, размеров и количества измерений символь-


ных массивов МОЖНО ИСПОЛЬЗОвать функции length, size И ndims
(пример 3.3).

i Пример 3.3. Определение размеров символьных массивов |

» s v='abcde fgh';
» whos
Name Size Bytes Class
sv 1x8 16 char array
Grand total is 8 elements using 16 bytes
>> size(sv) % возвращает число строк и число столбцов
ans =
1 8
» length(sv) % возвращает количество символов
ans =
8
>> ndims(sv) % возвращает количество измерений
ans =
2
» sm=['abcdefgh1; '12345678 ']
sm =
abcdefgh
12345678
>> size(sm) % возвращает число строк и число столбцов
ans =
2 8
» length(sm) % возвращает количество символов в строке (!)
ans =
8
>> ndims(sm) % возвращает количество измерений
ans =
2
92 Глава 3

3.1.2. Целочисленные данные в MATLAB


Ни один из универсальных алгоритмических языков не обходится без це-
лочисленных данных. MATLAB до версии 7 в этом смысле стоял несколь-
ко особняком. Он допускал создание и хранение числовой информации в
виде одно-, двух- и четырехбайтовых форматов со знаком или без знака.
Во всех версиях пакета были предусмотрены функции конвертирования
вещественных и комплексных данных типа double в любой из допустимых
форматов целых и вещественных чисел (табл. 3.1), а также обратные пре-
образования. Однако арифметические операции над целочисленными дан-
ными до 7-й версии были запрещены.
Таблица 3.1

Функция Назначение Диапазон допустимых


значений

int8 Преобразование в формат однобайто- от-128 до 127


вых целых чисел со знаком
uint8 Преобразование в формат однобайто- от 0 до 255
вых целых чисел без знака
intl6 Преобразование в формат двухбайто- от -32 768 до 32 767
вых целых чисел со знаком
uintl6 Преобразование в формат двухбайто- от 0 до 65 535
вых целых чисел без знака
int32 Преобразование в формат четырех- о т - 2 147 483 648
байтовых целых чисел со знаком до 2 147 483 647
uint32 Преобразование в формат четырех-
байтовых целых чисел без знака от 0 до 4 294 967 295

int64 Преобразование в формат восьмибай-


товых целых чисел со знаком от - 2 6 3 до 2 6 3 - 1

uint64 Преобразование в формат восьмибай-


товых целых чисел без знака от 0 до 2 6 4 - 1

double Преобразование числового аргумента


в формат вещественного числа с удво- От 2.225x10~308
енной точностью до 1.798x10+308 (по модулю)
single Преобразование числового аргумента От 1.175x10"38
в формат вещественного числа с оди- до 3.403x10 +38 (по модулю)
нарной точностью

Версия MATLAB 7 принципиально отличается от предшествующих версий


не только тем, что в нее включены восьмибайтовые целые числа. Самое су-
щественное, что в новых целочисленных классах (кроме int64 и uint64)
Типы данных 93_

определены все арифметические операции. Это может послужить важным


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

I Пример 3.4. Целочисленные массивы

» x=intl6(12)
х=
12
» whos
Name Size Bytes Class
x lxl 2 intl6 array
Grand total is 1 elements using 2 bytes
» format hex
» x

X —
000с
>:> y=uintl6([5 25 30])

У =
0005 0019 OOie
>;> whos
Name Size Bytes Class
X lxl 2 intl6 array
У 1x3 6 uintl6 array
Grand total is 4 elements using 8 bytes

Как вы заметили, вывод целочисленных данных неплохо уживается с фор-


матом hex. Аргумент, преобразуемый к целому типу, может иметь дробную
часть, и тогда MATLAB использует стандартное округление, принятое в ма-
тематике (пример 3.5).

i Пример 3.5. Округление аргументов

» int8(2.1)
ans =
2
» int8(2.5)
94 Глава 3

ans =
3
» int8(-2.5)
ans =
-3
» int (2.9)
ans =
3

Максимальное и минимальное значения, соответствующие тому или иному


целому типу, можно определить с помощью функций intmin и intmax:
» intmin('intl6')
ans =
-32768
» intmax(!uint8')
ans =
255

Если конвертируемый аргумент выходит за пределы заданного диапазона, то


MATLAB возвращает левую или правую границу:
» int8(450)
ans =
127
» int8(-450)
ans =
-128

Точно такое же обрезание происходит и при получении результата, выходя-


щего за допустимые пределы:
» int8(100)+int8(150)
ans =
127

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


операции за допустимые пределы, обратившись к функции intwarning с
аргументом 'on 1 :
>> intwarning('on')
» x=int8(200)
Warning: Out of range value converted to intmin('int8') or
intmax('int8').
Типы данных 95

х =
127

По умолчанию этот режим отключен (intwarning (' of f )).


Функции формирования стандартных матриц ones, zeros и eye могут быть
использованы для формирования целочисленных массивов при условии, что
последним аргументом задается строка с указанием типа (пример 3.6).

; Пример 3.6. Формирование стандартных матриц j

» x=ones (2,2, 'Lnt8')


:
X =
1 1
1 1
» y=zeros(2,3, 'uint8')
У =
0 0 0
0 0 0
» z=eye (2,'intl6')
z =
1 0
0 1
>> whos
Name Size Bytes Class
X 2x2 4 int8 array
У 2x3 6 uint8 array
z 2x2 8 intl6 array
Grand total is 14 elements using 18 bytes

Целочисленная арифметика в MATLAB 7 налагает ряд ограничений на до-


пустимые сочетания операндов, участвующих в выражениях. Так, например,
целочисленные операнды, входящие в формулу, должны быть одного типа.
То есть нельзя складывать однобайтовый скаляр или массив с двухбайтовым
операндом. Однако если один операнд (скаляр или массив) имеет целый
тип, то вторым операндом формулы может быть скаляр типа double
(пример 3.7). MATLAB выполняет такую операцию с удвоенной точностью
и преобразует результат к типу целочисленного операнда. Но когда количе-
ство операндов в формуле больше двух, то вычисления могут привести к
неверным результатам (пример 3.8).
06 Глава 3

; Пример 3.7. Комбинация целочисленного массива со скаляром типа double ;

» int8([l 2 3 4 5])*0.8
ans =
1 2 2 3 4

Следует отметить, что версия MATLAB 7, как и любой новый программный


продукт, еще не прошедший достаточную обкатку, содержит определенное
количество ошибок. Одну из них нам удалось обнаружить на примере 3.8.

\ Пример 3.8. Ошибка MATLAB

» int8(10)/int8(100)*20.5
ans =
0
» 20.5*int8(10)/int8(100)
ans =
1

С точки зрения программиста, обрабатывающего формулу слева направо,


приведенные выше результаты можно объяснить, но не оправдать. После
деления двух целых чисел (10/100) получается целочисленный 0, что и пре-
допределило первый результат. Во второй формуле MATLAB "сообразил",
что результат первого умножения (205) надо преобразовать к типу int8 (т. е.
заменить на 127) и после деления на 100 получил целочисленную 1. С точки
зрения математика здесь нарушен закон коммутативности (перестановка
сомножителей привела к разным результатам). Видимо, правильней было бы
выполнить все операции в формате double, получив 2.05, а затем преобразо-
вать результат в целочисленный, т. е. в 2.
Еще одну несуразицу с перестановкой слагаемых удалось обнаружить на
примере 3.9.

| Пример 3.9. Другая ошибка MATLAB ;

» 0.5+int8(10)/int8(120)
ans =
1
» 0.25+int8(10)/int8(100)+0.2S
ans =
0
Типы данных 97

С точки зрения математика обе формулы идентичны, а результаты вычисле-


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

Таблица 3.2

Функция Выполняемое действие

b i t a n d (А, в) Поразрядное логическое умножение


b i t o r (А, в) Поразрядное логическое сложение
b i t x o r (А, В) Поразрядное исключающее ИЛИ
b i t c m p (А, п) Инвертирование А С сохранением п битов
b i t s e t (А, п) Установка n-го бита числа А в единицу
b i t s e t (A,n, v) Установка n-го бита числа А в значение v (0 или 1)
b i t g e t (А, п) Опрос значения n-го бита в числе А
b i t s h i f t (А, п) Сдвиг двоичного кода А на П разрядов влево (п > 0) или
вправо (п < 0)

В двоичных операциях действуют следующие правила. Оба операнда, участ-


вующие в логических операциях and, or и хог, должны быть одного типа.
Результат выполнения операций стр и set не должен выходить за разряд-
ную сетку первого операнда. Те разряды, которые при операции сдвига вы-
ходят за пределы разрядной сетки, теряются. Ниже приведены результаты
выполнения битовых операций над самыми короткими числами, которые
легко проверить.
» A = u i n t 8 ( [ 0 1; 0 1 ] ) ;
» B = u i n t 8 ( [ 0 0; 1 1] ) ;
» T_AND=bitand(A,B)
T_AND =
0 0
0 1
» T_OR=bitor(А,В)
T__OR =
0 1
1 1
» Т XOR=bitxor(А,В)
98 Глава 3

T_XOR =
0 1
1 О
» C=uint8(5);
>> bitcmp(C,6)
ans =
58
» bitset(С,2)
ans =
7
» bitset(C,3,0)
ans =
1
» bitget(C,3)
ans =
1
» bitget(C,2)
ans =
0
» bitshift(C,2)
ans =
20
» bitshift(C,-l)
ans =
2

3.1.3. Вещественные данные


с одинарной точностью (single arrays)
В отличие от данных типа double, где каждый элемент массива представлен
одним или двумя 8-байтовыми значениями, в массивах типа single (single
arrays) на каждую числовую составляющую отводится по 4 байта и тем са-
мым экономится 50% памяти. Однако диапазон представления числовых
данных здесь существенно ниже (Ю 38 вместо 10 308 ), да и точность вычисле-
ний гарантирует получение, максимум, 7—8 значащих цифр вместо 15—16 в
стандартном режиме. В отличие от предыдущих версий MATLAB 7 разреша-
ет почти все арифметические операции и над вещественными данными с
одинарной точностью. Воспринимают такие аргументы и многие элемен-
тарные функции.
Типы данных 99

Более того, многие процедуры линейной алгебры в новой версии адаптиро-


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

» x=single(5)

5
» whos
Name Size Bytes Class
x lxl 4 single array
Grand total is 1 elements using 4 bytes
» abs(y)
ans =
1.1180

Следует заметить, что преобразование в формат single может привести к


небольшим искажениям исходных данных. Это объясняется тем, что в дво-
ичном коде числа может быть достаточно много дробных разрядов, которые
при обрезании мантиссы и принятом правиле округления вызывают не-
большую погрешность:
>>format long
» single(3.4)
ans =
3.4000001

Ошибка на одну единицу в 8-й значащей цифре вполне допустима.


Арифметика с одинарной точностью тоже накладывает определенные огра-
ничения на операнды формулы, которые могут быть либо типа single, либо
комбинироваться со скалярами или массивами типа double. Результат опе-
рации в последнем случае тоже имеет тип single:
» x=single(5)+single(3)

» y=single(5)+3
У=
8
» whos
100 Глава 3

Name Size Bytes Class


X lxl 4 single array
У lxl 4 single array
Grand total is 2 elements using 8 bytes
Для того чтобы узнать наименьшее и наибольшее значения для данных типа
s i n g l e , МОЖНО обратиться К функциям realmin И realmax С аргумеНТОМ-
строкой, задающей тип:
» realmin('single')
ans =
1.1754944е-038
» realmax('single')
ans =
3.4028235e+038
Если при вычислениях с данными типа single результат превосходит мак-
симально допустимое значение этого типа, то MATLAB возвращает inf:
>> realmax('single')*2
ans =
Inf

3.1.4. Разреженные матрицы


(sparse arrays)
Довольно много задач математической физики, теории прочности и пла-
стичности приводят к решению специфических систем линейных алгебраи-
ческих уравнений с так называемыми ленточными или блочными матрицами .
Кроме нескольких диагоналей или небольших блоков, заполненных коэф-
фициентами, в этих матрицах находится огромное число нулей (sparse
arrays). Держать их в оперативной памяти невыгодно, поэтому в ряде при-
кладных программ было предложено хранить наряду со значениями ненуле-
вых элементов их индексы. Способы такого представления данных могут
быть разными. Например, можно хранить тройки (value, i, j). MATLAB
использует более экономный вариант, при котором разреженная матрица
рассматривается как вектор-столбец, компонентами которого являются раз-
реженные векторы-строки. Ненулевые компоненты разреженных строк тре-
буют задания не двух индексов, а одного, на чем, собственно, и экономится
объем хранимой информации. На самом деле хранятся не индексы отдель-
ных элементов столбца, а диапазон индексов, соответствующий подряд
идущим ненулевым элементам. В MATLAB предлагается довольно много
функций по обработке разреженных матриц и по их преобразованию в
обычный матричный формат представления данных.
Типы данных 101

Для того чтобы представить себе экономию от хранения разреженных мат-


риц, приведем пример 3.11.

! Пример 3.11. Разреженная матрица

» а=еуе(100);
» b=sparse(eye(100));
>> whos
Name Size Bytes Class
a 100x100 80000 double array
b 100x100 1604 sparse array
Grand total is 10100 elements using 81604 bytes

В разреженных матрицах могут храниться элементы только типа double.

3.1.5. Структуры и массивы структур


(struct arrays)
Структуры, или записи (в C++ и Java — struct, в Pascal — record), пред-
ставляют собой тип данных, порожденный общепринятыми таблицами. Для
таблиц характерны строки данных единого формата, определяемого заголов-
ком таблицы. Каждая строка таблицы представлена последовательностью
полей. Одноименные поля образуют колонки таблицы, в которых распола-
гаются данные одинакового типа. Друг от друга поля отличаются идентифи-
каторами, соответствующими заголовкам колонок таблицы. Таблицы широ-
ко используются в реляционных базах данных, они позволяют повысить
эффективность представления данных в памяти ЭВМ, ускоряют обмен с
файлами, повышают наглядность представления результатов работы многих
программ.
Представим себе простейшую таблицу с тремя колонками, содержащими
сведения об авторах (табл. 3.3), которую мы хотим оформить в виде массива
authors, включающего три структуры. Наименования колонок — полей
структуры — продублированы на английском языке, т. к. в идентификаторах
полей употребление русских букв запрещено.
Таблица 3.3

Фамилия, И. О. (Name) Возраст (Age) Телефон (Phone)

Иванов И. И. 31 11-11-11
Петров П. П. 32 22-22-22
Сидоров С. С. 33 33-33-33
102 Глава 3

Одним из способов формирования структуры является использование функ-


ции s t r u c t (пример 3.12), которая заполняет указанный элемент массива
структур. Аргументами этой функции являются пары, содержащие имя поля
и соответствующее значение. Все предшествующие элементы массива струк-
тур формируются как поля с такими же наименованиями, значения которых
заполнены пустыми матрицами 1x1. Очевидно, что в левой части оператора
присваивания удобнее заполнить последнюю структуру массива, иначе из-
начально не будет создан массив нужного размера. Однако это вовсе необя-
зательно, и в первый раз мы можем вызвать функцию struct для создания
первого элемента массива структур. А потом добавлять последующие строки
таблицы. Дело в том, что размер массива все равно будет изменяться в зави-
симости от длины значений, присваиваемых полям незаполненных ранее
структур. Тем не менее, формирование массива структур целиком позволит
избежать дополнительных затрат, возникающих при увеличении количества
элементов.

| Пример 3.12. Формирование структуры \

» authors(3)=struct('Name','Сидоров С.С.','Age',33,...
'Phone','33-33-33');
» whos
Name Size Bytes Class
authors 1x3 440 struct array
Grand total is 28 elements using 440 bytes

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


используя индексирование элементов массива и составные имена соответст-
вующих полей:
» authors(I).Name='Иванов И.И.';
» authors(I).Age=31;
» authors(1).Phone='11-11-11';
» authors(2).Name='Петров П.П.';
» authors(2).Age=32;
» authors(2).Phone='22-22-22';
С помощью функции fieldnames можно получить информацию об именах
полей указанной структуры:
» fieldnames(authors)
ans =
'Name'
'Age'
'Phone'
Типы данных 103

Однако для вывода содержимого полей приходится набирать имя каждой


структуры — элемент соответствующего массива:
>> authors(1)
ans =
Name: 'Иванов И.И.'
Age: 31
Phone: 41-11-11'
» authors(2)
ans =
Name: 'Петров П.П. '
Age: 32
Phone: '22-22-22'
» authors(3)
ans =
Name: 'Сидоров С.С.'
Age: 33
Phone: '33-33-33'

Второй способ, который требует существенно меньших затрат по набору


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

! Пример 3.13. Список ячеек ;


; ....;.....:Л .'.........:.....-. ................;

» authors=struct('Name',{'Иванов И. И.','Петров П. П.',...


'Сидоров С. С.'},'Age',{31,32,33},'Phone',{41-11-11','22-22-22', ...
'33-33-33'});
>> whos
Name Size Bytes Class
authors 1x3 1058 struct array
Grand total is 67 elements using 1058 bytes

Может оказаться полезной и еще одна возможность сформировать массив


структур, содержимое полей которых заполнено одинаковой строкой табли-
цы. Она достигается многократным размножением одной структуры с по-
мощью функции repmat (от англ. repeat matrix — повторить матрицу):
» authors=repmat(struct('Name','Abe','Age',100,...
'Phone','00-00-00'),1,3);
104 Глава 3

Два последних аргумента функции repmat определяют первый и последний


индексы формируемых структур.
В существующем массиве структур легко добавить новое поле путем при-
своения значения в любом элементе массива:
» authors(2).gonorar=1500;

К двум оставшимся записям автоматически добавится поле с именем gonorar,


которое будет временно заполнено пустой матрицей размерности 1x1.
Для удаления ненужного поля из всех записей используется функция
rmfield!
» authors = rmfield(authors,'gonorar');
В качестве значения какого-либо поля структуры может, в частности, вы-
ступать и массив. Тогда, чтобы добраться до конкретного значения в этом
массиве, необходимо использовать два индекса — индекс структуры (напри-
мер, i_s) в массиве структур и индекс конкретного элемента массива (на-
пример, i_f) в заданном поле:
» у = name_ms(i_s).name_f(i_f);
Здесь через names обозначено имя массива структур, а через namef — имя
поля в структуре. Как правило, в качестве индексов выступают либо кон-
кретные числа, либо значения переменных, пробегающие в цикле тот или
иной диапазон. Однако в некоторых задачах и имя массива, и имя поля мо-
жет вычисляться программным путем. Тогда имя нужного компонента будет
представлено неявно — как значение переменной символьного типа. В этом
случае для доступа к значениям полей структуры необходимо использовать
ОДНУ ИЗ функций — getfield ИЛИ putfield:
» у = getfield(var_ms,i_s,var_f,i_f);
» putf ield(var__ms, i_s,var_f, i_f, value);
Параметр value здесь представляет значение, засылаемое в указанное поле.

3.1.6. Массивы ячеек (cell arrays)


Числовые массивы состоят из элементов одного типа. Массивы структур в
простейшем случае представляют набор строк таблицы, устроенной по еди-
ному формату (но в пределах одной записи содержимое полей может быть
разного типа). И тот, и другой тип массивов был хорошо известен в систе-
мах программирования общего назначения. Однако в MATLAB появился
совершенно новый тип массивов c e l l array, в которых каждый элемент
может быть представлен значением любого типа, независимо от типа сосед-
них элементов. Каждый такой элемент называют ячейкой (cell) по аналогии с
электронными таблицами, где каждая клетка может содержать индивидуаль-
Типы данных 105

ное значение любого типа. Конечно, единообразные действия, которые


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

3.1.7. Массивы указателей на функции


(function handle arrays)
Еще одним типом данных, заслуживающим внимания, является класс
functionhandie. С термином handle (произносится — хэндл) многие про-
граммисты сталкивались при работе с файлами при создании подпрограмм
обработки событий в различных визуальных средах. Термин handle пока не
получил единообразной трактовки в отечественной литературе. Под этим тер-
мином скрывается системный способ идентификации некоторых программ-
ных компонентов. Так, например, при работе с файлами вместо их идентифи-
каторов (имен дисковых файлов или их полных спецификаций) в операторах
обмена указывается тем или иным способом созданный handle. Им может
быть конкретное число, которое операционная система присваивает откры-
ваемым файлам (int fi=open...), или указатель на блок управления файлом
(см. в C++ описание типа FILE *fi;). Иногда этот термин именуют дескрип-
тором (т. е. описателем). На наш взгляд, наиболее точно термину handle в рус-
ском языке соответствуют термины указатель или ссылка.
Указатель на функцию (function handle) обеспечивает возможность доступа
ко всей информации, необходимой для вычисления значения этой функции.
Создается такой указатель (а по терминологии MATLAB — массив указате-
лей) одним из двух следующим способов:
» f_h=@funl;
» f_h=str2func('funl')
В результате и той, и другой операции создается указатель f_h, который
"смотрит" на функцию с именем funi. Первый вариант очень напоминает
присвоение адреса переменной указателю соответствующего типа в C++
(int x; i n t *px=&x;). Указатель f_h может быть передан в качестве аргу-
мента другой функции:
>> у = i n t e g r a l ( a , b , f _ h ) ;
Для того чтобы функция integral могла воспользоваться значением функ-
ции funi (x), она использует системную процедуру fevai:
» z = feval(f_h,x);
В фирменных руководствах утверждается, что использование указателей не-
сколько повышает производительность интерпретатора при многократных
обращениях к функции.
106 Глава 3

3.1.8. Логические массивы (logical arrays)


Логические массивы (logical arrays) появляются в результате различных прове-
рок, выполняемых с помощью стандартных функций — i s i e t t e r (проверка
на буквы), isspace (проверка на пробелы), isprime (проверка чисел на про-
стоту) и др. (пример 3.14). Элементы логического массива занимают в памяти
по одному байту, в котором может находиться либо i (логическая истина),
либо о (логическая ложь).

Пример 3.14. Логический массив

» А = [ 2 3 4 5 6 7 8 9] ;
» isprime(А)
ans =
1 1 0 1 0 1 0 0
» who's
Name Size Bytes Class
A 1x8 64 double array
ans 1x8 8 logical array
Grand total is 16 elements using 72 bytes

Другим способом создания логических массивов является использование


логических констант true и false, эквивалентных однобайтовым 1 и 0:
» x=[true false true]
X =
1 0 1
» whos
Name Size Bytes Class
X 1x3 3 logical array
Grand total is 3 elements using 3 bytes

Для создания логических массивов, все элементы которых одновременно


являются либо истиной, либо ложью, можно воспользоваться функциями
true ИЛИ false:

» x=true(2)
X =
1 1
1 1
» y=true(2,3)
Типы данных 107

У =
1 1 1
1 1 1
» z=false( [2 3])
z =
0 0 0
0 0 0
» а=[5 6 ] ;
» v=false(a)
V =
-• 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

Единственный числовой аргумент в указанных функциях задает размерность


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

3.1.9. Создание массивов


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

Таблица 3.4

Тип char int single double logical


char char char char char Запрещено
int char int int int int
single char int single single single
1
double char int single double double
logical Запрещено int single double logical
108 Глава 3

Ниже приводится несколько примеров, заимствованных из справочных


файлов. На наш взгляд, пользоваться такими возможностями не стоит
(пример 3.15).
f • ................................... ....................................... .....^
I Пример 3.15. Экзотическое формирование массивов j
I. •..< ..;..,.,....;..... ,.^.„. ......U.................; .-.'Л.' ........Л.......;..;;;; .... ;

»% Пустой массив в списке значений игнорируется


» А = [5.36; 7.01; []; 9.44]
А =
5.3600
7.0100
9.4400
» % Сочетание данных типа single и double
» х = [single(4.5) single(-2.8) pi 5.73*10A300]
x =
4.5000 -2.8000 3.1416 Inf
» % Сочетание данных типа int8 и double
» x = [int8(21) int8(-22) int8(23) pi 45/6]
x =
21 -22 23 3 8
» % Сочетание данных типа char и double
» x = ['А1 'В1 'С 68 69 70]

ABCDEF
» % Сочетание данных типа logical и double
» х = [true false false pi sqrt(7)]

1.0000 0 0 3.1416 2.6458

3.2. Программа тестирования данных


В состав пакета MATLAB включена программа explore, которая анализиру-
ет тип данных, указанных в качестве аргумента, и отображает значения всех
переменных, относящихся к данному аргументу. Программа эта находится в
каталоге ...\MATLAB7\extern\examples\mex, который надо сделать текущим
перед ее запуском:
» cd('с:\MATLAB7\extern\examples\mex');
» str='Привет';
>> explore(str);
Типы данных 109

Результат работы этого фрагмента таков:

Name: prhs[0]
Dimensions: 1x6
Class Name: char

(1,1) Привет

Предыдущая версия этой профаммы из пакета MATLAB 6.5 в качестве зна-


чения параметра Name выводила имя своего аргумента. В новой версии при
любом аргументе профамма explore почему-то выдает одно и то же. Один
из разделов справочной системы предлагает опробовать профамму на неко-
тором наборе данных разного типа, и приводимый ниже протокол получен
по этой рекомендации:
>> а=[]; % пустой массив
» explore(a);

Name: prhs[0]
Dimensions: 0x0
Class Name: double

» a=[l 2 3 ] ; % вектор-строка
» explore(a)

Name: prhs[0]
Dimensions: 1x3
Class Name: double

(1.1) = 1
(1.2) = 2
(1.3) = 3
» a=[l;2;3]; % вектор-столбец
» explore(a) ;

Name: prhs[0]
Dimensions: 3x1
Class Name: double
110 Глава 3

(1,1) = 1
(2,1) = 2
(3,1) = 3
» а={1 2 3}; % массив ячеек
» explore(a);

Name: prhs[0]
Dimensions: 1x3
Class Name: cell

total num of cells = 3


Cell Element: (1,1)

Dimensions: lxl
Class Name: double

(1,1) = 1
Cell Element: (1,2)

Dimensions: lxl
Class Name: double

(1,1) = 2
Cell Element: (1,3)

Dimensions: lxl
Class Name: double

(1,1) = 3
» explore 1 2 3

Name: prhs[0]
Dimensions: lxl
Class Name: char

(1,1) 1
Типы данных 111

Name: prhs[l]
Dimensions: lxl
Class Name: char

(1,1) 2

Name: prhs[2]
Dimensions: lxl
Class Name: char

(1,1) 3
» a=int8([1 2 3])
>> explore(a);

Name: prhs[0]
Dimensions: 1x3
Class Name: int8

(1.1) = 1
(1.2) = 2
(1.3) = 3
» a=sparse(eye(3)
>> explore(a);

Name: prhs[0]
Dimensions: 3x3
Class Name: sparse

(1.1) = 1
(2.2) = 1
(3.3) = 1
» explore(struct{'Name','Иванов И. И.','Age',31,'Phone', 41-11-11')

Name: prhs[0]
Dimensions: lxl
Class Name: struct
112 Глава 3

(1,1).Name

Dimensions: lxll
Class Name: char

(1,1) Иванов И. И.
(1,1)-Age

Dimensions: lxl
Class Name: double

(1,1) = 31
(1,1).Phone

Dimensions: 1x8
Class Name: char

(1,1) 11-11-11
» explored, 2, 3)

Name: prhs[0]
Dimensions: lxl
Class Name: double

(1,1) = 1

Name: prhs[1]
Dimensions: lxl
Class Name: double

(1,1) = 2

Name: prhs[2]
Dimensions: lxl
Class Name: double

(1,1) = 3
Типы данных 1_13_

3.3. Анализ типа данных


и состояния элементов массивов
Довольно многие системные и пользовательские функции допускают в ка-
честве некоторых параметров данные разного типа. Очевидно, что обработка
таких данных не всегда может вестись по единому алгоритму. Поэтому в
системе MATLAB предусмотрен довольно большой набор функций, выпол-
няющих анализ на принадлежность данных тому или иному классу и кон-
тролирующих состояние объектов (например, на наличие в числовом масси-
ве нечисловых данных или бесконечных значений).
Проверка на принадлежность объекта тому или иному типу данных осуще-
ствляется с помощью функции isa:
а = isa(имя_объекта,'класс');
Функция isa возвращает логическую истину (a=l), если объект с указанным
именем принадлежит заданному классу. В противном случае значением
функции isa является логическая ложь (а=о). Список значений аргумента
•класс1 приведен в табл. 3.5.
Таблица 3.5

Класс Функция i s a проверяет, является ли ее первый аргумент:


char символьным массивом
numeric числовым массивом (целочисленным или вещественным)
logical логическим массивом
int8 массивом однобайтовых целых чисел со знаком
uint8 массивом однобайтовых целых чисел без знака
intl 6 массивом двухбайтовых целых чисел со знаком
uintl6 массивом двухбайтовых целых чисел без знака
int32 массивом четырехбайтовых целых чисел со знаком
uint32 массивом четырехбайтовых целых чисел без знака
int64 массивом восьмибайтовых целых чисел со знаком
uint64 массивом восьмибайтовых целых чисел без знака
single массивом вещественных чисел с одинарной точностью
double массивом вещественных чисел с удвоенной точностью
cell массивом ячеек
struct массивом структур
function_handle массивом указателей на функции
114 Глава 3

В качестве аргумента 'класс' у функции isa может выступать нестандарт-


ный класс, объявленный пользователем. В справочных файлах такая воз-
можность демонстрируется на объекте типа poiynom:
polynom_obj = polynom([l 0 -2 -5] ) ;
isa(polynom_obj, 'poiynom')
ans =
1

Ко второй группе функций, анализирующих свойства своих аргументов,


относятся более 30 процедур. Их единственным аргументом является имя
объекта, значения компонентов которого подвергаются той или иной про-
верке. Размерность результата, возвращаемая любой из этих функций,
совпадает с размерностью аргумента. Проверке подвергается каждый ком-
понент аргумента, и если анализируемое свойство удовлетворяет предна-
значению функции, то в соответствующий элемент результата заносится
логическая истина. В противном случае в соответствующий элемент ре-
зультата заносится логическая ложь. Более подробно специфика некото-
рых функций обсуждается ниже.
Функция i s r e a l (q) проверяет, являются ли элементы массива q веществен-
ными или комплексными числами (пример 3.16). Если хотя бы один эле-
мент указанного массива содержит мнимую часть (даже равную нулю), то
функция i s r e a l возвращает логическую ложь. Если переменная х имеет ве-
щественное значение, то y=compiex(x) представляет комплексное значение
с нулевой мнимой частью. Но i s r e a l (у) =0. Если аргументом функции
i s r e a l является массив ячеек, отдельные элементы которого — комплекс-
ные числа, то в возвращаемом векторе значений нулевые компоненты соот-
ветствуют комплексным ячейкам, а единичные компоненты — всем осталь-
ным (среди остальных компонентов массива могут быть и нечисловые
ячейки).

Пример 3.16. Демонстрация работы функции i s r e a l О

» q{1,1}='Text'; % строка
» q{l,2}=3; % число типа double
>> q{l,3}=magic(2); % массив 2x2 типа double
» q{l,4}=l+i; % комплексное число
» q{l,5}=isreal(pi); % логическое значение
» q
q =
'Text' [3] [2x2 d o u b l e ] [1.0000+ l.OOOOi] [1]
» for j = l : 5 , a ( j ) = i s r e a l ( q { l , j } ) ; end
Типы данных 115

» а
а =
1 1 1 0 1

Функция isnumeric(q) проверяет, являются ли ее аргументы числовыми


данными, в разряд которых причислены вещественные и комплексные
значения (пример 3.17). А вот символы, строки, логические значения,
структуры и массивы перечисленных данных к группе чисел не относятся.
Для приведенного выше массива ячеек q эта проверка дает следующие ре-
зультаты.

I Пример 3.17. Демонстрация работы функции xsnmneric () I

» for j=l:5, a(j)=isnumeric (q{l, j }) ; end


» a
a =
0 1 1 1 0

Функция ischar(q) проверяет, являются ли ее аргументы символьными


данными. Для приведенного выше массива ячеек q эта проверка дает ре-
зультаты, представленные в примере 3.18.

I Пример 3.18. Демонстрация работы функции i s c h a r () . :

» for j=l:5, a(j)=ischar(q{l,j}); end


» a
a =
1 0 0 0 0

Функция islogical(q) проверяет, являются ли ее аргументы данными ло-


гического типа. Для приведенного выше массива ячеек q эта проверка дает
следующие результаты (пример 3.19).

Пример 3.19. Демонстрация работы функции i s l o g i c a l ()

» for j=l:5, a(j)=islogical(q{l,j}); end


» a
a =
0 0 0 0 1
116 Глава 3

Функции i s c e i i ( q ) и i s c e i i s t r ( q ) позволяют узнать, является ли аргумент


q массивом ячеек и представлена ли каждая ячейка строкой (пример 3.20).
• •••••••• ••••••••..••..,•,••••••;••••••• • • . , . . . , . . . . . . . . . . . . . . . . . . . . . ;

; Пример 3.20. Демонстрация работы функций i s c e l l О и i s c e l l s t r () I

» iscell(q)
ans =
1
» iscellstr(q)
ans =
0

С помощью функции i s s t r u c t можно убедиться, является ли ее аргумент


структурой (пример 3.21).

| Пример 3.21. Демонстрация работы функции i s s t r u o t O i

» a.fl='abc';
» a.f2=[0 1 2];
» a.f3=[Cabc'},{0,l,2}];
» a

fl: 'abc'
f2: [0 1 2 ]
f3: {'abc' [0] [1] [2]}
» isstruct(a)
ans =
1
Функция issparse(A) проверяет, является ли матрица А разреженной. Если
это так, то функция возвращает логическую истину.
С помощью функции isempty можно убедиться в том, что ее аргумент пред-
ставлен пустым массивом (пример 3.22).

i Пример 3.22. Демонстрация работы функции isempty () :

» х=[];
>> isempty(х)
ans =
1
Типы данных 117

Функции isfinite(A), i s i n f (А) и isnan (А) анализируют значения элемен-


тов вещественного массива А И ВЫЯСНЯЮТ, какие из них принадлежат
к допустимому диапазону числовых значений (Finite — конечный), к бес-
конечным значениям ( i n f i n i t e — бесконечный), к неопределенным значе-
ниям (NaN — Not a Number) — пример 3.23. ,
. , , , . ... , -••-••• -

! Пример 3.23. Демонстрация работы функций i s f i n i t e { ) , i s i n f () и i s n a n () I

» x=[l 0 inf nan];


» y=l./x
Warning: Divide by zero.
У=
1 Inf 0 NaN
» zf=isfinite(y)
zf =
1 0 1 0
» zi=isinf(y)
zi =
0 1 0 0
» zn=isnan(y)
zn =
0 0 0 1

Для выделения букв в символьной строке или в символьном массиве можно


воспользоваться функцией i s l e t t e r (пример 3.24).

| Пример 3.24. Демонсл рация работы функции i s l e t t e r {)

» х='а1Ь2сЗ';
» isletter(x)
ans =
1 0 1 0
» y=['al';'Ь2';'сЗ']
У=
al
Ь2
сЗ
118 Глава 3

» isletter(y)
ans =
1 О
1 О
1 О

Функция isprime(Й) выясняет, какие элементы массива А ЯВЛЯЮТСЯ про-


стыми числами. Проверяемые числовые значения должны быть положи-
тельными целыми и не превосходить по величине 2 32 . В противном случае
функция isprime выдает сообщение об ошибке. К спорному моменту отно-
сится значение isprime(l)=o. Ряд математиков относит единицу к простым
числам, т. к. она не имеет других делителей кроме 1 и самой себя.
С помощью функции issorted(v) можно проверить, упорядочены ли по
возрастанию компоненты числового или символьного вектора v
(пример 3.25). Если первым аргументом этой функции является двумерный
массив — issorted(A, 'rows'), — то проверка упорядоченности распростра-
няется на каждый столбец матрицы А.

; Пример 3.25. Демонстрация работы функции i s s o r t e d () :

» а=[1 2 3 4 5];
» issorted(а)
ans =
1
» Ь=[5 4 3 2 1];
» issorted(Ь)
ans =
О
» с='abc';
» issorted(с)
ans =
1
» d='bac';
» issorted(d)
ans =
0
» e=[l 2 3; 2 3 4]
Типы данных 119

е =
1 2 3
2 3 4
>> i s s o r t e d ( e , ' r o w s ' )
ans =
1

3.4. Редактирование массивов


Массивы, сформированные вручную или полученные в результате вычисле-
ний, хранятся в рабочем пространстве (workspace). Любой из них или не-
сколько одновременно могут быть подвергнуты коррекции с помощью Array
Editor (Редактор массивов). Последний вызывается двойным щелчком по
имени массива в рабочем пространстве (рис. 3.2).

Top/Bottom Split- Maximize


Left/Right Split Float -i
Tile

File Edit Ve i w Graphc


i s Debug Desktop Wn
idow Hep
l
Shortcus II How to Add'£Wa St'tNew в Array Editor \ \ \

I value j Pass
[100,200] double
[1 2 3,4 5 6] double

Рис. З.2. Редактирование массивов А и В

Для размещения двух или более массивов поле редактора можно разбить
несколькими способами с помощью управляющих кнопок:
• Tile — в клетках матрицы;
• Left/Right Split — в вертикальных колонках;
5 Зак. 899
120 Глава 3

П Top/Bottom Split — в горизонтальных полосках;


• Float — друг за дружкой;
• Maximize — текущая таблица занимает все поле.
Для изменения значения элемента массива необходимо либо с помощью
клавиш управления курсором, либо используя мышь, выделить нужную
ячейку и набрать в ней новое значение. Ввод изменяемого числа завершает-
ся нажатием клавиши <Enter>. Новое значение немедленно отображается в
соответствующей позиции колонки Value (Значение) в рабочем пространст-
ве (рис. 3.3).

LkMATIAB ЩШЯКЩ И_|п|х|


File Edit View Graphics Debug Desktop Window Help
Shortcuts ?J How to Add >] What's New

Worfcspac r x «[Array Editor


"3
% Й © «a# , | % lЩ • 1 ,(5Й >•! * %
x
; N a m e "••
"' Value Cites
ЦБ ' 1
Вв [100,20] double
1" ..2,. v L •, 3 1 2 •

BA [1 2 3,4 5 6] double i 1 ioo


Щ~ 7.4 20
3
1 3j
4 i
4

Command Window * x _sj 5

>> A=[l 2 3; 4 5 6] .- - _
— 7 ! 7

A= 81 8

1 2 3 9j 9

4 5 6 m, 10

11 ; 11
» B=[100 ;200]
12 ; I" 1
в=
100
> ЛИ JLJ
200 I

РИС. 3.3. Изменение значения В (2)

Окно с тем или иным массивом можно снять с якоря и перетащить на более
удобное место. В этом случае к окну автоматически приклеивается меню
(рис. 3.4). С помощью команды View | Numeric Array Format (Вид | Формат:
числовой массив) можно выбрать подходящий формат отображения число-
вых данных. Команды меню Desktop (Рабочий стол) позволяют вновь поста-
вить на якорь текущее окно или все окна-массивы, находящиеся в свобод-
ном плавании.
Типы данных 121

( ^Замечание }
С помощью Array Editor (Редактор массивов) можно изменять векторы или
матрицы. Массивы более высокой размерности в этом редакторе не обрабаты-
ваются.

_Ja|X!
File Edit |View. Graphics'Debug Desktop Window Help
Numeric Array Format > * short
-••, и . " i i i One short£
shortG
20
long
longE
longG
_ __ hex
bank
+• • :
rational

Рис. З.4. Окно с массивом В, снятое с якоря


Глава 4

Программирование
вычислительных процессов
До сих пор мы использовали командное окно MATLAB в режиме диалога
пользователя с системой. Пользователь набирал в текущей строке очередную
команду и нажимал клавишу <Enter> — система выполняла соответствую-
щее действие и, при необходимости, выдавала результат этого действия. Все
набираемые команды повторялись в окне Command History (История
команд) и запоминались в специальном стеке, откуда могли извлекаться для
повторного выполнения ранее набранных действий или для формирования
похожих команд. Однако такой пошаговый режим хорош только для разо-
вого расчета. Даже повторение одной и той же вычислительной схемы с не-
большой модификацией алгоритма или с изменением исходных данных в
пошаговом режиме превращается в обременительное занятие.

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


В простейшем случае мы могли бы включить ту же самую цепочку команд в
текстовый файл, записать его на диск, а затем вызвать и уже автоматически
выполнить, не нажимая клавишу <Enter> после очередной команды. По-
добного рода программы по терминологии MATLAB принято называть
скриптами (scripts). В книгах некоторых российских авторов для их обозна-
чения используют термин сценарий, хотя с этим словом ассоциируются со-
вершенно другие понятия. Главной особенностью скриптов является то, что
они работают только с переменными Workspace (Рабочее пространство).
Скрипт может извлекать данные из файлов, запрашивать их у пользователя,
обращаться к любым стандартным и нестандартным функциям. Несколько
скриптов могут работать последовательно друг за другом, передавая данные
следующему скрипту через общее рабочее пространство или запоминая
промежуточные результаты в файлах. Однако отсутствие локальных пере-
менных в скриптах затрудняет Создание цепочек программ из-за необходи-
мости согласованного использования общих переменных. Скрипт может
быть подготовлен в любом текстовом редакторе и записан в дисковый файл
124 Глава 4

с расширением т . Однако MATLAB располагает собственным редактором


m-файлов, который вызывается командой File | New | M-File (Файл | Создать |
М-файл) — рис. 4.1.

k». MATLAB
File Edit Debug Desktop Window Help

Open...:: •' , . •• •:.'-.•• Ctri+O figure


Close Command Window Variable
ImportData... •}'•• '' Model
:
Save Workspace As.,. Ctrl+S GUI:
Я Editor - Untitled*
File Edit Text Cell Tools Debug Desktop Window Help
'
1 a-1
i T r T
2 foe i=l:5
3 a=a*i
4 end
5 a

Рис. 4 . 1 . ОКНО редактора кода.

Строки, набираемые в окне редактора, автоматически нумеруются. Это по-


зволяет идентифицировать сообщения об ошибках набора, выдаваемых в
командное окно. Обратите внимание на специфику набора строк програм-
мы. Если в языке С каждый оператор завершался точкой с запятой, то в
языке MATLAB точка с запятой в конце оператора подавляет вывод резуль-
тата. Вторая неожиданность — формат оператора цикла, который на С вы-
глядел бы следующим образом:
for(i=l; i<=5; i++)

По аналогии с языками Fortran и Basic единичное приращение управляю-


щей переменной цикла можно опускать (более полный формат MATLAB —
for i = i : i : 5 ) . Наконец, еще одно наследие Basic, в,котором тело цикла FOR
завершается оператором NEXT. В MATLAB нет операторных скобок, таких
как в С и Pascal, в которые заключаются операторы, образующие тело цик-
ла. Поэтому для определения его конца необходимо использовать оператор
end. Этим же оператором в MATLAB завершаются и другие структурные
единицы (if, switch, try, while).

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

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


команду Run (Запуск) в меню Debug (Отладка) или нажать клавишу <F5>.
Результаты его работы появятся в командном окне, т. к. никаких других
окон для визуализации результатов расчета мы не предусмотрели:
а =
120

Для запоминания программы, набранной в окне редактора кода, можно


воспользоваться командой File | Save As (Файл | Сохранить как). Пример,
приведенный выше, мы запомнили под именем fact5. Для его повторного
выполнения в текущей строке командного окна достаточно набрать имя
файла:
» fact5

120

Более удобной разновидностью m-файлов являются функции, первой стро-


кой которых является заголовок, использующий оператор function. В отли-
чие от скриптов, функции могут получать исходные данные в виде списка
входных параметров и возвращать результаты своей работы также в виде
списка выходных параметров. Если некоторые переменные Workspace
(Рабочее пространство) объявлены глобальными (оператор global) и такое
объявление global с указанием имен общих переменных присутствует в теле
функции, то функция имеет доступ к указанным переменным. Эта идея в
явном виде заимствована из Fortran, хотя там был разработан более гибкий
механизм блоков общей памяти (оператор COMMON), ПОЗВОЛЯВШИЙ общаю-
щимся модулям называть общие переменные по-разному, сохраняя их поря-
док и тип данных в общих блоках. И только имена блоков у них должны
были называться одинаково.
Одной из самых важных особенностей функций является аппарат локальных
переменных. Все переменные, появляющиеся в теле функции, за исключе-
нием глобальных переменных, входных и выходных параметров, считаются
локальными. Они образуют локальное рабочее пространство и доступны
только в теле породившей их функции, и никакие скрипты или другие
функции воспользоваться ими не могут. Это развязывает руки при написа-
нии программ-функций, т. к. имена локальных переменных не надо ни с
кем согласовывать.
При написании программ-функций требуется, чтобы имя m-файла, в кото-
ром запоминается программа, обязательно совпадало с именем функции.
Пример более универсальной программы, вычисляющей ы , может быть на-
126 Глава 4

писан так, как представлено в примере 4.1, и должен быть сохранен под
именем factn.m.

.Пример 4.1. Функция вычисления факториала

function y=factn(n)
k=l;
for(i=l:n)
k=k*i;
end
y=k;

Для вычисления 5! достаточно набрать в текущей строке команду:


»k=factn(5)
к=
120
»

В любом m-файле, подобно языку C++, можно описать несколько функций.


Самая первая из них обладает тем преимуществом, что ее можно вызвать извне.
Все остальные функции считаются внутренними и доступны только в рамках
данного т-файла. Их принято называть подфункциями (subfunctions).
Система MATLAB выполняет m-файлы, как правило, в режиме интерпрета-
ции, что существенно снижает скорость решения задач по сравнению с воз-
можностями компилирующих систем. С целью повышения производитель-
ности MATLAB в режиме интерпретации использует промежуточный
псевдокод (так называемый p-code — от англ. pseudocode). Происходит такая
замена исходного текста при первом обращении к скрипту или функции.
Псевдокод позволяет свести к минимуму работу по синтаксическому разбо-
ру многократно выполняющихся операторов программы. Особенно это важ-
но при повторных вызовах функций. Псевдокод остается в памяти либо до
конца сеанса, либо до очистки оперативной памяти с помощью одной из
команд:
clear имя_функции % удаление конкретного псевдокода
clear functions % удаление псевдокодов всех функций
clear all % удаление всех функций и переменных

Любой ni-файл может быть превращен в псевдокод с помощью процедуры


pcode:

pcode имя_т-файла
Программирование вычислительных процессов 127

Результатом ее работы является двоичный файл с тем же именем и расши-


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

4.2. Специфика выполнения операций


При составлении алгебраических выражений MATLAB разрешает использо-
вание традиционных знаков арифметических операций и символов специ-
альных операций, полный список которых приведен в табл. 2.3.
Но даже такие традиционные операции, как сложение, в выражениях
MATLAB выполняются особым способом. Самым привычным является
сложение скалярных величин (т. е. массивов размерности 1x1), соответст-
вующее аналогичному действию в большинстве алгоритмических языков.
Если обоими операндами являются массивы одинаковой размерности, то
осуществляется покомпонентное сложение элементов с одинаковыми ин-
дексами. Такой подход в свое время наблюдался в ранних версиях Basic,
включавшего операторы типа МАТ А=В+С. Однако если в MATLAB к массиву
любой размерности добавляется скалярная величина, то она добавляется к
каждому элементу массива. По сути дела, добавляемое скалярное значение
преобразуется в массив такой же размерности, что и первое слагаемое
(аналог приведения типов в выражениях с разнокалиберными операндами),
и каждый элемент расширенного массива равен этому значению. Попытку
сложить массивы разной размерности (за исключением случая, когда один
из операндов — массив 1x1) система пресекает с выдачей соответствующего
сообщения об ошибке.
Аналогичное приведение типов выполняется для большинства операций,
когда одним из операндов является массив, а вторым — скаляр.
При выполнении логических операций над числами действует соглашение,
принятое в С, — ненулевые значения рассматриваются как истина, а нуле-
вые как ложь. В качестве небольшой странности языка MATLAB отметим,
что такая распространенная логическая операция, как исключающее ИЛИ,
здесь подключена в виде функции хог (х, у).

4.3. Синтаксис операторов MATLAB


Входной язык MATLAB насчитывает всего 9 операторов, использующих
14 служебных слов. Соответствующие синтаксические конструкции приве-
дены в табл. 4.1.
128 Глава 4

Таблица 4.1
№ Формат оператора Пояснение
var = expr Оператор присваивания. Вычисляет значения вы-
ражения expr и заносит результаты вычислений в
переменную v a r
if условие_1 Условный оператор. Если справедливо усло-
операторы_1 вие_1, то выполняется группа операторы_1, если
справедливо условие_2, то выполняется группа
[elseif условие_2
операторы_2, ... Если все указанные условия ока-
операторы_2 зываются ложными, то выполняются операторы,
elseif условие_3 расположенные между e l s e и end
операторы_3

else
операторы ]
end
switch expr Переключатель по значению выражения expr.
case vail Если оно совпадает с величиной v a i l , то выпол-
няется группа операторы_1, если оно совпадает с
операторы_1
величиной v a l 2 , то выполняется группа операто-
case val2 ры_2, ... Если значение expr не совпадает ни с
операторы_2 одной из перечисленных величин, то выполняются
операторы, расположенные между o t h e r v i s e и
end
[ othervise
операторы]
end
for var=el:[e2:]e3 Цикл типа арифметической прогрессии, в котором
операторы переменная v a r при каждом повторении тела цик-
ла изменяется от начального значения e l с шагом
end
е2 до конечного значения еЗ
while условие Цикл с предусловием, повторяющийся до тех пор,
операторы пока истинно указанное условие
end
try Попытка выполнить группу операторы_1. При ус-
операторы_1 ловии, что в результате их выполнения возникает
исключительная ситуация, управление передается
catch
группе операторы_2 (обработка сбойных ситуа-
операторы 2 ций). Если ошибка не возникла, то группа опера-
end торы_2 не выполняется
break Досрочный выход из управляющих конструкций
типа f o r , w h i l e , s w i t c h , t r y - c a t c h
Программирование вычислительных процессов 129_

Таблица 4.1 (окончание)

№ Формат оператора Пояснение


8 function f 1 Заголовок функции
function ( x l , х2, ... - входные параметры; y l , у2, ... -
f2 ( x l , х 2 , . . . ) выходные параметры)
function
y=f3(xl,x2,...)

function
[yl,y2,...]=f4(xl,x2,
. . .)
g return Досрочный выход из тела функции

Для ярых поклонников Дейкстры отметим, что язык MATLAB не содержит


оператора goto. В связи с этим в текстах m-файлов отсутствуют метки опе-
раторов. Для идентификации строк, в которых возникают аварийные ситуа-
ции, используются внутренние номера, присваиваемые системой автомати-
чески.
Комментарии в m-файлах начинаются с символа %. Они могут располагаться
с начала строки или находиться правее любого оператора. Однако при
оформлении m-файлов начальные комментарии выполняют особую роль.
Первая группа строк с подряд идущими комментариями до пустой строки
образует текст, выдаваемый в командном окне по команде help с именем
m-файла. Добавим, например, к приводившейся выше программе вычисле-
ния 5! комментарий (пример 4.2) и сохраним файл fact5.m.

[Пример 4.2. Комментарий-подсказка ;

% Эта программа находит 5!

а=1;
for i=l:5
a=a*i;
end
a

Если в текущей строке командного окна обратиться за помощью к этой яв-


но несистемной функции, то MATLAB выдаст начальный комментарий:
» help fact5
Эта программа находит 5!
130 Глава 4

Обратите внимание, насколько тщательно оформляются системные т -


файлы. В качестве примера мы выбрали программу определения корней по-
линома roots.m, расположенную в каталоге c:\MATLAB7\toolbox\MATLAB\
polyfun:
function r = roots(с)
%ROOTS Find polynomial roots.
% ROOTS(С) computes the roots of the polynomial whose coefficients
% are the elements of the vector C. If С has N+l components,
% the polynomial is С(1)*Х Л Ы + ... + C(N)*X + С(N+l).
%
% Class support for input c:
% float: double, single
%
% See also POLY, RESIDUE, FZERO.

% J.N. Little 3-17-86


% Copyright 1984-2004 The MathWorks, Inc.
% $Revision: 5.12.4.2 $ $Date: 2004/03/02 21:48:05 $

% ROOTS finds the eigenvalues of the associated companion matrix.

if size(c,l)>l & size(c,2)>l


error('MATLAB:roots:NonVectorInput', 'Input must be a vector.')
end
с = c(: ) . ' ;
n = size(c,2);
r = zeros(0,1,class(c));

inz = find(c);
if isempty(inz),
% All elements are zero
return
end

% Strip leading zeros and throw away.


% Strip trailing zeros, but remember them as roots at zero.
nnz = length(inz);
с = с(inz(1):inz(nnz));
r = zeros(n-inz(nnz),1);
Программирование вычислительных процессов 131

% Polynomial roots via a companion matrix


n = length(c);
if n > 1
a = diag(ones(l,n-2) , -1) ;
a(l, :) = -c(2:n) ./ c(l);
r = [r;eig(a)];
end

Справка, выдаваемая системой в командное окно, имеет вид:


>> help roots

ROOTS Find polynomial roots.


ROOTS(C) computes the roots of the polynomial whose coefficients
are the elements of the vector C. If С has N+l components,
the polynomial is C(1)*XAN + ... + C(N)*X + С(N+l).

Class support for input c:


float: double, single

See also POLY, RESIDUE, FZERO.

Как видите, в выдаваемом кадре помощи могут находиться пустые строки,


соответствующие пустым комментариям (т. е. строкам, содержащим единст-
венный символ %). Обратите внимание на то, что функция roots может ра-
ботать не только с обычными данными типа double, но и с коэффициента-
ми одинарной точности (типа single).
Комментарий в строке, начиная с символа %, является не единственной
возможностью для включения пояснений в текст программы. Мы уже упо-
минали, что текст, расположенный в строке правее символов переноса (три
точки), тоже воспринимается как комментарий. Во входном языке MATLAB 7
появилась возможность включения многострочного комментария. Ему обя-
зательно должна предшествовать строка, содержащая только два символа — % {.
Признаком конца многострочного комментария является строка, содержа-
щая также два символа — %}:
%{
Первая строка комментария
Вторая строка комментария
132 Глава 4

Многострочный комментарий может включать в себя вложенный много-


строчный комментарий. С помощью признаков начала и конца многостроч-
ного комментария можно отключать фрагменты программы во время ее от-
ладки.
В арифметических выражениях помимо операндов-массивов допустимо
смешение типов данных. Например, к числовому значению можно приба-
вить значение типа char. MATLAB заменит символьное значение его число-
вым ASCII-кодом и выполнит предписанное действие, несмотря на кажу-
щуюся несуразность такой операции:
» х=5+'а'
х = .
102

Множественное присваивание, допустимое во многих языках программиро-


вания, в MATLAB запрещено:
» а=Ь=2;
??? Error: Assignment statements cannot produce a result.
» whos

Зато набрать в одной строке несколько операторов присваивания, разделяя


их запятыми или точками с запятыми, не возбраняется (пример 4.3).

I Пример 4.3. Оператор присваивания


» х=2; у=3;
» х
X =
2
» У
У =
3
» х=2, у=3
х =
2
У =
3

В условных операторах некоторый протест со стороны пользователей может


вызвать возможность сравнения комплексных чисел. С точки зрения мате-
матики комплексные данные можно сравнивать либо на равенство, либо на
Программирование вычислительных процессов 133

неравенство. Это соответствует и геометрическому представлению комплекс-


ных чисел как точек на плоскости: координата х совпадает с вещественной
частью числа, а координата у — с мнимой. Но никому не приходит в голову
утверждать, что точка (10, 0) больше, чем точка (5, 4). Наиболее естествен-
ные отношения двух точек — одна точка находится левее или правее другой,
расположена выше или ниже. A MATLAB при сравнении комплексных чи-
сел допускает использование операции отношения "больше", "меньше" и
сопоставляет при этом только вещественные части.
Большинство операторов языка MATLAB напоминает аналогичные конст-
рукции языка C++. Одна из немногих особенностей — завершение управ-
ляющих конструкций оператором end — вряд ли смутит программистов, ос-
воивших даже базовые операторы языка С. Наиболее существенные детали
связаны с программированием функций, допускающих переменное число
аргументов, среди которых могут встречаться массивы, и четкое разделение
параметров на входные и выходные. Этим особенностям и специфике пере-
дачи параметров разного типа мы посвятим отдельный раздел.

4.4. Ввод числовых


и символьных данных
Простейший способ ввода числовой и символьной информации, набирае-
мой на клавиатуре, использует функцию input. Она допускает два формата
обращения, первый из которых:
х = input('приглашение')
В ответ на приглашение, выданное программой, пользователь может набрать
требуемое значение или ввести выражение, величина которого будет под-
считана с учетом текущего состояния переменных рабочего пространства и
возвращена в качестве значения функции. Если пользователь в ответ на
приглашение нажимает только клавишу <Enter>, то функция возвращает
пустой массив типа double размером 0x0. Обратите внимание на то, что
текст приглашения выдается в начале следующей строки. Если вы не хотите
набирать вводимую информацию вплотную к подсказке, то можно предва-
рительно нажать клавишу <Пробел> или переместить курсор соответствую-
щей клавишей-стрелкой. А можно предусмотреть дополнительный пробел в
тексте приглашения.
Второй формат обращения к функции input имеет вид:
х = input('приглашение','s')

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


символов, которая и возвращается в качестве значения функции. В обоих
случаях текст приглашения может содержать символы \п, управляющие пе-
134 Глава 4

реводом курсора в начато следующей строки. Это обеспечивает, в случае


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

4.5. Вывод результатов вычислений


Для вывода значения выражения, в частном случае которого может быть
имя любой переменной, достаточно не набрать после него символ "точка с
запятой", подавляющий выдачу результата. В других случаях можно прибег-
нуть к функции disp (от англ. display — отобразить), которая отличается от
автоматического вывода только тем, что не выводит имя отображаемого зна-
чения — имя переменной, которой присваивается результат вычислений,
или имя системной переменной ans:
disp(выражение)

В частном случае аргументом функции disp может быть строка, заключен-


ная в одинарные кавычки.
Функциями error или warning можно воспользоваться для выдачи сообще-
ния об ошибке или предупреждения. Их основным аргументом является
текст сообщения, после вывода которого работа программы будет либо за-
вершена (использована функция error), либо продолжена (использована
функция warning) — пример 4.4.

: Пример 4.4. Предупреждение и сообщение об ошибке j

>> warning('Предупреждение !')


Warning: Предупреждение !
» error('Ошибка')
??? Ошибка

Вообще говоря, функция warning обладает гораздо более широкими воз-


можностями и напоминает функцию cprintf в языке C++. Ее общий фор-
мат таков:
warning('name w','format',список)

Строка name_w используется в качестве идентификатора группы сообщений.


При необходимости вывод всех сообщений одной группы можно заблокиро-
вать, обратившись к процедуре warning следующим образом:
warning('off','name_w')

При этом не понадобится удалять все строки, содержащие сообщения дан-


ной группы.
Программирование вычислительных процессов 135

Если снова понадобится включить эти сообщения, то вызывается процедура


warning с параметром on:
1
warning('on ,'name_w')

Строка format используется для форматных преобразований элементов вы-


водного списка, и ее запись в точности повторяет форматные спецификации
языка C++:
warning('qq:','x=%d y =% 8 . 4 f ' , х , у )

Более подробно все форматные преобразования описаны в функции sprintf.

4.6. Типы функций


Существует несколько разновидностей m-функций. В разд. 4.1 мы познако-
мились с головными функциями, имена которых совпадают с именами т -
файлов. В фирменной документации они фигурируют под названием
"первичные М-файлы" (Primary M-File Functions). К ним можно обращаться
из других функций или из строк Command Window (Окно команд), переда-
вать им параметры. Характерной особенностью m-функций является нали-
чие индивидуального рабочего пространства — механизма локальных пере-
менных. Наряду с последними, m-функции могут использовать переменные
из других рабочих пространств, где эти общие переменные объявлены как
глобальные.
Вторую разновидность m-функций составляют подфункции (subfunctions),
описания которых расположены в m-файле вслед за головной функцией.
Подфункции т-файла не могут быть вызваны извне. Это своего рода функ-
ции внутреннего пользования. Они могут общаться между собой в пределах
m-файла и обращаться к другим головным функциям, расположенным в
других m-файлах. Цепочку вызовов подфункций инициирует головная
функция т-файла.
В предыдущих версиях MATLAB преобладала идеология, близкая к языку С,
в результате которой каждая функция выступала в роли отдельного кирпи-
чика — вложения функций друг в друга не допускались. Седьмая версия
сделала шаг навстречу языку Pascal и разрешила использование вложенных
функций:
function yl=fl(pl,p2)

function y2=f2(x,z) % вложена в функцию fl

function y3=f3(a,b) % вложена в функцию f2


136 Глава 4

end % конец функции f3

end % конец функции f2

end % конец функции fl

При вызове вложенных функций соблюдается общепринятое правило: к


вложенной функции может обращаться только непосредственно окаймляю-
щая ее функция. В приведенном выше примере функция fl может вызвать
функцию f2, но не может напрямую обратиться к функции f3.
Вообще говоря, внятного объяснения по поводу преимуществ вложенных
функций авторы MATLAB 7 не дали. До сих пор идеи, заложенные в
Fortran, не признававшем вложенных функций, и в Algol, разрешавшем
вложения, сосуществовали параллельно. В MATLAB 7 было решено их объ-
единить, но пока не ясно, зачем.
Кроме вложенных (nested functions) в 7-й версии появились анонимные
(anonymous functions) функции. По сути дела, у этих функций нет собствен-
ного имени, вместо которого используется указатель функции. Формат их
объявления таков:
h__F=@ (список_параметров) формула

Очевидно, что описания функций такого типа имеют смысл при работе с
достаточно простыми формулами. Например, анонимная функция возведе-
ния в квадрат с указателем sqr может быть описана и использована сле-
дующим образом:
» sqr = @(х) х.Л2;
» s q r ( [ l 2 чЗ])
ans =
1 4 ' 9

С точки зрения пользователя эта анонимная функция ничем не отличается


от обычной функции с именем sqr. Однако мы допускаем, что реализация
анонимной функции более эффективна.
Указатель на анонимную функцию может быть передан другим функциям в
качестве параметра. Например, мы можем обратиться к функции вычисле-
ния определенного интеграла от х2 на интервале от о до 1 следующим обра-
зом:
» quad(sqr, 0, 1)
ans =
0.3333

Часть m-функций может быть помещена в каталог со специальным именем


private. Эти функции будут доступны только из родительского каталога, со-
Программирование вычислительных процессов 137

держащего каталог private. Функции, хранящиеся в этом каталоге, считаются


частными (private functions). Основное их назначение — заменить некоторые
системные функции одноименными пользовательскими. MATLAB начинает
поиск вызываемых функций с каталога private, поэтому они вызываются в
первую очередь.
Наконец, следует упомянуть еще об одной группе функций, для которых в
литературе используется не очень удачный термин — перегружаемые функ-
ции (overloaded functions). В объектно-ориентированном программировании
широко используется возможность определять несколько функций с одина-
ковыми именами, которые отличаются друг от друга либо количеством па-
раметров, либо их типами, либо типом возвращаемого значения. Компиля-
тор анализирует очередное обращение к функции и вызывает ту из них,
которая соответствует шаблону вызова.

4.7. Параметры функций


Почти все универсальные алгоритмические языки объединяют входные и
выходные аргументы функций в общие скобки и возвращают в качестве
своего значения единственный результат, обычно присваиваемый имени
функции. Большинство алгоритмических языков использует позиционный
принцип задания аргументов — каждый аргумент расположен на фиксиро-
ванном месте в списке параметров. Только некоторые системы (в частности,
ассемблер) наряду с позиционными аргументами позволяют использовать
ключевой способ задания параметров в форме имя=значение. Ключевые па-
раметры всегда располагаются вслед за списком позиционных аргументов и
могут следовать в любом порядке. Вызывающая функция обычно передает
свои параметры через стек, помещая туда значения или адреса соответст-
вующих аргументов. Существуют два принципиально разных способа записи
параметров в стек — один из них в стиле С (модификатор cdeci) первым
заносит в стек последний аргумент списка, а второй в стиле языка Pascal
(модификатор pascal) первым заносит в стек первый аргумент списка.
Обычно с этим приходится считаться в тех случаях, когда фрагменты про-
граммы реализованы в разных системах программирования. Для функций,
допускающих переменное число параметров, программист или система
программирования наряду с фактическими аргументами функций должны
помещать в стек либо количество передаваемых параметров, либо завершать
их список обусловленным признаком конца.
В языке MATLAB входные и выходные аргументы функций четко разделе-
ны. Все входные параметры используют только позиционный принцип и
задаются в круглых скобках после имени функций. Все выходные параметры
объявляются как массив результатов и в операторах присваивания обычно
записываются в квадратных скобках. Программистам, работающим на языке
138 Глава 4

C++, известно, что иногда функции могут иметь переменное число пара-
метров (список формальных аргументов в заголовке функции завершается
многоточием), и для создания такого рода программ используются специ-
альные средства — функции (точнее, макроопределения) va_start, vaend,
v a a r g , v a i i s t . Нечто похожее имеется и в языке MATLAB. Хотя пере-
менное число параметров, как входных, так и выходных для m-файлов, ско-
рее, является правилом, нежели исключением.
MATLAB упаковывает все входные параметры в массив ячеек с именем
varargin и запоминает количество передаваемых функции аргументов в
глобальной переменной nargin. Функция, возвращающая переменное число
значений, обычно начинается с заголовка:
function [varargout] = имя_функции(аргументы)

Это означает, что результаты работы функции должны присваиваться ком-


понентам массива ячеек varargout. К таким образом определенной функ-
ции можно обращаться с разным количеством выходных параметров:
[yl,у2,уЗ] = имя_функции(аргументы)
[zl,z2] = имя_функции(аргументы)
wl = имя функции(аргументы)

В первом случае переменной yi будет присвоено значение ячейки


varargout{1}, переменной у2 — значение ячейки varargout(2}, перемен-
ной уз — значение ячейки varargout{3}. Во втором случае будут использо-
ваны значения первых двух ячеек, в третьем случае — единственное значе-
ние первой ячейки массива varargout. Чтобы функция вычисляла только
требуемое количество результатов, ей сообщают в глобальной переменной
nargout фактическое число запрашиваемых данных.
Для контроля за допустимым количеством входных и выходных аргументов
m-фуНКЦИИ могут ИСПОЛЬЗОвать функции nargchk И nargoutchk:
msg = nargchk(min, max, nargin);
msg = nargoutchk(min, max, nargout);
Обе функции формируют сообщение msg о недопустимом числе входных
или выходных параметров, которое можно вывести с помощью функции
error (msg). Если количество параметров принадлежит диапазону [min, max],
то сообщение msg представлено пустой строкой и сообщения об ошибке не
последует.
Продемонстрируем использование описанных глобальных переменных на
примерах, которые мы заимствовали из файлов помощи, но слегка модифи-
цировали в сторону упрощения.
Программирование вычислительных процессов 139

Функция polyline.m получает массив переменной длины с координатами то-


чек (xl,yl), (х2,у2) и т. д. и строит ломаную линию, соединяющую эти
точки (пример 4.5).

i Пример 4.5. Построение ломаной линии !

function polyline(varargin)
for k=l:length(varargin)
x(k)=varargin{k}(1);
у(k)=varargin{k}(2) ;
end
axis([min(x) max(x) min(y) max(y)])
plot (x,y)

Результат обращения к этой функции с шестью следующими точками:


» p o l y l i n e ( [ 2 3 ] , [1 5 ] , [ 48 ] , [ 65] , [ 42 ] , [ 2 3 ] )

приведен на рис. 4.2.

Рис. 4 . 2 . Полигон из 6 точек

Результат обращения к этой же функции с другим количеством точек:


polyline([-1 0],[3 -5],[4 2 ] , Ц 1 ] )

приведен на рис. 4.3.


Функция array2vec получает массив размерности лх2, первый столбец ко-
торого содержит координаты xl, х2, ..., а второй — координаты yi, y2, ...
Задача функции разнести строки матрицы по выходным векторам, содер-
140 Глава 4

жащим координаты соответствующих точек— (xl,yl), (х2,у2),... (при-


мер 4.6).

Рис. 4.3. Ломаная линия из 4 точек

Пример 4.6. Передача аргументов функции

function [varargout] = array2vec(a)


for k=l:nargout
varargout(k}=a(k, :) ;
end

Результат двух последовательных обращений с разным количеством выход-


ных параметров приведен ниже:
» а1={1 2; 3 4; 5 6; 7 8; 9 10; 11 12};
» [pi p2]=array2vec(al)
pi =
[1] [2]
р2 =
[3] [4]
>> [ql q2 q3 q4 q5]=array2vec(al)
ql =
[1] [2]
q2 =
[3] [4]

[5] [6]
Программирование вычислительных процессов 141

q4 =
[7] [8]
q5 =
[9] [10]
» whos
Name Size Bytes Class

al 6x2 816 cell array


pi 1x2 136 cell array
p2 1x2 136 cell array
qi 1x2 136 cell array
q2 1x2 136 cell array
q3 1x2 136 cell array
q4 1x2 136 cell array
q5 1x2 136 cell array

Если в качестве входного параметра передать обычный числовой массив, то


результатом работы той же функции будут обычные числовые векторы:
» al=[l 2; 3 4; 5 6; 7 8; 9 10; 11 12];
» [pi p2]=array2vec(al)
pi =
1 2
р2 =
3 4
» [ql q2 q3 q4 q5]=array2vec(al)
ql =
1 2
q2 =

q3 =

q4 =

q5 =
9 10
» whos
Name Size Bytes Class
al 6x2 96 double array
Pi 1x2 16 double array
142 Глава 4

Р2 1x2 • 16 double a r r a y
qi 1x2 16 double a r r a y
q2 1x2 16 double a r r a y
q3 1x2 16 double a r r a y
q4 1x2 16 double a r r a y
q5 1x2 16 double a r r a y

Библиотека раздела s t r i n g . h в системе программирования Borland C++


включает функцию s t r t o k ( s t r , d e l ) , с помощью которой осуществляется
выделение лексем в строке s t r . Второй аргумент этой функции содержит
набор символов, отделяющих одну лексему от другой. Например, при запи-
си дат могут использоваться такие разделители, как пробелы ("март 14
1 9 7 2 ' ) , ДефиСЫ ('Март-14-1972 ' ) , Прямые СЛЭШИ ( ' М а р т / 1 4 / 1 9 7 2 ' ) . ФуНК-
ция strtok (date," -/") возвращает указатель на первую обнаруженную
лексему и заносит нулевой код на место символа-разделителя. Это позволя-
ет обработать найденную лексему как строку. Вторая и следующие лексемы
выделяются этой же функцией, если в качестве ее первого аргумента задает-
ся указатель NULL. Аналогичная функция с таким же названием содержится
в каталоге MATLAB7\toolbox\MATLAB\strfun. В отличие от своего аналога,
функция strtok.m умеет работать с одним или двумя аргументами, а в каче-
стве результата возвращать (если попросят) две строки — найденную лексе-
му и оставшуюся часть строки. Она активно использует глобальные пере-
менные nargin, nargout, и когда к ней обращаются с единственным
аргументом string, то в качестве разделителей использует так называемые
белые пробелы— символы ASCII с кодами 9, 10, 11, 12, 13 и 32. В приме-
ре 4.7 приводится текст этой функции, в котором комментарии переведены
на русский язык и добавлены некоторые пояснения.

; Пример 4.7. Функция s t r t o k I

function [token, remainder] = s t r t o k ( s t r i n g , delimiters)


% STRTOK находит лексемы (token) в строке string.
% STRTOK(S) возвращает первую лексему в строке S, завершающуюся
% "белым пробелом". Лидирующие пробелы игнорируются
%
% STRTOK(S,D) возвращает первую лексему, завершающуюся одним
% из символов, заданных в D. Лидирующие разделители игнорируются
%
% [T,R] = STRTOK(...) возвращает остаток исходной строки
% Если лексема в S не найдена, то R равно пустой строке, a T=S
%
if nargin<l, error('He хватает входных параметров'); end
Программирование вычислительных процессов 143

token = []; remainder = [ ] ;


len = length(string);
if len == 0
return
end
if (nargin == 1) % Если входной аргумент один
delimiters = [9:13 32]; % Коды "белых пробелов"
end
i = 1;
% Пропуск лидирующих разделителей
while (any(string(i) == delimiters))
i = i + 1;
if (i > len), return, end
end
start = i;
% Цикл до появления первого разделителя
while (-any(string(i) == delimiters))
i = i + 1;
if (i > len), break, end
end
finish = i - 1;
token = string(start:finish);
if (nargout ==2) % Если задан второй выходной аргумент
remainder = string(finish + 1:length(string));
end

Вообще говоря, nargin и nargout являются не глобальными переменными,


а функциями. К ним можно обратиться, задав в качестве аргумента имя ш-
функции. И тогда они возвращают количество входных и выходных пара-
метров, указанных в заголовке функции:
» nargin('strtok')
ans =
2
» nargout('strtok')
ans =
2

Вы уже обратили внимание на то, что функции с фиксированным числом


входных или выходных параметров вовсе не обязаны прибегать к услугам
массивов varargin и varargout. Однако когда число параметров может быть
144 Глава 4

переменным, то их использование способно существенно упростить процесс


программирования. Очень изящно смотрится пример функции построения
графиков, которой можно передать любой набор свойств и значений объек-
та типа Line:
function myplot(x,varargin)
plot(x,varargin{:})

К ней, например, можно обратиться с набором следующих аргументов:


myplot(sin(0:.1:1),'color',[.5 .7 .3],'linestyle',':')

И тогда в массиве varargin система сформирует четыре ячейки, элементами


которых будут строка с именем свойства color, массив RGB-составляющих
[.5 .7 .3], строка с именем свойства l i n e s t y l e и символ :, управляющий
стилем линии. А в самой функции myplot не нужно прилагать никаких уси-
лий по распаковке массива varargin и анализу его элементов.
Массивы varargin и varargout могут появляться в заголовках функций в
комбинации с обычными формальными параметрами, однако подобно клю-
чевым параметрам их следует располагать в конце списка:
function [yl,y2] = funl(xl,x2,varargin)
function [yl,y2,varargout] = fun2 (xl,x2,x3,x4)

4.8. Функции evalw feval


MATLAB предлагает пользователю две системные функции eval и feval,
прямых аналогов которым нет ни в одной системе программирования ком-
пилирующего типа.
Главным аргументом функции eval (от англ. evaluation — вычисление) явля-
ется строка, представленная любым допустимым выражением MATLAB или
командой вызова известного системе m-файла. Функция eval исполняет
(интерпретирует) эту строку, как если бы она была набрана в командном
окне. Так можно вычислить формируемое во время работы программы вы-
ражение, исполнить функцию, введенную пользователем по запросу прило-
жения. Наиболее распространенными форматами вызова функции eval яв-
ляются:
eval(strl)
eval(strl,str2)
[yl,y2,...] = evalt'fun(xl,x2,...)')

Для формирования выполняемой строки можно использовать операцию


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

В справочной документации приводится редкий по изяществу фрагмент,


формирующий в цикле 12 магических квадратов с именами MI, М2, ..., М12
(пример 4.8).

I Пример 4.8. Формирование 12 магических квадратов


:.......... ..,.
for n = 1:12
magic_str = ['М',int2str(n),' = magic(n)'};
eval(magic_str)
end

Вторая необязательная строка str2 в списке параметров функции eval зада-


ет действия, которые нужно выполнить, если во время исполнения s t r l
возникла ошибочная ситуация.
В тестовом примере showdemo.m, содержащем всего пять строк, выполняет-
ся одна из демонстрационных программ, хранящихся в каталоге MATLAB7\
toolbox\matlab\demos (пример 4.9).

: Пример 4.9. Запуск демонстрационной программы •I

function showdemo(demos)
errstring = 'Файла с таким именем в каталоге нет';
n = input('Выберите номер демонстрационного файла: ')
demos(n,:)
eval(demos(n,:),'[errstring demos(n,:)]')

Для запуска этой программы наберите в командном окне две следующие


строки:
» D = ['odedemo'; 'quademo'; 'fitdemo'];
» showdemo(D)

Первая из них содержит список имен m-файлов, два из которых действи-


тельно находятся в указанном каталоге (odedemo.m — демонстрация методов
решения обыкновенных дифференциальных уравнений и fitdemo.m — при-
ближение нелинейной функцией экспериментальных данных). После старта
приложения вам предложат ввести одно из чисел 1, 2 или 3 для выбора
имени демонстрационного примера. На выбор п=2 последует сообщение о
том, что файл с таким именем в каталоге не представлен.
Функция f eval по логике своей работы отчасти напоминает функцию eval.
146 Глава 4

Обычно ей передают указатель hFun на функцию, подлежащую выполне-


нию, и список параметров, передаваемых косвенно вызываемой функции:
[yl,y2,...] = feval(hFun,xl,x2,...);
Второй формат вызова функции feval предполагает, что ее первым аргу-
ментом является строка с именем функции:
[yl,y2,... , feval('Name_fun' ,xl,x2, . . . ) ;

Этот вариант считается устаревшим, но его сохранили для преемственности


с ранее разработанными приложениями MATLAB. Следует заметить, что
точными эквивалентами второго формата вызова являются и следующие об-
ращения:
[yl,y2,...] = f e v a l (@Name__fun, x l , x 2 , . . . ) ;
[yl,y2,...] = Name_fun(xl,x2,...);

Основное назначение функции feval — вычисление значения функции в


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

4.9. Специфика работы


в редакторе m-файлов
Редактор m-файлов вызывается по команде File | New | M-File (Файл | Соз-
дать | М-файл) или при одинарном щелчке на имени m-файла. Главное ме-
ню редактора несколько отличается от главного меню MATLAB, да и панель
инструментов здесь гораздо богаче (рис. 4.4).

Cut Find text Top/Bottom Split


С
Г °РУ г Show functions Left/Right Split
-Paste Step In -i r-Step Out Tile •

File Edit TtxtlCel Tools Debud Cfesktop Window help


••",•• 7 "I • l~ I -••- 5 1 , 1 : , -Z",-_ J~)..
L JQj? >a«*F

O S
p
e
na
v
e L
L P nr
i
t LR uIt
n JL
E x
ti De
bu
g M od
Je
fe
N
e
wli Me-F
lU Red
o
indo C L S
e/ltc
aetp F
o
lat
- Se elrarBb
e
re
raa
kpo
no
kps
itnitn
iMAa
lxize
m F
ie
lis
Р и с . 4 . 4 . Панель инструментов редактора m-файлов
Программирование вычислительных процессов 147

Большинство разделов главного меню в редакторе кода совпадает с анало-


гичными разделами главного меню среды MATLAB. Однако состав команд в
соответствующих разделах поменялся, в основном в сторону увеличения ко-
личества команд.
Так, например, в меню File (Файл) появились команды Publish To HTML
(Экспортировать в HTML) и Publish To (Экспортировать). С их помощью
программа, набранная в поле редактора, может быть экспортирована в до-
кумент, создаваемый в одном из форматов — HTML, XML, LaTeX, MS Word,
MS PowerPoint. Документ, экспортированный в формате HTML, сохраняет
раскраску синтаксических единиц, действующую в редакторе кода.
В окне редактора можно открыть несколько m-файлов и одновременно на-
блюдать тексты нескольких программ, разделив поле редактора на части
(Tile), горизонтальные (Top/Bottom Split) или вертикальные (Left/Right Split)
полоски, расположив панели с профаммами друг за другом (Float) или раз-
вернув одну из программ на все окно (Maximize). На рис. 4.5 приведен ва-
риант горизонтального расслоения поля редактора после вызова профамм
array2vec.m и fem.ni. Имена вызванных программ отображаются в строке
Document Bar (Строка документа).

ЩEditor I- |D|X
File Edit Text Cell Tools Debug Desktop Window Help ..II
ffl|f 6tQ
1 function [varargout] = array2vec(a)
2- for k=l:nargout
3 - varargout)к }=a (k,:);
4 - end
H:\MATLAB7\work\fern.ra
1 function fern
2 VFBRH MATLAB iwplementation of the Fractal Fern
.3 1 Michael Batnsley, Fractals Everywhere, Academic Press,199;
•4 i This version runs forever, or until stop is toggled.
5 ; % See also: FIHITEE'ERN.
6 - shg
7 - elf reset
8- set ( a c f , ' c o l o r ' , ' a h i t e ' , ' u r i i i u b a r * , ' n o n e ' , . . . Щ
array2vec.m * !|Jern.m x

••••••••'. •.-•••.. Hem [Cn 1" Col 1

Рис. 4 . 5 . Две m-программы в поле редактора кода

Среди разделов главного меню появились новые разделы — Text (Текст),


Cell (Ячейка) и Tools (Сервис).
148 Глава 4

4.9.1. Меню Text


Меню Text (Текст) главным образом ориентировано на управление текстом
программы на поле редактора (рис. 4.6).

Text|
Evaluate Selection1' F9
Wrap Selected Comments :•
: :
Comment Ctrl+R
: Uncomment Ctrl+T'
Deaease Indent Ctr(-+-£
Increase Indent Ctrl+]
: Smart Indent > Ctrl+1

Рис. 4.6. Команды меню Text

Команда Evaluate Selection (Вычисление выбранного) обеспечивает вычис-


ление выделенного выражения, если в этот момент известны значения всех
переменных, входящих в формулу. Результат вычислений отображается в
Command Window (Окно команд).
Команда Wrap Selected Comments (Переносить выбранные комментарии)
имеет смысл только в том случае, когда отключен режим автоматического
перехода на следующую строку при наборе длинных комментариев. В на-
стройках Preferences | Editor/Debugger | Language (Предпочтения | Редак-
тор/Отладчик | Язык) имеется возможность управлять форматом наби-
раемой программы. Во-первых, это список языков программирования —
М (MATLAB), C/C++, Java или HTML. Во-вторых, это подключение или
отключение режима подсветки синтаксических конструкций (Enable syntax
highlighting). В-третьих, это выбор режима отступа (Indenting for Enter key)
для выделения вложенных конструкций. Наконец, это управление длиной
строки комментария (Comment formatting) и его автоматическим продолже-
нием со следующей строки при превышении установленной границы
(Autowrap comments). Если режим автоматического переноса отключен, а
комментарий набран без соблюдения установленного предела, то любой его
фрагмент (хотя бы один символ) надо выделить. После выполнения коман-
ды Wrap Selected Comments (Переносить выбранные комментарии) длинные
комментарии будут автоматически укорочены за счет переноса избыточных
хвостов в начало следующих строк.
Команда Comment (Комментировать) позволяет закомментировать текущую
строку. Конечно, это можно сделать и вручную, установив символ % в пер-
вой позиции текущей строки. Превращение текущей строки в комментарий
позволяет временно отключить некоторые операторы на время отладки оп-
Программирование вычислительных процессов 149

ределенных фрагментов программы. Команда Uncomment (Раскомменти-


ровать) возвращает закомментированный в текущей строке оператор в пер-
воначальное состояние.
Термин indent (отступ) означает автоматический отступ текущей строки по
отношению к предыдущей строке. Вы, наверное, наблюдали, как после опе-
ратора for следующая строка автоматически сдвинулась вправо, наглядно
представляя вложенность тела цикла. И все последующие строки тела цикла
начинаются с этой же границы. Иногда полезно вмешаться в этот режим,
например, чтобы очередной оператор end, завершающий тот или иной
программный блок, оказался на уровне заголовка блока. И тут на помощь
приходят команды Decrease Indent (Уменьшить отступ), Increase Indent
(Увеличить отступ) и Smart Indent (Интеллектуальный отступ). Первая из
них смещает текущую строку или выделенный блок строк влево на установ-
ленное число позиций (величина этого смещения регулируется в окне Pref-
erences (Предпочтения)). Вторая команда осуществляет аналогичный сдвиг
текущей строки или выделенного блока строк вправо. Команда Smart Indent
(Интеллектуальный отступ) реализует интеллектуальный отступ — напри-
мер, выравнивает на общую границу пару f o r . . .end или подравнивает все
внутренние команды блока, если они по какой-то причине начинаются с
разных позиций.

4.9.2. Меню Debug


Меню Debug (Отладка) включает команды, управляющие режимами отладки
(рис. 4.7).

Debug [_
•• Open M-Files when Debugging .•••••
Step FiO
Step 1П :: • .....;.: Fll .../..
Step Out Shift+Fll
Run ., : F5
Go Until Cursor
Set/Clear Breakpoint F12
Set/Modify Conditional Breakpoint..
: Enable/Disable Breakpoint •
; Clear Breakpoints in All Files
Step if Errors/Warnings...
Exit Debug Mode

Рис. 4.7. Команды меню Debug


150 Глава 4

Команда Run (Запуск) или нажатие клавиши <F5> инициируют автоматиче-


ское исполнение программы.
Команда Step (Шаг) включает режим пошагового выполнения m-файла —
при каждом нажатии клавиши <F10> система интерпретирует очередную
исполняемую строку программы. Режим Step In (Шаг внутрь) устанавливает
точки останова на первых исполняемых строках каждой подфункции. Это
позволяет проконтролировать в отладочном режиме выполнение тех или
иных операторов внутри подфункций. Режим Step Out (Шаг наружу) ис-
ключает подфункции из отладочного режима, предоставляя им возможность
выполняться автоматически.
Во время выполнения программы команда Run (Запуск) подменяется
командой Continue (Продолжить), которая после останова программы вновь
переводит ее в режим автоматического исполнения.
Термин breakpoint (точка прерывания) обозначает строку программы, на ко-
торой компьютер должен приостановить режим автоматического выполне-
ния, предоставив пользователю возможность произвести некоторые отла-
дочные действия. Самый простой способ выделения строки в качестве точки
останова — щелчок по знаку "минус", расположенному справа от номера
строки.
Строки, отмеченные как точки прерывания, выделяются красными марке-
рами между колонкой номеров строк и первой позиции. Если вы пытаетесь
объявить какую-либо исполняемую строку точкой останова, и вместо крас-
ного маркера появляется серый, то это означает, что программа в поле ре-
дактора подверглась модификации и еще не была сохранена. После запо-
минания ее текста в дисковом файле серые точки останова становятся крас-
ными.
Команда Set/Clear Breakpoint (Установить/Убрать точки прерывания) выде-
ляет текущую строку как точку останова или отменяет ранее сделанное вы-
деление. Команда Set/Modify Conditional Breakpoint (Установить/Изменить
условие точки прерывания) открывает диалоговое окно (рис. 4.8), в котором
можно задать дополнительное условие. Если оно будет выполнено, то про-
изойдет останов на заданной строке программы (точки условного останова
появились только в MATLAB 7). В противном случае точка останова будет
проигнорирована.
Команда Enable/Disable Breakpoint (Восстановить/Отключить точку преры-
вания) позволяет восстановить или временно отключить точку останова.
В последнем случае красный маркер перечеркивается крестиком, но не уда-
ляется из программы. Повторное выполнение команды отменяет предыду-
щее действие.
Команда Clear Breakpoints in All Files (Удалить точки прерывания из всех
файлов) отменяет все выделения во всех одновременно открытых файлах.
Программирование вычислительных процессов 151

alMATLAB Editor
Fle
i H;WATLAB7\worktarray2vec.m
Conditon for line 4 (for example, x>=» 1 f.

Note: the condition will be checked before the line is executed.


OK I Cancel I Hep
l

Рис. 4 . 8 . Окно для набора условия в точке останова

Команда Stop if Error/Warnings (Остановить при ошибке/сообщении) от-


крывает диалоговое окно (рис. 4.9), в котором имеется 4 вкладки — Errors
(Ошибки), Try/Catch Errors (Ошибки try/catch), Warnings (Сообщения), Nan
or Inf (Nan или Inf). На каждой из них можно установить один из режимов:
• Always stop if warning (dbstop if warning) — всегда останавливаться
в соответствующей ситуации;
П Never stop if warning (dbstop if warning) — никогда не останавливаться
в соответствующей ситуации.
Кроме того, системное сообщение о произошедшем событии можно заме-
нить пользовательским сообщением.

IS Stop if Errors/Warnin.
Errors ] TryC
l atch Errors Warnn
i gs | Man or Inf |
С Never stop if warning (dbclear if warning)
f Always stop if warning (cfbstop if warning)
P Use message Identifiers (dbstop It warning messageld)
Add Message Identifier Qj
Identifier: jMy Toolbox: FileNatFoundError
Example: My Toolbox: FileNotFoundError

; OK Cancel Help

Рис. 4 . 9 . Изменение условий останова при ошибках или предупреждениях

Команда Go Until Cursor (Продолжать до текущей строки) добавляет к точ-


кам останова текущую строку.
Прерывание программы в случае выхода на точку останова или в результате
возникновения запланированного события переводит MATLAB в режим от-
ладки. Отличительным признаком этого режима является изменение под-
6 Зак. 899
152 Глава 4

сказки в командной строке — вместо символов » появляется тройка к » .


В качестве рабочего пространства теперь выступает локальное рабочее про-
странство отлаживаемой функции, и пользователю доступны все команды
MATLAB. С их помощью он может проанализировать значения тех или
иных переменных, вычислить нужные выражения, предпринять другие от-
ладочные действия.
Команда Continue (Продолжить) продолжает работу приостановленной
программы. Выход из режима отладки обеспечивает команда Exit Debug
Mode (Выйти из режима отладки).
Первые 10 кнопок на панели инструментов редактора дублируют наиболее
часто используемые команды меню File (Файл) и Edit (Правка). Смысл
большинства кнопок в правой части панели инструментов становится ясным
после знакомства с командами назначения точек останова и управления ре-
жимами отладки.
Кнопка Show function (Показать функцию) позволяет быстро перейти к тек-
сту нужной подфункции. Щелчок по этой кнопке выдает окно со списком
всех подфункций данного m-файла (рис. 4.10). Последующий щелчок по
имени нужной подфункции переводит курсор в начало выбранной функции.

И Editor - C:\MATLAB6p5\workl\calll.m
File Edit Text Cell Tools Debug Desktop Window Help

1 function varargout = <calll


2 . % CALL1 M-file for ca call l_OpeningFcn
3 i CALL1, by i t s e calll_Outputfcn 1 or raise? the existing
singleton*, figure l_ButtonDownFcn
pushbutton2_Callback
H = CALLl r.fitm >v CALL! or the handle to
the existing singleton*.

Рис. 4.10. Список подфункций файла calH.m

4.9.3. Меню Edit


Быстрые перемещения по программе в поле редактора дополнительно обес-
печиваются командой перехода на строку с заданным номером и использо-
ванием закладок (bookmarks). Эти средства сосредоточены в разделе Edit
(Правка) главного меню редактора (рис. 4.11).
Выполнение команды Go To Line (Перейти к строке) приводит к появлению
диалогового окна (рис. 4.12), в котором следует набрать номер искомой
строки.
Программирование вычислительных процессов 153

Ж]
Undo . ,/ :• Ctrl+Z
Redo Ctr.l+Y
Cut Ctrl+X
Copy Ctri+C
Paste' •,.'•• " : Ctrl+V
Paste Special,..
Select All Ctrl+A
Delete Delete
, Find and Replace.. Ctrl+F;T'
FindNext F3 ";
Find Previous Shift+F3
• Find Selection Ctrl+F3
Find Files....
Go To Line Ctrl+G.
Set/Cel ar Bookmark Ctrl+F2
Next Bookmark F.2
Prev Bookmark Shlft+F2
Cel ar Command Wn i dow
Clear Command History
Cel ar Workspace
Рис. 4 . 1 1 . Меню Edit

1 Go To L i n e E3|
Line number: | OK
;• . •: Cancel I

Рис. 4 . 1 2 . Диалоговое окно перехода


на строку с указанным номером

Bookmarks (закладки) могут быть присвоены наиболее посещаемым строкам


программы с помощью команды Set/Clear Bookmark (Установить/Удалить
закладку). Слева от такой строки появляется голубенький прямоугольник
(рис. 4.13). Повторное выполнение этой же команды, когда курсор находит-
ся в помеченной строке, удаляет закладку. Естественно, что применение
закладок имеет смысл только в длинных программах, текст которых полно-
стью не отображается на экране.
Переход к ближайшей закладке, расположенной ниже текущей строки, вы-
полняется с помощью команды Next Bookmark (Следующая закладка). Воз-
154 Глава 4

врат на ближайшую закладку, расположенную выше текущей строки, осу-


ществляет команда Prev Bookmark (Предыдущая закладка).

Ц E d i t o r - H:\MATLAB7\work\array2vec.m
File Edit Text Cell Tools Debug Desktop Window Help

1 function [varargout] = 'ari:ay2vec (a)


2- tor k=l:nargout
3-D vacargoutf k}=a (k, :) ;
4 -: end

Рис. 4.13. Закладка возле третьей строки

Работа в любом текстовом редакторе, как правило, предполагает активное


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

Таблица 4.2

Клавиша/комбинация Операция
клавиш

<Т> Переход на предыдущую строку


<4-> Переход на следующую строку
«—> Возврат на один символ
<—» Переход на один символ вправо
Переход на одно слово вправо
Возврат на одно слово влево
<Home> Возврат в начало строки
<End> Переход в конец строки
<Delete> Удаление символа над курсором
<Backspace> Удаление символа слева от курсора
<Shift>+<Home> Выделение текста от начала строки до курсора
<Shift>+<End> Выделение текста от курсора до конца строки
<Ctrl>+<Home> Перемещение в начало файла
<Ctrl>+<End> Перемещение в конец файла
Программирование вычислительных процессов 155

4.10. Отладочные команды


Команды меню Debug (Отладка), обеспечивающие работу с точками преры-
вания, и кнопки панели инструментов редактора, дублирующие некоторые
из этих команд, являются не единственным набором отладочных средств.
Кроме них MATLAB предоставляет в распоряжение пользователя группу
команд (функций), к которым можно обращаться из командной строки
(табл. 4.3).
Таблица 4.3

Команда Назначение

dbclear Очистка указанных или всех точек и условий останова


dbcont Продолжение выполнения программы после останова
dbdown Переход на рабочее пространство следующего уровня *
dbquit Выход из режима отладки
dbstack Опрос состояния стека вложенных вызовов функций
dbstatus Опрос установленных точек и условий останова
dbstep Задание количества строк, выполняемых на очередном шаге
dbstop Задание точек .или условий останова
dbtype Вывод m-файла или его фрагмента с номерами строк
dbup Переход на рабочее пространство предыдущего уровня

С помощью функции dbtype можно вывести в командном окне текст т -


файла с номерами строк или фрагмент этого файла:
» dbtype array2vec

1 function [varargout] = array2vec(a)


2 for k=l:nargout
3 varargout{k}=a(k, :) ;
4 end

» dbtype array2vec 2:3 -,

2 for k=l:nargout
3 varargout{k}=a(k,:);

Такой текст позволит вам выбрать строки программы, которые целесообраз-


но назначить точками останова. В командном окне для этой цели можно
156 Глава 4

воспользоваться функцией dbstop, обращение к которой допускает не-


сколько модификаций:
» dbstop in array2vec at 3
% останов в файле array2vec.m на строке с номером 3

» dbstop in array2vec
% останов на первой выполняемой строке в файле array2vec.m

» dbstop in funl at subfun2


% останов на первой выполняемой строке подфункции subfun2
% в файле funl.m

» dbstop if error
% переход в режим отладки, если будет обнаружена ошибка

» dbstop i f warning
% переход в режим отладки, если будет выдано предупреждение

» dbstop i f naninf
» dbstop i f infnan
% переход в режим отладки, если обнаружено NaN или °°

Служебные слова-связки типа if, in, at не являются обязательными и могут


быть опущены. Для набора точек условного останова три первые модифика-
ции допускают расширение типа "if выражение". Останов происходит в том
случае, если при выполнении указанного оператора значение выражения
оказывается истинным. Вообще говоря, количество вариантов останова по
dbstop достигает 17, и с их полным перечнем можно познакомиться, набрав
В ОКНе КОМаНД СТрОКу h e l p d b s t o p ИЛИ doc d b s t o p .
Обращаясь к функции dbstatus, вы можете получить список всех точек оста-
нова, действующих в данный момент (рис. 4.14).
Для отмены конкретной точки останова или всех точек останова можно
воспользоваться услугами функции dbciear:
» dbciear in array2vec at 3
% отмена точки останова в строке 3 файла array2vec.m

» dbciear all in array2vec


% отмена всех точек останова в файле array2vec.m
Программирование вычислительных процессов 157

» dbclear all
% отмена всех установленных точек останова

» dbclear if error
» dbclear if warning
» dbclear if naninf '
% отмена заданных условий останова

\Щ E d i t o r :\MATLAB6p5\work\array2vec.m
File.Edit Text Cell Tools Debug Qesktop Window"Help
D & Ш I' X *» © ••" '-• i © i f t . / . : B i ; * ' t ill
1 function [varargout] = array2vec(a)
2 * foe k=l:nacgout
3* varargout(k)=a (k, :) ;
4 " end
-AMATLAB
File |dit Debjg Qesktop Window Help
D Ш | Щ 3 * I V j: Curreri Diectgrj;: | C:»MAILAB6p5\work ^

>> dbstop array2vec 2


» dbstop ai:ray2vec 3
>> dbstatus

Breakpoints for array2vec are on lines 2, 3.

Рис. 4.14. Установка точек останова и опрос статуса

Останов по любому поводу (попадание в точку останова, выполнение одного


из заданных условий) переводит программу в режим отладки, о чем свиде-
тельствует появление буквы к перед символами >>. В этот момент в команд-
ном окне действует локальное рабочее пространство функции — инициатора
останова. Для пошагового выполнения программы в режиме отладки можно
воспользоваться клавишей <F10> (эквивалент команды Debug | Step (Отлад-
ка | Шаг)) или функцией dbstep. Нажатие клавиши <F10> или вызов функ-
ции dbstep без параметров приводят к выполнению следующей строки про-
граммы. Числовой параметр в функции dbstep обеспечивает выполнение ука-
занного количества строк на очередном шаге отладки:
» dbstep 5
Если в точке останова находится оператор вызова функции, то возможны
два варианта — воспользоваться командой Debug | Step In (Отладка | Шаг
внутрь) (эквивалент— клавиша <F11>) или командой Debug | Step Out
(Отладка | Шаг наружу) (эквивалент — комбинация клавиш <Shift>+<Fll>).
158 Глава 4

В первом случае пошаговый режим выполнения программы распространяет-


ся на операторы вызываемой функции. Во втором случае вызываемая функ-
ция выполняется в автоматическом режиме, а после возврата из нее восста-
навливается режим пошаговой отладки.
После выхода программы на очередную точку останова вы можете просмот-
реть переменные локального рабочего пространства в окне, раскрывающемся
по команде View | Workspace (Вид | Рабочее пространство) или при выпол-
нении команды whos. Если имела место цепочка вызовов, то кроме текущего
локального пространства могут представить интерес и переменные, принад-
лежащие предшествовавшим функциям. Перемещения по локальным рабо-
чим пространствам вперед или назад обеспечиваются командами dbup
(возврат в рабочее пространство предыдущего уровня) и dbdown (переход в
рабочее пространство следующего уровня). Цепочку предшествовавших вы-
зовов можно проследить по содержимому стека обращений. Оно отобража-
ется по команде dbstack. Находясь в отладочном режиме, можно не только
просматривать текущие переменные, но и менять их значения, а также вы-
полнять любые команды, которые разрешается набирать в командном окне.
С помощью функции dbquit осуществляется выход из отладочного режима.
Ее эквивалентом в главном меню является команда Debug | Exit Debug Mode
(Отладка | Выйти из режима отладки).
К режиму проверки корректности программы относится ее проверка с по-
мощью сервисной программы M-Lint, которая вызывается по команде
Tools | Check Code with M-Lint (Сервис | Проверить код с помощью M-Lint).
Идея полного синтаксического контроля программы и выявления в ней по-
дозрительных мест принадлежит сотрудникам BELL Laboratories. Она была
реализована примерно 30 лет тому назад в виде утилиты lint, через которую
пропускались все программы, написанные на языке С. В программе lint
проверялись такие ситуации, как неправильное использование типов, ошибки
в передаче параметров функциям, неиспользуемые и неинициализируемые
переменные и многое другое. В том числе она выдавала сообщения о труд-
ностях переноса программы на компьютеры другого типа, связанные с раз-
рядностью, количеством регистровых переменных, порядком следования
байтов, размножением знака при сдвиге чисел вправо и т. п. Если програм-
ма проходила такой контроль, то она компилировалась с помощью доста-
точно простого компилятора, не предусматривающего столь тщательные
проверки. Своим названием программа lint предположительно обязана аб-
бревиатуре от Language Interpreter (интерпретатор языка).
Попытка реализации аналогичной идеи была предпринята в MATLAB 7.
Возможно, что работа над сервисом подобного рода будет продолжена, т. к.
некоторые наши попытки внести ошибки в достаточно простую программу
ставили M-Lint в тупик. На рис. 4.15 приведен результат анализа функции
polyline, не содержащей ошибок.
Программирование вычислительных процессов 159

Editor - H:\MATLAB7\work\polyline.m
File Edit Text Cell Tools De^ug Desktop: Window Help
QSa i *««-<•* A I M / . Q f i • ;•>•> О
1 |f unction polyline(varargin)
2 •» for k=l: length (varargin)
3- x(k)=varargin(k) (1) ;
4- y(k) = v a r a r g i n ( k } (2) ;
5 * end
6- a x i s {[min (x) max(x) min(y) max (y) ])
" Plot(x,y)
7

VM-Lint Code Check Report


File Edit View Go Debug Desktop Window Help
^ . . „ _ ^ . ...^ . .

M-Liiit Code Checker Report

Report for f i l e H: \MATbAB7N-woik\polyline


H: \MATLAB7\work\polyline.in

T
;3: Array x T is constructed using subscripting.
messages
Consider preallocating for speed
T
4: Array y' is constructed using subscripting.
Consider preallocating for speed

Рис. 4.15. Сообщения синтаксического анализатора M-Lint

VM-Lint Code Check Report


File Edit. View Go Debug Desktop Window Help.

M-Lint Code Checker Report

Report for f i l e H: \ l"iAT LAB 1 \ w Q r k\ p_ о 1 у l i n e


H:\MATLAB7\work\polyline. m

4 1^ Invalid character
messages
"X •_ Function name ' olyline' will be known to MATLAB
.by its file name: TpolylineT.
•3 •._ Array f x* is constructed using subscripting.
Consider preallocating for speed
4j_ Array T y T is constructed using subscripting.
Consider preallocating for speed

Рис. 4.16. Пример хорошей реакции на ошибку в программе


160 Глава 4

Несмотря на это, M-Lint выдала сообщения о том, что в 3-й и 4-й строках
программы использованы индексированные массивы и не мешало бы поду-
мать над способами повышения скорости работы программы.
Над попытками включить в программу неинициализированные переменные
анализатор M-Lint надолго задумывался, но никаких сообщений не выдавал.
Зато на использование запрещенного имени функции (вместо polyline мы
набрали noiyiine) выдал очень разумное сообщение (рис. 4.16).

4.11. Анализ эффективности программы


MATLAB 7 отличается от предыдущих версий еще и тем, что в его состав
входит утилита Profiler, которая позволяет построить профиль программы,
т. е. получить статистику по времени ее выполнения вплоть до каждой стро-
ки исходного кода. Это помогает определить узкие места программы, выде-
лить строки программы, которые никогда не выполняются, узнать количест-
во обращений к той или иной функции и время ее работы.
Вызов программы Profiler может производиться разными способами: из сре-
ды MATLAB (команда Desktop | Profiler (Рабочий стол | Профайлер)), из ре-
дактора кода (команда Tools | Open Profiler (Сервис | Открыть профайлер)),
из окна Command Window (Окно команд) с помощью строки profile
viewer. В окне Profiler (Профайлер) в поле раскрывающегося списка Run
this code (Запустить код) набирается имя анализируемой программы
(рис. 4.17) и нажимается кнопка Start Profiling (Создание профиля). Как
видно из приведенных ниже рисунков, анализировалась программа bench.m,
которая используется для определения производительности компьютера и
сравнения ее с лучшими моделями ПК.
Рисунок 4.17 отражает первичную выдачу результатов анализа, которая на-
чинается со списка выполнявшихся функций. В колонке Function name (Имя
функции) указывается имя функции, в колонке Calls (Вызовы) — количест-
во ее вызовов, в колонке Total Time (Всего времени) — общее время пребы-
вания в теле этой функции, включая и время работы всех вызываемых ею
функций, в колонке Self Time (Собственное время) — исключено время ра-
боты вызываемых функций, а в последней колонке графически отображены
оба указанных времени, выделенные разными цветами.
Порядок функций в списке соответствует последовательности их вызовов.
Если щелкнуть мышью по заголовку Function name (Имя функции), то спи-
сок перестраивается в алфавитном порядке, что упрощает поиск нужной
функции (рис. 4.18).
Щелчок по имени функции перемещает нас на соответствующий кадр отче-
та (рис. 4.19). В нашем примере была выбрана функция ode45.m.
Программирование вычислительных процессов 161

Start Prof iing j Run this code: j bench jrj • Profile tlrocMO sec

! Profile Summary
\ Generated ll-Sep-2004 18:54:26
\ Function name Calls Total Self Total Time Plot
Time lime* (dark band = self
time)

bench 1 i 6.797 s 4.703 s —


ode45 :2 : 0.984 s 0.547 s H

newplot 47 0.422 s 0.031 s l .. i

: newploOObserveAxesNextPlot 47 0.391s 0.000 s i ',

1
graphics » rivate\clo ;47 0.359 s 0.156 s I ; '•' j

! barh 2 0.219 s 0.000 s i i.' 1

membrane Ц ! 0.203 s 0.063 s I ; ;• ••;

reemat 2166 j 0.203 s 0.203 s

iimfun\privale\iitrp4J 1080 0.188 s 0.031 s


Prof Jer i Commeind window |

Рис. 4.17. Начальный кадр отчета программы Profiler

И'ЛиИ-Я————
+ 4 с 0:\ШШ
•••••Ml
Start Proflbfl I RLBI W« code J bench •^1 eProffletimeMOsec

Profile Summary
j denerated 1 l-Sep-2004 21:06:32
• Fiuittion name Calls Total Self i Total Time Plot
Time Time* (dark band = self
i time)

ancestor 60 0.063 s function is recursive

ancestor>isatvpe 120 0.031 s function is recursive

automesh 7 Os 0.000 s

j axes (Opaque-function) 80 0s 0.000 s |

I axesclieck 5 0.016 s 0.016 s | i

Sa x k 3 0.031s 0.016 s

1 ffid?>LocSetLiniite 1 0.016 s 0.016 s

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


162 Глава 4

:
•• «• с _]в :«
Start Profiling I Run tins сей*, bench J*J •prontethiaiOsec

j ode45 (2 calls, 0.984 sec)


j Generated ll-Sep-2004 21:09:54
' M-function in file H:\MATXAB7\toolboxWitlab\funfiin\ode45.m
! [Copy to new.window.for comparing multiple runs]
I Refresh J

P Show parent files F Show busy lines P Show child files


P Show M-Lint results P Show file coverage P Show file listing

Parents (calling functions)

! Filename j File Type Calls

'• beach ! M-function I 2


1
Lines where the most time was spent

% Time
; Line Number Code Calls _ . :
Time Time Plot »
f4 "' ' :.'••: __
Profiler 1 Command VWKlow : ' " .

ф S t a r t j • . •:;.' • • • ••' ;' : •• . !• • • . ; ' " -i"1'.1:^ /..' . . . , •'-

Рис. 4 . 1 9 . Начало профиля по функции ode45.m

*• •* о _ i : # i «
Start Profahg j RuntNs code: j bench bprotietiiwlOsec
....-d
Lines where the most time was spent • -•••" _ J

Total Time
Line Number Code Calls
Time Time Plot
434 jyout_now = [ntrp45(tref, t , y, [ ] . . • 1080 0.234 s 23.8%

326 t(:,4) = feval(odeFcn,t+hA(3),.. • 1326 0.094 s 9.5% •


505 solvsr_o jtput = odefin&lize(so.. • 2 0.063 s 6.3% I j

325 £(:.3) = feval(odeFcn,t+hA(2),.. • 1326 0.063 s 6.3% •

' 324 £<--2) = feval(odeFcn,t+hA(l),.. • 1326 0.063 s 6.3% •


Other lines & ;
0.469 s 47.6% —
overhead

Totals 0.984 s 100%

Children (called functions)

Profiler J Command VA-idowj


*Sttrt|
I i
Рис. 4 . 2 0 . Статистика по работе функции ode45.m
Программирование вычислительных процессов 163

В этом фрагменте профиля можно увидеть (рис. 4.20) статистику по наибо-


лее долго выполнявшимся строкам программы. Следующий кадр (рис. 4.21)
отражает статистику работы вызываемых функций.

ШЛ±И-ПИ
•НИ•i •HI шшшшшшШшшшшша
Start Profiling j Run this code: j bench jrj ^Proiietime- 10 sec

Children (called functions)

Filename File Type Calls Total Time %Time Time Plot


ll
fimfun''.private\ntrp45 M-function 1080 0.188 s 19.0% "••
vdpl M-function 7956 0.109 s 11.1% •
funfun\private'.odear.guments M-fiinction 2 0.063 s 6.3% •
: funfun'ijjnvatelodefinalize M-function \ 2 0.063 s 6.3% •
j fimfim\private\odemass M-fimction 2 0.016 s 1.6% i
odeget M-function 6 0s 0%
1
funftm.\private\odeevents M-function 2 0s 0%

Self time (built-ins, overhead, etc.) 0.547 s 55.6% — — :


| Totals 0.984 s 100%

'«1
Profiler 1 Command Window ..'
:
j il

Рис. 4.21. Статистика по работе функций,


вызываемых из ode45.m

Предпоследний фрагмент отчета (рис. 4.22) включает предупреждения про-


граммы M-Lint и итоговые результаты профилирования. Самая последняя
часть отчета содержит текст анализируемой программы с указанием времени
работы каждой строки. Не выделенные цветом строки — затратившие
меньше всего времени, слева от их текста ничего не указано. Затем по мере
возрастания времени работы окраска строк изменяется от светло-розовой до
темно-красной (рис. 4.23).
Полученный профиль можно сохранить в файле для последующего изуче-
ния узких мест программы с целью повышения ее производительности.
164 Глава 4

Profiler , X

Start Prptiing j Run this code: J bench J*J #Рго(йеИте:10ввс:

i M-Lint results IJ
\ Line number Message _j
T
402 he value assigned here to variable 'ignore' i s never used

I Coverage results

i Total lines in file 513


I Non-code lines (comments, blank lines) 199 !
J Code lines (lines that can run) 283 '
j Code lines that did run 155 :
; Code lines that did not run 128
| Coverage (did run/can run) 54.77%
:
••' ' ' ' ' . . . 1
Protiter! Commend VUndow j

Р и с . 4 . 2 2 . Итоговые результаты профилирования

li-J-UM.VJi
^
••••••
"Ф 't tj$ ' a ' i t •••• ••••••••
Start Profing j Run this code j bench 2 Ф Profle tfme: 10 sec

| •< С 0.1 1080 320


! -.,. IH OHi DEI
nofailed = t r u e ; » no f a i l e d a t t e m p t s A
:'.'. u> lf.iso
321 while t r u e
C.Cli 132 6 3 2 2 hA = h * A;
132 6 3 2 3 hB = h • B ;
| 0.116 1326_ 3 2 4 t(:,2) « feval(odeFcn,t+hA(l),y+f*hB(: ,1),odeAcys{:});
i :.3S 132s _325 f ( : , 3 ) = feval(odeFcn, t+hA(2),y+f»hB(: ,2), odeArgs{:});
'. й.й" 1326 3 2 6 ( 0 , 4 ) = feval(odeFcn,t+hA(3), y+f*hB(: , 3 ) , o d e A r g s l : } ) ;
O.J5 132Й 3 2 7 f ( ! , 5 ) = teval(odeFcn,t+hA(4),y+f*hB(: , 4 ) , o d e A r g a j : ) ) ;
n.Oi 132Й . 3 2 Я £ ( : , 6 ) = feval (odeFcn, t+hA(5J , y+f *"hB ( :, 5 ) , odeArgs{:});

1 t 0.ГЦ 1 3 2 6 __
330 tnew = t + hA(6);
1 t и.о.: 132a 3 3 1 i f done
' •• i\. j ; 3 •fl? tnew = t f i n a l ; % H i t end p o i n t e x a c t l y .
333 end
| ' 0.03. 132o 3 34 h = tnew - t ; % P u r i f y h.

1326 336 ynew = •/ + f * h B ( : , 6 ) ;


i :..;;. 1.3 г ь £ ( : ,7) = feval(odeFcn, tnew, ynew,odeArc
3f ))
i}
' ' I ZJ
Profiler) Command Vvlndow)

Р и с . 4 . 2 3 . Текст исходной программы с информацией о работе каждой строки


Глава 5

Обработка символьных данных


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

символьным переменным

% Формирование вектора-строки
» str='ABCDE'
str =
ABCDE
» whos
Name Size Bytes Class
str 1x5 10 char array
Grand total is 5 elements using 10 bytes
% Формирование массива строк
» str_mas=['1234';'ABCD']
str_mas =
1234
ABCD
» whos
Name Size Bytes Class
str_mas 2x4 16 char array
Grand total is 8 elements using 16 bytes
% Формирование массива символьных ячеек
» str cell=[{'123','ABCD'};{'4567','abc'}]
166 Глава 5

str_cell =
423' 'ABCD'
•4567' 'abc'
» whos
Name Size Bytes Class
str cell 2x2 268 cell array
Grand total is 18 elements using 268 bytes

На каждый символ во внутреннем представлении отводится по 2 байта в


кодировке ASCII Unicode. Однако для программистов, привыкших к одно-
байтовой кодировке ASCII (в Windows — кодовая страница 1251), никаких
вопросов с числовыми кодами букв латинского алфавита не возникает:
char(65)=A char(66)=B ... char(90)=Z
int8('A')=65 int8('B')=66 ... int8('Z')=90
char(97)=a char(98)=b ... chart 122)=z
int8('a')=97 int8('b')=98 ... int8('z')=122

Для преобразования символа в числовой код можно воспользоваться любым


ДОПУСТИМЫМ форматом — uint8, i n t l 6 , u i n t l 6 , int32, u i n t 3 2 , single,
double. Однако с типами int8 или uint8 вас могут поджидать неожиданно-
сти, т. к. в этом преобразовании участвуют только 7 или 8 младших битов.
Если преобразуемый код выходит за пределы допустимого интервала, то ре-
зультат заменяется соответствующим граничным значением:
int8('я')=127 uint8('H')=255

Дело в том, что для символов русского алфавита используется настоящая


двухбайтовая кодировка:
char(1040)=A char(1041)=E ... спаг(1071)=Я char(1025)=Е
intl6('A')=104 intl6('B')=104 ... intl6('Я')=107 intl6('E')=1025
0 1 1
char(1072)=a char(1073)=6 ... char(1103)=я char(1105)=e
intl6('a')=lO7 intl6('6')=107 ... intl6('я')=110 intl6('e1)=1105
2 3 3

Аргументом функции char может быть не только целое положительное зна-


чение в формате double, но и любой числовой массив с такими же компо-
нентами:
» char({48 49 50; 65 66 67; 1088 1089 1090])
ans =
012
ABC
рст
Обработка символьных данных 167

С помощью индексной конструкции типа сокращенного цикла (nl:n2) и


функции char можно сформировать строки, представляющие наиболее
употребительные фрагменты таблицы ASCII (пример 5.2).

\ Пример 5.2. Печать таблицы ASCII !


i ....:... ....'....^Л....:..........<.... . ,.,• j .......,„;

» char(32:64)
ans =
!"#$%&' ()* + ,-./0123456789:;<=>?@
» char(65:96)
ans =
ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]Л_~
» char(97:126)
ans =
abcdefghijklmnopqrstuvwxyz{I}~
» char(1025 1105)
ans =
Ее
» char(1040:1071)
ans =
АБВГДЕЖЗИЙКПМНОПРСТУФХЦЧШЩЬЫЬЭЮЯ
» char(1072:1103)
ans =
абвгдежзийклмнопрстуфхцчшщъыьэюя

Если в качестве аргументов функции char выступают строки разной длины,


то функция возвращает символьный массив, дополняя более короткие аргу-
менты пробелами справа:
» char ('ABC, 4234')
ans =
ABC
1234
Наконец, аргументом функции char может быть массив ячеек, каждая из
которых, в свою очередь, представлена строкой. И в этом случае функция
char в качестве результата тоже возвращает символьный массив, размещая в
каждой его строке очередную ячейку и выравнивая длины строк (при-
мер 5.3).
168 Глава 5
; " ' • • " • " ' — .

; Пример 5.3. Преобразование массива ячеек в символьный массив j


• •--. —...;.....,...,.:;.. ...;.....-......... .,;,, ;:.....:....;....... ...;.-......,«л....,,) ;...^i

» S=char({'ABC, 4234'})
S =
ABC
1234
» whos
Name Size Bytes Class
S 2x4 16 char array
Grand total is 8 elements using 16 bytes

Таким образом, с помощью функции char допустимо формировать сим-


вольные строки или массивы строк. И в качестве ее аргументов могут вы-
ступать не только отдельные строки, но и символьные массивы.
Для доступа к любому фрагменту строки можно использовать пару индек-
сов, разделенных двоеточием (пример 5.4).
; — • — • • • • •

I Пример 5.4. Выделение фрагментов строки

» S='C Новым Годом!';


» S(l:2)
ans =
С
» S(3:8)
ans =
Новым
» S(9:end)
ans =
Годом!

Служебное слово end заменяет максимальное значение индекса.


Из массива строк с помощью двух индексов i и j (i — номер строки, j
номер столбца) можно извлечь любой символ (пример 5.5).

;..,,............................. ,.
; Пример 5.5. Извлечение символа из массива строк •
» s = c h a r ( [ 4 8 49 50; 65 66 67; 1088 1089 1090])

012
Обработка символьных данных 169

две
рст
» s(2,3)
ans =
С

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

llIliiMMllWlIUlMl
нение строки из массива

ans =
ABC
» s (2,l:end)
ans =
ABC

Из массива ячеек с помощью индексных выражений можно извлечь кон-


кретную ячейку, строку или столбец ячеек (пример 5.7).

Пример 5.7. Извлечение строки из массива ячеек

» s _ c = [ { U 2 3 \ 'ABCD'};{'4567', ' a b c ' } ]


s_c =
'123' 'ABCD'
M567 1 'abc'
» s_c(l,2)
ans =
'ABCD'
» s_c(l:2)
ans =
423' '4567'
» s_c
ans =
'123' 'ABCD'

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


качестве разделителей слов. Иногда их приписывают в начало или в конец
строки для того, чтобы произвести соответствующее выравнивание по левой
границе или по длине. Для формирования строки, содержащей заданное
170 Глава 5

количество пробелов, можно воспользоваться функцией blanks (п). Лиди-


рующие и концевые пробелы можно удалить с помощью функции debiank.
Если в строке присутствуют начальные и конечные пробелы, то, не изменяя
длину строки, с помощью функции s t r j u s t можно ее значимое содержимое
разместить строго по центру, прижать к левой или правой границе
(пример 5.8).

! Пример 5.8. Выравнивание строки i

» S=' 12345
S =
12345
» SL=strjust(S,'left')
SL =
12345
» SC=strjust(S,'center')
SC =
12345
» SR=strjust(S,'right')
SR =
12345
» SRl=strjust(S)
SRI =
12345
>> whos
Name Size Bytes Class
S lxll 22 char array
SC 1x11 22 char array
SL lxll 22 char array
SR lxll 22 char array
SRI lxll 22 char array
Grand total is 55 elements using 110 bytes

В отличие от языка С, строки MATLAB не завершаются нулевым байтом.


Это означает, что набор символьных данных класса char хранит длину те-
кущего значения строки, которое может быть опрошено с помощью функ-
ции length:
» length ('ABC)
ans =
3
Обработка символьных данных 171

Применение функции length к символьному массиву позволяет определить


длину любой его строки:
» S=['ABC '; 4234']
S=
ABC
1234
» length(S)
ans =
4

MATLAB позволяет работать со строками практически неограниченной длины.


Строку или массив строк, запрлненные одним и тем же символом, можно
создать с помощью функции repmat (размножение матрицы) — пример 5.9.

I Пример 5.9. Заполнение строки

» repmat('=',1,4)
ans =

» repmat('*',3,4)
ans =

5.2. Конкатенация строк


В простейшем случае результатом конкатенации двух строк si и S2 является
строка, получаемая приписыванием значения S2 вслед за значением si. Та-
кая процедура носит название горизонтальной конкатенации и выполняется с
помощью функции strcat:
S = strcat (SI,S2,S3,...)
Если аргументами функции s t r c a t являются строки, то она возвращает
строку, полученную в результате последовательного присоединения значе-
ний входных операндов друг за другом (пример 5.10).

| Пример 5.10. Конкатенация строк

» S=strcat('123\ 'ABCDEFG')
S =
123ABCDEFG
172 Глава 5

» whos
Name Size Bytes Class
S 1x7 14 char array
Grand total is 7 elements using 14 bytes

Однако в качестве аргументов этой функции могут выступать и символьные


массивы, содержащие одинаковое количество строк. В этом случае результа-
том работы функции s t r c a t является символьный массив, каждая строка
которого получена как горизонтальная конкатенация соответствующих строк-
операндов (пример 5.11).

; Пример 5.11. Конкатенация массивов строк

» S=strcat(['123';'ABC],['5678';'abed'])
n

1235678
ABCabcd
» whos
Name Size Bytes Class
S 2x7 28 char array
Grand total is 14 elements using 28 bytes

Аргументами функции s t r c a t могут быть и массивы ячеек, содержащие


строки разной длины. В этом случае результирующий массив также будет
состоять из ячеек, полученных с помощью горизонтальной конкатенации
содержимого соответствующих ячеек (пример 5.12).
г ,
; Пример 5.12. Конкатенация массивов ячеек I

» S=strcat({'123','ABCD'},{'45678','xz'})
S =
42345678' 'ABCDxz'
» whos
Name Size Bytes Class
S 1x2 148 cell array
Grand total is 16 elements using 148 bytes

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


ее выполнения — в отличие от аналогичной операции сцепления строк мас-
сива функция s t r c a t игнорирует пробелы в конце строки (пример 5.13).
Обработка символьных данных 173

эок с пробелаи

» strcatCC ','Новым ' , 'Годом!')


ans =
СНовымГодом!
» strcatCC',' Новым',' Годом!')
ans =
С Новым Годом!
» ['С ','Новым ','Годом!']
ans =
С Новым Годом!
1
» ['С.', Новым',' Годом!']
ans =
С Новым Годом!

Кроме горизонтальной конкатенации строк MATLAB предлагает и верти-


кальную конкатенацию, выполняемую с помощью функции strvcat
(пример 5.14).

; Пример 5.14. Вертикальная конкатенация строк


'.. .„ ....... :..:...;....,.........;
» S=strvcat('123','ABCDEFG')
S =
123
ABCDEFG
» whos
Name Size Bytes Class
S 2x7 28 char array
Grand total is 14 elements using 28 bytes

В отличие от горизонтального присоединения операндов при вертикальной


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

: Пример 5.15. Вертикальная конкатенация масси

» S=strvcat(['123';'ABC'],['5678';'abed']
S=
123
174 Глава 5

ABC
5678
abed
» whos
Name Size Bytes Class
S 4x4 32 char array
Grand total is 16 elements using 32 bytes

Вертикальная конкатенация массива ячеек, состоящего из строк, преобразу-


ет свой единственный операнд в символьный массив (пример 5.16).

i Пример 5.16. Вертикальная конкатенация массива ячеек ;


;, }

» S=strvcat({'123*,'ABCD'})
S —
123
ABCD
» whos
Name Size Bytes Class
S 2x4 16 char array
Grand total is 8 elements using 16 bytes

Несмотря на то, что процедура горизонтальной конкатенации напоминает


функцию с аналогичным названием из библиотеки С (раздел string.h), воз-
можности ее в системе MATLAB гораздо шире за счет использования опе-
рандов-массивов.

5.3. Сравнения символьных данных


Так как символьные данные представлены в памяти компьютера числовыми
кодами своих символов, упорядоченными в алфавитном порядке, то их можно
сравнивать примерно как и значения числового типа. В- большинстве алго-
ритмических языков именно так и поступают, выясняя, равны или не равны
сравниваемые строки, какая из них меньше или больше. Два последних соот-
ношения позволяют определить порядок следования строк при их лексико-
графическом упорядочивании (т. е. при сортировке в алфавитном порядке).
В большинстве систем программирования, конечно, возникают разного рода
проблемы, связанные со сравнением русскоязычных строк или с преобразо-
ванием символьных данных к верхнему или нижнему регистрам. Например, в
кодовой странице MS-DOS с номером 866 между кодами малых букв "п" и "р"
затесались символы псевдографики, а коды букв "ё" и "Ё" расположены не на
Обработка символьных данных 175

своих законных местах. Такого же рода участь постигла буквы "ё" и "Ё" в-ко-
довой странице Windows с номером 1251.
Функции сравнения символьных данных, представленные в MATLAB, про-
изводят проверку только на равенство или неравенство операндов, в качест-
ве которых могут выступать не только строки, но и массивы строк. В по-
следнем случае операция сравнения выполняется над каждой парой
элементов с одинаковыми индексами. Результат каждого такого сравнения
вырабатывает логический признак 1 (истина) в случае совпадения значений
и логический признак о (ложь) в случае несовпадения. Если все промежу-
точные сравнения выработали единичные признаки, что свидетельствует об
абсолютном тождестве сравниваемых данных, то функция возвращает логи-
ческое значение 1. Если хотя бы в одном промежуточном сравнении обна-
ружено расхождение, то функция возвращает логическое значение о. Если
сравниваемые данные представлены массивами ячеек одинаковой размерно-
сти, то функция сравнения возвращает логический массив той же размерно-
сти, где каждый элемент равен 1 или о в зависимости от совпадения или
несовпадения значений соответствующих ячеек.
Для сравнения символьных данных язык MATLAB предлагает четыре функ-
ции: strcmp, strcmpi, strncmp и strncmpi. Первая из них производит по-
символьную проверку на равенство или неравенство всех элементов сравни-
ваемых операндов, вторая выполняет аналогичное сравнение, игнорируя
разницу между кодами больших и малых букв, третья сравнивает только за-
данное количество начальных символов, четвертая сочетает в себе возмож-
ности второй и третьей (пример 5.17).

: Пример 5.17. Сравнение символьных данных :


• '...., ,.,.,.., ,» ,, , , „ i

%Сравнение векторов-строк

» S1='ABCDEFGH';
» S2='ABCDefgh';
» S3='ABCabc';
% Сравнение на абсолютное совпадение всех символов
» strcmp(S1,S2)
ans =
О
% Сравнение с игнорированием разницы между большими и малыми буквами
» strcmpi(SI,S2)
ans =
1
176 Глава 5
% Сравнение на абсолютное совпадение первых 3 символов
» strncmp(Sl,S2,3)
ans =
1
» whos
Name Size Bytes Class
SI 1x8 16 char array
S2 1x8 16 char array
S3 1x6 12 char array
ans lxl 1 logical array
Grand total is 23 elements using 45 bytes
% Сравнение символьных массивов

» SM1=['1234567';• АБВГДЕЕ'];
» SM2=['1234567';' АБВГдее'];
» strcmp(SMl,SM2)
ans =
1
» strncmp(SMl,SM2,4)
ans =
1
» strcmpi(SMI,SM2)
ans =
0
» SM3=['1234 56';' АБВГДЕ'];
» SM4=['123456';' АБВгде'];
» strcmpi(SM3,SM4)
ans =
1
% Сравнение массивов символьных ячеек
g. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

» SC1=[{'1234'},{'ABCDEFGH'}];
» SC2=[{4235'},{'ABCDefgh'}];
» strcmp(SCl,SC2)
ans =
0 0
» strcmpi(SCI,SC2)
ans =
0 1
Обработка символьных данных 177

» whos
Name Size Bytes Class
SCI 1x2 144 cell array
SC2 1x2 144 cell array
ans 1x2 2 logical array
Grand total is 30 elements using 290 bytes
>> strncmp(SCl,SC2 ,3)
ans =
1 1

Обратите внимание на результаты сравнения массивов (SMI, SM2) И


(SM3, SM4) с помощью функции strcmpi. В операционной системе Windows
ХР буквы "Ё" и "ё" сравниваются нормально, несмотря на то, что разница
между их числовыми кодами отличается от разницы между числовыми ко-
дами больших и малых букв русского алфавита. В предыдущих версиях
MATLAB результат такого сравнения был противоположным.
Одним из аргументов в операции сравнения может быть скалярная величи-
на, и тогда она сопоставляется с каждым элементом второго аргумента —
массива строк или ячеек. Возвращаемый результат в этом случае будет логи-
ческим массивом.
К группе процедур сравнения следует отнести функции isspace и i s i e t t e r ,
операндами которых могут быть строки, массивы строк или массивы сим-
вольных ячеек. Обе функции возвращают логический массив такой же раз-
мерности, как и размерность операнда. Функция isspace заносит в пози-
цию результата, соответствующую каждому проверяемому символу, 1
(логическая истина) или о (логическая ложь) в зависимости от того, являет-
ся или не является анализируемый символ белым пробелом. Множество бе-
лых пробелов составляют символы НТ (горизонтальная табуляция — код
0x09), LF (перевод строки — код ОХОА), VT (вертикальная табуляция — код
Охов), FF (новая страница — код Охос), CR (возврат каретки — код OXOD) И
настоящий пробел (код>0х20). Функция i s i e t t e r анализирует, является или
не является проверяемый символ буквой (пример 5.18).

I Пример 5.18. Проверка наличия пробелов и символов в

» isspace('С Новым Годом!')


ans =
Columns I through 11
0 1 0 0 0 0 0 1
Columns 12 through 14
0 0 0
178 Глава 5

» isletter('C Новым Годом!')


ans =
Columns 1 through 11
1 0 1 1 1 1 1 0 1 1 1
Columns 12 through 14
1 1 0
» whos
Name Size Bytes Class
ans 1x14 14 logical array
Grand total is 14 elements using 14 bytes

5.4. Поиск и замена


Функции findstr и strfind предназначены для поиска всех вхождений од-
ной строки в другую (пример 5.19). Разница между ними заключается в том,
что функция findstr демократичнее и позволяет задавать операнды в лю-
бом порядке — сначала более длинная строка, а потом более короткая, и
наоборот. Функция s t r f i n d выполнена в стиле стандартов универсальных
алгоритмических языков, и искомая подстрока обязательно должна быть
представлена вторым аргументом.

; в символьных данных

» Sl='00';
» S2='2OO3';
» S3='100002';
» findstr(SI,S2) % Порядок операндов роли не играет
ans =
2
» findstr(S2,SI) % Порядок операндов роли не играет
ans =
2
» strfind(SI,S2) % Порядок операндов важен
ans =
[]
» strfind(S2,SI) % Порядок операндов важен
ans =
2
» S3='100002';
Обработка символьных данных 179

» findstr(S3,S1) % Пример множественного вхождения


ans =
2 3 4
» whos
Name Size Bytes Class
51 1x2 4 char array
52 1x4 8 char array
53 1x6 12 char array
ans 1x3 24 double array

Приведенные выше функции возвращают результат поиска в виде числового


массива типа double, каждый элемент которого определяет индекс символа,
с которого обнаружено очередное вхождение.
Другой вариант поиска можно осуществить в массиве строк или в массиве
ячеек с помощью функции strmatch (пример 5.10). Ее особенность заклю-
чается в том, что в массиве, представленном первым аргументом, отыскива-
ются строки, начинающиеся со значения второго аргумента. Внутреннее
вхождение поискового образа здесь во внимание не принимается. При до-
бавлении третьего аргумента 'exact 1 функция strmatch возвращает номера
только тех строк первого операнда, которые в точности совпадают с поиско-
вым образом.

Пример 5.20. Поиск в символьных данных с использованием функции


:
strmatch . '., ' . • • :
' . . .' • ' .:••:;'••••''•"]

Поиск в массиве строк

» SM=strvcat('com','compare','computer')
SM =
com
compare
computer
» strmatch('com',SM) % поиск строк, начинающихся с 'com'
ans =
1
2
3
» strmatch('com',SM,'exact') % поиск точного совпадения
ans =
1
180 Глава 5

» S='123com';
» strmatch{'com',S) % внутреннее вхождение игнорируется
ans =
[]
% Поиск в массиве ячеек

» SC={ 'com';'compare'; 'computer'}


SC =
'com'
'compare
'computer'
» strmatch( •com'jSC)
ans =
1
2
3
» whos
Name Size Bytes Class
S 1x6 12 char array
SC 3x1 216 cell array
SM 3x8 48 char array
ans 3x1 24 double array

Как можно заметить из приведенного примера, возвращаемое значение


функции strmatch представлено числовым массивом типа double.
Функция s t r r e p ( s t r i , s t r 2 , str3) предназначена для поиска в строке s t r i
всех вхождений заданной цепочки символов str2 и замены каждой из них
новым значением s t r 3 (пример 5.21). Если поиск не увенчался успехом, то
функция s t r r e p возвращает строку s t r i .
: "
I Пример 5.21. Поиск и замена в символьных данных •
-.. .;......; ;..... *; .:......;...... V......... ....:
» S='12341234';
» Sl=strrep(S,'123','ABCD')
51 =
ABCD4ABCD4
» S2=strrep(S,424','ABCD')
52 =
12341234
Обработка символьных данных 181

Замещающее значение может быть пустой строкой, и таким образом легко


удалить ненужную цепочку символов (пример 5.22).
. . , . . ; , . . . . . . . . . . . . . . . . . . . . . . . . . . , . . . . ^ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , . , . ..•-••• • - :

: Пример 5.22. Удаление цепочки символов ;


; i ;........ ..........: ....: ..; ..;.....; ;..;„, ........... ....„...„ i

» S3=strrep(S,'123', " )
S3 =
44

Если один из аргументов функции s t r r e p представлен массивом ячеек, то


возвращаемый результат тоже преобразуется в массив ячеек (пример 5.23).

;•• • • ..,,.,..,.......,... , ......,.....„.....,,..,.„ .,„...,
I Пример 5.23. Поиск и замена в массиве ячеек ;

» Sl='12341234';
» S2=strrep(Sl, 423', { " } )
S2 =
'44'
» whos
Name Size Bytes Class
51 1x8 16 char array
52 lxl 64 cell array

Термин лексема обозначает цепочку символов, завершающуюся тем или


иным разделителем. Например, в предложении лексемами являются слова,
признаком конца которых могут быть разные разделители — пробелы, запя-
тые, точки, тире и др. При разработке трансляторов довольно часто прихо-
дится выделять лексемы типа служебных слов, имен функций, операндов,
выражений и т. п. Облегчить эту работу вам поможет функция strtok, ос-
новным аргументом которой является анализируемая строка. По умолчанию
данная функция рассматривает в качестве символа-разделителя любой бе-
лый пробел. Выходных аргументов у этой функции два:
[t,r]=strtok(S)
В строку t заносится найденная лексема, а в строку г — оставшаяся часть
строки s (пример 5.24).

> 5.24. Выделение лексем :


" ..: ........ .:
» S='С Новым Годом!',
» [tl,rl]=strtok(S)
182 Глава 5

tl =
С
rl =
Новым Годом!
» [t2,r2]=strtok(rl)
t2 =
Новым
r2 =
Годом!
» [t3,r3]=strtok(r2)
t3 =
Годом!
гЗ =
Empty string: l-by-0

Второй необязательный аргумент функции s t r t o k позволяет задать нестан-


дартный набор символов-разделителей (пример 5.25).
; • • • • • ' • — • • • • • • • - • • • • . .............*........... ............ .............

; Пример 5.25. Выделение лексем с нестандартными разделителями :


;..., .......... .:...............-........ .......Г.......... ;
» S='a+b*c';
» [tl,rl]=strtok(S,'+*')
tl =
а
rl =
+b*c
» [t2,r2]=strtok(rl,'+*')
t2 =
b
r2 =
*c
» [t3,r3]=strtok(r2,'+*')
t3 =
с
гЗ =
Empty string: l-by-0
Обработка символьных данных 183

5.5. Преобразования к верхнему


и нижнему регистрам
Функция strcmpi позволяет сравнивать строки, игнорируя разницу между
большими и малыми буквами. На самом деле для выполнения такой процеду-
ры можно воспользоваться одним из двух алгоритмов — предварительно пре-
образовать коды всех символов к нижнему (т. е. к строчным буквам) или к
верхнему (т. е. к прописным буквам) регистру, а затем произвести посимволь-
ное сравнение. Такое преобразование, если оно понадобится в вашей про-
грамме, МОЖНО ВЫПОЛНИТЬ С ПОМОЩЬЮ ОДНОЙ ИЗ ФУНКЦИЙ — lower ИЛИ upper
(пример 5.26).

I Пример 5.26. Преобразование регистра !


• ........,..' ...... . . . . . . . . . . , .... i

>> lower('Happy New Year - С Новым Годом!')


ans =
happy new year - с новым годом!

» upper('Happy New Year - С Новым Годом!')


ans =
HAPPY NEW YEAR - С Новым Годом!

MATLAB 7, в отличие от предыдущих версий, правильно обрабатывает


строки, содержащие буквы "ё" и "Ё":
» lower('ЁЛКА')
ans =
ёлка
» upper('ёлка')
ans =
ЁЛКА

5.6. Преобразования строк и чисел


Значения числовых скалярных величин и элементов массивов типа double
могут быть преобразованы из машинного представления в соответствующие
символьные строки с помощью функций num2str и i n t 2 s t r . Первая из них
преобразует компоненты единственного аргумента с четырьмя цифрами в
дробной части (пример 5.27).

7 Зак 899
184 Глава 5

а Н и е Ч И С Л а
I '. .'.... .ВС1рОку... ' < * » • < , « . » U l . K K d t l ' I . M «
••.

k . k

l t . O K

M
' " - • ' • • '

> * ' • •
!

» num2str(pi)
ans =
3.1416
» whos
Name Size Bytes Class
ans 1x6 , 12 char array
Grand t o t a l i s 6 elements using 12 bytes

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


цифр в дробной части результата, однако бесполезно задавать его значение
большим, чем это предусмотрено форматом double (пример 5.28).
••••• ' ' • • • • • • • • — • •• - • ••••*•••:

Пример 5.28. Преобразование I в строку с заданной точностью

» num2str(pi,10)
ans =
3.141592654
» num2str(pi, 20) % Больше 17 цифр формат double не хранит!
ans =
3.1415926535897931

Аргумент функции num2str может быть и комплексным числом (при-


мер 5.29).

! Пример 5.29. Преобразовани


'.. . ......\.ъ:;;.-.г..м..ж.-..:-.,.я :

» x=sqrt(-2)
х=
0 + 1.4142i
» num2str(x,10)
ans =
0+1.4142135621
» whos
Name Size Bytes Class
ans 1x14 28 char array
x lxl 16 double array (complex)
Grand total is 15 elements using 44 bytes
Обработка символьных данных 185

Вообще, функция num2str допускает гибкое управление форматом преобра-


зования числовых данных (пример 5.30) подобно тому, как это делает про-
цедура sprint f.
; " • • • • • • • - • :•••••• • • • • • • • - • • • • • • • • • • -

; Пример 5.30. Форматное преобразование числа в строку

» num2str(pi,'pi=%6.2f )
ans =
pi= 3.14
» whos
Name Size Bytes Class
ans 1x9 18 char array
Grand total is 9 elements using 18 bytes

Функция i n t 2 s t r предварительно округляет компоненты своего числового


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

I Пример 5.31. Преобразование целого числа в строку ;


I. .................'..-...... ;....i i'.. J

» x = [ [ 0 . 1 0.5 0 . 8 ] ; [ 1 0 0 . 1 100.5 100.8]]

0.1000 0.5000 0.8000


100.1000 100.5000 100.8000
» int2str(x)
ans =
0 1 1
100 101 101
» whos
Name Size Bytes Class
x 2x3 4 8 double array
ans 2x13 52 char array
Grand total is 32 elements using 100 bytes
» x=NaN;
» int2str(x)
ans =
NaN
» x=Inf;
» int2str(x)
186 Глава 5

ans =
Inf
» x=realmin
x=
2.2251e-308
» int2str(x)
ans =
0
» x=realmax

1.7977e+308
» int2str(x)
ans =
17 97 693134 862315700000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000
» length(ans)
ans =
309

Если в качестве аргумента функции i n t 2 s t r задано комплексное число,


то преобразование выполняется только над вещественной частью (при-
мер 532).

Пример 5.32. Преобразование комплексного числа в строку


функцией int2str

» x=sqrt(-2)+5.8
X =
5.8000 + 1.4142i
» int2str(x)
ans =
6

Обратные преобразования числовых данных из символьного представления


в машинный формат типа double выполняются с помощью функций
str2double и str2num. Первая из них осуществляет преобразование единст-
венного значения, в символьном представлении которого использованы все
Обработка символьных данных 187

допустимые знаки — цифры, точка, плюс или минус, буква е, предшест-


вующая порядку числа, запятые, разделяющие число тысяч, буквы i или j ,
символизирующие мнимую часть комплексного числа (пример 5.33).
р..... ;
| Пример 5.33. Преобразование строки в число :

» Sl=str2double('3.14159265')
S1 =
3.1416
» Sl=str2double( 4,000, 000'•)
SI =
1000000
» Sl=str2double('le6')
SI =
1000000 .
» Sl=str2double('l-2j')
SI =
1.0000 - 2.0000i

Функция str2num позволяет преобразовать числовые данные, представлен-


ные элементами символьного массива (пример 5.34).

j Пример 5.34. Преобразование символьного массива в число :

>;> S=['1 2' •3 4']


S =
1 2
3 4
>:> str2num(S)
ans =
1 2
3 4
>> whos
Name Size Bytes Class
S 2x3 12 char array
ans 2x2 32 double array
Grand total is 10 elements using 44 bytes
188 Глава 5

В символьной записи чисел не должно быть лишних пробелов, т. к. это мо-


жет привести к труднообнаруживаемой ошибке (пример 5.35).

! Пример 5.35. Влияние пробелов на преобразование строки в число I


! .. Г. :.. .....~ ~. Г. .. •
» x=str2num('1-2j ')
х =
1.0000 - 2.0000i
» y=str2num('1 -2j')
У =
1.0000 0 - 2.0000i

» whos
Name Size Bytes Class
x lxl 16 double array (complex)
у 1x2 32 double array (complex)

В первом случае результатом преобразования является единственное ком-


плексное число, тогда как во втором случае — вектор из двух чисел.
В отдельную группу функций следует выделить процедуры преобразования
числовых данных, символьное представление которых зависит от исполь-
зуемой системы счисления, — dec2bin, dec2hex, dec2base, bin2dec,
hex2dec, base2dec, hex2num. Шесть первых функций ИМеЮТ дело С цеЛЫМИ
десятичными числами (dec — от англ. decimal) и их символьным представ-
лением в двоичной (bin — от англ. binary) и шестнадцатеричной (hex — от
англ. hexadecimal) системах, а также в любой другой системе счисления с
заданным основанием (base) в диапазоне от 2 до 36. Цифра 2 в названии
каждой функции ассоциируется с предлогом "в" (англ. two — "два" и to — "в"
звучат одинаково). Эти функции осуществляют прямое и обратное преобра-
зования между целыми десятичными числами формата double и соответст-
вующим символьным представлением этих же чисел в заданной системе
счисления. Функция dec2base очень напоминает функцию itoa из библио-
теки C++. Для тех, кто недоумевает по поводу диапазона основания систе-
мы счисления от 2 до 36, поясним, что для обозначения цифр в системах с
основанием больше 10 используются буквы латинского алфавита. Поэтому
10 цифр и 26 букв латинского алфавита обеспечивают представление чисел в
системе с максимальным основанием 36.
Функция dec2bin(N) преобразует целочисленный положительный аргумент,
не превосходящий 2 5 2 , в строку с двоичным представлением аргумента
(пример 5.36).
Обработка символьных данных 189

1\'-щшшшшшшдшш5: •• • : """""шшш
Перевод числа в двоичную систему
* ' . • • • . . . •
\
;

» dec2bin(792) % Перевод в двоичную систему


ans =
1100011000

Второй необязательный аргумент функции dec2bin(N,k) задает количество


двоичных цифр, которое следует сохранить в результате. Его не имеет смыс-
ла указывать меньше, чем фактическое количество разрядов в двоичном
представлении числа:
» dec2bin(792,5) % Перевод в двоичную систему с 5 цифрами
ans =
1100011000
» dec2bin{792,12) % Перевод в двоичную систему с 12 цифрами
ans =
001100011000
Если основной аргумент функции dec2bin представлен числовым массивом,
то результат преобразования будет получен в виде массива строк, длина ко-
торых выровнена по максимальному числу:
» а=[148 1023;525 7 9 2 ] ;
» dec2bin(a) % Перевод в двоичную систему числового массива
ans =
0010010100
1000001101
1111111111
1100011000
Аналогичный перевод в строку с шестнадцатеричным представлением аргу-
мента выполняет функция dec2hex (пример 5.37).
• : : •••••• • •

Пример 5.37. Перевод числа в шестнадцатеричную систему

» dec2hex(792) % Перевод в шестнадцатеричную систему


ans =
318
» dec2hex(792,5) % Перевод в шестнадцатеричную систему с 5 цифрами
ans =
00318
» а=[148 1023;525 792];
» dec2hex(a) % Перевод в шестнадцатеричную систему массива чисел
190 Глава 5

ans =
094
20D
3FF
318

При переводе целого десятичного числа в систему с основанием р значение


р задается вторым аргументом функции dec2base. Необязательный третий
аргумент определяет количество цифр в результате (пример 5.38).
: •••••• ••••••• ••••• :•••:

: Пример 5.38. Перевод числа в произвольную систему счисления I


; ;........ .i.fMMHHI

» dec2base(792,5) % Перевод в пятеричную систему


ans =
11132
» dec2base(792,5,8) % Перевод в пятеричную систему с 8 цифрами
ans =
00011132

Функции bin2dec, hex2dec и base2dec преобразуют строку с символьной


записью числа в двоичной, шестнадцатеричной или произвольной системе
счисления в машинный формат целого числа типа double (пример 5.39).

i Пример 5.39. Преобразование числа в десятичную систему !

» bin2dec('1100011000')
ans =
792
» hex2dec('318')
ans =
7 92
» base2dec('11132',5)
ans =
792

Если аргументом этих функций является массив строк, то каждая строка


рассматривается как символьный эквивалент целого положительного числа
в соответствующей системе счисления (пример 5.40).
Обработка символьных данных 191

• " - •
• : ----- • ' '''ШШШШШШ
I Пример 5.40. Преобразование массива строк в десятичную систему I

» bin2dec(['101100';'001101'])
ans =
44
13
» whos
Name Size Bytes Class
ans 2x1 16 double array

Вещественное число в формате типа double занимает 8 байтов оперативной


памяти и может быть компактно записано с помощью 16 шестнадцатеричных
цифр, включающих знак, порядок и мантиссу числа в соответствии со стан-
дартом IEEE — 1 бит на знак, 11 битов на порядок в дополнительном коде и
52 бита на мантиссу. В такой записи, например, число я на IBM-совместимых
Компьютерах ВЫГЛЯДИТ СЛедуЮЩИМ образом — 400921FB54442D18.
Для преобразования такой строки символов в число используется функция
hex2num (пример 5.41).
£.'£••••---• - • •- - -• ..— .......
I Пример 5.41. Преобразование шестнадцатеричного числа
I в десятичную систему !

» format long
» hex2num('400921FB54442D18')
ans =
3.14159265358979

Если аргумент функции hex2num содержит менее 16 символов, то он допол-


няется справа нулями.
Функции mat2str и str2mat занимаются преобразованиями между символь-
ной записью двумерных числовых матриц и их машинным представлением
(пример 5.42).

.
! Пример 5.42. Преобразования символьной записи матриц
:;....,.,;!.... ....:
192 ' Глава 5

У=
[1 2;3 4]
» z=str2mat С [1 2;3 4] ')
z=
[1 2;3 4]
» whos
Name Size Bytes Class
X 2x2 32 double array
У 1x9 18 char array
z 1x9 18 char array
Grand t o t a l i s 22 e l e m e n t s u s i n g 68 b y t e s » x = [ l 2 ; 3 4]

В целесообразность последней процедуры верится с трудом.

5.7. Форматные преобразования


(sprintf, sscanf)
Идеологию функций преобразования числовых и символьных данных по
заданному формату MATLAB заимствовал из языка С, почти полностью со-
хранив набор соответствующих спецификаций. Конечно, определенную
особенность вносит то, что элементом преобразуемых данных может быть
массив. Но тогда действие соответствующего форматного указателя распро-
страняется на каждый элемент массива.
Преобразование списка данных (ai, a2, ...) по формату fmt с записью ре-
зультата в строку s выполняется с помощью функции sprintf:
[s,s_err] = sprintf(fmt,al,a2,...)

Кроме результата преобразования функция sprintf может выработать со-


общение об ошибке во время выполнения операции, которое заносится в
строку s_err. При нормальном завершении операции вместо сообщения об
ошибке выдается пустая строка, которую можно проигнорировать, если об-
ратиться к функции с единственным выходным параметром:
s = sprintf(fmt,al,a2, . . . )

Однако ошибка, обнаруженная при выполнении преобразования, может


привести к получению пустой результирующей строки:
» sprintf (' %ld\pi)
ans =
3.141593е+000
» sprintf('%lf',pi)
Обработка символьных данных 793

ans =
Empty string: l-by-0

Формат %if, допустимый в С и обеспечивающий вывод вещественных чисел


с удвоенной точностью, в системе MATLAB считается недопустимым и при-
водит К сообщению Об ошибке s_err=Invalid format.
Строка формата fmt задает шаблон преобразования, состоящий из специфи-
каций, начинающихся с символа %, и набора литеральных символов, пере-
носимых без всяких изменений из строки формата в результат. Каждая спе-
цификация, управляющая способом преобразования, может содержать до
5 следующих компонентов:
%[флажки][ширина][.точность][{b,t}]a

Обязательными среди них являются начальный символ (%) и завершающая


буква (а).
Флажки задаются как комбинация от одного до трех символов из набора
(-, +, " ", #, 0).
Символ - устанавливает левый прижим. По умолчанию преобразуемое зна-
чение прижимается к правой границе поля заданной ширины.
Символ + устанавливает режим обязательного вывода знака числа (даже ес-
ли преобразуемые числа положительны).
Символ " " (пробел) устанавливает режим вывода Знака положительного
числа пробелом (по умолчанию на знак положительного числа специальная
позиция не отводится).
Символ # влияет на вывод восьмеричных, шестнадцатеричных и веществен-
ных чисел. Перед восьмеричными числами выводится о, перед шестнадцате-
ричными числами — префикс Ох или ох. В символьную запись вещественных
чисел, преобразуемых по форматам f, e и Е, обязательно включается десятич-
ная точка (по умолчанию она опускается, если дробная часть равна 0). В сим-
вольной записи вещественных чисел, преобразуемых по форматам g и G, не
удаляются лидирующие нули и всегда включается десятичная точка.
Символ о при правом прижиме чисел включает режим вывода лидирующих
нулей.
Ниже приведено несколько примеров, демонстрирующих влияние флажков
при выводе целых чисел (пример 5.43).

» s p r i n t f ( ' % - 5 d %+5d %05d',123,123,123)


ans = i
123 +123 00123
» sprintf('%x %#X\123,123)
194 Глава 5

ans =
7b 0X7B
» s p r i n t f ( ' % d',123)
ans =
123
» s p r i n t f ( ' % d',-123)
ans =
-123

Ширина, задаваемая целым числом, определяет количество позиций (симво-


лов), которое отводится под преобразуемое значение. Точность, также зада-
ваемая целым числом, определяет количество дробных цифр, сохраняемых в
преобразованном значении:
» sprintf (' %10. 6f,pi)
ans =
3.141593

Символ а, завершающий форматную спецификацию, определяет вид преоб-


разованного значения и должен согласовываться с типом преобразуемого
данного. Возможные варианты этого символа приведены в табл. 5.1.

Таблица 5.1

Спецификатор Ф о р м а т результата

%с Единственный с и м в о л
%d Целое десятичное число с о з н а к о м
%е В е щ е с т в е н н о е число в ф о р м е с п л а в а ю щ е й запятой (порядок
идентифицирует буква е)
%Е В е щ е с т в е н н о е число в ф о р м е с п л а в а ю щ е й запятой (порядок
и д е н т и ф и ц и р у е т буква Е )
%f В е щ е с т в е н н о е число в ф о р м е с ф и к с и р о в а н н о й запятой
%д Компактная ф о р м а числа с фиксированной или плавающей запятой
%G Компактная ф о р м а числа с фиксированной или плавающей запятой
%о Целое восьмеричное число без з н а к а
%s Строка символов
%и Целое десятичное число без з н а к а
%х Целое шестнадцатеричное число с м а л ы м и б у к в а м и a — f
%х Целое шестнадцатеричное число с б о л ь ш и м и б у к в а м и A—F
Обработка символьных данных 195

Спецификаторы %d, %u, %o, %x и %х имеет смысл применять к целочислен-


ным значениям (хотя и представленным в оперативной памяти в формате
double). Если соответствующий элемент списка не является целым числом,
то MATLAB заменяет целочисленную спецификацию на формат веществен-
ного числа:
>> sprintf('%d',pi)
ans =
3.141593e+000

Однако после округления спецификатор %d действует нормально:


» sprintf('%d',round(pi))
ans =
3
Символ ь или t, предшествующий символу-спецификатору, позволяет пре-
образовать в восьмеричный или шестнадцатеричный формат вещественные
числа стандарта IEEE. Они используются в сочетании с форматными указа-
телями %о, %х или %х. Однако результат их применения может удивить в
связи с перестановкой байтов, характерной для IBM-совместимых компью-
теров (пример 5.44).

» sprintf{'%bx',pi)
ans =
182d4454fb210940 % Здесь переставлены байты
» format long
» hex2num('400921FB54442D18')
ans =
3.14159265358979
» sprintf C%bx',l) \
ans =
000000000000f03f
» hex2num('3ff0000000000000')
ans =
1
» sprintf C%tx',l)
ans =
3f800000
196 ; Глава 5

Все символы, включенные в состав строки fmt и не относящиеся к формат-


ным спецификациям, являются литералами, которые без изменения перено-
сятся в результирующую строку:
» sprintf('rra=%10.8f',pi)
ans =
пи=3.14159265
Среди литералов могут присутствовать управляющие символы и специаль-
ные знаки, запись которых выполняется в соответствии с правилами языка
С (табл. 5.2).

Таблица 5.2

Символ Назначение
\Ь Удаление предшествующего символа (Backspace)
\f Перевод страницы (Form feed)
\п Перевод строки (New line)
\г Возврат каретки (Carriage return)
\t Горизонтальная табуляция (Horizontal tab)
\\ Обратная косая черта (Backslash)
\' Одинарная кавычка С)
%% Процент (%)

Обратная операция по извлечению данных из строки s, сформированной


функцией sprintf, выполняется с помощью функции sscanf:
А = sscanf(s,fmt)

Этот вариант вызова обеспечивает выборку всех данных и их обратное пре-


образование из символьного представления в машинное в соответствии с
форматными указателями строки fmt. Форматные спецификации здесь те же
самые, что и при преобразовании в строку (см. табл. 5.1), хотя некоторые
детали, характерные для вывода данных (прижим, точность, префиксы
и т. п.), в обратном преобразовании не используются.
Среди дополнительных средств управления форматом выделим использование:
• флажка, задаваемого символом *, обеспечивающего пропуск очередного
данного в строке s;
• форматов %hd, %id и %ig, позволяющих преобразовать извлекаемое число
в машинный формат короткого целого (%hd), длинного целого (%id) или
вещественного числа с удвоенной точностью (%lg);
Обработка символьных данных 197

П формата %[sis2...], обеспечивающего извлечение только тех символов


из строки s, которые перечислены в квадратных скобках;
• формата % [~sis2 . . . ], обеспечивающего извлечение только тех символов
из строки s, которые не перечислены в квадратных скобках.
Для программистов, работавших на языке С, будет довольно непривычно
увидеть следующее использование единственного форматного указателя
(пример 5.45).

| П р и м е р 5.45. И с п о л ь з о в а н и е е д и н с т в е н н о г о ф о р м а т н о г о у к а з а т е л я i
lnlMMII «••Illllttl, Milt ^ll.tLIHIll..!. мННКНММИНПП';* •••>« I I I • tl •• », • I i » „ j , I I I I „.. .. I ., .• I M I • I I I I M I. 1
» s = '2.7183 3.1416';
» A = sscanf(s,'%f')
A «.
2.7183
3.1416

Однако ведь и при прямом преобразовании в строку для массива А требова-


лась тоже только одна спецификация формата:
» sl=sprintf('%f ',A)
si =
2.718300 3.141600

Обратите внимание на использование литерального пробела в формате. Без


него оба числовых значения оказались бы "склеенными", и для их разделе-
ния потребовались бы определенные усилия (пример 5.46).
,.........,...,.......,......„...,, ,,..,.,,,....,..„,..,.,,,.-,... ••••— • — '
I Пример 5.46. Отсутствие разделителя в формате I
1 ... ........Т....Г......... ............................................. •

» sl=sprintf('%f',A)
si '=
2.7183003.141600
» s2=sl(l:8)
s2 =
2.718300
» s3=sl(9:end)
s3 =
3.141600
198 Глава 5

Впрочем, склейки можно было бы избежать за счет использования ширины,


точности и прижима:
» sl=sprintf ('%-8.4f \A)
si =
2.7183 3.1416

Функция sscanf допускает и другие варианты вызова, обеспечивающие из-


влечение только заданного количества данных или их извлечение в цикле:
А = sscanf(s,fmt,size)
[A,count,s_err,nextindex] = sscanf(s,fmt)

5.8. Регулярные выражения и поиск


В разд. 5.4 рассматривались процедуры поиска заданного текста. При этом
разрешались две возможности. Кроме абсолютного совпадения искомого
фрагмента с заданным текстом допускалось игнорировать разницу между
большими и малыми буквами. Более широкие возможности для поиска в
текстовом документе предоставляют так называемые регулярные выражения.
В шаблоне, формируемом с помощью регулярных выражений, разрешается
задавать не только те символы, которые должны присутствовать в искомом
фрагменте. Например, если мы собираемся извлечь из текста семизначный
номер телефона, то можно составить шаблон поиска следующим образом:
"три_цифры тире две_цифры тире две_цифры". Или мы точно не знаем фа-
милию человека — то ли "Корягин", то ли "Калягин". В этом случае может
помочь поисковый шаблон, в котором указано, что фамилия начинается с
буквы "К", после нее следуют две какие-то буквы, а окончание имеет вид
"ягин". Это позволит найти те данные, значения которых мы точно не зна-
ем. Нечто похожее используют программисты, когда производят поиск фай-
лов по некоторым шаблонам, задаваемым в фильтрах поиска. Например,
показать все файлы с расширением срр — шаблон поиска имеет вид *. срр.
Символ * заменяет собой произвольную цепочку символов, расположенную
перед четырьмя указанными.
Шаблон поиска с применением регулярных выражений представляет собой
строку или массив ячеек строк. Наряду с заранее известными символами в
составе шаблона допускается использование следующих управляющих кон-
струкций:
• точка (.) — для указания позиции любого символа, включая и белый
пробел. Для указания позиции, в которой искомый текст может содер-
жать точку, используется пара символов \.;
Обработка символьных данных 199

• \w — для указания позиции, в которой может находиться буква, цифра


или подчерк, т. е. те символы, которые участвуют в конструировании
слов;
П \w — для указания позиции, в которой может находиться любой символ,
кроме буквы, цифры или символа подчеркивания;
О \s — для указания позиции, в которой может находиться белый пробел;
• \s — для указания позиции, в которой может находиться любой символ
кроме белого пробела;
• \d — для указания позиции, в которой может находиться цифра;
П \D — для указания позиции, в которой может находиться любой символ,
кроме цифры;
• [sis 2 .. .s k ] — для указания позиции, в которой может находиться любой
из символов, перечисленных в квадратных скобках;
• [~sis2. . .sic] — для указания позиции, в которой может находиться лю-
бой из символов, кроме перечисленных в квадратных скобках.
Когда диапазон символов, указываемых в квадратных скобках, непрерывен,
то можно ограничиться заданием начального и конечного символов:
[abode] = [а-е]

Шаблон поиска оформляется в виде строки, в которой указанные выше


управляющие символы могут чередоваться с обычными символами. Напри-
мер, шаблон вида '\W*KO\S' означает, что мы собираемся искать слово,
оканчивающееся буквами "ко", вслед за которыми следует пробел. Заданным
буквам может предшествовать любая цепочка символов, включающая буквы,
цифры и символы подчеркивания.
Обозначим через R, R I , R2 элементарные регулярные выражения, образован-
ные из перечисленных выше конструкций. Их можно объединять в более
сложные шаблоны поиска, выписывая друг за другом, объединяя в круглые
скобки или сопровождая дополнительными указаниями следующего вида:
• (R) * — выражение R может повторяться 0 или более раз;
• (R) + — выражение R может повторяться 1 или более раз;
О (R) ? — выражение R может повторяться 0 или 1 раз;
П R{n,m} — выражение R ДОЛЖНО повторяться от п до m раз;
• R{n} — выражение R должно повторяться ровно п раз;
• R{n,} — выражение R ДОЛЖНО повторяться п или более раз;
• (R11R2) — искомый фрагмент может содержать тексты, удовлетворяющие
либо шаблону RI, либо шаблону R2;
200 Глава 5

• "R — искомый фрагмент должен находиться в начале строки;


• R$ — искомый фрагмент должен находиться в конце строки;
• \<R — искомый фрагмент должен находиться в начале слова;
П R\> — искомый фрагмент должен находиться в конце слова.
Для организации поиска фрагментов текста, удовлетворяющих заданному
шаблону, MATLAB предлагает три функции:
• regexp — поиск всех фрагментов в заданной строке;
П regexpi — поиск всех фрагментов в заданной строке с игнорированием
разницы между большими и малыми буквами;
• regexprep — поиск фрагментов и их замена другим контекстом.
Две первые функции допускают задание от двух до восьми аргументов:
• первый параметр (обязательный) определяет строку, в которой организу-
ется поиск;
• второй параметр (обязательный) представляет шаблон поиска;
• все последующие параметры необязательные. Они задаются строками
'match', 'start', 'end', 'tokens', ' t o k e n E x t e n t s ' , 'names', которые
определяют перечень возвращаемых результатов поиска.
Если ни один из необязательных параметров в обращении не задан, то
функции поиска возвращают начальные индексы найденных фрагментов:
» regexp(423_abc 456_78','\d{3}')
ans =
1 9
Если задан единственный дополнительный параметр 'match', то функция
regexp возвращает текст найденных фрагментов:
» regexp('123_abc 456_78','\d{3}','match')
ans =
423' '456'

Необязательный параметр ' s t a r t ' позволяет дополнительно получить ин-


декс символа, с которого начинается найденный фрагмент:
» [m s ] = r e g e x p ( ' 1 2 3 _ a b c 456J78','\d{3}','match','start')
m=
423' '456'

1 9
Обработка символьных данных 201
Перестановка местами необязательных параметров приводит к аналогичной
перестановке возвращаемых результатов:
» [m s]=regexp('123_abc 456_78','\d{3}','start','match')
т =
1 9
s =
423' '456'

Необязательный параметр 'end' включает в состав возвращаемых результа-


тов индекс последнего символа найденного фрагмента:
» [m indl ind2]=regexp('123_abc 456_78','\d{3}','match','start','end')
m =
'123' '456'
indl =
1 9
ind2 =
3 11

Приведем пример 5.47.

» s ='abCD_ 123#';
» [mat ind]=regexp(s,'\s','match','start';
mat =

ind =

» [mat ind]=regexp(s,'\S','match','start')
mat =
'a' 'b' 'C 'D' '_' '1' '2' '#'
ind =
1 2 3 4 5 7 8 10
» [mat ind]=regexp(s,'\d','match','start')
mat =
4' '2' '3'
ind =
7 8 9
202 Глава 5
» [mat ind]=regexp(s,'\D','match','start')
mat =
'a' 'b' 'C 'D' '_' ' ' '#'
ind =
1 2 3 4 5 6 10
» [mat i n d ] = r e g e x p f s , ' \ w ' , ' m a t c h ' , ' s t a r t ' )
mat =
'a' 'b' 'C 'D' '_' '1' '2'
ind =
1 2 3 4 5 7 8
» [mat ind]=regexp(s,'\W,'match','start')
mat =
' ' '#'
ind =
6 10

Тексты, в которых производится поиск, могут содержать и русские буквы


(пример 5.48).

• Пример 5.48. Использование кириллицы в регуля|


• !: г.
» str='Uapb, царевич, король, королевич';
» pat=' ар | op' ; % R1 или R2
» regexp(str,pat)

2 8 17 25
» patl='H4\>';
» regexp(str,patl) % R в конце слова
ans =
12 31
A
» pat3=' uap';
» regexpi(str,pat3) %R в начале строки
ans =
1

» regexpi(str,pat4) R в конце строки


Обработка символьных данных 203

ans =
31
» pat2='\<цар';
>> regexpi'(str,pat2) % R в начале слова
ans =
1 7

Параметр 'tokens' используется для выделения лексем— цепочек симво-


лов, заключенных между заданными разделителями. Продемонстрируем это
на примере из файла помощи, где лексемой считается цепочка символов,
расположенных между буквами s:
» str = 'six sides of a hexagon';
» pat = 's(\w*)s'; % Шаблон для поиска
» [m s t]=regexp(str,pat,'match','start','tokens')
m =
'sides' % Найденный фрагмент

5 % Начальный индекс
t =
{lxl cell} % Массив ячеек для лексем

ans =
1
ide' % Выделенная лексема
» whos
Name Size Bytes Class
ans lxl 66 cell array
m lxl 70 cell array
pat 1x7 14 char array
s lxl 8 double array
str 1x22 44 char array
t lxl 126 cell array

Мы могли бы заменить офаничитель ' s • набором знаков арифметических опе-


раций и круглыми скобками для того, чтобы выделить операнды в формуле.
Применение регулярных выражений расширяет возможности стандартных
функций поиска — мы можем осуществить поиск и выделение подстрок
текста, удовлетворяющих довольно сложным запросам. Наряду с этим име-
ется возможность произвести нестандартную замену найденного фрагмента
С ПОМОЩЬЮ фуНКЦИИ r e g e x p r e p .
204 Глава 5

В простейшем случае функция использует три обязательных аргумента —


строка, в которой ищется фрагмент, шаблон поиска, которому должен удов-
летворять найденный фрагмент, и текст замены:
» э='Я думаю, он думает, мы думаем';
» pat='дума';
» regexprep(s,pat,'no')
ans =
Я пою, он поет, мы поем

По умолчанию процесс поиска фрагмента учитывает разницу между боль-


шими и малыми буквами:
» Б='Я ДУМАЮ, он ДУмает, они думают';
» regexprep(s,pat,'no')
ans =
Я ДУМАЮ, он ДУмает, они поют

С помощью дополнительного параметра 'ignorecase' включается режим


игнорирования этой разницы:
» regexprep(s,pat,'по','ignorecase')
ans =
Я поЮ, он поет, они поют

Дополнительный параметр ' once' указывает, что замене подлежит только


первый найденный фрагмент:
» regexprep(s,pat,'по','ignorecase','once')
ans =
Я поЮ, он ДУмает, они думают
Процесс замены может использовать информацию о больших и малых бук-
вах. При задании необязательного параметра 'preservecase' в заменяемых
фрагментах сохраняются регистры заменяемых символов:
» s='A_b_C_d_123';
» pat='[A-Z]';
» regexprep(s,pat,'qwerty','preservecase')
ans =
QWERTY_qwerty_QWERTY_qwerty_12 3
Аналогичная операция правильно выполняется и при замене символов рус-
ского алфавита:
» s='Aa_B6_123';
» pat='[А-Я]';
Обработка символьных данных _ ^ 205

» regexprep(s,pat,'эЮя','preservecase')
ans =
ЭЮЯэюя_ЭЮЯэюя_123

Однако если шаблон поиска расширить до нескольких букв, то результат


замены выглядит следующим образом:
» s='Aa_B6_123';
» pat='[А-Я]*';
1
» regexprep(s,pat,'эЮя','preservecase )
ans =
Эюя_Эюя_123

Мы перебрали различные комбинации регистров заменяемых и замещаю-


щих букв, меняли длины старых и новых фрагментов, однако предсказать
результаты замен с использованием параметра 'preservecase' не удалось.
Судите сами:
» s='AbcD_aBCd' ;
» pat='[A-Z]*';
>> regexprep(s,pat,'zx1,'preservecase')
ans =
zx_zx
» regexprep(s,pat,'Zx','preservecase')
ans =
Zx_Zx
» regexprep(s,pat,'zX','preservecase')
ans =
zX_zX
» regexprep(s,pat,'EFgh','preservecase')
ans =
EFgh_EFgh
» regexprep(s,pat,'efgh','preservecase')
ans =
efgh_efgh
» s='ABCD_abcd';
» regexprep(s,pat,'efgh','preservecase')
ans =
EFGH_efgh
>> regexprep(s,pat,'EFgh','preservecase')
206 Глава 5

ans =
EFGH_efgh
» regexprep(s,pat,'EFGH','preservecase')
ans =
EFGH_efgh
» s='Abcd_aBCD';
» regexprep(s,pat,'EFGH','preservecase')
ans =
Efgh_EFGH
» regexprep(s,pat,'EFgh','preservecase1)
ans =
Efgh_EFgh

Очень похоже на то, что алгоритм до конца не продуман.


Глава 6

Работа с файлами
Как правило, файлы представляют собой именованные области внешней
(дисковой) памяти, с которыми программы могут обмениваться информаци-
ей. Необходимость в таких обменах возникает в разных ситуациях. Иногда
объем оперативной памяти недостаточен для хранения нужной информа-
ции, и тогда приходится прибегать к услугам внешней памяти, записывая
туда очередную порцию накопленных данных. В другой ситуации приложе-
ние может воспользоваться своими же данными, ранее записанными на
диск или полученными в результате работы других программ. Вообще гово-
ря, поставщиками или потребителями данных, с которыми наша программа
вступает в контакт, могут быть не только дисковые файлы, но и файлы-
устройства: дисплей, принтер, графопостроитель, сканер, клавиатура, кана-
лы связи и т. п. Данная глава посвящена работе с дисковыми файлами, хотя
обслуживание файлов-устройств происходит по аналогичной схеме.
Оценивая ключевые аспекты процесса обмена данными, можно сказать, что
работа с файлами в основном ограничивается тремя-четырьмя операциями:
• выделение ресурсов и приведение файла в состояние готовности к обме-
ну (именно это скрывается за термином открыть файл);
П чтение (ввод из файла) или запись (вывод в файл) очередной порции
данных;
• возврат выделенных ресурсов и завершение неоконченных операций
(этому соответствует термин закрыть файл).
К числу наиболее важных моментов, связанных с обменом информацией,
следует отнести формат представления данных на внешнем носителе. В боль-
шинстве своем почти все системы программирования (и MATLAB в этом
смысле — не исключение) используют два формата данных — текстовые и
двоичные.
Текстовые или символьные данные состоят из строк,, похожих на те, кото-
рые мы набираем при вводе с клавиатуры или видим при выводе на экране
дисплея. Для текстовых данных характерна переменная длина строки, за-
вершающейся невидимым признаком конца (обычно эту функцию выпол-
208 Глава 6

няют символы типа CR — возврат каретки, LF — перевод строки). Кроме


того, числовые данные в строках представлены в естественном для человека
виде. Это означает, что при вводе символьных данных служебные програм-
мы преобразуют числовую информацию во внутренний формат компьютера,
а при выводе работают другие сервисные программы, которые преобразуют
данные из машинного формата в приемлемый для человека вид.
Из-за переменной длины строк обмен с текстовыми наборами данных прихо-
дится вести последовательно — строка за строкой. Ведь для того чтобы опре-
делить, где в наборе данных находится строка с заданным номером, пришлось
бы перебирать байт за байтом все символы предшествующих строк.
Как правило, объем информации, хранящейся в символьном наборе данных,
заметно превышает длину той же информации в машинном формате.
В основном это относится к данным числового типа. Например, число
71=3.14159265358979 в символьном представлении занимает 16 байтов,
тогда как с таким же количеством значащих цифр его машинный эквива-
лент требует 8 байтов.
Таким образом, текстовое представление данных имеет ряд минусов — оно
менее эффективно по объему используемой памяти, требует дополнитель-
ных затрат на преобразование между машинным и символьным форматами,
допускает только последовательный обмен между программой и внешним
носителем. Однако главные преимущества текстовых данных заключаются в
их естественности для восприятия человеком и в независимости их пред-
ставления от компьютера и операционной системы. Последнее обстоятель-
ство очень важно при передаче данных между различными вычислительны-
ми платформами.
Информация, которая хранится в двоичных наборах данных, может иметь
совершенно разную природу. Это могут быть и символьные данные с 8- или
16-разрядной кодировкой символов, и числовые данные в машинном фор-
мате, и графические образы в одном из многочисленных форматов (PCX,
BMP, JPG, TIF и т. д.), и закодированные звуки, и многое другое. В отли-
чие от текстовой информации, в байтах двоичного набора может встретиться
любая двоичная комбинация, поэтому здесь отсутствует понятие управляющих
кодов, таких как CR, LF, Tab и т. п. Обмен информацией с двоичными
наборами данных не требует каких-либо преобразований. Поэтому он вы-
полняется быстрее и связан с меньшими объемами памяти. В отличие от
текстовых файлов, обмен данными с двоичными файлами выполняется пор-
циями заданной длины. Поэтому в зависимости от природы информации,
хранящейся в двоичных файлах, здесь имеется возможность прямого досту-
па к нужной порции данных. Таким образом, если файл предназначен для
временного хранения информации, используемой только программой, и его
содержимое не будет переноситься на компьютеры другого типа, предпочте-
ние следует отдавать двоичным файлам.
Работа с файлами 209

6.1. Подготовка файла кработе


Файлы открывают с помощью функции fopen, которая в случае удачного
завершения возвращает целочисленный положительный идентификатор
файла f i d (в дальнейшем мы будем называть его номером файла).
В простейшем варианте вызова указывается единственный входной аргу-
мент — имя открываемого файла:
f_id = fopen('name_file');

В качестве имени открываемого файла может быть задано короткое имя, и


тогда система пытается отыскать его сначала в рабочем каталоге, а затем
производит поиск по всем каталогам, доступным пакету MATLAB. Если вы
задаете полную спецификацию, то поиск осуществляется только в указанном
каталоге. В случае неудачи возвращаемое значение равно - 1 . Для получения
дополнительной информации, поясняющей причину ошибки при открытии
файла, к функции fopen можно обратиться с двумя выходными параметрами:
[f_id err_txt] = fopen('name_file');

В случае ошибки в переменную err_txt будет занесено соответствующее


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

Таблица 6.1

Формат вызова Выполняемое действие


fopen (' n a m e f i l e ' , ' г ' ) Открывается существующий двоичный файл для
чтения
fopen (' name_f i l e ' , ' r t ' ) Открывается существующий текстовый файл для
чтения
fopen (' n a m e f i l e ' , ' r + ' ) Открывается существующий двоичный файл, кото-
рый можно использовать как для чтения, так и для
записи (новый файл при этом не создается)
fopen ( ' n a m e f i l e ' , ' r t + ' ) Открывается существующий текстовый файл, ко-
торый можно использовать как для чтения, так и
для записи (новый файл при этом не создается)
fopen ('name_f i l e ' , ' w ' ) Открывается существующий или создается новый
двоичный файл для записи. Предыдущее содер-
жимое существующего файла пропадает
210 Глава 6

Таблица 6.1 (окончание)

Формат вызова Выполняемое действие


fopen('name file', 'wt' ) Открывается существующий или создается новый
текстовый файл для записи. Предыдущее содер-
жимое существующего файла пропадает
fopen('name_file','w+' Если существующий двоичный файл был ранее
открыт, то его содержимое от текущей позиции
указателя и до конца усекается. Если файл с та-
ким именем не существовал, то создается новый
файл. Открытый файл можно использовать для
записи и чтения
fopen('name_file','wt+' Если существующий текстовый файл был ранее
открыт, то его содержимое от текущей позиции
указателя и до конца усекается. Если файл с та-
ким именем не существовал, то создается новый
файл. Открытый файл можно использовать для
записи и чтения
fopen('name file','a') Открывается существующий двоичный файл для
дозаписи или создается новый файл
fopen('name_file' , 'at' Открывается существующий текстовый файл для
дозаписи или создается новый файл
fopen('name_file','a+ ' Открывается существующий двоичный файл для
чтения и дозаписи. Если файла с указанным име-
нем нет, то его создают
fopen('name_file' , 'at+') Открывается существующий текстовый файл для
чтения и дозаписи. Если файла с указанным име-
нем нет, то его создают

Иногда при открытии двоичных файлов по аналогии с C++ к символам ре-


жима добавляют букву ь (от англ. binary — двоичный): rb, wb и т. д.
Операции обмена как с текстовыми, так и с двоичными файлами использу-
ют указатель на начало текущей порции данных. Если файл открывают для
чтения или записи, этот указатель "смотрит" на первую строку или на пер-
вый байт в соответствующем наборе данных. Если файл открывают для до-
записи, то указатель перемещается в конец данных, что позволяет присое-
динять новые данные в хвост к уже существующей информации. Термин
усечение (truncate) обычно используют для операции удаления хвостовых
данных, начиная от текущей позиции указателя.
Поясним смысл еще одной операции, связанной с выводом в файл. В связи
с тем, что скорость работы периферийных устройств, на которых распола-
гаются внешние данные, много ниже быстродействия процессора, операции
обмена используют специачьные буферы, выделяемые системой. В этих бу-
Работа с файлами 211

ферах накапливается выводимая информация, которая после заполнения


буфера переписывается на внешнее устройство. Когда файл закрывают, на-
копленная в буфере информация автоматически выталкивается в файл, что-
бы не произошло потери последних данных. Это действие в англоязычной
документации связывают с термином flash, flashing. Процедура открытия
файлов для записи или дозаписи предоставляет программисту возможность
отказаться от автоматического опустошения буферов обмена — для этой це-
ли вместо малых букв а и w в режиме доступа следует применять их большие
эквиваленты — А И W. Такие режимы на IBM-совместимых компьютерах не
используются.
Существуют три системных файла — стандартный ввод (stdin), стандарт-
ный вывод (stdout) и файл, предназначенный для вывода сообщений об
ошибках (stderr). За этими файлами в MATLAB закреплены фиксирован-
ные номера — 0, 1 и 2 соответственно. Указанные файлы открывать не надо,
они доступны всегда. В демонстрационных примерах, приводимых в данной
главе, мы часто будем использовать стандартный вывод для того, чтобы на-
глядно представить данные, которые могли бы попасть в соответствующий
файл на диске.
Обращаясь к функции fopen с числовым аргументом, представляющим но-
мер открытого файла, мы можем получить информацию о статусе этого
файла (пример 6.1).
; • •• • •••••г •;•••- ".-•••••V........................ , ,....,„..,

Пример 6.1. Получение информации о статусе файла

» [name access]=fopen(0)
name =
"stdin"
access =
r
>> [name access]=fopen(1)
name =
"stdout"
access =
a
» [name access]=fopen(2)
name =
"stderr"
access =
a
» k=fopen('qq\ 'wt+')
212 Глава 6
к=
3
» [name access]=fopen(к)
name =
qq
access =
wt+

Функция f open допускает еще один формат вызова:


v = fopen('all')

В этом случае она возвращает вектор с номерами всех файлов, открытых к


данному моменту времени (файлы с номерами 0, 1 и 2 в этот список не
включаются).

6.2. Завершение работы с файлами


Файл, работа с которым завершена, должен быть закрыт. Эта операция, вы-
полняемая с помощью функции fciose, преследует две цели. Во-первых,
необходимо вытолкнуть в файл вывода ту часть информации, которая нако-
пилась в буфере обмена. Во-вторых, нужно освободить ресурсы, выделенные
системой для работы с файлом. Функция fciose допускает два формата вы-
зова:
s = fciose(f_id)
s = fciose('all')

В первом случае закрывается файл с указанным номером, во втором случае


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

6.3. Контроль за исчерпанием данных


При выборке информации из текстового или двоичного файла, открытого
для чтения, может наступить момент, когда прочитана последняя порция
данных и в файле больше ничего нет. Контроль за тем, достиг ли указатель
файла конца данных (end-of-file), обеспечивает функция f eof:
k = feof(f i d ) ;
Работа с файлами 213

Если возвращаемое функцией значение равно о, то в файле еще находятся


непрочитанные данные. При исчерпании данных значение, возвращаемое
функцией feof, равно 1.

6.4. Работа с двоичными файлами


Указатель файла "смотрит" на текущую порцию данных. При чтении эта
информация извлекается из файла, а указатель автоматически перемещается
на следующую доступную порцию, если таковая еще есть. При выводе в
файл новая информация записывается, начиная с адреса, на который
"смотрит" указатель, а по завершению обмена указатель автоматически уста-
навливается на позицию, следующую за выведенной порцией. В двоичных
файлах возможно дополнительное перемещение указателя по предписанию
программы.
Текущая позиция указателя определяется как смещение в байтах относи-
тельно начала файла. Для открытого файла с номером f_id текущее поло-
жение указателя можно узнать, обратившись к функции f t e i i :
pos = ftell(f_id);

Возврат указателя в начало файла обеспечивает функция frewind. Своим


названием она обязана оператору REWIND, который появился почти полсто-
летия назад и использовался в Fortran для перемотки магнитной ленты в
начало. Единственным входным аргументом этой функции является номер
открытого файла — frewind (f_id).
Все остальные перемещения указателя файла реализуются с помощью
функции fseek, близкий аналог которой имеется в C++. Перемещения ука-
зателя задаются относительно одной из трех позиций:
П от начала файла на заданное число байтов вперед (п>о)
st = fseek(f_id,n,'bof');

ИЛИ
st = f s e e k ( f _ i d , n , - l ) ;

Я от конца файла на заданное число байтов назад (п>о)


s t = fseek(f_id,n,'eof') ;

ИЛИ
s t = fseek(f_id,n,1);

О от текущей позиции указателя вперед (п>о) или назад (п<о) на заданное


число байтов
st = fseek(f id,n,'cof');
214 Глава 6

или
st = fseek(f_id,n,0);

Величина смещения п может быть, в частности, равна о. Например, дейст-


вие fseek(f_id,0, ' b o f ) Эквивалентно оператору frewind(f__id) .
Нулевое значение, возвращаемое функцией fseek, свидетельствует о нор-
мальном завершении операции. В случае ошибки возвращаемое значение
равно - 1 .

6.4.1. Чтение данных из двоичного файла


Для выборки данных из двоичного файла предназначена функция fread,
допускающая несколько форматов вызова. В простейшем случае, когда ее
единственным входным аргументом является номер открытого файла, функ-
ция возвращает содержимое этого файла и количество считанных байтов:
[array count] = fread(f_id);

При этом содержимое файла рассматривается как вектор-столбец, элемен-


тами которого являются однобайтовые числа без знака. Однако в массив
array эти числа поступают уже преобразованными в формат double.
Проведем несложный эксперимент. С помощью редактора m-файлов сфор-
мируем две следующие строки:
ABCD
012345

Сохраним их под именем test.m и обратим внимание на длину получивше-


гося файла. Несмотря на то, что мы набирали 10 символов, в файле их ока-
залось 12, т. к. в конце первой строки редактор вставил два управляющих
символа с кодами 13 (символ CR) и 10 (символ LF). По существу, файл
test.m является текстовым, но мы попробуем открыть его как двоичный
файл и прочитаем его содержимое (пример 6.2). Комментарии в строках с
прочитанными значениями вставлены вручную.
!»:•• •••.••v,•:••.••;••-•• ,..,•,.,..••,..••.•• • -

I Пример 6.2. Чтение из текстового файла как двоичного :

» f id=fopen('test.m','г'); % открываем файл как двоичный для чтения


» [a k]=fread(f_id) % читаем весь файл в массив а
а = % каждый элемент массива а - число типа
double
65 % код буквы А
66 % код буквы В
67 % код буквы С
Работа с файлами 215

68 % код буквы D
13 % к о д символа 'Возврат к а р е т к и '
10 % к о д символа 'Перевод с т р о к и '
48 % к о д цифры 0
49 % код цифры 1
50 % код цифры 2
51 % код цифры 3
52 % код цифры 4
53 % код цифры 5
к=
12 % количество считанных байтов
» a=char(a) % преобразование данных типа double в тип char
а = % теперь каждый элемент массива а — типа char
А % буква А
В % буква В
С % буква С
D % буква D
% неотображаемый символ 'Возврат каретки'
% неотображаемый символ 'Перевод строки'
% действие управляющего символа 'Перевод строки'
0 % цифра 0
1 % цифра 1
2 % цифра 2
3 % цифра 3
4 % цифра 4
5 % цифра 5
» а' % транспонирование вектора-столбца
ans = % вывод вектора-строки
ABCD
012345

Второй формат вызова функции f read использует второй входной аргумент,


который задает количество считываемых символов:
[array count] = fread(f_id, n);

Возвратим указатель файла test.m в начало и попробуем прочитать 8 байтов


(пример 6.3).

S Ък 899
216 Глава 6

vuriiuo

» frewind(f_id)
» [a k]=fread(f id,8)

a= элементы массива а имеют тип double


65
66
67
68
13
10
48
49

Количество фактически прочитанных элементов данных может не совпадать


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

Таблица 6.2

Описатель длины и типа элементов Пояснение

uchar' | •uintB1 Целое число без знака, 1 байт


'schar' | •int8' Целое число со знаком, 1 байт
'intl6' I 'integer* 2 ' Целое число со знаком, 2 байта
r 1
int32' | integer* 4 ' Целое число со знаком, 4 байта
p 1
int64' | integer* 8' Целое число со знаком, 8 байтов
r
uintl6' Целое число без знака, 2 байта
Работа с файлами 217

Таблица 6.2 (окончание)

Описатель длины и типа элементов Пояснение


' uint32 ' Целое число без знака, 4 байта
1
uint64 ' Целое число без знака, 8 байтов
'single' I 'float32' Вещественное число, 4 байта
'double' I 'float64' Вещественное число, 8 байтов

Вообще говоря, MATLAB позволяет рассматривать содержимое файла как


целочисленные данные с точностью до бита, если воспользоваться одним из
описателей вида:
П bitN — целое со знаком, длина N битов (1 < N < 64);
П ubitN — целое без знака, длина N битов (1 < N < 64).
Функция f read допускает наличие четвертого входного параметра, который
позволяет читать данные из файла не подряд, а с заданными пропусками.
Продемонстрируем эту возможность на примере того же файла test.m
(пример 6.4).
^l|ttlMI"IP'I"M,l.|,|*4MlMI,l"H"«."t('H|4IM,Mmtl""IMM"l|l"HMI»t|lMIM.4Mrtl'4"tM"4"1»>"M
(
"""l'l1l11*'l4
t
*IHl4Pt.,l4"4ftt|4lMM'imi|,(M"tMTU
) Пример 6.4. Чтение из файла с пропусками I

» frewind(f_id)
» [a k]=fread(f_id,20, 'uchar',3)
а=
65
13
50
к=
3

Пусть вас не смущает, что мы заказали чтение 20 байтов. В файле их всего


12, и больше, чем там находится, все равно никто не прочитает. Мы по-
прежнему рассматриваем содержимое файла как вектор из однобайтовых
целых чисел без знака. Но после того как прочитан очередной байт, в файле
пропускаются три следующих байта. Распечатка содержимого вектора а от-
четливо демонстрирует режим чтения с пропусками.
Режим чтения с пропусками допускает еще один вариант выборки данных из
файла — сначала читается порция из п элементов, затем пропускаются m эле-
ментов, и далее все повторяется в таком же порядке. Например, чтение пор-
циями из трех элементов с пропуском двух следующих может выглядеть так:
» [a k]=fread(f id,inf,'3*uchar',2)
218 Глава 6

Так как в нашем файле содержится 12 байтов, то в массив а будет считано


6 байтов — две полные порции по 3 байта, а два последние байта не будут
прочитаны (пример 6.5).
г" .....,.....^,.„.»..„....,.....,....^........,........,,....,...
: Пример 6.5. Чтение из файла порциями :

» f_id=fopen('test.m', 'r1) ;
» [a k]=fread(f_id, inf, '3*uchar',2)
а =
65 % первое число из первой порции
66 % второе число из первой порции
67 % третье число из первой порции
% два байта пропущены
10 % первое число из второй порции
48 % второе число из второй порции
49 % т р е т ь е ч и с л о и з второй порции
% д в а байта п р о п у щ е н ы
52 % первое число из третьей порции
53 % второе число из третьей порции
m =

Массив, в который считывается очередной фрагмент или полное содержи-


мое файла, не обязательно должен быть представлен одномерным вектором.
Используя указание о количестве считываемых элементов из файла в виде
вектора, можно сформировать результат выборки как двумерный массив
(пример 6.6).
; " • • • - , . . . • . . , . . . , . . . - - - - - • • ,

I Пример 6.6. Чтение из файла в двумерный массив \

» f_id=fopen('test.m','r');
» a=fread(f_id,[3 4]) % читаем данные из файла в двумерный массив

65 68 48 51
66 13 49 52
67 10 50 53
» whos
Name Size Bytes Class
а 3x4 96 double array
f id lxl 8 double array
Работа с файлами 219
Из приведенного примера видно, что последовательно считываемые из фай-
ла элементы данных заполняют столбцы результирующей матрицы.
Если количество считываемых элементов в обращении к f read явно не ука-
зано, то данные читаются до конца файла. Точно такого же эффекта можно
добиться, указав в качестве размера порции бесконечную длину inf (или
inf) — пример 6.7.

Пример 6,7. Чтение файла целиком

» f_id=fopen('test.m','r');
» a=fread(f_id,inf)
а =
65
66
67
68
13
10
48
49
50
51
52
53

Такой же константой можно воспользоваться и при задании числа столбцов


для матрицы-результата (пример 6.8).
: • • ••• ,

I Пример 6.8. Чтение файла целиком в двумерный массив

>> frewind(f_id)
» a=fread(f_id, [3,Inf])
a =
65 68 48 51
66 13 49 52
67 10 50 53

До сих пор рассматривались режимы чтения файловых данных, которые


могли интерпретироваться как целые или вещественные числа различной
длины. Но в принимающий массив, расположенный в оперативной памяти,
220 Глава 6

они поступали уже в формате double, т. е. в большинстве случаев числовые


данные подвергались преобразованию. На это тратилось дополнительное
машинное время, неэкономно использовалась оперативная память и своди-
лись на нет заявленные выше преимущества двоичных файлов. Однако
функция fread позволяет производить чтение двоичных файлов "один-в-
один" без какого-либо преобразования форматов или с преобразованием в
числовой формат, отличный от double. Для этого в параметре, определяю-
щем тип считываемых элементов, задается конструкция *
тип1=>тип2
Левая половина этой конструкции трактуется как тип данных, находящихся
в файле, а правая — как тип элементов принимающего массива (при-
мер 6.9).

5 п
Пример 6.9. Преобразование форма-roi ричтении.^.*аил£

» frewind(f .id) ;
» a=fread(f__id, [3 4],'uchar=>uchar
а=
65 68 48 51
66 13 49 52
67 10 50 53
» whos
Name Size Bytes Class
а 3x4 12 uint8 array
f id lxl 8 double array

Когда тип считываемых данных совпадает с типом принимающих данных,


то вместо конструкции тип1=>тип1 можно указывать более короткую строку
*тип1. В приведенном выше примере можно было бы заменить
uchar=>uchar на *uchar.

6.4.2. Запись в двоичный файл


Операция записи в двоичный файл отличается только направлением пере-
мещаемых данных и использует похожие аргументы с той лишь разницей,
что массив — поставщик информации — теперь является входным парамет-
ром функции fwrite;
count = fwrite(f_id,array,'type');
При этом в заранее открытый файл с номером f i d записываются все эле-
менты массива a r r a y с преобразованием данных в тип, определяемый
Работа с файлами 221

третьим аргументом. В качестве f_id можно использовать номера систем-


ных файлов stdout и stderr. Целочисленное значение, возвращаемое
функцией fwrite, определяет количество удачно записанных элементов
массива. Если значение count меньше, чем количество элементов в массиве
array, то причиной тому может быть нехватка места на диске.
Если массив array — двумерный, то запись его элементов в файл произво-
дится по столбцам.
Проделаем несложный эксперимент (комментарий для отображаемых дан-
ных вписан вручную) — пример 6.10.
• • - - • - • • •

[ример 6.10. Запись в двоичный файл

» al='ABCD'; % строка из четырех символов


» а2='012345'; % строка из шести символов
» k=fopen('abc.ra','w'); % открыли двоичный файл для вывода
» cl=fwrite(k,al,'uchar') % вывели в файл строку al
cl =
4 % количество записанных элементов
» c2=fwrite(k,a2,'uchar1) % вывели в файл строку а2
с2 =
6 % количество записанных элементов
» fclose(k); % закрыли выводной файл
» k=fopen{'abc.m','г'); % переоткрыли файл для ввода
>> [аЗ c3]=fread(k,inf,'*uchar') % прочитали все данные
аЗ =
65 % код буквы А
66 % код буквы В
67 % код буквы С
68 % код буквы D
48 % код цифры 0
49 % код цифры 1
50 % код цифры 2
51 % код цифры 3
52 % код цифры 4
53 % код цифры 5
сЗ =
10 % количество считанных элементов
» whos
222 Глава 6

Name Size Bytes Class


al 1x4 8 char array
a2 1x6 12 char array
a3 10x1 10 uint8 array
cl lxl 8 double array
c2 lxl 8 double array
c3 lxl 8 double array
к lxl 8 double array

Обратите внимание на то, что при записи в двоичный файл никаких допол-
нительных управляющих кодов типа CR, LF не пишется. Мы можем прочи-
тать данные в их первозданном формате, если указать соответствие типов
(пример 6.11).
•••••• — •••••• • •• •

р и м е р 6 1 Ч т е н и е и з д в о и ч н о г о а й л а
! : * ... ц „ 1 •. i

» frewind(k)
» a4=fread(k,inf,'uchar=>char': % чтение и транспонирование
a4 =
ABCD012345

Конечно, операция по преобразованию данных из однобайтового числового


представления в однобайтовый символьный формат ни с какими затратами
машинного времени не связана. Но мы могли бы и при записи в файл не
изменять тип передаваемых данных (пример 6.12).
•••••••••• •••••

Г Пример 6.1 и чтение в двоичный фа

» k=fopen('abc.m','w');
>> cl=fwrite(k,al,'char') ,
» c2=fwrite(k,a2,'char') ,
» fclose(k);
» k=fopen('abc. m', 'r');
» a4=fread(k,inf,'*char';
a4 =
ABCD012345

Четвертый входной аргумент функции fwrite позволяет записывать элемен-


ты указанного массива не подряд, а со вставкой перед каждым элементом
заданного количества нулевых данных (пример 6.13).
Работа с файлами 223
•• • • — • ' •
1

» al='ABCD';
» k=fopen('abc.m','w');
» cl=fwrite(k,al,'uchar',2) % запись с разрядкой
cl =
4 % количество переданных элементов массива
» fclose(k);
» k=fopen('abc.m','r');
» a4=fread(k,inf,'uchar')
a4 =
0 % первый элемент разрядки
О % второй элемент разрядки
65 % первый элемент массива al
О
О
66 % второй элемент массива al
О
О
67 % третий элемент массива,al
О
О
68 % четвертый элемент массива al

6.5. Работа с текстовыми файлами


Содержимым текстового файла являются строки — цепочки символов, за-
вершающиеся парой управляющих кодов CR (шестнадцатеричный код OD) И
LF (шестнадцатеричный код ОА). Такие разделители строк вписывает любой
текстовый редактор, когда мы завершаем набор строки нажатием клавиши
<Enter>. Признак конца строки может вписать и наша программа, если
формат записываемой строки (см. функцию fprintf) заканчивается управ-
ляющим кодом '\п. Для демонстрации процедур чтения строк и символов
создадим с помощью текстового редактора файл text.txt, содержащий две
строки:
ABCD
012345

Убедитесь в том, что длина файла 12 байтов и после кода буквы "С"
(шестнадцатеричный код 43) расположена пара байтов ODOA.
224 Глава 6

6.5.1. Последовательное чтение строк


из текстового файла
Чтение очередной строки из текстового файла осуществляется с помощью
функции fgeti. При этом информация из файла читается от текущей пози-
ции указателя до тех пор, пока не встретится признак конца строки или не
будут исчерпаны данные. Функция имеет единственный входной аргумент —
номер открытого текстового файла — и возвращает прочитанную строку.
Если данные в файле исчерпаны, а мы обращаемся к функции fgeti, то она
возвращает -1 (пример 6.14).

! Пример 6.14. Последовательное чтение из текстового файла I


;.....„..... V....... : ;
» k=fopen('text.txt','rt'); % открываем текстовый файл
» sl=fgetl(k) % читаем первую строку
si =
ABCD
» s2=fgetl(k) % читаем вторую строку
s2 =
012345
» s3=fgetl(k) % читаем несуществующие данные
s3 =
-1

Управляющие байты в состав считываемых строк не включаются.

6.5.2. Последовательное чтение


нескольких символов из файла
Один или несколько символов из текстового файла читаются с помощью
функции fgets, у которой могут быть один или два входных аргумента —
номер открытого текстового файла и количество считываемых символов.
Чтение данных из файла начинается с текущей позиции указателя и про-
должается до тех пор, пока не выполнится одно из условий:
• прочитано указанное количество символов;
• встретился признак конца строки;
• данные в файле исчерпаны.
Если второй аргумент не указан, то его можно считать равным бесконечно-
сти, и тогда операция будет прервана либо по исчерпанию текущей строки,
Работа с файлами 225

либо по достижению конца файла. При попытке прочитать данные после их


исчерпания функция fgets возвращает - 1 . Приводимый пример 6.15 демон-
стрирует все возможные варианты.

ильное чтение из текстового файла I


— ; / ,*«.ч!
» k=fopen('text.txtp,'rt')f % открываем текстовый файл
» sl=fgets(k) % читаем первую строку
si -
ABCD
» s2=fgets(k,3) % читаем три следующих символа
s2 =
012
» s3=fgets(k,5) % читаем пять следующих символов,
s3 = % а в файле их осталось всего три
345
» s4=fgets(к,1) % чтение после исчерпания данных
S4 =
-1

6.5.3. Форматирование выводимой строки


Даже в том случае, когда строка, записываемая в файл, представляет собой
цепочку символов, она обязана подвергнуться преобразованию (форматиро-
ванию) по двум следующим причинам:
П в оперативной памяти каждый символ представлен двумя байтами, а в
файле — одним;
• для того чтобы отделить одну строку от другой, вслед за последним сим-
волом на диск должна быть записана пара управляющих кодов.
На самом деле символьная информация обычно перемежается с числовыми
данными, которые должны быть тем или иным способом преобразованы из
машинного формата в соответствующие поля строки. Таким конвертирова-
нием данных из их внутреннего представления в символьное заведуют фор-
матные указатели, задаваемые в качестве одного из параметров функции
fprintf (пример 6.16).
• .,.,.„......,,,,...Л..,.,,, ;
\ Пример 6.16. Форматная запись в текстовый файл • !

» f_id=fopen('text.txt','wt'); % открыли текстовый файл


» cl=fprintf(f_id,'%s\n','ABCD') % вывели в файл строку
226 Глава 6

cl =
5
» fclose(f_id);

Форматные указатели всегда начинаются с символа %. В приведенном выше


примере такой указатель один — %s, и он означает, что перед записью на
диск необходимо преобразовать строку ABCD, занимающую в оперативной
памяти 8 байтов. Управляющая комбинация \п, следующая за форматным
указателем, записывается в файл как признак конца строки. Может вызвать
некоторое недоумение значение, возвращаемое функцией fprintf (рис. 6.1).

;Й view text.txt - Far

41 42 43 44 0D Qfl 'RBCDJfi

Рис. 6 . 1 . Просмотр содержимого файла text.txt

С одной стороны, информативных байтов записано четыре. К ним добавля-


ется признак конца строки. Несмотря на то, что он на диске представлен
двумя байтами (ею и ОА), функция fprintf рассматривает их как один
управляющий элемент данных (в англоязычной документации ему соответ-
ствует символ newiine — новая строка).
Первый входной аргумент функции fprintf задает номер открытого файла.
Им, в частности, может быть число 1, и тогда данные передаются в файл
стандартного вывода, т. е. в командное окно:
» f p r i n t f ( I , ' % s \ n \ 'ABCD 1 );
ABCD

To же самое происходит и при отсутствии первого аргумента:


» fprintf('%s\n','ABCD');
ABCD

Второй входной аргумент функции fprintf представлен строкой, содержа-


щей форматные указатели и так называемые литеральные константы. К по-
следним относятся все символы, не принадлежащие к форматным указате-
лям. Литеральные константы включаются в выводимую строку без каких-
либо преобразований. В частности, к литеральным константам в приводив-
шемся выше примере относится признак конца строки. Количество указате-
лей в строке форматов может не соответствовать количеству преобразуемых
данных. И этим MATLAB кардинально отличается от других систем про-
Работа с файлами 227

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


личество преобразуемых данных, то список циклически повторяется:
» fprintfC%4d',l,2,3,4)
1 2 3 4

В приведенном выше примере форматный указатель %4d повторился четыре


раза. Если количество указателей формата превышает длину выводимого
списка, то лишние форматные указатели игнорируются:
» fprintf('%d %f %e',l,2)
1 2.000000
Данные, подлежащие преобразованию перед записью в файл, задаются
третьим и последующими входными аргументами функции fprintf. Напри-
мер, если мы хотим записать в очередную строку текстового файла два це-
лых и одно вещественное значения переменных i i , i2 и гЗ, то это может
выглядеть так, как представлено в примере 6.17.

1риформатной записи

» il=125;
» i2=2003;
» r3=2.3456;
» fprintf('%5d %d %8.3f\n',il,i2,r3);
125 2003 2.346

Значение переменной i i преобразуется в формат целого числа (об этом сви-


детельствует буква d в первом форматном указателе), и для его записи в вы-
водной строке отводится 5 позиций. Между первым и вторым форматными
указателями находится один пробел, который считается литеральной кон-
стантой, разделяющей первое и второе число. Значение переменной ±2 пре-
образуется по формату %d и занимает в выводной строке 4 позиции. После
второго числа вставляется еще один литеральный пробел, расположенный
между вторым и третьим указателями формата. Следующие 8 позиций отве-
дены для результата преобразования вещественного числа (об этом свиде-
тельствует буква f в третьем форматном указателе), у которого сохраняются
3 значащие цифры в дробной части. Обратите внимание на то, что результат
форматного преобразования третьего числа округлен в соответствии с обще-
принятыми правилами.
Форматные указатели, используемые в функции fprintf, MATLAB позаим-
ствовал у языка C++ и слегка модифицировал их. Одна из наиболее сущест-
венных модификаций, на наш взгляд, заключается в том, что элементом вы-
228 Глава 6

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


определяет преобразование каждого элемента очередного столбца матрицы.
Указатель формата начинается с символа %, вслед за которым могут быть
расположены три необязательные компонента — флажки, ширина (w) и
точность (.п). Завершается указатель одним из символов, характеризующих
тип преобразования данных и приведенных в табл. 6.3.

Таблица 6.3

Символ Способ преобразования перед записью в текстовый файл


формата
d Преобразование целочисленного значения в десятичное число
со знаком
i Преобразование целочисленного значения в десятичное число
со знаком
о Преобразование целочисленного значения в восьмеричное число
без знака
и Преобразование целочисленного значения в десятичное число
без знака
х Преобразование целочисленного значения в шестнадцатеричное
число без знака с использованием малых букв а, Ь, с f
в качестве цифр
х Преобразование целочисленного значения в шестнадцатеричное
число без знака с использованием больших букв А, в, с, .... F В каче-
стве цифр
f Преобразование числового значения в вещественное число
с фиксированной запятой
е Преобразование числового значения в вещественное число
с плавающей запятой, признак порядка — буква е
Е Преобразование числового значения в вещественное число
с плавающей запятой, признак порядка — буква Е
g Преобразование числового значения в вещественное число с фик-
сированной или плавающей запятой в зависимости от того, какой
формат числа занимает меньше места (незначащие нули в дробной
части не выводятся)
G Преобразование числового значения в вещественное число с фик-
сированной или плавающей запятой в зависимости от того, какой
формат числа занимает меньше места (незначащие нули в дробной
части не выводятся)
s Преобразование текстового значения в строку символов
с Преобразование единственного символа
Работа с файлами 229

В качестве флажков, следующих непосредственно после символа %, могут


использоваться следующие символы:
• для вывода очередного символьного или числового значения, начи-
ная с левой границы текущего поля (левый прижим). По умолчанию вы-
водимое значение прижимается к правой границе текущего поля;
• + — для обязательного включения знака числа (обычно этот знак у поло-
жительных чисел опускается);
• пробел — для вывода пробела вместо знака положительного числа
(обычно такой пробел игнорируется);
П # — для формирования префиксов у восьмеричных и шестнадцатеричных
чисел (восьмеричное число начинается с о, шестнадцатеричное — с пары
символов Ох или ох).
Ширина w, задаваемая целым числом, определяет количество позиций в те-
кущем поле строки, в которых должна разместиться преобразуемая величи-
на. Вообще говоря, ширине может предшествовать о, и тогда старшие не-
значащие позиции чисел заполняются не пробелами, а нулями.
Продемонстрируем в примере 6.18 результат влияния флажков при заданной
ширине первого и единственного поля выводимой строки (комментарии в
выводимых строках проставлены вручную).

Пример 6.18. Использование различных форматов целых чисел

» а=1б;
» Ь=-1б;
» fprintf ('%5d\n%5d\a,b)
16 % число прижато к правой границе поля
-16 % число прижато к правой границе поля
» fprintf('% + 5d\n%5d\a,b)
+16 % знак + у положительного числа
-16
» fprintf('%-5d\n%-5d',a,b)
16 % число прижато к левой границе поля, знак + не выводится
-16 - % число прижато к левой границе поля
» fprintf('%- 5d\n%-5d',a,b)
16 % прижим к левой границе, пробел вместо знака +
-16 % прижим к левой границе
» fprintf('%5х\п%#5х',а,а);
10
0x10 % префикс Ох у шестнадцатеричного числа '
230 . Глава 6

» f p r i n t f ('%5X\n%#5X\a,a) ;
10
0X10 % префикс ОХ у шестнадцатеричного числа
» fprintfC%5o\n%#5o',a,a);
20
020 % префикс — цифра 0 у восьмеричного числа
» fprintf('%05d',a)
00016 % дополнение числа незначащими нулями

Обратите внимание на то, что использование целочисленных форматов (%d,


%i, %u, %x, %x, %o) предполагает, что преобразуемое значение действительно
является целым (пример 6.19).

( Замечание J
Приведенный выше текст в точности соответствует содержимому Command
Window (Окно команд) среды MATLAB 6.5. Однако в среде MATLAB 7 после
вывода данных по функции f p r i n t f символы новой команды (>>) не пере-
водятся в начало следующей строки. На результат вычислений и на продол-
жение работы это влияния не оказывает, но должного порядка на экране не
наблюдается.

; '. " , •••• •••••-••••• •••• |

| Пример 6.19. Использование различных форматов вещественных чисел

» z=1.8;
» fprintf('%d',z)
1.800000е+000 % вместо формата %d использован формат %е
» fprintf('%x',z)
1.800000е+000 % вместо формата %х использован формат %е
» fprintf('%u',z)
1.800000е+000 % вместо формата %и использован формат %е
» fprintf('%f',z)
1.800000 % незначащие нули в дробной части выводятся
» fprintf('%е',z)
1.800000е+000 % незначащие нули в дробной части выводятся
» fprintf('%E',z)
1.800000Е+000 % незначащие нули в дробной части выводятся
» fprintf('%g',z)
1.8 % незначащие нули в дробной части не выводятся
Работа с файлами 231

Если вы действительно хотите использовать один из целочисленных форма-


тов для преобразования вещественного значения, то перед выводом в файл
такие величины нужно округлить с помощью одной из функций: fix, round,
floor ИЛИ c e i l .

Однако MATLAB позволяет рассматривать вещественное число типа double


как 8 подряд идущих байтов и записывать их содержимое в текстовый файл
в виде последовательности из 16 шестнадцатеричных цифр. Для этой цели к
одному из целочисленных форматов ьх, %х, %о, %и добавляется символ ь
(пример 6.20).

; Пример 6.20. Вывод вещественного числа в

» fprintf('%bx\n%bx',l,-l)
3ff0000000000000
bffOOOOOOOOOOOOO

Еще одну возможность подобного рода предоставляет добавление символа t


к одному из указанных форматов. В этом случае вещественное значение
представляется как четырехбайтовое число типа float, и оно "преобра-
зуется" в цепочку из 8 шестнадцатеричных цифр (пример 6.21).
• • • " • • • • • — . . . . . . . . . . .

Пример 6.21. Вывод числа типа f l o a t в шестнадцатеричном виде

» fprintf('%tx\n%tx',l,-1)
3f800000
bf800000

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


такие "преобразования" не требуется. Тем не менее на некоторых вычисли-
тельных платформах после чтения данных из файла, возможно, придется
менять местами старшие и младшие байты слов.
Точность п, следующая за шириной и отделяемая от нее точкой, обычно
определяет количество значащих цифр у вещественного числа в дробной
части. Однако по правилам языка C++ точность может быть использована и
в сочетании с форматными преобразованиями целых чисел, и даже строк.
В первом случае преобразуемое число должно содержать в своей символь-
ной записи не менее чем п цифр. Если их меньше, то старшие позиции
числа дополняются недостающим количеством нулей. При преобразовании
строки по формату %io.5s в файл попадут не более 5 первых символов,
прижатых к правой границе поля, содержащего 10 позиций.
232 Глава 6

Руководства по языку C++ содержат еще несколько менее значительных


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

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

имер 6.22. Преобразование комплексных чисел при форматной запис


i в файл

» a=l+2*i

1.0000 + 2.0000i
» b=3+4*j
b =
3.0000 + 4.0000i
» fprintf ('%4.2f\n%4.2f,a,b)
1.00
3.00

Функция fprintf возвращает количество байтов, которое ей удалось запи-


сать в указанный файл (с учетом ранее сделанного замечания о том, что
признак конца строки рассматривается как один двухбайтовый символ
newiine). Обычно этим значением функции fprintf редко кто не пользуется.
Единственная ситуация, в которой возвращаемое значение может помочь,
связана с поиском ошибки в строке форматных указателей. Иногда
MATLAB не выдает никаких сообщений, но и не выполняет запись соответ-
ствующего значения выводного списка в файл (пример 6.23).
. - • " • • • • ' •:•••• . . . . . . . . . . . . . . . . . . . . . . : -

\ Пример 6.23. Ошибка в форматном указателе \


;....." i .:.„...... ...........................i.. ;.... ..;

» n=fprintf ('%d %bd\l,-l)


1 n = % формат %bd не обслуживается, но и не критикуется
2
» n=fprintf ('%d %d\l,-l)
1 -In =
4
Работа с файлами 233

Продемонстрируем действие форматных указателей в ситуациях, когда эле-


ментом выводного списка является вектор или матрица (пример 6.24).
1 | |T| 111
1Ш1ШШШШ№^Ж1 1111'1Т||''Т"" '1|"'"'"'''' '" ill ' 'iii i i '
дер 6.24. Форматный вывод матричных дань

» х=0:0.2:1 % вектор из 6 компонентов


х =
0 0.2000 0.4000 0.6000 0.8000 1.0000
» fprintf('%g ' х) % вывод компонентов вектора в одной строке
0 0.2 0.4 0.6 0.1 I 1
» у=[х; sin(x)] % массив размерности 2x6
У =
0 0.2000 0.4000 0.6000 0.8000 1.0000
0 0.1987 0.3894 0.5646 0.7174 0.8415
» fprintf('%4.1f %8.4f\n' ,у) % вывод массива в виде 6 строк
0.0 0.0000
0.2 0.1987
0.4 0.3894
0.6 0.5646
0.8 0.7174
1.0 0.8415

Среди литеральных констант в командной строке кроме уже упоминавшего-


ся признака конца строки ('\п') могут использоваться и другие управляющие
символы, известные под названием Esc-последователъности. Их перечень
приведен в табл. 6.4.
Таблица 6.4

Символ Описание

\Ь Удаление предыдущего символа (Backspace)


\f Перевод страницы (Form feed)
\п Новая строка (New line)
\г Возврат каретки (Carriage return)
\t Горизонтальная табуляция (Horizontal tab)

Некоторые символы форматной строки задействованы как управляющие:


• с символа % начинается форматный указатель;
• одиночная кавычка открывает и закрывает строку форматов;
• обратная косая черта использована в Esc-последовательностях.
234 Глава 6

Для того чтобы включать такие символы в состав литеральных констант и


не путать их с управляющими комбинациями, в форматной строке действу-
ют следующие соглашения:
• %% — воспринимается как символ процента;
О \\ — воспринимается как обратная косая черта;
• ' ' — воспринимается как одиночная кавычка;
• \" — воспринимается как двойная кавычка.

Замечание
В том случае, когда в текстовый файл с помощью функции f p r i n t f записыва-
ется единственная строка, строка форматных указателей может быть опущена
(пример 6.25).

• - • •

Пример 6.25. Запись в текстовый файл без форматных указателей

» m=fprintf('ABCDEFGH IJKLMN1);
ABCDEFGH IJKLMN
» m
m=
15

6.5.4. Чтение данных из текстового файла


Выборка данных из текстового файла может быть произведена с помощью
функции fscanf, обращение к которой в общем виде выглядит следующим
образом:
[a n]=fscanf (f_id, 'format',. m) ;

Здесь:
• a — принимающий массив, в элементы которого заносятся считываемые
данные;
П п — количество фактически считанных значений;
• f_id — номер открытого файла;
• format — список форматных указателей, в соответствии с которыми
осуществляется преобразование считываемых данных;
• m — количество запрашиваемых данных.
Обязательными параметрами в этом обращении являются массив а, иденти-
фикатор файла f i d и хотя бы один форматный указатель в списке format.
Отсутствие количества запрашиваемых значений или константа inf в каче-
Работа с файлами 235

стве третьего параметра воспринимаются как задание прочитать данные до


конца файла. Если количество запрашиваемых значений задано числом т, то
считываемые данные размещаются в векторе-столбце размерности mxi. Од-
нако, указав количество запрашиваемых данных в виде вектора [р q], мы
можем прочитать данные из файла в матрицу размерности pxq.
Продемонстрируем описанные возможности на следующем примере — сге-
нерируем магический квадрат размером 5x5, запишем его элементы как це-
лые числа в текстовый файл a.txt, а затем попробуем разными способами
прочитать эту информацию (пример 6.26).
г ,. ,
| Пример 6.26. Запись и чтение из текстового файла

>> k=fopen('а.txt', 'wt'); открыли файл для вывода


>> a=inagic(5) сформировали магический квадрат

17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
n=fprintf(к, •%d \a) % записали массив а в файл

66 % количество байтов, записанных в файл


» fclose(к); % закрыли файл
» k=fopen('a.txt', ' r t ' ) ; % открыли файл для чтения
» [b n]=fscanf (k, ' % d \ [5 5]) % читаем матрицу 5x5
b
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9

25 % количество считанных значений


» frewind(k); % вернули указатель файла в начало
» [c n]=fscanf(k,'Id1,5) % прочитали 5 значений (1-й столбец)
с
17
23
2 3 6 Г л а в а 6

4
10

n—
5
» whos
Name Size Bytes Class
a 5x5 200 double array
b 5x5 200 double array
с 5x1 40 double array
к lxl 8 double array
n lxl 8 double array

Обратите внимание на разницу в возвращаемых количествах между функ-


циями fprintf и fscanf. Первая из них считает количество байтов, записы-
ваемых в файл, а вторая возвращает количество элементов данных, счи-
танных из файла. При выводе в файл кроме указателя %d в форматной
строке присутствует пробел, разделяющий числовые данные. Если вы по-
считаете количество цифр в элементах магического квадрата и добавите к
ним 25 пробелов (по одному пробелу после каждого числа), то получится
66 байтов.
Форматные указатели, задаваемые в строке формата у функции fscanf, поч-
ти те же, что и у функции fprintf (см. табл. 6.3). Но если точность при вы-
воде имеет определенный смысл, то на ввод она не оказывает влияние. При
считывании вещественных данных из текстового файла указатели типа %f,
%е и %g выполняют одинаковые функции, преобразуя считанное значение в
машинный формат типа double. Форматные указатели типа %d, %i выбирают
из очередного поля текстового файла целочисленные данные, однако в эле-
менты принимающего массива результат преобразования заносится в фор-
мате double.
Если форматный указатель начинается с комбинации %*, то соответствую-
щее значение, считанное из файла, в принимающий массив не передается.
Это дает возможность пропускать ненужные данные. В примере 6.27 пока-
зано считывание данных из файла с магическим квадратом и пропуском ка-
ждого второго числа.

! Пример 6.27. Чтение из текстового файла с пропусками .1

» frewind(k);
» [d n]=fscanf(k,'%d %*d')
Работа с файлами 237
d =
17
4
11
5
12
1
13
25
14
21
15
22
9

13

Форматные указатели типа %s на выводе и на вводе действуют по-разному.


Строка данных, записываемая в файл, например, может содержать пробелы.
Однако если мы читаем единичный элемент по формату %s, то чтение пре-
рывается на первом же пробеле. Если мы запрашиваем чтение более чем
одного элемента, то белые пробелы, встречающиеся в текстовой строке, иг-
норируются (пример 6.28).
: ••••••••••: •••••

I Пример 6.28. Обработка пробелов пр


• Г.. ......Г.......

» k=fopen('а.txt','wt');
» fprintf(k,'%s\'ABCD 012345' % записали строку с пробелом
ans =
11 количество записанных байтов
» fclose(k);
» k=fopen('a.txt', 'rt') ;
» [a n]=fscanf (k, '%s', 1) % прочитали 1 элемент до первого пробела
a=
ABCD
n =

» frewind(k) ;•
» [a n]=fscanf(k,'%s',2) прочитали 2 элемента
238 Глава 6

ABCD012345 % пробел проигнорирован


п =
2
» k=fopen('а.txt','wt'); % открыли файл
» fprintf(k,'%s\n%s','ABCD','012345'); % записали 2 строки
» fclose(k);
» k=fopen('a.txt','rt');
» [a n]=fscanf(k, '%s') % читаем все данные
a =
ABCD01234 5 % признак конца 1-й строки проигнорирован
п =
2 % прочитаны 2 элемента '

6.6. Форматные преобразования


в оперативной памяти
Все, что выше было сказано о работе функций fprinf и fscanf, можно по-
вторить для функций sprintf и sscanf. Если в первом случае в качестве
сторон, обменивающихся информацией, выступали массив, расположенный
в оперативной памяти, и файл, находящийся на диске, то во втором случае
вместо файла выступает строка, расположенная, как и массив, в оператив-
ной памяти:
[str errtxt] = sprintf('format',al,a2,...); % запись в строку str
[a n] = sscanf(str,'format',m); % чтение из строки str

Достаточно подробно работа этих функций рассматривалась в разд. 5.7.

6.7. Анализ ошибок


в файловых операциях
Обмен с файлом может завершиться ошибкой. Получить соответствующее
сообщение и узнать номер ошибки поможет функция ferror:
msg_err = ferror(f_id) ;
[msg_err num_err] = ferror(f_id);

Если последняя операция обмена с указанным файлом завершилась нор-


мально, то в символьную переменную m s g e r r записывается пустая строка,
а в качестве номера ошибки в переменную num_err заносится о. Если же
Работа с файлами 239

обнаружена нештатная ситуация, то числовой код ошибки будет отличен от


о. Для продолжения работы с данным файлом необходимо сбросить признак
аварийной ситуации:
[msg_err num_err] = f e r r o r ( f _ i d , ' c l e a r ' ) ;

6.8. Альтернативный доступ


к текстовым файлам
Функция textread (пример 6.29), которая позволяет читать данные из тек-
стового файла, отличается от функции fscanf в первую очередь тем, что
файл не нужно открывать. Обращение к файлу производится не по номеру
открытого заранее файла, а по его имени. Конечно, такой способ менее
удобен, т. к. переключение на другой файл данных связано с внесением
большего количества исправлений.
Вторая особенность функции textread заключается в том, что при чтении
из текстового файла, заполненного только числовой информацией, можно
не задавать строку форматных преобразований.
Наконец, функция textread обладает большей гибкостью, т. к. с помощью
дополнительной пары аргументов типа "параметр — значение" позволяет
пропускать строки комментариев, управлять выбором символов-разделите-
лей, регулировать размеры буфера обмена и др.
В простейшем случае у функции textread может быть задан единственный
аргумент.

! Пример 6.29. Чтение из текстового файла с помощью функции t e x t r e a d I


•.. , ;

» k=fopen('а.txt','wt'); % открыли текстовый файл


» fprintf(k,'%d ',1,2,3,4,5); % записали 5 чисел
» fclose(k);
» a=textread('a.txt')
a =
1 2 3 4 5

Замечание
В среде MATLAB 7 этот пример выполняется неправильно — вслед за пятым
числом извлекается несуществующий 0. Скорее всего это ошибка системы.

Для того чтобы читать не все данные, среди входных аргументов должны
находиться форматная строка и количество запрашиваемых чисел (при-
мер 6.30).
240 Глава 6

.Пример 6.30.
ное чтение из текстового файла с
шшшшшшшшшшшшшшшт .шмттшшш
» b=textread('a.txt','%d',2)
b -

Если задан формат, но не указано количество запрашиваемых чисел, то из


файла извлекаются все данные (пример 6.31).

b = t e x t r e a d ( ' a . t x t ' , '%d':


b=
1
2
3
4
5

Данные можно прочитать не только в массив, но и разбросать их по отдель-


ным переменным, но при этом каждой выходной переменной должен соот-
ветствовать свой форматный указатель (пример 6.32).

fо файла в отдельные: переменные


_ : • :

[Ы Ь2 ЬЗ Ь4 b51-textreadCa.txt 1 , %d %d %d
bl

b2 =

ЬЗ =

Ь4 =

Ь5 =
Работа с файлами 241

Приписав символ * к любому из перечисленных выше форматных указателей,


мы можем пропустить соответствующее числовое значение (пример 6.33).

[Пример 6.33. Чтение с пропуском ^ )


; _ • •

1
» [ Ы Ь З b 5 ] = t e x t r e a d ( ' a . t x t , ' % d % * d %d % * d % d ' )
Ы =
1
ЬЗ =
3
Ь5 =
5

Форматная строка может быть пуста, но при этом из текстового файла мож-
но прочитать только числовые данные (пример 6.34).

| Пример 6.34. Чтение из текстового файла с пустой форматной строкой

» b=textread('а.txt', " )
b=
1 2 3 4 5

С Замечание ^
В среде MATLAB 7 этот пример выполняется неправильно — вслед за пятым
числом извлекается несуществующий 0. Скорее всего это ошибка системы.

Форматные указатели, используемые в функции textread, немного отлича-


ются от тех, которые приводились в табл. 6.3. Их специфика отражена в
табл. 6.5.
Таблица 6.5

Формат Выполняемое преобразование


%п Целое или вещественное число преобразуется из символьного
формата в формат d o u b l e
%d Целое число со знаком преобразуется из символьного формата в
формат d o u b l e
%u Целое число без знака преобразуется из символьного формата в
формат d o u b l e
%f Вещественное число преобразуется из символьного формата в
формат d o u b l e
242 Глава 6

Таблица 6.5 (окончание)

Формат Выполняемое преобразование

%s Строка, завершающаяся белым пробелом, преобразуется в эле-


мент массива ячеек
%q Строка, возможно, заключенная в двойные кавычки, преобразуется
в элемент массива ячеек
%с Символ или белый пробел преобразуется в символьный массив
%[ s l s 2 . . . ] Строка из символов, входящих в заданный набор, преобразуется в
элемент массива ячеек. Чтение прерывается при выборе символа,
не входящего в заданный набор
% [A s l s 2 . . . ] Строка из символов, не входящих в заданный набор, преобразуется
в элемент массива ячеек. Чтение прерывается при выборе символа,
входящего в заданный набор

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


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

Таблица 6.6

Свойство Пояснение, возможные значения


'buf s i z e ' Максимальная длина строки в байтах (по умолчанию — 4096)
'commentstyle' Комментарий при выборке из текстового файла можно проиг-
норировать. Допустимые значения свойства:
• 'matlab': начало комментария в m-файлах — символ %;
• ' s h e l l ' : начало комментария — символ #;
• 'с': комментарий в С-программах — /* комментарий */;
• 'с++': начало комментария в программах на C++— символ//
'delimiter' Символ-разделитель элементов в считываемой строке
'emptyvalue' Способ передачи пропущенного значения
'endofline' Признак конца строки
Работа с файлами 243

Таблица6.6 (окончание)

Свойство Пояснение, возможные значения

'expchars' Символ десятичного порядка (по умолчанию — 'eEdD')


'headerlines' Количество пропускаемых строк в заголовке файла
'whitespace' Белые пробелы (по умолчанию — '\b\t')

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


примеров, иллюстрирующих особенности выборки данных из текстового
файла и использования дополнительных параметров "свойство — значение".
Прокомментируем эти слегка модифицированные примеры.
Пусть в текстовом файле с именем datal.dat должны находиться три строки-
записи, содержащие по пять полей со следующей информацией:
Sally Typel 12.34 45 Yes
Joe Type2 23.54 60 No
Bill Typel 34.90 12 No

Сформируем эти значения с помощью функции fprintf (пример 6.35).

i Пример 6.35. Формирование текстового файла j


'. .......s. ..,..,..;.....,...<..•....'.<,.... ..."
» k=fopen('datal.dat', 'wt') ;
» fprintf(k,'%s\n','Sally Typel 12.34 45 Yes');
» fprintf(k,'%s\n', 'Joe Type2 23.54 60 No');
» fprintf(k,'%s\n','Bill Typel 34.90 12 No');
» fclose(k);

А теперь попробуем извлечь информацию из этих полей в соответствующие


массивы. Разделителями данных в нашем случае являются белые пробелы, в
число которых входят настоящие пробелы между значениями полей и сим-
волы перехода на новую строку. Как только список форматных указателей
исчерпывается, он повторяется заново, а считываемые данные пополняют
следующие элементы наших массивов:
» [names,types,х,у,answer] = textread('datal.dat','%s%s%f%d%s')
names =
'Sally'
'Joe'
'Bill'
types =
'Typel1
244 Глава 6
'Туре2'
'Typel1
х =
12.3400
23.5400
34.9000
У =
45
60
12
answer =
'Yes'
'No'
'No'
» whos
Name Size Bytes Class
answer 3x1 194 cell array
names 3x1 204 cell array
types 3x1 210 cell array
x 3x1 24 double array
У 3x1 24 double array

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


по формату %s, поступает в массивы ячеек, а содержимое числовых полей —
в массивы типа double.
Теперь попробуем прочитать из содержимого того же файла только значе-
ния первого поля, пропуская все остальные данные каждой строки до при-
знака newline (пример 6.36).

—••••••• - • • .••———.—•— ''ЖИР


эе чтение из текстового файла !
Л
» [names]=textread('datal.dat','%s%*[ \п]')
names =
'Sally'
'Joe'
'Bill'

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


было бы оформить и с помощью следующей строки форматных указателей —
%s%*s%*f%*d%*s. Однако здесь продемонстрирован сравнительно редко ис-
Работа с файлами 245

пользуемый формат, который в данном примере звучит как "пропускать все


символы кроме символа newiine ('\n')". Обратите внимание на то, что фор-
матный указатель %s пропускает все белые пробелы, в т. ч. и символы пере-
хода на новую строку.
Заменим в предыдущем примере формат %s на указатель %с (пример 6.37).
; • ...
; Пример 6.37. Выборочное чтение символов из текстового файла ;
• „..'...............„I .'. .,..„.....,. ....;.....;;./..... J
» [names]=textread('datal.dat', '%с%*[Л\п]')
names =
S
J
В
» whos
Name Size Bytes Class
names 3x1 6 char array

После выборки первого символа строки ее остаток был проигнорирован до


появления символа newiine, затем список форматов повторился и из сле-
дующей строки был извлечен еще один символ. И все это повторилось еще
один раз (пример 6.38). В отличие от формата %s, по которому результаты
преобразования имели тип c e l l array, результат преобразования по форма-
ту %с имеет ТИП char array.
;•:•••- - ' •- ]
| Пример 6.38. Выборочное чтение из файла в переменные разных типов I

» [names,types,у,answer] = textread('datal.dat','%9c%5s%*f%2d%3s')
names =
Sally
Joe
Bill
types =
'Typel'
•Type2'
'Typel'
У =
45
60
12
246 Глава 6

answer =
'Yes'
'No'
'No'
» whos
Name Siz Bytes Class

answer 3x1 194 cell array


names 3x9 54 char array
types 3x1 210 cell array
У 3x1 24 double array

Интересен результат преобразования при чтении данных по формату, пред-


ставленному в примере 6.39.
ч
; - - '
\ Пример 6.39. Чтение текстового файла по заданному формату
» [names,typenum,х,у,answer]=textread('datal.dat','%sType%d%f%d%s']
names =
'Sally'
'Joe'
'Bill'
typenum -
1
2
1
x=
12.3400
23.5400
34.9000
У=
45
60
12
answer =
'Yes'
'No'
'No'
Работа с файлами 247
» whos
Name Size Bytes Class
answer 3x1 194 cell array
names 3x1 204 cell array
typenum 3x1 24 double array
X 3x1 24 double array
У 3x1 24 double array

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


привело к тому, что аналогичные символы из считываемой строки были из-
влечены в воздух. Зато следующий за ними символ был воспринят как целое
число и результат его преобразования по указателю %d был сохранен в эле-
ментах вектора typenum в формате double.
Содержимое текстового файла в естественном виде по строкам можно про-
читать так, как показано в примере 6.40.
•-•••••••• -

Пример 6.40. Построчное чтение текстового файла

» file = textreadCdatal.dat','%s','delimiter','\n','whitespace','')
file =
'Sally Typel 12.34 45 Yes1
'Joe Type2 23.54 60 No 1
'Bill Typel 34.90 12 No'
» whos
Name Size Bytes Class
file 3x1 338 cell array

Без подмены стандартных разделителей и белых пробелов результат чтения


был бы совершенно другим (пример 6.41).

| Пример 6.41. Ошибки при отсутствии обработки разделителей

>> file = textread('datal.dat','%s')


file =
'Sally'
'Typel 1
42. 34'
'45'
'Yes'
'Joe'

9 Зак 899
248 Глава 6
1
Туре2'
'23.54'
'60'
'No'
•Bill'
'Typel'
'34.90'
'12'
'No'
» whos
Name Size Bytes Class
file 15x1 1010 cell array

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


оказаться "пустые" поля (две подряд идущие запятые), можно воспользоваться
свойствами delimiter и emptyvaiue. Сформируем в текстовом файле с име-
нем data2.dat следующие строки:
1,2,3,4
5,6,7,8
9,10,11,12
При чтении по пустой форматной строке числа, разделенные запятыми, за-
полняют строку результирующей матрицы. Но как только встречается сим-
вол newiine, происходит переход к следующей строке результирующей мат-
рицы (пример 6.42).

Пример 6.42. Чтение текстового <

» data = textread('data2.dat','','delimiter',',')
data =
1 2 3 4
5 6 7 8
9 10 11 12

Однако стоит нам задать какой-либо форматный указатель, как возвращае-


мые значения заполняют вектор-столбец (пример 6.43).

! Пример 6.43. Чтение текстовых данных с разделителем (

» [data]=textread('data2.dat','%n','delimiter',',')
data =
1
Работа с файлами 249

2
3
4
5
6
7
8
9
10
11
12

Варьируя количество выходных аргументов и пропуская часть строки, мож-


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

» [coll, col2] = textreadCdata2.dat','%n%n%*[A\n]','delimiter',',')


coll =
1
5
9
col2 =
2
6
10

Сформируем третий текстовый файл с именем data3.dat, в котором заданы


некоторые пустые поля:

5,6,,8
9,10,11,,
Воспользуемся свойством emptyvalue, которое позволяет заменить отсутст-
вующие данные указанным значением (пример 6.45).
1
• • • • - •••••••••••• •••••
: • '••••

I Пример 6.4 эвого файла с пустыми полями


I
» data = textread('data3.dat', ",'delimiter',',','emptyvalue',NaN)
data =
1 NaN 3 4
250 Глава 6

5 6 NaN 8
9 10 11 NaN

( Замечание ^
В среде MATLAB 7 этот пример выполняется неправильно — в результате по-
является лишний пятый столбец, содержащий только элементы NaN. Мы сохра-
нили правильную выдачу, полученную в среде MATLAB 6.5. Скорее всего это
ошибка системы.

Обратите внимание на пропущенное значение в третьей строке файла


data3.dat — оно расположено между двумя запятыми. Между ними может
быть несколько пробелов, которые не оказывают никакого влияния на ре-
зультат преобразования. Но стоит нам удалить последнюю запятую, как из-
меняется результат преобразования последнего элемента матрицы (при-
мер 6.46).

Пример 6.46. Ошибочная трактовка последнего данного

5,6,,8
9,10,11,
» data = textread('data3.dat','','delimiter',',', 'emptyvalue',NaN)
data =
1 NaN 3 4
5 6 NaN 8
9 10 11 0

C~ Замечание ^
В среде MATLAB 7 и этот пример выполняется неправильно — вместо послед-
него нулевого элемента появляется NaN. Скорее всего это ошибка системы.

6.9. Числовые файлы с разделителями


MATLAB предлагает еще одну разновидность текстовых файлов, содержа-
щих последовательность чисел, отделяемых друг от друга символами-
разделителями. Создаются такие файлы с помощью функции dimwrite:
dlmwrite('file_name',a,dim);
В этом случае создается файл с именем f iie_name, и в него записываются
элементы числового массива в символьном представлении. Вслед за каждым
числовым значением в файл записывается символ dim. Если записываемый
Работа с файлами 251

массив двумерный, то его элементы выводятся в файл по строкам (при-


мер 6.47).

i Пример 6.47. Запись в числовой файл с разделителями • • • j


; .7. ~. ~. ........Г....."........ ................................: ;
» а = magic(4)
а=
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
» dlmwrite('dlm.txt',а, ';')

( Замечание ^
Данные в dim-файл записываются только один раз. Любая последующая за-
пись в файл с тем же именем уничтожает предыдущие данные.

Из созданного таким образом текстового файла, строки которого заверша-


ются символом LF (шестнадцатеричный код ОА), числовые данные читаются
с помощью функции dimread (пример 6.48), допускающей три формата об-
ращения:
b = dimread('file_name',dim);
b = dimread('file_read',dlm,n,m) ;
b = dimread('file_name',dim,[nl ml n2 m2]);

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


строка которых образует строку в выходном массиве. Во втором случае из
файла читается только фрагмент расположенной там матрицы. Левый верх-
ний угол этого фрагмента задается номером строки п и номером столбца m
(отсчет индексов ведется от о, а не от 1, как это принято во всех матричных
операциях MATLAB). В третьем формате вызова задается не только верхний
левый угол фрагмента, но и индексы правого нижнего угла.
• • • - •••••- •••• ••••••••• •• • щ

: Пример 6.48. Чтение из числового файла с разделителями

» b=dlmread( 'dlm.txt
b=
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
252 Глава 6
» c=dlmread('dim.txt',';',2,1)
с =
7 6 12
14 15 1
I 1
» d=dlmread( dlm.txt ,'; \ [0 1 2 3]
d =
2 3 13
11 10 8
7 6 12

При записи массива в файл с помощью функции dimwrite тоже имеется


возможность задания двух дополнительных индексов. Но речь идет не о вы-
воде части массива, а о месте расположения записываемых данных в файле
(пример 6.49).

» dimwrite('dim.txt', a, '; ' ,2,1)


» d=dlmread('dim.txt',';')
d =
0 0 0 0 0
0 0 0 0 0
0 16 2 3 13
0 5 11 10 8
0 9 7 6 12
0 4 14 15 1

Попытка задать отрицательные дополнительные индексы не расценивается


как ошибка, но они автоматически заменяются нулевыми значениями
(пример 6.50).

• ь •> Ь'У

» dimwrite('dim.txt', а, ', ',-2,-1)


» b=dlmread('dim.txt',',')
b =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
Работа с файлами 253

А для того; чтобы записать часть массива, можно воспользоваться обычным


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

ШШШШШЙЁЙШ " • • :

I Пример 6.51. Запись части массива в ЧИСЛОЕ АП


ШШ......:....;

» d l m w r i t e C d l m . t x t 1 , а (2: 4,2 : 3 ) , ' , ' )


» b=dlmread(•dim.txt',',')
Ь =
11 10
7 6
14 15

Если в dim-файл записываются вектор-строка или вектор-столбец, то число-


вые данные в файле имеют такую же организацию, как и исходные данные
(пример 6.52).

при записи в числовой •"• !

» а=[1 2 3 4 5 6] ;
» dlmwrite('dlm.txt',a,',')
» b=dlmread('dim.txt',',')
b =
1 2 3 4
» c=[l;2;3;4;5;6];
» dlmwrite('dim.txt', с,', ')
» d=dlmread('dim.txt',',')
d =
1
2
3
4
5
6
Глава 7

Иерархия графических объектов


и их свойства
Для более точного понимания материала настоящей главы нам потребуются
некоторые термины, присущие объектно-ориентированному подходу (ООП)
в современных системах программирования.
Понятие класс обычно связывают с некоторым шаблоном, по образцу и по-
добию которого строятся объекты — фрагменты программы, объединяющие
в себе данные и функции обработки этих данных. Объявление класса экви-
валентно объявлению структуры данных и описанию методов (функций) их
обработки. Когда создаются несколько объектов, порожденных данным
классом, то каждый объект получает личную оперативную память для хра-
нения своих данных. А функции их обработки при этом не дублируются.
Набор методов класса обслуживает данные любого объекта этого же класса
подобно тому, как стандартные функции получают разные аргументы и для
каждого из них выдают соответствующие результаты. Данные в каждом объ-
екте, порожденном одним и тем же классом, имеют одинаковые имена и,
чтобы различать, с какими аргументами должен проработать вызываемый
метод, он должен получить не только набор соответствующих параметров,
но и узнать, какой объект должен быть обслужен. В большинстве универ-
сальных алгоритмических языков вызов методов класса по форме отличает-
ся от вызова обычных подпрограмм и функций (табл. 7.1).

Таблица 7.1

Язык Вызов Вызов метода Пояснение


программи- функции
рования
Visual Basic z = f(х,у) z = Obj.F(a,b) Obj — имя объекта
pObj — указатель на
объект
F — имя метода
256 Глава 7

Таблица 7.1 (окончание)


Язык Вызов Вызов метода Пояснение
программи- функции
рования

C++ Builder Z = f (X, y); z = pOb]->F(a,b)


z = Obj.F(a,b);
Delphi z : = f ( x -y) z := Obj.F(a,b) ;

Может показаться, что объектно-ориентированный подход существенно


усложняет жизнь программиста. Однако первое впечатление обманчиво.
Поясним это на простом примере.: Пусть существует несколько классов, ка-
ждый из которых связан соответственно с обработкой точек, отрезков пря-
мых и окружностей. Предположим, в каждом классе определен свой метод
отображения соответствующей графической фигуры на экране дисплея.
А называются эти методы, представленные, естественно, разными програм-
мами, все одинаково — show. Насколько прозрачнее выглядит обращение к
отображению точки Р1(х,у), отрезка ы (xl f yi,x2,y2) и окружности
oi(xO,yO,R) по сравнению с традиционными вызовами соответствующих
функций:
putpixel(х,у); PI.Show;
Iine(xl,yl,x2,y2); LI.Show;
circle(xO,yO,R); 01.Show;

На самом деле, сообщая методу имя объекта, мы неявно передаем и сведения


об этом объекте, которые хранятся в соответствующих информационных
полях. Класс позволяет защитить нужные данные от внешнего воздействия,
проконтролировать правильность их задания, поскольку к определенной
информации доступ возможен только через методы типа set (установить
новое значение) и get (опросить текущее значение). Такой подход, несмот-
ря на дополнительные накладные расходы, позволяет предотвращать многие
ошибки и разрабатывать достаточно хорошо защищенные программы.
Для создания объекта с именем nam_obji, построенного в соответствии с
шаблоном класса nam_cis, в языке C++ прибегают к специальным функци-
ям — конструкторам, имена которых совпадают с именем класса:
nam_cls nam_objl;
nam_cls nam_obj1(al,a2);
nam_cls nam_objl(nam_obj2);
В первом случае конструктор создает объект, присваивая каким-то его дан-
ным значения по умолчанию, предусмотренные шаблоном класса. Во втором
Иерархия графических объектов и их свойства 257

случае конструктору передаются параметры (ai,a2), которые используются


для начальной инициализации некоторых данных объекта. В третьем случае
вновь создаваемый объект получает начальные значения, которые были ис-
пользованы при создании уже существующего объекта nam_obj2. Конструкто-
ры обладают двумя полезными свойствами. Во-первых, они могут проконтро-
лировать правильность выделения ресурсов (в первую очередь, оперативной
памяти), необходимых для нормального функционирования объекта. Во-
вторых, они не допустят инициализации параметров объекта непредусмотрен-
ными значениями. Именно поэтому прямой доступ к жизненно важным дан-
ным объекта запрещен, и для установки новых значений или опроса текущих
значений обычно прибегают к функциям-посредникам, которые в состоянии
проконтролировать правильность той или иной операции.
Еще одна важная процедура, называемая деструктором, используется в
ООП для автоматического уничтожения объекта после выхода из блока
программы, в которой объект был объявлен. Деструкторы создаются и, как
правило, вызываются автоматически, освобождая программиста от заботы
по возврату занятых ресурсов. В C++ имена деструкторов тоже совпадают с
именем класса, однако им предшествует символ - (~nam_cls).
Еще один термин, который появился немного позже и активно использует-
ся в системах визуального программирования, представляет наиболее харак-
терные свойства объекта (properties по терминологии C++). Большинство
из них определяет внешний вид объекта и/или управляет его функциониро-
ванием во время выполнения программы. К свойствам, присущим многим
объектам, относятся их габариты (ширина, высота), местоположение на эк-
ране или внутри некоторой области, цвет, характеристики используемого
шрифта (имя шрифта, высота символов, наклон, утолщение контура, под-
черкивания), видимость объекта, его активность или пассивность и др. Не-
которые из таких свойств могут изменяться на стадии проектирования про-
граммы, и пользователь способен визуально оценить принимаемые им
решения. Другие свойства оказываются доступными только на стадии вы-
полнения программы, причем некоторые из них можно только) опросить
(доступны только для чтения). Для работы со свойствами объектов^ в уни-
версальных системах программирования используются составные имена:
Labell->Caption="CKopocTb"; //так это выглядит в C++
Labe11.Caption:='Скорость'; (так это выглядит в Delphi}
В приведенном примере свойству Caption (заголовок) объекта с именем
Label 1 (метка) присваивается указанное символьное значение.
Объектно-ориентированное программирование никогда бы не состоялось,
если бы в нем не была предусмотрена процедура порождения новых классов
из уже существующих с наследованием данных, методов и разграничением
способа доступа к ним. На основе существующего класса А (базовый класс)
мы можем определить класс в (производный класс), который получит в на-
258 Глава 7

следство все или часть методов и данных базового класса. Производный


класс способен переопределить часть методов, доставшихся по наследству,
добавить новые данные и методы. Класс в может, в свою очередь, стать
"родителем" для следующего класса с, и таким образом легко построить ге-
неалогическое дерево некоторой программной системы. Язык C++ допуска-
ет порождение нового класса из двух или более базовых классов (множест-
венное наследование).
Для разграничения прав доступа к методам и данным в ООП введены такие
понятия, как общедоступные (public), защищенные (protected) и личные
(private) компоненты. К первой категории данных и методов могут обра-
щаться любые внешние функции. Данные и методы второй категории могут
быть переданы по наследству производному классу, но от других внешних
функций они защищены. Наконец, личные данные доступны только в том
классе, где они определены.
В системах визуального программирования появился еще один тип данных,
которые можно было бы назвать сверхдоступными (published). Он относится
к свойствам объекта, которые можно изменять на стадии конструирования
программы.
Изложенные выше соображения были приведены только для того, чтобы
подчеркнуть разницу между общепринятой терминологией и подходами к
реализации идей объектно-ориентированного программирования и вопло-
щением близких по содержанию, но все-таки иных по форме понятий в
системе MATLAB. Возможно, что причина расхождений лежит в истории
создания системы, которая сначала была реализована на Fortran — языке, в
котором до поры до времени никакого намека на объектно-ориентирован-
ный подход и не было.
Тем не менее термины класс и иерархия классов, наследование и переопределе-
ние функций, объекты и их свойства, события и реакция на них лежат в осно-
ве таких разделов MATLAB, как структуры данных, графика и организация
диалогового взаимодействия с пользователем. На рис. 7.1 приведена схема
классов, отражающая структуру и иерархию компонентов графического ин-
терфейса пользователя (Graphic User Interface, GUI).
Сразу же договоримся о переводе термина handle, лежащего в основе всех
манипуляций с объектами. В системе MATLAB им пользуются для иденти-
фикации различных объектов — открываемых файлов, графических окон,
координатных осей, линий графика, источников света, текстовых меток,
компонентов диалогового взаимодействия (кнопки, меню, окна ввода/
вывода). Значение того или иного handle можно отобразить как число, но
его величина для пользователя никакого смысла не несет. Исключение со-
ставляет handle единственного объекта, порожденного классом Root. Его
значение равно о, и именно его приходится указывать при опросе или уста-
новке каких-либо свойств данного объекта. Во всех остальных случаях роль
Иерархия графических объектов и их свойства 259

handle станет выполнять какая-либо переменная, значение которой будет


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

Рис. 7 . 1 . Иерархия классов GUI

В каждый конкретный момент выполнения программы выделяют три объек-


та — активное окно (текущая фигура), только что созданный или активизи-
рованный графический объект (текущий объект) и текущий график, вла-
дельцем которого считаются координатные оси. Независимо от способа
создания этих объектов можно обратиться к одной из системных функций:
gcf (от англ. get handle of the current figure), gco (от англ. get handle of the cur-
rent object) и gca (от англ. get handle of the current axes) для получения значе-
ния соответствующего указателя. Полученным значением можно пользо-
ваться при обращении к тому или иному методу обработки текущего окна,
объекта или графика.
Любой графический объект обладает определенным набором свойств, каж-
дое из которых имеет индивидуальное имя. Для опроса текущего или уста-
новки нового значения того или иного свойства предназначены функции
get И set:
v = get(h,'Свойство')
set(h,'Свойство',Новое_значение)

Первая из них возвращает значение указанного свойства, которым обладает


графический объект с указателем ь. Вторая изменяет текущее значение ука-
260 Глава 7

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


В качестве первого аргумента может выступать массив указателей, и тогда
соответствующая операция распространяется на группу объектов. Результат,
возвращаемый функцией get, в этом случае представлен массивом ячеек,
длина которого совпадает с длиной вектора h. В каждую ячейку результата
заносится значение указанного свойства для соответствующего объекта. Ар-
1
гумент 'свойство тоже может быть представлен не только скалярным зна-
чением, но и массивом ячеек, значение каждой из которых определяет имя
соответствующего свойства.
К функции get можно обратиться и с единственным аргументом — get(h).
В этом случае она возвращает значения всех свойств указанного объекта в
виде пар
имя = значение
Количество таких свойств довольно велико, так, например, у объекта типа
Axes их порядка 100. И большинством из них пользователь так или иначе
может управлять. Поэтому важно знать, как влияет то или иное свойство на
поведение соответствующего объекта.
Функция set тоже допускает различные варианты обращения, основная
идея которых заключается в задании множества пар "имя — значение":
set(h,'Свойство_1',Значение_1,'Свойство_2',Значение_2,...)
set(h,struct)
set(h,cell_name,cell_value)

В первом случае имена свойств и соответствующие им значения перечисля-


ются в виде списка переменной длины. Во втором случае аналогичные пары
задаются как значения полей структуры struct. В третьем случае группа
имен задается ячейками массива ceii_name, а соответствующий им набор
значений — ячейками массива c e i i v a i u e .

7.1. Объект Root


Корнем генеалогического дерева является класс Root, символизирующий
экран дисплея. Единственным объектом этого класса выступает наше при-
ложение, которое система создает автоматически. Полный перечень его
свойств и набор соответствующих им значений можно получить, обратив-
шись к функции get с нулевым указателем (пример 7.1).

I :;£*^££;*£Х?;:' Z ;
\ Пример 7.1. Свойства объекта Root ;
L , ,.;.. : :

get(0)
CallbackObject = []
Иерархия графических объектов и их свойства 261

CoimandWindowSize = [81 18]


CurrentFigure = [1]
Diary = off
DiaryFile = diary
Echo = off
FixedWidthFontName = Courier
Format = short
FormatSpacing = compact
Language = russian
M o n i t o i r P o s i t i o n s = [ 0 0 1024 768]
More = o f f
PointerLocation = [376 361]
PointerWindow = [0]
RecursionLimit = [500]
ScreenDepth = [32]
ScreenPixelsPerlnch = [116]
ScreenSize = [ 1 1 1024 768]
ShowHiddenHandles = off
Units = pixels
BeingDeleted = off
ButtonDownFcn =
Children = []
Clipping = on
CreateFcn =
DeleteFcn =
BusyAction = queue
HandleVisibility = on
HitTest = on
Interruptible = on
Parent = []
Selected = off
SelectionHighlight = on
Tag =
Type = root
UIContextMenu = []
UserData = []
Visible = on

Познакомимся более подробно с каждым из свойств объекта Root, тем бо-


лее, что многие из них будут повторяться и в других объектах.
262 Глава 7

Термин Callback довольно часто встречается в документации в сочетании


со словами object (объект) и Function (функция, сокращенно — Fen). Он
немного непривычен для программистов, работавших в визуальных средах,
но достаточно понятен по смыслу. Речь идет об объекте, который в данный
МОМеНТ ЯВИЛСЯ ИНИЦИаТОрОМ некоторого События (CallbackObject), И
функции-обработчике данного события (caiibackFunction). Префикс
callback, символизирующий "потусторонний вызов", просто означает, что
действия, связанные с возникшим событием и его обработкой, иницииру-
ются не выполняющейся программой, а поведением пользователя и средой,
управляющей прохождением задач. Значением свойства CallbackObject яв-
ляется указатель на активизированный таким образом объект, если тот в
данный момент существует.
Свойство commandwindowsize определяет текущие размеры (ширину и вы-
соту) командного окна в текущих единицах измерения длин (см. значение
свойства units).
Свойство currentFigure задает номер текущего графического окна (i в при-
веденном выше примере). В качестве такового может выступать только что
созданное графическое окно либо активизированное пользователем или
программой в результате выполнения одной из команд:
• figure (h) % — окно с указателем h выдвинуто на передний план;
• set (0, 'CurrentFigure',h) % — активизировано окно с указателем п.
Два следующих свойства — Diary и DiaryFiie — связаны с ведением прото-
кольного файла, в который могут быть записаны все шаги, фиксирующие
ваши операции во время сеанса, т. е. то, что дублируется в окне History
Command (История команд). Запись Diary=of f означает, что запись в про-
токольный файл отключена.
Свойство Echo, принимающее значение on (включено) или off (выклю-
чено), связано с возможностью повторения текста выполняемых команд
т-файла в командном окне. Во время отладки программы включение такого
эха может оказаться полезным.
Свойство FixedwidthFontName определяет имя моноширинного (ширина
всех символов одинакова) шрифта, который используется в командном ок-
не. В противоположность этому, Windows располагает большим количеством
пропорциональных шрифтов, в которых существуют узкие (например — 1,0
и широкие символы (например — w, щ). Их применение привело бы к пла-
вающей ширине колонок в выводимых таблицах.
Свойства Format и Formatspacing задают формат вывода числовых данных,
наличие или отсутствие дополнительных пустых строк. Выбор их значений
подробно обсуждался в гл. 2.
Иерархия графических объектов и их свойства 263

Свойство Language отражает текущий язык, установленный в операционной


системе.
Свойство MonitorPositions определяет координаты левого верхнего угла мо-
нитора (0, 0) и разрешение в пикселах, установленное в данный момент
(1024x768).
При выводе данных, объем которых превышает размеры экрана, полезно
установить режим постраничного вывода (моге=оп), который приостанавли-
вает работу программы после заполнения области вывода. Для продолжения
работы достаточно нажать любую клавишу. Такая возможность была преду-
смотрена еще в операционной системе MS-DOS.
Свойство pointerLocation фиксирует текущие координаты (х, у) курсора
мыши в графическом окне, указатель которого хранится в свойстве
Pointerwindow. В нашем примере этот указатель равен о (указатель на объ-
ект Root), т. к. ни одного графического окна еще не было создано.
В свойстве RecursionLimit задается глубина рекурсии, т. е. максимальное
количество вложенных обращений к m-функциям. По достижению указан-
ного лимита выполнение программы будет прервано.
В свойстве ScreenDepth хранится количество битов, отводимых для хране-
ния компонентов цвета одного пиксела.
Свойство screenPixeisPerinch определяет количество пикселов, приходя-
щихся на 1 дюйм. Им можно воспользоваться при масштабировании изо-
бражения на экране с другим разрешением.
Текущие координаты левого верхнего и правого нижнего углов объекта Root
в пикселах фиксируются в векторе Screensize (в нашем примере установ-
лено разрешение 1024x768, и объект занимает весь экран). При измерении
длин в пикселах левый верхний угол имеет координаты (1, 1), во всех ос-
тальных единицах измерения ему соответствует точка с нулевыми координа-
тами. Обратите внимание на положение начала координат в нижнем левом
углу, что характерно для всех математических учебников в отличие от эк-
ранной системы координат, к которой привыкли программисты.
Свойство showHiddenHandies определяет, надо ли показывать объекты, чьи
указатели помечены как скрытые. Это напоминает возможности таких обо-
лочек, как Norton Commander или ДИСКо Командир по отображению имен
файлов с атрибутом hidden (скрытый).
В свойстве units хранится установленная система измерения длин. Допус-
тимый набор значений представляют следующие константы:
• normalized — при этом левым нижним углом поля вывода считается точ-
ка с координатами (0, 0), правым верхним — точка с координатами
(1.0, 1.0). Приведением программных значений координат к фактическо-
му размеру окна занимается система. Это позволяет менять размеры гра-
фического окна с одновременной адаптацией поля графика;
264 Глава 7

П pixels — все размеры задаются в пикселах, и пересчет программных ко-


ординат в пикселы выполняется программой пользователя;
• inches — все размеры задаются в дюймах (1 дюйм = 2,54 см) и не меня-
ются при изменении габаритов графического окна;
• centimeters — все размеры задаются в сантиметрах и не меняются при
изменении габаритов графического окна;
• points — все размеры задаются в пунктах (1 пункт = 1/72 дюйма =
= 0,3528 мм) и не меняются при изменении габаритов графического
окна;
• characters — размеры измеряются в "буквах". За ширину "буквы" прини-
мается ширина буквы "х" шрифта, установленного в операционной системе
по умолчанию, а за высоту — расстояние между базовыми линиями двух
смежных строк текста. Выбор такой единицы измерения длины позволяет
создавать приложения, имеющие одинаковый внешний вид на компьюте-
рах, управляемых различными операционными системами.
По умолчанию для объекта Root измерения производятся в пикселах. Одна-
ко при построении графиков функций наиболее удобным является режим
normalized, который и установлен для объектов типа Figure по умолчанию.
Задание координат в единицах типа "сантиметры", "дюймы" или "пункты"
полезно при выводе на принтер документов, где должны быть соблюдены
абсолютные размеры.
Довольно многие свойства описаны в классе Root только для того, чтобы
быть переданными по наследству порожденным классам. Очень немногие из
них имеют смысл для самого объекта Root. Однако мы объясняем их назна-
чение с единственной целью — не повторять соответствующий материал в
последующих разделах.
Свойства BusyAction (действие в случае занятости) и interruptibie
(возможность прерывания) определяют режим обработки текущего события в
момент